Issue 0001-Cannot select multiple photos in Android system album

Issue 0001-Cannot select multiple photos in Android system album

Select multiple

  • Android: I don t know if it s okay to select multiple pictures in system album

    • After experimenting, you can choose multiple photos, but the problem is: There is no way to limit the number that can be selected, and most scenes are now at most N photos.
    • The types returned by getData() and getClipData() are different. If the addresses of multiple pictures are returned, they must be processed by getClipData(). At this time, getData() returns null. The type returned by getClipData() can be understood as a list of the type returned by getData()
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
          try {
              Intent intent = new Intent();
              intent.setType("image/*");
              intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
              intent.setAction(Intent.ACTION_GET_CONTENT);
              startActivityForResult(Intent.createChooser(intent, "Select Picture"), REQUEST_CODE_IMAGE);
          }catch(Exception e){
              Intent photoPickerIntent = new Intent(this, XYZ.class);
              startActivityForResult(photoPickerIntent, REQUEST_CODE_IMAGE);
          }
      } else {
          Intent photoPickerIntent = new Intent(this, XYZ.class);
          startActivityForResult(photoPickerIntent, REQUEST_CODE_IMAGE);
      }
      
      protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
          Uri uri;
          List<String> fileList = new ArrayList<>();
          if (requestCode == REQUEST_CODE_IMAGE && data != null) {
              ClipData imageNames = data.getClipData();
              if (imageNames != null) {
                  for (int i = 0; i < imageNames.getItemCount(); i++) {
                      Uri imageUri = imageNames.getItemAt(i).getUri();
                      fileList.add(imageUri.toString());
                  }
              } else {
                  uri = data.getData();
                  fileList.add(uri.toString());
              }
          } else {
              uri = data.getData();
              fileList.add(uri.toString());
          }
          if(!fileList.isEmpty()){
              for(String item:fileList){
                  Log.d("testCreateFeedback","iamge item: " + item);
              }
          }
      }
       
  • Choose Android local pictures and know your own open source library

  • Let's take a look at Zhihu's open source image selection library

Open camera and photo album

Open album

private void choosePicture(){
  //select single image via original api
  //
  // Intent.ACTION_PICK:
  //  , ;
  //  URI , ;
  // Intent.ACTION_GET_CONTENT:
  //  , 
  //  URI , ;
  //Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
  Intent intent = new Intent(Intent.ACTION_PICK);
  intent.setType("image/*");
  startActivityForResult(intent, REQUEST_CODE_IMAGE);
}
 

Get the image path according to Uri

  1. Query the database directly
    public static String gainImagePathFromUri(Context context, Uri imageUri) {
        String[] filePathColumn = {MediaStore.Images.Media.DATA};
        Cursor cursor = context.getContentResolver().query(imageUri,
                filePathColumn, null, null, null);//Uri 
        cursor.moveToFirst();
        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String path = cursor.getString(columnIndex);  //
        cursor.close();
        return path;
    }
     
  2. General method of obtaining file path based on URI, not limited to pictures
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public static String gainPathFromUri(final Context context, final Uri uri) {
        //DocumentProvider
        if (Platform.hasKitKat() && DocumentsContract.isDocumentUri(context, uri)) {
            //ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
    
                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
    
                //TODO handle non-primary volumes
            } else if (isDownloadsDocument(uri)) { //DownloadsProvider
    
                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
    
                return getDataColumn(context, contentUri, null, null);
            } else if (isMediaDocument(uri)) { //MediaProvider
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
    
                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }
    
                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };
    
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) { //MediaStore (and general)
            return getDataColumn(context, uri, null, null);
        } else if ("file".equalsIgnoreCase(uri.getScheme())) { //File
            return uri.getPath();
        }
    
        return null;
    }
    
    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {
    
        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };
    
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int columnIndex = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(columnIndex);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }
    
    
    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }
    
    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }
    
    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }