Próbuję naprawić problem po dodaniu nowej funkcji w systemie plików Android, ale pojawia się ten błąd:
android.os.FileUriExposedException: file:///storage/emulated/0/MyApp/Camera_20180105_172234.jpg exposed beyond app through ClipData.Item.getUri()
Mam więc nadzieję, że ktoś pomoże mi to naprawić :)
Dzięki
private Uri getTempUri() {
// Create an image file name
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
String dt = sdf.format(new Date());
imageFile = null;
imageFile = new File(Environment.getExternalStorageDirectory()
+ "/MyApp/", "Camera_" + dt + ".jpg");
AppLog.Log(
TAG,
"New Camera Image Path:- "
+ Environment.getExternalStorageDirectory()
+ "/MyApp/" + "Camera_" + dt + ".jpg");
File file = new File(Environment.getExternalStorageDirectory() + "/MyApp");
if (!file.exists()) {
file.mkdir();
}
imagePath = Environment.getExternalStorageDirectory() + "/MyApp/"
+ "Camera_" + dt + ".jpg";
imageUri = Uri.fromFile(imageFile);
return imageUri;
}
Odpowiedzi:
W przypadku pakietu SDK 24 i nowszych, jeśli chcesz pobrać identyfikator Uri pliku poza magazynem aplikacji, występuje ten błąd.
Rozwiązania @ eranda.del pozwalają na zmianę zasad, aby to umożliwić i działa dobrze.
Jeśli jednak chcesz postępować zgodnie z wytycznymi Google bez konieczności zmiany zasad API swojej aplikacji, musisz użyć FileProvider.
Najpierw, aby uzyskać identyfikator URI pliku, musisz użyć metody FileProvider.getUriForFile ():
Uri imageUri = FileProvider.getUriForFile( MainActivity.this, "com.example.homefolder.example.provider", //(use your app signature + ".provider" ) imageFile);
Następnie musisz skonfigurować swojego dostawcę w manifeście Androida:
<application> ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.example.homefolder.example.provider" android:exported="false" android:grantUriPermissions="true"> <!-- ressource file to create --> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"> </meta-data> </provider> </application>
(W „organach” użyj tej samej wartości, co drugi argument metody getUriForFile () (podpis aplikacji + „.provider”))
I na koniec musisz utworzyć plik zasobów: "file_paths". Ten plik należy utworzyć w katalogu res / xml (prawdopodobnie musisz również utworzyć ten katalog):
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="external_files" path="." /> </paths>
źródło
<external-path ...
jest używany, gdy chcesz, aby Environment.getExternalStorageDirectory (). i użyj,<files-path ...
jeśli potrzebujesz Context.getFilesDir (). Lepiej najpierw sprawdź oficjalne dokumenty: developer.android.com/reference/android/support/v4/content/ ...androidx
nim jest:android:name="androidx.core.content.FileProvider"
Dodaj następujący blok kodu przed rozpoczęciem przeglądania kamery lub plików
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build());
Zapoznaj się z trybem ścisłym linku polecającego i wyjaśnij wszystkie szczegóły użytkowania i techniczne.
źródło
Nie należy zezwalać na żadną wymaganą konfigurację dostawcy w AndroidManifest tylko uprawnienia Aparat i pamięć. Użyj poniższego kodu, aby uruchomić kamerę:
final int REQUEST_ACTION_CAMERA = 9; void openCamra() { Intent cameraImgIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); cameraImgIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID +".provider", new File("your_file_name_with_dir"))); startActivityForResult(cameraImgIntent, REQUEST_ACTION_CAMERA); }
Po przechwyceniu obrazu możesz znaleźć przechwycony obraz w:
"your_file_name_with_dir"
źródło
dodaj kod w
onCreate(Budle savedInstancesState){ if (Build.VERSION.SDK_INT >= 24) { try { Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure"); m.invoke(null); } catch (Exception e) { e.printStackTrace(); } }
źródło