【发布时间】:2019-02-26 00:59:52
【问题描述】:
我正在将照片下载到智能手机。对于低于奥利奥的版本,没有问题。但是对于奥利奥,我的代码不起作用。我在模拟器中试过这段代码:
我实现了一个将图像保存到外部存储的功能。
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);
}
});
}
我正在请求使用 dexter 库的权限。
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();
我使用异步任务保存图像
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();
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();
}
}
};
当我查看我的应用程序的设置 --> 应用程序时,我可以看到已授予存储权限。但图像未正确保存。事实上图像被保存,但它们都是像这样的绿色正方形。
因此,尽管授予了权限,但它给出了权限被拒绝错误。
09-21 13:11:08.023 17636-17765/xx.xx W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Pictures/xx/imag2.jpg (Permission denied)
09-21 13:11:08.024 17636-17765/xx.xx W/System.err: at java.io.FileOutputStream.open0(Native Method)
09-21 13:11:08.024 17636-17765/xx.xx W/System.err: at java.io.FileOutputStream.open(FileOutputStream.java:308)
09-21 13:11:08.033 17636-17765/xx.xx W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:238)
09-21 13:11:08.033 17636-17765/xx.xx W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:180)
09-21 13:11:08.033 17636-17765/xx.xx W/System.err: at xx.xx.MainActivity.saveImageToExternalStorage(MainActivity.java:804)
09-21 13:11:08.033 17636-17765/xx.xx W/System.err: at xx.xx.MainActivity.access$000(MainActivity.java:62)
09-21 13:11:08.033 17636-17765/xx.xx W/System.err: at xx.xx.MainActivity$1.doInBackground(MainActivity.java:119)
09-21 13:11:08.033 17636-17765/xx.xx W/System.err: at xx.xx.MainActivity$1.doInBackground(MainActivity.java:89)
09-21 13:11:08.033 17636-17765/xx.xx W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:333)
09-21 13:11:08.033 17636-17765/xx.xx W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
09-21 13:11:08.033 17636-17765/xx.xx W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
09-21 13:11:08.033 17636-17765/xx.xx W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
09-21 13:11:08.033 17636-17765/xx.xx W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
09-21 13:11:08.033 17636-17765/xx.xx W/System.err: at java.lang.Thread.run(Thread.java:764)
【问题讨论】:
-
外部存储是指SD卡吗?
-
是的,它适用于较低版本的模拟器,但对于 oreo 不起作用。
-
你不能像那样访问存储卡...你需要使用称为 DocumentTree 的东西
-
我可以在低于 oreo 的版本中访问。 5.0 或 6.0 模拟器没问题
-
是的,因为从奥利奥引入它是出于安全原因。
标签: java android permissions android-permissions android-8.0-oreo