Android Select the photo album and return the function of the implementation code

  • 2021-08-28 21:01:14
  • OfStack

First, due to the read and write operation, the permissions should be declared in AndroidManifest. xml:


<uses-permission android:name= " android.permission.READ_EXTERNAL_STORAGE "  /> 
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 

Call the system album:


private static final int CHOOSE_PHOTO=0; 
Intent intent = new Intent( " android.intent.action.GET_CONTENT " ); 
intent.setType( " image/* " ); 
startActivityForResult(intent, CHOOSE_PHOTO); 
[java] view plain copy
private static final int CHOOSE_PHOTO=0; 
Intent intent = new Intent("android.intent.action.GET_CONTENT"); 
intent.setType("image/*"); 
startActivityForResult(intent, CHOOSE_PHOTO); 

Then call back:


@Override 
  protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    switch (requestCode) { 
      case CHOOSE_PHOTO: 
        if (resultCode == RESULT_OK) { 
          Bitmap bitmap = null; 
          // Judge the version number of the mobile phone system  
          if (Build.VERSION.SDK_INT >= 19) { 
            //4.4 And above systems use this method to process pictures  
            bitmap = ImgUtil.handleImageOnKitKat(this, data);    //ImgUtil It is realized by itself 1 Tool classes  
          } else { 
            //4.4 The following system uses this method to process pictures  
            bitmap = ImgUtil.handleImageBeforeKitKat(this, data); 
          } 
          ImageView view = (ImageView) findViewById(R.id.personal_info_header_img); 
          view.setImageBitmap(bitmap); 
        } 
        break; 
      default: 
        break; 
    } 
  } 

@Override 
  protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    switch (requestCode) { 
      case CHOOSE_PHOTO: 
        if (resultCode == RESULT_OK) { 
          Bitmap bitmap = null; 
          // Judge the version number of the mobile phone system  
          if (Build.VERSION.SDK_INT >= 19) { 
            //4.4 And above systems use this method to process pictures  
            bitmap = ImgUtil.handleImageOnKitKat(this, data);    //ImgUtil It is realized by itself 1 Tool classes  
          } else { 
            //4.4 The following system uses this method to process pictures  
            bitmap = ImgUtil.handleImageBeforeKitKat(this, data); 
          } 
          ImageView view = (ImageView) findViewById(R.id.personal_info_header_img); 
          view.setImageBitmap(bitmap); 
        } 
        break; 
      default: 
        break; 
    } 
  } 

Encapsulate the related operations on images into an ImgUtil class for easy use:


import android.annotation.TargetApi; 
import android.content.ContentUris; 
import android.content.Context; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.database.Cursor; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.net.Uri; 
import android.preference.PreferenceManager; 
import android.provider.DocumentsContract; 
import android.provider.MediaStore; 
import android.text.TextUtils; 
import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
/** 
 * Created by wbin on 2016/3/22. 
 */ 
