簡體   English   中英

遇到“運行時” Android WRITE_EXTERNAL_STORAGE權限

[英]Struggling with a 'run-time' Android WRITE_EXTERNAL_STORAGE permission

我有一個片段。 在此片段中,當用戶選擇選擇一張照片並將該照片導入我的應用程序時,我使用onActivityResult()捕獲意圖:

Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CAMERA) {
        if (resultCode == Activity.RESULT_OK) {
            Uri takenPhotoUri = ImageUtils.getInstance().getPhotoFileUri(getContext(), imageFileName);
            actionsListener.onSignalPhotoSelected(takenPhotoUri.getPath());
        }
    }

    if (requestCode == REQUEST_GALLERY && resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {

        Uri fileUri = data.getData();
        String path = null;
        File photoFile = new File(fileUri.toString());

        // Differentiate between SDK versions
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            // Code for Android 6 and > goes here
            if(getActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                //showPermissionDialog(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);
                ActivityCompat.requestPermissions(getActivity(), new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);
            }
            try {
                ParcelFileDescriptor parcelFileDesc = getActivity().getContentResolver().openFileDescriptor(fileUri, "r");
                FileDescriptor fileDesc = parcelFileDesc.getFileDescriptor();
                Bitmap photo = BitmapFactory.decodeFileDescriptor(fileDesc);
                path = MediaStore.Images.Media.insertImage(getContext().getContentResolver(), photo, "temp", null);
                parcelFileDesc.close();

                // DRY!!
                photoFile = ImageUtils.getInstance().getFromMediaUri(getContext(), getContext().getContentResolver(), Uri.parse(path));

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        else {
            // DRY!!
            photoFile = ImageUtils.getInstance().getFromMediaUri(getContext(), getContext().getContentResolver(), data.getData());
        }
        if(photoFile != null) {
            actionsListener.onSignalPhotoSelected(Uri.fromFile(photoFile).getPath());
        }
    }

    if (requestCode == REQUEST_SIGNAL_DETAILS) {
        if (resultCode == Activity.RESULT_OK) {
            Signal signal = data.getParcelableExtra("signal");
            if (signal != null) {
                actionsListener.onSignalStatusUpdated(signal);
            }
        }
    }
}

我的問題是這樣的:當用戶從Google相冊中選擇一張照片(僅存在於雲中且尚未在本地下載的照片)時,我的應用程序崩潰並出現以下錯誤:

E / MediaStore:無法插入圖像java.lang.SecurityException:權限拒絕:從pid = 9851編寫com.android.providers.media.MediaProvider uri content:// media / external / images / media,uid = 10091需要android。權限.WRITE_EXTERNAL_STORAGE或android.os.Parcel.readException(Parcel.java:1943)上的grantUriPermission(),android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)上的android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java) :135),位於android.content.ContentProviderProxy.insert(ContentProviderNative.java:476),位於android.content.ContentResolver.insert(ContentResolver.java:1539),位於android.provider.MediaStore $ Images $ Media.insertImage(MediaStore.java: 984),位於org.helpapaw.helpapaw.signalsmap.SignalsMapFragment.onActivityResult(SignalsMapFragment.java:738),位於android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:151),位於android.app.Activity.dispatchActivityResult(Activity .java:7235),位於android.app.ActivityTh android.app.ActivityThread.handle上的read.deliverResults(ActivityThread.java:4320)android.app.ActivityThread $ H.handleMessage上的sendResult(ActivityThread.java:4367)在android.app.ActivityThread.-wrap19(Unknown Source:0) (ActivityThread.java:1649)在android.os.Handler.dispatchMessage(Handler.java:105)在android.os.Looper.loop(Looper.java:164)在android.app.ActivityThread.main(ActivityThread.java: 6541)在com.android.internal.os.Zygote $ MethodAndArgsCaller.run(Zygote.java:240)在java.lang.reflect.Method.invoke(本機方法)在com.android.internal.os.ZygoteInit.main( ZygoteInit.java:767)D / AndroidRuntime:關閉VM E / AndroidRuntime:致命例外:主進程:org.helpapaw.helpapaw,PID:9851 java.lang.RuntimeException:無法傳遞結果ResultInfo {who = null,request = 196611 ,結果= -1,數據=目的{dat = content://com.google.android.apps.photos.contentprovider/0/1/mediakey:/ local%3Aabc88a06-d518-4fae-b85d-73f727595a90 / ORIGINAL / NONE / 1144559444 flg = 0x1剪輯= {text / uri-lis t U:content://com.google.android.apps.photos.contentprovider/0/1/mediakey%3A%2Flocal%253Aabc88a06-d518-4fae-b85d-73f727595a90/ORIGINAL/NONE/1144559444}}} org.helpapaw.helpapaw / org.helpapaw.helpapaw.signalsmap.SignalsMapActivity}:java.lang.NullPointerException:uriString在android.app.ActivityThread.deliverResults(ActivityThread.java:4324)在android.app.ActivityThread.handleSendResult(ActivityThread。 java:4367)位於android.app.ActivityThread.-wrap19(未知來源:0)位於android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1649)位於android.os.Handler.dispatchMessage(Handler.java:105 )的android.os.Looper.loop(Looper.java:164)的com.android.java.lang.reflect.Method.invoke(本機方法)的android.app.ActivityThread.main(ActivityThread.java:6541)。在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)處的internal.os.Zygote $ MethodAndArgsCaller.run(Zygote.java:240)原因:java.lang.NullPointerException:android.net上的uriString。烏里$ StringUri。(Uri.java:4 76)位於android.net.Uri $ StringUri(未知來源:0),位於android.net.Uri.parse(Uri.java:438),位於org.helpapaw.helpapaw.signalsmap.SignalsMapFragment.onActivityResult(SignalsMapFragment.java:742 )於android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:151)於android.app.Activity.dispatchActivityResult(Activity.java:7235)於android.app.ActivityThread.deliverResults(ActivityThread.java:4320)在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1649)在android.app.ActivityThread.ww19(未知來源:0)在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1649)在android.app.ActivityThread.handleSendResult(ActivityThread.java:4367) os.Handler.dispatchMessage(Handler.java:105)在android.os.Looper.loop(Looper.java:164)在android.app.ActivityThread.main(ActivityThread.java:6541)在java.lang.reflect.Method com.android.internal.os.Zygote $ MethodAndArgsCaller.run(Zygote.java:240)上的.invoke(本機方法)com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)上的.invoke(本機方法)

該錯誤的第一行讓我想到了WRITE_TO_EXTERNAL權限錯誤:

E / MediaStore:無法插入圖像java.lang.SecurityException:權限拒絕:從pid = 9851編寫com.android.providers.media.MediaProvider uri content:// media / external / images / media,uid = 10091需要android。權限.WRITE_EXTERNAL_STORAGE或grantUriPermission()

因此,我檢查以確保此API版本需要“運行時”權限(如您在上面的代碼中可以看到的),並顯示以下行:

ActivityCompat.requestPermissions(getActivity(), new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);

被擊中,但屏幕上沒有確認對話框出現。 另一個有趣的事實是,該錯誤僅在我第一次運行該應用程序時(在API 8.0上)發生,並且在5.1、6.0、7.1和8.1上運行良好,但在8.0(模擬器)上崩潰。 我想念什么?

對於那些在相似方面掙扎的人; 關鍵是使用Fragment.requestPermissions(String[] permissions, int requestCode);一次全部請求必要的權限Fragment.requestPermissions(String[] permissions, int requestCode); 方法。 此方法允許將權限數組傳遞到其第一個參數:

    String[] permissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
        if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
                ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(permissions, READ_WRITE_EXTERNAL_STORAGE_FOR_GALLERY);
}
  • 我希望我知道的是:

    一旦有新的意圖被調用,無論是相機還是照相館; 試圖向用戶詢問權限不再有效; 含義-相機或相冊打開后,我們將失去自己應用的上下文,因此無法再提示用戶任何權限。 至關重要的是在用戶離開我們的應用程序之前 ,必須先請求所有權限(在我的情況下,必須使用數組來請求對外部存儲設備進行讀取和寫入的權限。用戶離開當前上下文,然后通過意圖重定向到新的活動。

我希望這可以幫助別人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM