Я хочу записать изображение в устройство, используя публичное внешнее хранилище.Таким образом, я 1) написал в манифесте теги разрешений и 2) использовал checkSelfPermission
для запроса разрешений при необходимости.Но у меня все еще есть это исключение: java.io.FileNotFoundException: /storage/emulated/03b3d97bd-5186-4506-97dc-9994b7ce0761 (Permission denied)
.
Почему?Я уже прочитал https://developer.android.com/guide/topics/permissions/overview#normal-dangerous, но он не отвечает на мой вопрос.
Формализация проблемы
Я предоставил разрешения на хранение на моем устройстве Android.Таким образом, мое условие if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
(см. Ниже) правильно НЕ выполнено, а else
выполнено.И этот else
содержит строку для сохранения файла в хранилище: однако он возвращает это исключение ...
Источники
Цель состоит в том, чтобы вызвать saveImageAndShareIt
, если пользователь предоставилразрешение.
Манифест
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Обычно чтение должно быть неявно распознано благодаря разрешению на запись.
В DialogFragment
Ниже,метод onRequestPermissionsResult
.saveImageAndShareIt
вызывается, если пользователь согласился предоставить разрешение.
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
System.out.println("onrequestPR");
if (grantResults.length > 0) {
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
System.out.println("onrequestPR accepted");
saveImageAndShareIt();
}
}
}
onRequestPermissionsResult
вызывается requestPermissions
, представленным ниже:
if (Build.VERSION.SDK_INT >= 23) {
int permissionCheck = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
} else {
System.out.println("last_case1");
saveImageAndShareIt();
System.out.println("last_case2");
}
} else {
System.out.println("peperoni");
saveImageAndShareIt();
System.out.println("pizza");
}
То есть, если пользователь имеетуже предоставлено разрешение, нет необходимости вызывать requestPermissions
и, таким образом, saveImageAndShareIt
вызывается напрямую (другими словами: onRequestPermissionsResult
не нужно выполнять для вызова saveImageAndShareIt
).
saveImageAndShareIt
Исключение составляет экземпляр FileOutputStream
.
private void saveImageAndShareIt() {
OutputStream output;
try {
System.out.println("siasi1");
output = new FileOutputStream(Environment.getExternalStorageDirectory() + image_uuid);
byte[] buffer = new byte[1024];
int bytesRead;
BitmapDrawable bitmapDrawable = (BitmapDrawable) temp.getDrawable();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmapDrawable.getBitmap().compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] imageInByte = stream.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(imageInByte);
while ((bytesRead = bis.read(buffer, 0, buffer.length)) >= 0) {
output.write(buffer, 0, bytesRead);
}
output.close();
System.out.println("siasi2");
intent_share.putExtra(Intent.EXTRA_STREAM, Uri.parse(Environment.getExternalStorageDirectory() + image_uuid));
activity.startActivity(Intent.createChooser(intent_share, "Share to"));
System.out.println("siasi3");
} catch(IOException e) {
e.printStackTrace();
}
}
Трассировка стека
W / System.err: java.io.FileNotFoundException: / storage / emulated / 03b3d97bd-5186-4506-97dc-9994b7ce0761 (в доступе отказано) W / System.err: в java.io.FileOutputStream.open0 (собственный метод) в java.io.FileOutputStream.opream (FileOutJutStut.utava.put): 287) W / System.err: в java.io.FileOutputStream. (FileOutputStream.java:223) W / System.err: в java.io.FileOutputStream. (FileOutputStream.java:110) в com.example ...ClipboardDialogFragment.saveImageAndShareIt (ClipboardDialogFragment.java:115) в com.example ... ClipboardDialogFragment.access $ 300 (ClipboardDialogFragment.java:42) W / System.err: в com.example ... ClipboardDialogFragment $ 1 $ 2 $ 1.onTaskCompleted (ClipboardDialogFragment.java:75) W / System.err: в com.example ...DownloadImageTask.onPostExecute (DownloadImageTask.java:34) на com.example ... DownloadImageTask.onPostExecute (DownloadImageTask.java:10) W / System.err: на android.os.AsyncTask.finish (AsyncTask.java:695) и на.os.AsyncTask.-wrap1 (неизвестный источник: 0) W / System.err: at android.os.AsyncTask $ InternalHandler.handleMessage (AsyncTask.java:712) W / System.err: at android.os.Handler.dispatchMessage(Handler.java:105) на android.os.Looper.loop (Looper.java:164) на android.app.ActivityThread.main (ActivityThread.java:6944) W / System.err: на java.lang.reflect.Method.invoke (собственный метод) в com.android.internal.os.Zygote $ MethodAndArgsCaller.run (Zygote.java:327) в com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1374)