public class ImgUtil { 
  //4.4 And above systems use this method to process pictures  
  @TargetApi(19) 
  public static Bitmap handleImageOnKitKat(Context context, Intent data) { 
    String imagePath = null; 
    Uri uri = data.getData(); 
    if (DocumentsContract.isDocumentUri(context, uri)) { 
      // If it is document Type of Uri, Then pass the document id Deal with  
      String docId = DocumentsContract.getDocumentId(uri); 
      if ( " com.android.providers.media.documents " .equals(uri.getAuthority())) { 
        String id = docId.split( " : " )[1]; // Parse out the digital format id 
        String selection = MediaStore.Images.Media._ID +  " = "  + id; 
        imagePath = getImagePath(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection); 
      } else if ( " com.android.providers.downloads.documents " .equals(uri.getAuthority())) { 
        Uri contentUri = ContentUris.withAppendedId( 
            Uri.parse( " content://downloads/public_downloads " ), Long.valueOf(docId)); 
        imagePath = getImagePath(context, contentUri, null); 
      } 
    } else if ( " content " .equalsIgnoreCase(uri.getScheme())) { 
      // If not document Type of Uri, Is processed in the normal way  
      imagePath = getImagePath(context, uri, null); 
    } 
    return getImage(imagePath); 
  } 
  //4.4 The following system uses this method to process pictures  
  public static Bitmap handleImageBeforeKitKat(Context context, Intent data) { 
    Uri uri = data.getData(); 
    String imagePath = getImagePath(context, uri, null); 
    return getImage(imagePath); 
  } 
  public static String getImagePath(Context context, Uri uri, String selection) { 
    String path = null; 
    // Pass Uri And selection To get the real picture path  
    Cursor cursor = context.getContentResolver().query(uri, null, selection, null, null); 
    if (cursor != null) { 
      if (cursor.moveToFirst()) { 
        path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); 
      } 
      cursor.close(); 
    } 
    return path; 
  } 
  // Right bitmap Carry out mass compression  
  public static Bitmap compressImage(Bitmap image) { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// Mass compression method, here 100 Indicates that the compressed data is not compressed, and the compressed data is stored in baos Medium  
    int options = 100; 
    while (baos.toByteArray().length / 1024 > 100) {  // Loop to judge if the compressed picture is larger than 100kb, Greater than Continue Compression  
      baos.reset();// Reset baos Empty baos 
      image.compress(Bitmap.CompressFormat.JPEG, options, baos);// Compress here options% The compressed data is stored in the baos Medium  
      options -= 10;// Decrease every time 10 
    } 
    ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// Put the compressed data baos Deposit to ByteArrayInputStream Medium  
    Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// Put ByteArrayInputStream Data generation picture  
    return bitmap; 
  } 
  // Pass in the picture path and return the compressed bitmap 
  public static Bitmap getImage(String srcPath) { 
    if (TextUtils.isEmpty(srcPath)) // If the picture path is empty   Direct return  
      return null; 
    BitmapFactory.Options newOpts = new BitmapFactory.Options(); 
    // Start reading the picture. At this time, put options.inJustDecodeBounds  Set back true It's over  
    newOpts.inJustDecodeBounds = true; 
    Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// Return at this time bm Empty  
    newOpts.inJustDecodeBounds = false; 
    int w = newOpts.outWidth; 
    int h = newOpts.outHeight; 
    // Now there are more mainstream mobile phones 800*480 Resolution, so we set the height and width to  
    float hh = 800f;// Set the height here to 800f 
    float ww = 480f;// Here, the width is set to 480f 
    // Scaling ratio. Because it is a fixed scale, it is only high or wide 1 Data can be calculated  
    int be = 1;//be=1 Indicates non-scaling  
    if (w > h && w > ww) {// If the width is large, scale according to the fixed size of the width  
      be = (int) (newOpts.outWidth / ww); 
    } else if (w < h && h > hh) {// If the height is high, it will be scaled according to the fixed size of the width  
      be = (int) (newOpts.outHeight / hh); 
    } 
    if (be <= 0) 
      be = 1; 
    newOpts.inSampleSize = be;// Set the scale  
    // Re-read the picture, notice that the options.inJustDecodeBounds  Set back false It's over  
    bitmap = BitmapFactory.decodeFile(srcPath, newOpts); 
    return compressImage(bitmap);// After compressing the proportion, mass compression is carried out  
  } 
} 

import android.annotation.TargetApi; 
import android.content.ContentUris; 
import android.content.Context; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.database.Cursor; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.net.Uri; 
import android.preference.PreferenceManager; 
import android.provider.DocumentsContract; 
import android.provider.MediaStore; 
import android.text.TextUtils; 
import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
/** 
 * Created by wbin on 2016/3/22. 
 */ 
