Android - 通过 AsyncTask 将图像保存到 SD 卡失败

Android - Saving image into SD Card through AsyncTask fails

我的可绘制文件夹中有图像。 Activity 打开它们,我选择需要的图片并点击按钮。它们必须通过扩展 AsyncTask.

ImageSavingTask class 实例执行保存在我的 SD 卡上

这是我的 onClick 代码:

@Override
public void onClick(View v) {
    for (int i = 0; i < 26; i++)
        if (checkBoxes[i].isChecked()) {
            imageIndex = new ImageIndex(); //ImageIndex-a class with single index field which reserves the checked checkbox indexes.
            imageIndex.index = i;
            Bitmap bitmap = ((BitmapDrawable) (images[i].getDrawable())).getBitmap();
            SaveImageTask saveImageTask = new SaveImageTask();
            saveImageTask.execute(bitmap); //The class SaveImageTask extends AsyncTask<Bitmap, Void, Void>
        }
}

然后选择的图像在doInBackground方法中处理。

    @Override
    protected Void doInBackground(Bitmap... params) {
        FileOutputStream outStream = null;
        try {
            Bitmap bitmap = params[0];
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
            byte[] imageBytes = stream.toByteArray();

            File sdCard = Environment.getExternalStorageDirectory();
            Drawable drawable = new BitmapDrawable(getResources(), bitmap);
            File dir = new File(sdCard.getAbsolutePath());
            dir.mkdirs();

            String fileName = "Saved image " + imageIndex.index; //The reserved index of checkbox creates a name for the new file.
            File outFile = new File(dir, fileName);

            outStream = new FileOutputStream(outFile);
            outStream.write(imageBytes);
            outStream.flush();
            outStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

我的清单中添加了 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 行。

将 USB 连接到我的 phone 后,没有发生任何错误,但没有图像保存到我的 SD 卡中。我无法使用 windows 搜索在我的 phone 上找到图片。调试没有给出任何答案。这可能是什么问题?

您似乎没有请求在 SD 卡上写入文件的运行时权限。从 Android M 及更高版本开始,您需要在运行时询问写入权限才能将任何文件保存在外部 SD 卡上。

检查此 link 以了解如何请求运行时权限- https://developer.android.com/training/permissions/requesting.html

您也可以使用 google 库 - https://github.com/googlesamples/easypermissions 请求权限。

我将选定的索引添加到索引和位图的 2 个 ArrayLists 中。在 doInBackground 方法中我创建了一个循环。

为了立即在卡片上显示图像,我使用了 MediaScannerConnection.scanFile 方法。

for (int i = 0; i < 26; i++)
    if (checkBoxes[i].isChecked()) {
        index.add(i);
        bitmap.add(bitmaps[i]);
    }
if (bitmap.size() > 0)
    new SaveImageTask().execute();

doInBackground方法:

protected Void doInBackground(Void... params) {
            for (int i = 0; i < bitmap.size(); i++) {
                try {
                    fname = "Saved image " + (index.get(i)) + ".jpg";
                    file = new File(myDir, fname);
                    if (file.exists()) file.delete();
                    FileOutputStream out = new FileOutputStream(file);
                    bitmap.get(i).compress(Bitmap.CompressFormat.JPEG, 100, out);
                    out.flush();
                    out.close();
                    MediaScannerConnection.
                            scanFile(getApplicationContext(), new String[]{file.getPath()}, new String[]{"image/jpeg"}, null);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }

我离开 ImageSavingTask 没有字段和参数。

我认为您尝试写入字节的问题。

使用以下解决方案..

@Override
protected Void doInBackground(Bitmap... params) {
      Bitmap bitmap = params[0];
      saveToInternalStorage(bitmap, "MyImage"); // pass bitmap and ImageName
      return null;
}

//Method to save Image in InternalStorage
private void saveToInternalStorage(Bitmap bitmapImage, String imageName) {

            File mypath = new File(Environment.getExternalStorageDirectory(), imageName + ".jpg");

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

注意:确保您已添加存储 read/write 权限,并且不要忘记在 Marshmallow 和更高版本上请求权限。