来自Android 6图片库的图片(棉花糖)

时间:2021-10-31 00:21:00

In My Application I am trying to Pick image from galley, so as to pass that image to server.

在我的应用程序中,我试图从galley中选择映像,以便将该映像传递到服务器。

Code is working fine on Android 5 and below, but for Android 6 on Nexus 5 I am not able to get image information. Log trace which I got

代码在Android 5和下面都很好用,但是对于Nexus 5的Android 6,我无法获得图像信息。我得到的日志跟踪

Note: Code is working fine on Android 5 and below versions

注意:Android 5和以下版本的代码运行良好

11-06 12:27:43.736: W/System.err(31678): java.lang.SecurityException: Permission Denial: reading com.google.android.apps.photos.contentprovider.MediaContentProvider uri content://com.google.android.apps.photos.contentprovider/0/1/content%3A//media/external/images/media/19138/ACTUAL/94710853 from pid=31678, uid=10111 requires the provider be exported, or grantUriPermission()
11-06 12:27:43.757: W/System.err(31678): 
at android.os.Parcel.readException(Parcel.java:1599)
11-06 12:27:43.757: W/System.err(31678): 
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
11-06 12:27:43.757: W/System.err(31678): 
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
11-06 12:27:43.757: W/System.err(31678): 
at android.content.ContentProviderProxy.query(ContentProviderNative.java:421)
11-06 12:27:43.757: W/System.err(31678): 
at android.content.ContentResolver.query(ContentResolver.java:491)
11-06 12:27:43.757: W/System.err(31678): 
at android.content.ContentResolver.query(ContentResolver.java:434)
11-06 12:27:43.758: W/System.err(31678): 
at org.apache.cordova.file.ContentFilesystem.openCursorForURL(ContentFilesystem.java:258)
11-06 12:27:43.758: W/System.err(31678): 
at org.apache.cordova.file.ContentFilesystem.getFileMetadataForLocalURL(ContentFilesystem.java:169)
11-06 12:27:43.758: W/System.err(31678): 
at org.apache.cordova.file.FileUtils.getFileMetadata(FileUtils.java:822)
11-06 12:27:43.758: W/System.err(31678): 
at org.apache.cordova.file.FileUtils.access$500(FileUtils.java:52)
11-06 12:27:43.758: W/System.err(31678): 
at org.apache.cordova.file.FileUtils$15.run(FileUtils.java:394)
11-06 12:27:43.758: W/System.err(31678): 
at org.apache.cordova.file.FileUtils$25.run(FileUtils.java:551)
11-06 12:27:43.758: W/System.err(31678): 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
11-06 12:27:43.758: W/System.err(31678): 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
11-06 12:27:43.758: W/System.err(31678): 
at java.lang.Thread.run(Thread.java:818)

5 个解决方案

#1


20  

DO it this way... on Button Click check for SDK Version

这样做……在按钮上单击“检查SDK版本”

 if (Build.VERSION.SDK_INT >= 23){
    // Here, thisActivity is the current activity
                        if (ContextCompat.checkSelfPermission(MainActivity.this,
                                Manifest.permission.READ_EXTERNAL_STORAGE)
                                != PackageManager.PERMISSION_GRANTED) {

                            // Should we show an explanation?
                            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                                    Manifest.permission.READ_EXTERNAL_STORAGE)) {

                                // Show an expanation to the user *asynchronously* -- don't block
                                // this thread waiting for the user's response! After the user
                                // sees the explanation, try again to request the permission.

                            } else {

                                // No explanation needed, we can request the permission.

                                ActivityCompat.requestPermissions(MainActivity.this,
                                        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                                        MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);

                                // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
                                // app-defined int constant. The callback method gets the
                                // result of the request.
                            }
                        }else{
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                                    MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
                        }
                    }else {

                        Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                        photoPickerIntent.setType("image/*");
                        startActivityForResult(photoPickerIntent, SELECT_PHOTO);
                    }

after that in Override method onRequestPermissionsResult write this code:

