Android-파일 공급자-권한 거부
app1과 app2의 두 가지 앱이 있습니다.
App2에는 다음이 있습니다.
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.android.provider.ImageSharing"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/paths" />
</provider>
paths.xml :
<paths>
<files-path name="my_images" path="images/"/>
</paths>
App2는 App1의 Activity에서 이미지에 대한 URI를 가져 오기 위해 요청을받습니다. App2 활동은 URI가 결정되면 다음을 수행합니다.
Intent intent = new Intent();
intent.setDataAndType(contentUri, getContentResolver().getType(contentUri));
int uid = Binder.getCallingUid();
String callingPackage = getPackageManager().getNameForUid(uid);
getApplicationContext().grantUriPermission(callingPackage, contentUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
setResult(Activity.RESULT_OK, intent);
finish();
App2에서 결과를 받으면 App1은 다음을 수행합니다.
Uri imageUri = data.getData();
if(imageUri != null) {
ImageView iv = (ImageView) layoutView.findViewById(R.id.imageReceived);
iv.setImageURI(imageUri);
}
App1에서 App2에서 돌아올 때 다음 예외가 발생합니다.
java.lang.SecurityException : 권한 거부 : 내 보내지 않은 ProcessRecord {52a99eb0 3493 : com.android.App1.app/u0a57} (pid = 3493, uid = 10057)에서 제공 업체 android.support.v4.content.FileProvider 열기 uid 10058
내가 도대체 뭘 잘못하고있는 겁니까 ?
이 문제를 해결하는 유일한 방법은 다음과 같이 필요할 수있는 모든 패키지에 권한을 부여하는 것입니다.
List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
첫째, 나는 멀리 전환하려고 할 것입니다 grantUriPermission()
단순히 넣어 FLAG_GRANT_READ_URI_PERMISSION
온 Intent
자체 를 통해addFlags()
또는 setFlag()
.
어떤 이유로 작동하지 않는 경우 getCallingUid()
논리가있는 위치 onCreate()
대신 논리를 이동하여 실제 "호출자"를 찾을 수 있는지 확인할 수 있습니다.
Android <= Lollipop (API 22)
이전 Android 버전에서이 문제를 해결하는 Lorenzo Quiroli 의 훌륭한 기사 가 있습니다.
그는 Intent의 ClipData를 수동으로 설정하고 이에 대한 권한을 다음과 같이 설정해야한다는 것을 발견했습니다.
if ( Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP ) {
takePictureIntent.setClipData( ClipData.newRawUri( "", photoURI ) );
takePictureIntent.addFlags( Intent.FLAG_GRANT_WRITE_URI_PERMISSION|Intent.FLAG_GRANT_READ_URI_PERMISSION );
}
나는 이것을 API 17에서 테스트했고 훌륭하게 작동했습니다. 작동하는 곳에서 해결책을 찾을 수 없습니다.
추가 setData(contentUri);
하고 요구 사항에 따라 추가 addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
하거나addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
이것은 java.lang.SecurityException : Permission Denial을 해결합니다.
확인되었습니다.
이것은 https://developer.android.com/reference/android/support/v4/content/FileProvider.html#Permissions에 따라 수행됩니다.
파일 공급자를 사용하여 Nougat에서 카메라를 사용하여 이미지를 캡처하는 방법.
파일 공급자에 대해 읽으려면이 링크를 클릭하십시오. 파일 공급자
, 키트 캣과 마시멜로가 다음 단계를 따릅니다. 먼저 MainfestFile의 애플리케이션 태그 아래에있는 광고 태그 제공 업체입니다.
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
res 폴더 아래에 (provider_paths.xml) 파일 이름을 만듭니다.
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
이 문제는 kitkat 버전에서 해결되었습니다.
private void takePicture() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
Uri photoURI = null;
try {
File photoFile = createImageFileWith();
path = photoFile.getAbsolutePath();
photoURI = FileProvider.getUriForFile(MainActivity.this,
getString(R.string.file_provider_authority),
photoFile);
} catch (IOException ex) {
Log.e("TakePicture", ex.getMessage());
}
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
takePictureIntent.setClipData(ClipData.newRawUri("", photoURI));
takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION|Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
startActivityForResult(takePictureIntent, PHOTO_REQUEST_CODE);
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM), "Camera");
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
나는 그런 식으로 문제를 해결했습니다.
Intent sIntent = new Intent("com.appname.ACTION_RETURN_FILE").setData(uri);
List<ResolveInfo> resInfoList = activity.getPackageManager().queryIntentActivities(sIntent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
activity.grantUriPermission(FILE_PROVIDER_ID, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
sIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.setResult(RESULT_OK, sIntent);
이 조언에 대해 @CommonsWare에게 감사드립니다.
내 문제는 호출 패키지에있었습니다. 어떤 이유로, Binder.callingUid()
그리고 getPackageManager().getNameForUid(uid)
날의 이름을 패키지주고 있었다 App2
대신 App1
.
I tried calling it in App2's onCreate
as well as onResume
, but no joy.
I used the following to solve it :
getApplicationContext().grantUriPermission(getCallingPackage(),
contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
Turns out, activity has dedicated API for this. See here.
You need to set permission of specific package name, after that you can able to access it..
context.grantUriPermission("com.android.App1.app", fileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
ReferenceURL : https://stackoverflow.com/questions/24467696/android-file-provider-permission-denial
'IT TIP' 카테고리의 다른 글
PHP : 현재 날짜의 월을 가져 오는 날짜 함수 (0) | 2020.12.26 |
---|---|
요청이 중단되었습니다. SSL / TLS 보안 채널을 만들 수 없습니다. (0) | 2020.12.26 |
Google 인앱 결제, IllegalArgumentException : Android L Dev Preview로 업그레이드 한 후 서비스 의도가 명시 적이어야합니다. (0) | 2020.12.26 |
Facebook Graph API GET 요청- "fields"매개 변수를 포함해야합니다 (Swift, Facebook SDK v4.5.1). (0) | 2020.12.26 |
오류 : npm ERR! (0) | 2020.12.26 |