Get/pick an image from Android's built-in Gallery app programmatically

前端 未结 19 1184
终归单人心
终归单人心 2020-11-22 00:49

I am trying to open an image / picture in the Gallery built-in app from inside my application.

I have a URI of the picture (the picture is located on the SD card).

相关标签:
19条回答
  • 2020-11-22 00:59

    Here is an update to the fine code that hcpl posted. but this works with OI file manager, astro file manager AND the media gallery too (tested). so i guess it will work with every file manager (are there many others than those mentioned?). did some corrections to the code he wrote.

    public class BrowsePicture extends Activity {
    
        //YOU CAN EDIT THIS TO WHATEVER YOU WANT
        private static final int SELECT_PICTURE = 1;
    
        private String selectedImagePath;
        //ADDED
        private String filemanagerstring;
    
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            ((Button) findViewById(R.id.Button01))
            .setOnClickListener(new OnClickListener() {
    
                public void onClick(View arg0) {
    
                    // in onCreate or any event where your want the user to
                    // select a file
                    Intent intent = new Intent();
                    intent.setType("image/*");
                    intent.setAction(Intent.ACTION_GET_CONTENT);
                    startActivityForResult(Intent.createChooser(intent,
                            "Select Picture"), SELECT_PICTURE);
                }
            });
        }
    
        //UPDATED
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (resultCode == RESULT_OK) {
                if (requestCode == SELECT_PICTURE) {
                    Uri selectedImageUri = data.getData();
    
                    //OI FILE Manager
                    filemanagerstring = selectedImageUri.getPath();
    
                    //MEDIA GALLERY
                    selectedImagePath = getPath(selectedImageUri);
    
                    //DEBUG PURPOSE - you can delete this if you want
                    if(selectedImagePath!=null)
                        System.out.println(selectedImagePath);
                    else System.out.println("selectedImagePath is null");
                    if(filemanagerstring!=null)
                        System.out.println(filemanagerstring);
                    else System.out.println("filemanagerstring is null");
    
                    //NOW WE HAVE OUR WANTED STRING
                    if(selectedImagePath!=null)
                        System.out.println("selectedImagePath is the right one for you!");
                    else
                        System.out.println("filemanagerstring is the right one for you!");
                }
            }
        }
    
        //UPDATED!
        public String getPath(Uri uri) {
            String[] projection = { MediaStore.Images.Media.DATA };
            Cursor cursor = managedQuery(uri, projection, null, null, null);
            if(cursor!=null)
            {
                //HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
                //THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
                int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();
                return cursor.getString(column_index);
            }
            else return null;
        }
    
    0 讨论(0)
  • 2020-11-22 01:01

    Assuming you have an image folder in your SD card directory for images only.

    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    // tells your intent to get the contents
    // opens the URI for your image directory on your sdcard
    intent.setType("file:///sdcard/image/*"); 
    startActivityForResult(intent, 1);
    

    Then you can decide with what you would like to do with the content back in your activity.

    This was an example to retrieve the path name for the image, test this with your code just to make sure you can handle the results coming back. You can change the code as needed to better fit your needs.

    protected final void onActivityResult(final int requestCode, final int
                         resultCode, final Intent i) {
        super.onActivityResult(requestCode, resultCode, i);
    
      // this matches the request code in the above call
      if (requestCode == 1) {
          Uri _uri = i.getData();
    
        // this will be null if no image was selected...
        if (_uri != null) {
          // now we get the path to the image file
         cursor = getContentResolver().query(_uri, null,
                                          null, null, null);
         cursor.moveToFirst();
         String imageFilePath = cursor.getString(0);
         cursor.close();
         }
       }
    

    My advice is to try to get retrieving images working correctly, I think the problem is the content of accessing the images on the sdcard. Take a look at Displaying images on sd card.

    If you can get that up and running, probably by the example supplying a correct provider, you should be able to figure out a work-around for your code.

    Keep me updated by updating this question with your progress. Good luck

    0 讨论(0)
  • 2020-11-22 01:01

    Retrieve a specific type of file

    This example will get a copy of the image.

    static final int REQUEST_IMAGE_GET = 1;
    
    public void selectImage() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(intent, REQUEST_IMAGE_GET);
        }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
            Bitmap thumbnail = data.getParcelable("data");
            Uri fullPhotoUri = data.getData();
            // Do work with photo saved at fullPhotoUri
            ...
        }
    }
    

    Open a specific type of file

    When running on 4.4 or higher, you request to open a file that's managed by another app

    static final int REQUEST_IMAGE_OPEN = 1;
    
    public void selectImage() {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.setType("image/*");
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
        startActivityForResult(intent, REQUEST_IMAGE_OPEN);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) {
            Uri fullPhotoUri = data.getData();
            // Do work with full size photo saved at fullPhotoUri
            ...
        }
    }
    

    Original source

    0 讨论(0)
  • 2020-11-22 01:05
    public class BrowsePictureActivity extends Activity {
    
        // this is the action code we use in our intent, 
        // this way we know we're looking at the response from our own action
        private static final int SELECT_PICTURE = 1;
    
        private String selectedImagePath;
    
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            ((Button) findViewById(R.id.Button01))
                    .setOnClickListener(new OnClickListener() {
    
                        public void onClick(View arg0) {
    
                            // in onCreate or any event where your want the user to
                            // select a file
                            Intent intent = new Intent();
                            intent.setType("image/*");
                            intent.setAction(Intent.ACTION_GET_CONTENT);
                            startActivityForResult(Intent.createChooser(intent,
                                    "Select Picture"), SELECT_PICTURE);
                        }
                    });
        }
    
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (resultCode == RESULT_OK) {
                if (requestCode == SELECT_PICTURE) {
                    Uri selectedImageUri = data.getData();
                    selectedImagePath = getPath(selectedImageUri);
                }
            }
        }
    
        /**
         * helper to retrieve the path of an image URI
         */
        public String getPath(Uri uri) {
                // just some safety built in 
                if( uri == null ) {
                    // TODO perform some logging or show user feedback
                    return null;
                }
                // try to retrieve the image from the media store first
                // this will only work for images selected from gallery
                String[] projection = { MediaStore.Images.Media.DATA };
                Cursor cursor = managedQuery(uri, projection, null, null, null);
                if( cursor != null ){
                    int column_index = cursor
                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                    cursor.moveToFirst();
                    return cursor.getString(column_index);
                }
                // this is our fallback here
                return uri.getPath();
        }
    
    }
    
    0 讨论(0)
  • 2020-11-22 01:06

    Additional to previous answers, if you are having problems with getting the right path(like AndroZip) you can use this:

      public String getPath(Uri uri ,ContentResolver contentResolver) {
            String[] projection = {  MediaStore.MediaColumns.DATA};
            Cursor cursor;
            try{
                cursor = contentResolver.query(uri, projection, null, null, null);
            } catch (SecurityException e){
                String path = uri.getPath();
                String result = tryToGetStoragePath(path);
                return  result;
            }
            if(cursor != null) {
                //HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
                //THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
                cursor.moveToFirst();
                int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
                String filePath = cursor.getString(columnIndex);
                cursor.close();
                return filePath;
            }
            else
                return uri.getPath();               // FOR OI/ASTRO/Dropbox etc
        }
    
        private String tryToGetStoragePath(String path) {
            int actualPathStart = path.indexOf("//storage");
            String result = path;
    
            if(actualPathStart!= -1 && actualPathStart< path.length())
                result = path.substring(actualPathStart+1 , path.length());
    
            return result;
        }
    
    0 讨论(0)
  • 2020-11-22 01:07

    hcpl's methods work perfectly pre-KitKat, but not working with the DocumentsProvider API. For that just simply follow the official Android tutorial for documentproviders: https://developer.android.com/guide/topics/providers/document-provider.html -> open a document, Bitmap section.

    Simply I used hcpl's code and extended it: if the file with the retrieved path to the image throws exception I call this function:

    private Bitmap getBitmapFromUri(Uri uri) throws IOException {
            ParcelFileDescriptor parcelFileDescriptor =
                 getContentResolver().openFileDescriptor(uri, "r");
            FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
            Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
            parcelFileDescriptor.close();
            return image;
    }
    

    Tested on Nexus 5.

    0 讨论(0)
提交回复
热议问题