在覆盖方法onRequestPermissionsResult中写入以下代码:

 case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
                    Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                    photoPickerIntent.setType("image/*");
                    startActivityForResult(photoPickerIntent, SELECT_PHOTO);
                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

After that

在那之后

@Override
    protected void onActivityResult(int reqCode, int resultCode, Intent data) {
        super.onActivityResult(reqCode, resultCode, data);

        switch (reqCode) {
 case SELECT_PHOTO:
                if (resultCode == RESULT_OK) {
                    try {
                        final Uri imageUri = data.getData();
                        final InputStream imageStream = getContentResolver().openInputStream(imageUri);
                        final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
                        contactimage.setImageBitmap(selectedImage);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }

                }

#2


5  

I believe you'll need to request the permissions to the user at runtime (this is one of the most noticeable changes from api 22 to 23).

我相信您将需要在运行时向用户请求权限(这是从api 22到23最明显的变化之一)。

You can try this snippet, extracted from the Android Developers permission page

您可以尝试从Android开发人员权限页面提取的这个代码片段

if (Build.VERSION.SDK_INT >= 23){    
// Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(thisActivity,
                    Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                Manifest.permission.READ_EXTERNAL_STORAGE)) {

            // Show an expanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.

        } else {

            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(thisActivity,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);

            // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    }
  }

Let me know if it helped.

如果有用就告诉我。

#3


3  

I had the same issue. The image showed in Imageview after picking the image from gallery using

我也有同样的问题。使用Imageview从图库中选取图像后显示的图像

Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, videoIdentifier);

and decoding the bitmap image from the URI

并从URI解码位图图像

But saving the URI for future use and reopening the app and reusing the saved URI not worked. Couldn't decoding the bitmap from URI.

但是保存URI以供将来使用,重新打开应用程序并重用保存的URI无效。无法从URI解码位图。

I solved the issue by extracting the original content uri from URI path

我通过从uri路径中提取原始内容uri解决了这个问题

public String RemoveUnwantedString(String pathUri){
    //pathUri = "content://com.google.android.apps.photos.contentprovider/-1/2/content://media/external/video/media/5213/ORIGINAL/NONE/2106970034"
    String[] d1 = pathUri.split("content://");
    for (String item1:d1) {
        if (item1.contains("media/")) {
            String[] d2 = item1.split("/ORIGINAL/");
            for (String item2:d2) {
                if (item2.contains("media/")) {
                    pathUri = "content://" + item2;
                    break;
                }
            }
            break;
        }
    }
    //pathUri = "content://media/external/video/media/5213"
    return pathUri;
}

#4


2  

In order to get image from Gallery in Marshmallow, You are required to grant READ_EXTERNAL_STORAGE permission at run time. Android Version M has changed the way permissions are granted to applications.

为了从Marshmallow中的Gallery获得映像,您需要在运行时授予READ_EXTERNAL_STORAGE权限。Android版本M改变了授予应用程序权限的方式。

Before Marshmallow, all required permissions are granted at once and that is at the time of installation. But in Marshmallow, User is asked for permission at the time only if that permission is required, and the User has to either Allow or Deny that permission.

在Marshmallow之前,同时授予所有必需的权限,这是在安装时。但是在Marshmallow中,用户只在需要权限时才被请求权限,并且用户必须允许或拒绝该权限。

Below two links will help you more. Link 1 is from official documentation of Android, and Link 2 is a blog which has explained this issue with a working example.

下面的两个链接将对你有更大的帮助。链接1来自Android的官方文档,链接2是一个博客,它用一个工作示例解释了这个问题。

Link1: http://developer.android.com/training/permissions/requesting.html

Link1:http://developer.android.com/training/permissions/requesting.html

Link2: http://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en

Link2:http://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en

#5


0  

Try this

This is the simple method that i have created with other examples

