【问题标题】:How to save a URI as a jpg file to a custom folder on the internal storage?如何将 URI 作为 jpg 文件保存到内部存储上的自定义文件夹中?
【发布时间】:2018-07-27 17:55:51
【问题描述】:

我有一个包含 "0/data/app/data/croppedimage.jpg" 的 URI,我想将它保存在内部存储中,并使用我的文件名为 的新文件夹“/storage/emulated/0/myfolder/myimage.jpg”来自onActivity结果。

代码如下,

    @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
        CropImage.ActivityResult result = CropImage.getActivityResult(data);
        if (resultCode == RESULT_OK) {
            Uri resultUri = result.getUri();}}

我已尝试使用 FileOutputStream,但 myImage 文件崩溃或损坏。

代码如下,

 File folderPath = new File(Environment.getExternalStorageDirectory() + "/OCR");

            if (!folderPath.exists()) {
                if (folderPath.mkdir()) ; //directory is created;
            } else {
                File photo = new File("/storage/emulated/0/myfolder/myimage.jpg");
                try {
                    FileOutputStream fileOutputStream = new FileOutputStream(photo);
                    fileOutputStream.write(Integer.parseInt(resultUri.toString()));
                    fileOutputStream.flush();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

【问题讨论】:

  • 你得到了哪些例外?
  • 我的任务是uri有不同的路径,我想把它保存在不同的路径中。
  • 我可以看到一些事情:(a) 如果folderPath 目录不存在,您或者创建它,或者 你尝试写一个文件——不是两者都写! (b) 您忽略了folderPath,并为您似乎要保存到的文件使用硬编码路径。 (c) 据我所知,您写入该文件的所有内容都是尝试将 URI 解析为数字的结果……您似乎从未真正读取过 i> 来自 URI。
  • 查看我的新答案并尝试一下。

标签: java android internal-storage


【解决方案1】:

我认为您正在使用图像裁剪库。在这种情况下,您可以像这样使用 FileProviders 概念

您应该将您的包名称附加到.fileprovider,例如 com.yourpackagename.fileprovider

将此添加到AndroidManifest.xml

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

在 res 文件夹中创建 xml 子文件夹并在此子文件夹中添加此文件

provider_path.xml

  <?xml version="1.0" encoding="utf-8"?>
<paths>
  <external-path name="/storage/emulated/0" path="."/>
</paths>

将此作为全局变量添加到您的活动中

private static final String CAPTURE_IMAGE_FILE_PROVIDER = "com.yourpackage.name.fileprovider";

然后像这样更改您的startCropImageActivity() 方法

    private void startCropImageActivity(Uri imageUri)
{
    File file = null;
    try
    {
        file = createImageFile();
        Uri mUri = FileProvider.getUriForFile(this,
                CAPTURE_IMAGE_FILE_PROVIDER, file);
        CropImage.activity(imageUri)
                .setGuidelines(CropImageView.Guidelines.ON)
                .setMultiTouchEnabled(true)
                .setAllowFlipping(false)
                .setAspectRatio(1, 1)
                .setRequestedSize(350, 350)
                .setMinCropResultSize(350, 350)
                .setMaxCropResultSize(800, 800)
                .setOutputCompressFormat(Bitmap.CompressFormat.PNG)
                .setOutputCompressQuality(90)
                .setOutputUri(mUri)
                .start(this);
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

    private File createImageFile() throws IOException
{

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "MYAPPNAME-" + timeStamp + ".jpg";
    File mediaStorageDir = new File(Environment.getExternalStorageDirectory(),
            "YourAppFolder");
    File storageDir = new File(mediaStorageDir + "/Profile_Images");
    if (!storageDir.exists())
    {
        storageDir.mkdirs();
    }
    File image = new File(storageDir, imageFileName);
    return image;
}

最后

@SuppressLint("NewApi")
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{

    // handle result of pick image chooser
    if (requestCode == CropImage.PICK_IMAGE_CHOOSER_REQUEST_CODE && resultCode == Activity.RESULT_OK)
    {
        Uri imageUri = CropImage.getPickImageResultUri(this, data);

        // For API >= 23 we need to check specifically that we have permissions to read external storage.
        if (CropImage.isReadExternalStoragePermissionsRequired(this, imageUri))
        {
            // request permissions and handle the result in onRequestPermissionsResult()
            mCropImageUri = imageUri;
            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
        }
        else
        {
            // no permissions required or already grunted, can start crop image activity
            startCropImageActivity(imageUri);
        }
    }

    // handle result of CropImageActivity
    if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE)
    {
        CropImage.ActivityResult result = CropImage.getActivityResult(data);
        if (resultCode == RESULT_OK)
        {
            profileImageFilepath = result.getUri().getPath();
            Log.d("cropImageUri", result.getUri().getPath());
            new PostDataAsyncTask().execute();
            Toast.makeText(this, "Photo Selected Successfully", Toast.LENGTH_LONG).show();
        }
        else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE)
        {
            Toast.makeText(this, "Photo Selection Failed", Toast.LENGTH_SHORT).show();
        }
    }
}

获取权限

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

此解决方案会将您裁剪的图像保存到/storage/emulated/0/yourfolder/yourimage.jpg

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多