web-dev-qa-db-ja.com

Android 6(Marshmallow)のギャラリーからの画像

私のアプリケーションでは、画像をサーバーに渡すために、ゲラから画像を選択しようとしています。

コードはAndroid 5以下では問題なく機能していますが、Android 6の場合、画像情報を取得できません。取得したログトレース

:コードは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)
10
Harsh

このようにしてください...ボタンをクリックして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);
                    }

その後、Overrideメソッド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;
            }

その後

@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();
                    }

                }
21
Ashwani

実行時にユーザーに権限をリクエストする必要があると思います(これは、api 22から23で最も顕著な変更の1つです)。

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.
        }
    }
  }

問題が解決したかどうかをお知らせください。

5
mmark

同じ問題がありました。を使用してギャラリーから画像を選択した後、Imageviewに表示された画像

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

そして、URIからビットマップ画像をデコードします

ただし、将来の使用のためにURIを保存し、アプリを再度開いて、保存されたURIを再利用することはできませんでした。 URIからビットマップをデコードできませんでした。

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;
}
2
Abi

マシュマロのギャラリーから画像を取得するには、実行時にREAD_EXTERNAL_STORAGE権限を付与する必要があります。 AndroidバージョンMは、アプリケーションへのアクセス許可の付与方法を変更しました。

マシュマロの前は、必要なすべての権限が一度に付与され、それはインストール時に行われます。ただし、マシュマロでは、ユーザーはその許可が必要な場合にのみ許可を求められ、ユーザーはその許可を許可または拒否する必要があります。

以下の2つのリンクは、さらに役立ちます。リンク1はAndroidの公式ドキュメントからのものであり、リンク2は実際の例を使用してこの問題を説明したブログです。

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

2

これを試して

これは私が他の例で作成した簡単な方法です

  1. 必要な場所で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();
        }
    }
      }
    

注意

  1. フラグメントでは、activity.thisの代わりにgetactivity()を使用してください。
  2. android.Manifest.permission.READ_EXTERNAL_STORAGEが機能しない場合は、すべての場所でこれをManifest.permission.READ_EXTERNAL_STORAGEに変更します。
0
Sunil