这是我用其他例子创建的简单方法

  1. call CHECKGALLERYPERMISSION() method where you want and paste the code inside method

    调用CHECKGALLERYPERMISSION()方法,并将代码粘贴到方法内部

     private void CHECKGALLERYPERMISSION()
     {
        int MY_READ_PERMISSION_REQUEST_CODE =1 ;
        int PICK_IMAGE_REQUEST = 2;
        if (ContextCompat.checkSelfPermission(YourActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED)
        {
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
        }
        else
        {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            {
                requestPermissions(
                        new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
                        MY_READ_PERMISSION_REQUEST_CODE);
            }
            else
            {
            }
        }
      }
      @Override
      public void onRequestPermissionsResult(int requestCode, String[] 
      permissions, int[] grantResults) {
       if (requestCode == MY_READ_PERMISSION_REQUEST_CODE
            && grantResults[0] == PackageManager.PERMISSION_GRANTED)
       {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
    }
       }
      @Override
       public void onActivityResult(int requestCode, int resultCode, Intent data)
      {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null)
    {
        Uri uri = data.getData();
        try
        {
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(YourActivity.this.getContentResolver(), uri);
            imageview.setImageBitmap(bitmap);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
      }
    

Note

  1. in fragement use getactivity() instead of activity.this
  2. 在fragement使用getactivity()而不是activity.this。
  3. if android.Manifest.permission.READ_EXTERNAL_STORAGE not working change this to Manifest.permission.READ_EXTERNAL_STORAGE in all places
  4. 如果android.Manifest.permission。READ_EXTERNAL_STORAGE无效,将其更改为Manifest.permission。READ_EXTERNAL_STORAGE在所有地方

#1


20  

DO it this way... on Button Click check for SDK Version

这样做……在按钮上单击“检查SDK版本”

 if (Build.VERSION.SDK_INT >= 23){
    // Here, thisActivity is the current activity
                        if (ContextCompat.checkSelfPermission(MainActivity.this,
                                Manifest.permission.READ_EXTERNAL_STORAGE)
                                != PackageManager.PERMISSION_GRANTED) {

                            // Should we show an explanation?
                            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                                    Manifest.permission.READ_EXTERNAL_STORAGE)) {

                                // Show an expanation to the user *asynchronously* -- don't block
                                // this thread waiting for the user's response! After the user
                                // sees the explanation, try again to request the permission.

                            } else {

                                // No explanation needed, we can request the permission.

                                ActivityCompat.requestPermissions(MainActivity.this,
                                        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                                        MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);

                                // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
                                // app-defined int constant. The callback method gets the
                                // result of the request.
                            }
                        }else{
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                                    MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
                        }
                    }else {

                        Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                        photoPickerIntent.setType("image/*");
                        startActivityForResult(photoPickerIntent, SELECT_PHOTO);
                    }

after that in Override method onRequestPermissionsResult write this code:

在覆盖方法onRequestPermissionsResult中写入以下代码:

 case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
                    Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                    photoPickerIntent.setType("image/*");
                    startActivityForResult(photoPickerIntent, SELECT_PHOTO);
                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

After that

在那之后

@Override
    protected void onActivityResult(int reqCode, int resultCode, Intent data) {
        super.onActivityResult(reqCode, resultCode, data);

        switch (reqCode) {
 case SELECT_PHOTO:
                if (resultCode == RESULT_OK) {
                    try {
                        final Uri imageUri = data.getData();
                        final InputStream imageStream = getContentResolver().openInputStream(imageUri);
                        final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
                        contactimage.setImageBitmap(selectedImage);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }

                }

#2


5  

I believe you'll need to request the permissions to the user at runtime (this is one of the most noticeable changes from api 22 to 23).

我相信您将需要在运行时向用户请求权限(这是从api 22到23最明显的变化之一)。

You can try this snippet, extracted from the Android Developers permission page

您可以尝试从Android开发人员权限页面提取的这个代码片段

if (Build.VERSION.SDK_INT >= 23){    
// Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(thisActivity,
                    Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                Manifest.permission.READ_EXTERNAL_STORAGE)) {

            // Show an expanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.

        } else {

            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(thisActivity,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);

            // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    }
  }

Let me know if it helped.

如果有用就告诉我。

#3


3  

I had the same issue. The image showed in Imageview after picking the image from gallery using

我也有同样的问题。使用Imageview从图库中选取图像后显示的图像

Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, videoIdentifier);