public class ImgUtil { 
  //4.4 And above systems use this method to process pictures  
  @TargetApi(19) 
  public static Bitmap handleImageOnKitKat(Context context, Intent data) { 
    String imagePath = null; 
    Uri uri = data.getData(); 
    if (DocumentsContract.isDocumentUri(context, uri)) { 
      // If it is document Type of Uri, Then pass the document id Deal with  
      String docId = DocumentsContract.getDocumentId(uri); 
      if ("com.android.providers.media.documents".equals(uri.getAuthority())) { 
        String id = docId.split(":")[1]; // Parse out the digital format id 
        String selection = MediaStore.Images.Media._ID + "=" + id; 
        imagePath = getImagePath(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection); 
      } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) { 
        Uri contentUri = ContentUris.withAppendedId( 
            Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId)); 
        imagePath = getImagePath(context, contentUri, null); 
      } 
    } else if ("content".equalsIgnoreCase(uri.getScheme())) { 
      // If not document Type of Uri, Is processed in the normal way  
      imagePath = getImagePath(context, uri, null); 
    } 
    return getImage(imagePath); 
  } 
  //4.4 The following system uses this method to process pictures  
  public static Bitmap handleImageBeforeKitKat(Context context, Intent data) { 
    Uri uri = data.getData(); 
    String imagePath = getImagePath(context, uri, null); 
    return getImage(imagePath); 
  } 
  public static String getImagePath(Context context, Uri uri, String selection) { 
    String path = null; 
    // Pass Uri And selection To get the real picture path  
    Cursor cursor = context.getContentResolver().query(uri, null, selection, null, null); 
    if (cursor != null) { 
      if (cursor.moveToFirst()) { 
        path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); 
      } 
      cursor.close(); 
    } 
    return path; 
  } 
  // Right bitmap Carry out mass compression  
  public static Bitmap compressImage(Bitmap image) { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// Mass compression method, here 100 Indicates that the compressed data is not compressed, and the compressed data is stored in baos Medium  
    int options = 100; 
    while (baos.toByteArray().length / 1024 > 100) {  // Loop to judge if the compressed picture is larger than 100kb, Greater than Continue Compression  
      baos.reset();// Reset baos Empty baos 
      image.compress(Bitmap.CompressFormat.JPEG, options, baos);// Compress here options% The compressed data is stored in the baos Medium  
      options -= 10;// Decrease every time 10 
    } 
    ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// Put the compressed data baos Deposit to ByteArrayInputStream Medium  
    Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// Put ByteArrayInputStream Data generation picture  
    return bitmap; 
  } 
  // Pass in the picture path and return the compressed bitmap 
  public static Bitmap getImage(String srcPath) { 
    if (TextUtils.isEmpty(srcPath)) // If the picture path is empty   Direct return  
      return null; 
    BitmapFactory.Options newOpts = new BitmapFactory.Options(); 
    // Start reading the picture. At this time, put options.inJustDecodeBounds  Set back true It's over  
    newOpts.inJustDecodeBounds = true; 
    Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// Return at this time bm Empty  
    newOpts.inJustDecodeBounds = false; 
    int w = newOpts.outWidth; 
    int h = newOpts.outHeight; 
    // Now there are more mainstream mobile phones 800*480 Resolution, so we set the height and width to  
    float hh = 800f;// Set the height here to 800f 
    float ww = 480f;// Here, the width is set to 480f 
    // Scaling ratio. Because it is a fixed scale, it is only high or wide 1 Data can be calculated  
    int be = 1;//be=1 Indicates non-scaling  
    if (w > h && w > ww) {// If the width is large, scale according to the fixed size of the width  
      be = (int) (newOpts.outWidth / ww); 
    } else if (w < h && h > hh) {// If the height is high, it will be scaled according to the fixed size of the width  
      be = (int) (newOpts.outHeight / hh); 
    } 
    if (be <= 0) 
      be = 1; 
    newOpts.inSampleSize = be;// Set the scale  
    // Re-read the picture, notice that the options.inJustDecodeBounds  Set back false It's over  
    bitmap = BitmapFactory.decodeFile(srcPath, newOpts); 
    return compressImage(bitmap);// After compressing the proportion, mass compression is carried out  
  } 
} 

In order to be compatible with the new and old versions of mobile phones, we made a judgment. If it is a mobile phone with 4.4 and above systems, we will call handleImageOnKitKat () method to process pictures, otherwise we will call handleImageBeforeKitKat () method to process pictures. The reason for this is that the Android system starts from version 4.4, and the selected pictures of photo albums no longer return the real Uri, but a packaged Uri, so if it is a mobile phone above version 4.4, it needs to analyze this Uri.

Of course, it is not recommended to directly use BitmapFactory. decodeFile (imgPath) to obtain bitmap after obtaining the picture path, because some pictures may be very large, and loading them directly into memory may cause the program to crash (I have encountered it.. You can directly load the original picture taken by the mobile phone with high pixels and try =. =). So it's better to compress the picture properly and then load it into memory (which is implemented in the above code).

Summarize


Related articles: