Android读取图像权限外部存储

时间:2017-06-08 15:31:08

标签: android android-permissions android-image android-internal-storage

我想从内部存储中读取并保存图像/位图。

在我的布局中,我有一个按钮和一个imageview。当我点击按钮时,我想选择一个图库来保存它。当我点击imageview时,我想要显示保存的图像。

这就是我的尝试:

布局:

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="80dp"
        android:layout_marginRight="80dp"
        android:text="Upload Image"
        android:onClick="onClickUpload"
        android:layout_marginBottom="30dp" />

    <ImageView
        android:id="@+id/imgPicker"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_marginTop="15dp"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="30dp"
        android:onClick="onClickShow"
        app:srcCompat="@android:color/holo_orange_dark" />

请求许可时读取功能

public void onClickUpload(View view) {

    // request permission to read external storage (explicit necessary since API Level 23)

    // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(DetailActivity.this,
            Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {

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

            // Show an explanation 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(DetailActivity.this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);

            // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
            // app-defined int constant. The callback method gets the
            // result of the request.
            }
    } else {
        startActivityForResult(new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI), GET_FROM_GALLERY);
    }
}

覆盖onRquestPermissionResult

/*
    find out whether the permission was granted
 */
@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        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) {

                // start Activity if granted
                startActivityForResult(new Intent(Intent.ACTION_PICK,
                        MediaStore.Images.Media.INTERNAL_CONTENT_URI), GET_FROM_GALLERY);

            } else {

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

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

授予权限后运行:

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

    //Detects request codes
    if(requestCode==GET_FROM_GALLERY && resultCode == Activity.RESULT_OK) {
        Uri selectedImage = data.getData();
        Bitmap bitmap = null;
        try {
            bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);

            ContextWrapper cw = new ContextWrapper(getApplicationContext());
            // path to /data/data/yourapp/app_data/imageDir
            File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
            // Create imageDir
            File mypath=new File(directory,"profile.jpg");

            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(mypath);
                // Use the compress method on the BitMap object to write image to the OutputStream
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            directory.getAbsolutePath();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在我的清单中,我还有权限:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".activities.LoginActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".activities.RegisterActivity"
        android:screenOrientation="portrait" />
    <activity
        android:name=".activities.CategoryActivity"
        android:screenOrientation="portrait" />
    <activity android:name=".activities.SuggestionActivity" />
    <activity
        android:name=".activities.DetailActivity"
        android:theme="@style/AppTheme" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</application>

然而,当点击按钮(设备是API 24)时,我得到错误

06-08 19:56:28.903 18770-18782/android.process.media E/DatabaseUtils: Writing exception to parcel
                                                                      java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/file from pid=20240, uid=10046 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
                                                                          at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:608)
                                                                          at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:483)
                                                                          at android.content.ContentProvider$Transport.query(ContentProvider.java:212)
                                                                          at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
                                                                          at android.os.Binder.execTransact(Binder.java:565)

1 个答案:

答案 0 :(得分:0)

else

无论是否授予许可,都会执行上述代码。您的意思是将if包裹在public void onClickUpload(View view) { // Here, thisActivity is the current activity if (ContextCompat.checkSelfPermission(DetailActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(DetailActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) { // Show an explanation 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(DetailActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an // app-defined int constant. The callback method gets the // result of the request. } } else { startActivityForResult(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI), GET_FROM_GALLERY); } } 吗?

public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String permissions[],
                                           @NonNull int[] grantResults)

我假设你已经超越了

{{1}}

听取是否授予许可。