and decoding the bitmap image from the URI

并从URI解码位图图像

But saving the URI for future use and reopening the app and reusing the saved URI not worked. Couldn't decoding the bitmap from URI.

但是保存URI以供将来使用,重新打开应用程序并重用保存的URI无效。无法从URI解码位图。

I solved the issue by extracting the original content uri from URI path

我通过从uri路径中提取原始内容uri解决了这个问题

public String RemoveUnwantedString(String pathUri){
    //pathUri = "content://com.google.android.apps.photos.contentprovider/-1/2/content://media/external/video/media/5213/ORIGINAL/NONE/2106970034"
    String[] d1 = pathUri.split("content://");
    for (String item1:d1) {
        if (item1.contains("media/")) {
            String[] d2 = item1.split("/ORIGINAL/");
            for (String item2:d2) {
                if (item2.contains("media/")) {
                    pathUri = "content://" + item2;
                    break;
                }
            }
            break;
        }
    }
    //pathUri = "content://media/external/video/media/5213"
    return pathUri;
}

#4


2  

In order to get image from Gallery in Marshmallow, You are required to grant READ_EXTERNAL_STORAGE permission at run time. Android Version M has changed the way permissions are granted to applications.

为了从Marshmallow中的Gallery获得映像,您需要在运行时授予READ_EXTERNAL_STORAGE权限。Android版本M改变了授予应用程序权限的方式。

Before Marshmallow, all required permissions are granted at once and that is at the time of installation. But in Marshmallow, User is asked for permission at the time only if that permission is required, and the User has to either Allow or Deny that permission.

在Marshmallow之前,同时授予所有必需的权限,这是在安装时。但是在Marshmallow中,用户只在需要权限时才被请求权限,并且用户必须允许或拒绝该权限。

Below two links will help you more. Link 1 is from official documentation of Android, and Link 2 is a blog which has explained this issue with a working example.

下面的两个链接将对你有更大的帮助。链接1来自Android的官方文档,链接2是一个博客,它用一个工作示例解释了这个问题。

Link1: http://developer.android.com/training/permissions/requesting.html

Link1:http://developer.android.com/training/permissions/requesting.html

Link2: http://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en

Link2:http://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en

#5


0  

Try this

This is the simple method that i have created with other examples

这是我用其他例子创建的简单方法

  1. call CHECKGALLERYPERMISSION() method where you want and paste the code inside method

    调用CHECKGALLERYPERMISSION()方法,并将代码粘贴到方法内部

     private void CHECKGALLERYPERMISSION()
     {
        int MY_READ_PERMISSION_REQUEST_CODE =1 ;
        int PICK_IMAGE_REQUEST = 2;
        if (ContextCompat.checkSelfPermission(YourActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED)
        {
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
        }
        else
        {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            {
                requestPermissions(
                        new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
                        MY_READ_PERMISSION_REQUEST_CODE);
            }
            else
            {
            }
        }
      }
      @Override
      public void onRequestPermissionsResult(int requestCode, String[] 
      permissions, int[] grantResults) {
       if (requestCode == MY_READ_PERMISSION_REQUEST_CODE
            && grantResults[0] == PackageManager.PERMISSION_GRANTED)
       {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
    }
       }
      @Override
       public void onActivityResult(int requestCode, int resultCode, Intent data)
      {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null)
    {
        Uri uri = data.getData();
        try
        {
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(YourActivity.this.getContentResolver(), uri);
            imageview.setImageBitmap(bitmap);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
      }
    

Note

  1. in fragement use getactivity() instead of activity.this
  2. 在fragement使用getactivity()而不是activity.this。
  3. if android.Manifest.permission.READ_EXTERNAL_STORAGE not working change this to Manifest.permission.READ_EXTERNAL_STORAGE in all places
  4. 如果android.Manifest.permission。READ_EXTERNAL_STORAGE无效,将其更改为Manifest.permission。READ_EXTERNAL_STORAGE在所有地方