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 和更高版本上请求权限。
我的可绘制文件夹中有图像。 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 和更高版本上请求权限。