Crop Image Located in Internal Storage

冷暖自知 提交于 2019-12-08 12:30:57

问题


I am having trouble using the crop intent in Android.

I am storing images in the internal storage allocation for my app and I want to be able to crop them and then set them as the wallpaper.

I can get it to work with an image stored in external storage and using this code:

cropIntent.setDataAndType(Uri.fromFile(new File(uri)), "image/*");

When I execute the code below the intent fails to launch the crop intent and a 0 result code is returned.

Intent cropIntent = new Intent("com.android.camera.action.CROP");

cropIntent.setDataAndType(FileProvider.getUriForFile(activity, "com.example.test.fileprovider", new File(uri)), "image/*");

cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 9);
cropIntent.putExtra("aspectY", 16);
cropIntent.putExtra("return-data", true);
cropIntent.putExtra("scale", true);

activity.startActivityForResult(cropIntent, PIC_CROP);

回答1:


From Storage Options | Android Developers:

By default, files saved to the internal storage are private to your application and other applications cannot access them (nor can the user).

ACTION_CROP launches an "other application" that supports cropping, and passes it the URI of the file to crop. If that file is in internal storage, it is not directly accessible to the cropping application.

Using a FileProvider to provide an internal file to other apps requires some configuration. From Setting Up File Sharing | Android Developers:

Specify the FileProvider

Defining a FileProvider for your app requires an entry in your manifest. This entry specifies the authority to use in generating content URIs, as well as the name of an XML file that specifies the directories your app can share.

<snip>

Specify Sharable Directories

Once you have added the FileProvider to your app manifest, you need to specify the directories that contain the files you want to share. To specify the directories, start by creating the file filepaths.xml in the res/xml/ subdirectory of your project.

The following FileProvider sample integrates your code and successfully opens the crop activity on an image in internal storage (tested on a Nexus 5, stock Android 5.1.1):

AndroidManifest.xml

    <application
        ...>
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.example.test.fileprovider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
        </provider>
        ...
    </application>

res/xml/filepaths.xml

<paths>
    <files-path path="images/" name="images" />
</paths>

MainActivity.java

            // Manually stored image for testing
            final File imagePath = new File(getFilesDir(), "images");
            final File imageFile = new File(imagePath, "sample.jpg");

            // Provider authority string must match the one declared in AndroidManifest.xml
            final Uri providedUri = FileProvider.getUriForFile(
                    MainActivity.this, "com.example.test.fileprovider", imageFile);

            Intent cropIntent = new Intent("com.android.camera.action.CROP");

            cropIntent.setDataAndType(providedUri, "image/*");

            cropIntent.putExtra("crop", "true");
            cropIntent.putExtra("aspectX", 9);
            cropIntent.putExtra("aspectY", 16);
            cropIntent.putExtra("return-data", true);
            cropIntent.putExtra("scale", true);

            // Exception will be thrown if read permission isn't granted
            cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

            startActivityForResult(cropIntent, PIC_CROP);


来源:https://stackoverflow.com/questions/30961250/crop-image-located-in-internal-storage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!