Я загружаю изображения на смартфон. Для более старых версий не проблема, мой код работает, но для Oreo он не работает. Я попробовал этот код в эмуляторе.
Я реализовал функцию сохранения изображения на внешнее хранилище.
private void saveImageToExternalStorage(Bitmap finalBitmap,String name) {
String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
File myDir = new File(root + "/xx");
myDir.mkdirs();
String fname = name + ".jpg";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
}
catch (Exception e) {
e.printStackTrace();
}
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this, new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
}
Я прошу разрешения на использование библиотеки Декстера. Если разрешение предоставлено, я запускаю task .
Dexter.withActivity(MainActivity.this)
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(new PermissionListener() {
@Override
public void onPermissionGranted(PermissionGrantedResponse response) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
if (!prefs.getBoolean("firstTime", false)) {
task.execute();
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("firstTime", true);
editor.commit();
}
}
@Override
public void onPermissionDenied(PermissionDeniedResponse response) {
Toast.makeText(MainActivity.this, "You need to allow permission if you want to use camera", Toast.LENGTH_LONG).show();
}
@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
token.continuePermissionRequest();
Toast.makeText(MainActivity.this, "You need to allow permission if you want to use camera", Toast.LENGTH_LONG).show();
}
}).check();
Затем я сохраняю изображения с помощью asynctask.
final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
private ProgressDialog dialog;
@Override
protected void onPreExecute()
{
this.dialog = new ProgressDialog(MainActivity.this);
this.dialog.setMessage(getString(R.string.newfeature));
this.dialog.setCancelable(false);
this.dialog.setOnCancelListener(new DialogInterface.OnCancelListener()
{
@Override
public void onCancel(DialogInterface dialog)
{
// cancel AsyncTask
cancel(false);
}
});
this.dialog.show();
}
@Override
protected Void doInBackground(Void... params)
{
// do your stuff
Bitmap myBitmap2 = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im2);
saveImageToExternalStorage(myBitmap2,"imag2");
myBitmap2.recycle();
Bitmap myBitmap3 = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im3);
saveImageToExternalStorage(myBitmap3,"image3");
myBitmap3.recycle();
Bitmap myBitmap4 = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im4);
saveImageToExternalStorage(myBitmap4,"image4");
myBitmap4.recycle();
Bitmap myBitmap5= BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im5);
saveImageToExternalStorage(myBitmap5,"image5");
myBitmap5.recycle();
Bitmap myBitmap6 = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im6);
saveImageToExternalStorage(myBitmap6,"image6");
myBitmap6.recycle();
Bitmap myBitmap7 = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im7);
saveImageToExternalStorage(myBitmap7,"image7");
myBitmap7.recycle();
Bitmap myBitmap8 = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im8);
saveImageToExternalStorage(myBitmap8,"image8");
myBitmap8.recycle();
Bitmap myBitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im1);
saveImageToExternalStorage(myBitmap,"image1");
myBitmap.recycle();
Bitmap myBitmap9 = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im9);
saveImageToExternalStorage(myBitmap9,"image9");
myBitmap9.recycle();
Bitmap myBitmap10 = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im10);
saveImageToExternalStorage(myBitmap10,"image10");
myBitmap10.recycle();
Bitmap myBitmap11 = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im11);
saveImageToExternalStorage(myBitmap11,"image11");
myBitmap11.recycle();
Bitmap myBitmap12 = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im12);
saveImageToExternalStorage(myBitmap12,"image12");
myBitmap12.recycle();
Bitmap myBitmap13 = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im13);
saveImageToExternalStorage(myBitmap13,"image13");
myBitmap13.recycle();
Bitmap myBitmap14 = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.im14);
saveImageToExternalStorage(myBitmap14,"image14");
myBitmap14.recycle();
return null;
}
@Override
protected void onPostExecute(Void result)
{
//called on ui thread
if (this.dialog != null) {
this.dialog.dismiss();
}
}
@Override
protected void onCancelled()
{
//called on ui thread
if (this.dialog != null) {
this.dialog.dismiss();
}
}
};
Наконец-то выдается эта ошибка в эмуляторе Oreo:
09-18 12:32:52.167 5818-5936/x.x W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Pictures/xx/imag2.jpg (No such file or directory)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at java.io.FileOutputStream.open0(Native Method)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at java.io.FileOutputStream.open(FileOutputStream.java:308)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:238)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:180)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at x.x.MainActivity.saveImageToExternalStorage(MainActivity.java:776)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at x.x.MainActivity.access$000(MainActivity.java:62)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at x.x.MainActivity$1.doInBackground(MainActivity.java:119)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at x.x.MainActivity$1.doInBackground(MainActivity.java:89)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:333)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
09-18 12:32:52.168 5818-5936/x.x W/System.err: at java.lang.Thread.run(Thread.java:764)
Для более старых версий эмуляторов или более старых версий смартфонов проблем нет. Изображения сохранены правильно. Я не пробовал с настоящим смартфоном Oreo, но для эмулятора - Oreo это дает эту проблему. В результате, как я могу решить мою проблему? Какова главная причина этой ситуации? Права доступа? сохранить изображение на внешнее хранилище? или создание файла - папки?