2

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

在我的布局中,我有一个按钮和一个图像视图。当我单击按钮时,我想选择画廊的图片来保存它。当我单击图像视图时,我希望显示保存的图像。

这就是我尝试过的:

布局:

    <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)
4

1 回答 1

0
startActivityForResult(new Intent(Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI), GET_FROM_GALLERY);

无论是否授予权限,都会执行上述代码。你的意思是把它包起来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)

用于收听是否授予权限。

于 2017-06-08T21:37:23.897 回答