【问题标题】:Crop Image Located in Internal Storage裁剪图像位于内部存储
【发布时间】:2015-06-21 04:24:26
【问题描述】:

我在 Android 中使用裁剪 Intent 时遇到问题。

我将图像存储在我的应用的内部存储分配中,我希望能够裁剪它们,然后将它们设置为壁纸。

我可以让它处理存储在外部存储中的图像并使用以下代码:

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

当我执行意图下方的代码时,无法启动裁剪意图并返回 0 结果代码。

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

【问题讨论】:

    标签: android image android-intent crop android-fileprovider


    【解决方案1】:

    来自Storage Options | Android Developers

    默认情况下,保存到内部存储的文件对您的应用程序是私有的,其他应用程序无法访问它们(用户也不能)。

    ACTION_CROP 启动一个支持裁剪的“其他应用程序”,并将文件的 URI 传递给它以进行裁剪。如果该文件在内部存储中,则裁剪应用程序无法直接访问它。

    使用FileProvider 向其他应用提供内部文件需要进行一些配置。来自Setting Up File Sharing | Android Developers

    指定 FileProvider

    为您的应用定义 FileProvider 需要在清单中添加一个条目。此条目指定用于生成内容 URI 的权限,以及指定您的应用程序可以共享的目录的 XML 文件的名称。

    指定可共享目录

    将 FileProvider 添加到应用清单后,您需要指定包含要共享的文件的目录。要指定目录,首先在项目的 res/xml/ 子目录中创建文件 filepaths.xml。

    以下FileProvider 示例集成了您的代码,并成功地在内部存储中的图像上打开了裁剪活动(在 Nexus 5、库存 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);
    

    【讨论】:

    • 我原以为实现“FileProvider”可以解决这个问题。有解决办法吗?
    • 抱歉,我发帖时的回答不完整,昨天无法回复。刚刚更新。
    • cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);忘了加上这个,花了一整天。非常感谢
    猜你喜欢
    • 2022-06-15
    • 2013-03-25
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    相关资源
    最近更新 更多