How retrieve image from gallery?

2019-09-09 17:34发布

问题:

I am trying to retrieve an image from gallery in Android but unfortunately it failed with permission.

this is my code:

public void loadImagefromGallery(View view) {
    // Create intent to Open Image applications like Gallery, Google Photos
    Intent galleryIntent = new Intent(Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    // Start the Intent
    startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    try {
        // When an Image is picked
        if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK
                && null != data) {
            // Get the Image from data

            Uri selectedImage = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };

            // Get the cursor
            Cursor cursor = getContentResolver().query(selectedImage,
                    filePathColumn, null, null, null);
            // Move to first row
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            Toast.makeText(this, "Image picked" +
                            columnIndex,
                    Toast.LENGTH_LONG).show();

        } else {
            Toast.makeText(this, "You haven't picked Image",
                    Toast.LENGTH_LONG).show();
        }
    } catch (Exception e) {
        Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
                .show();
        Log.d("ERROR",e.getMessage());
    }

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.melas.app_3" >

   <uses-permission android:name="android.permission.INTERNET" />
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
   <uses-permission android:name="android.permission.CALL_PHONE" />
   <uses-permission android:name="android.permission.READ_PHONE_STATE" />

   <application
     android:name=".StartApps"
     android:allowBackup="true"
     android:icon="@mipmap/ic_launcher"
     android:label="@string/app_name"
     android:supportsRtl="true"
     android:theme="@style/Theme.AppCompat.NoActionBar" >
<meta-data
    android:name="com.parse.APPLICATION_ID"
    android:value="" />
<meta-data
    android:name="com.parse.CLIENT_KEY"
    android:value="" />

<activity
    android:name=".MainActivity"
    android:label="@string/app_name">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity android:name=".Register" >
</activity>
<activity android:name=".Register2" >
</activity>
<activity android:name=".LoginActivity" >
</activity>

Error :

12-28 15:15:07.100 1847-1859/android.process.media E/DatabaseUtils: Writing exception to parcel
12-28 15:15:07.100 1847-1859/android.process.media E/DatabaseUtils: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/28 from pid=13141, uid=10060 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
12-28 15:15:07.100 1847-1859/android.process.media E/DatabaseUtils:     at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:605)
12-28 15:15:07.100 1847-1859/android.process.media E/DatabaseUtils:     at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:480)
12-28 15:15:07.100 1847-1859/android.process.media E/DatabaseUtils:     at android.content.ContentProvider$Transport.query(ContentProvider.java:211)
12-28 15:15:07.100 1847-1859/android.process.media E/DatabaseUtils:     at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
12-28 15:15:07.100 1847-1859/android.process.media E/DatabaseUtils:     at android.os.Binder.execTransact(Binder.java:453)

回答1:

I'd suggest you drop the storage permission requests and use ACTION_GET_CONTENT.

The usage would be some like this:

    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    startActivity(Intent.createChooser(intent, "Select image"));

This way is super awesome because your app doesn't any storage permission at all. Only if you target API < 18 you'll need to request the permission. In such case, you can use maxSdkVersion=18 in your manifest to request the permission only when there is no other way.



回答2:

whole AndroidManifest.xml :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.melas.app_3" >

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<application
    android:name=".StartApps"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/Theme.AppCompat.NoActionBar" >
    <meta-data
        android:name="com.parse.APPLICATION_ID"
        android:value="" />
    <meta-data
        android:name="com.parse.CLIENT_KEY"
        android:value="" />

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".Register" >
    </activity>
    <activity android:name=".Register2" >
    </activity>
    <activity android:name=".LoginActivity" >
    </activity>
</application>



回答3:

It works but I try to retrieve filename to put on parse....

public void loadImagefromGallery(View view) {
     Intent galleryIntent = new Intent(Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    // Start the Intent
    startActivityForResult(galleryIntent, RESULT_LOAD_IMG);


}
 @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data); 
txttest = (TextView)findViewById(R.id.textViewtest);
        ImageView ig=(ImageView)findViewById(R.id.imageViewTest);


      try {
            // When an Image is picked
            if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK
                    && null != data) {
                // Get the Image from data

                Uri selectedImage = data.getData();
                String[] filePathColumn = { MediaStore.Images.Media.DATA };

                // Get the cursor
                Cursor cursor = getContentResolver().query(selectedImage,
                        filePathColumn, null, null, null);
                // Move to first row
                cursor.moveToFirst();

                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);

                Bitmap bitmap = BitmapFactory.decodeFile(selectedImage.toString());
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
                byte[] image = stream.toByteArray();
                Glide.with(this)
                        .load(selectedImage)
                        .into(ig);

                Toast.makeText(this, "Image picked" +
                               selectedImage,
                        Toast.LENGTH_LONG).show();

//txttest.setText();
                } else {
                    Toast.makeText(this, "You haven't picked Image",
                            Toast.LENGTH_LONG).show();
                }
            } catch (Exception e) {
                Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
                        .show();
                Log.d("ERROR", e.getMessage());
            }


    }