13

두 개의 응용 프로그램이 있습니다. FileProvider를 사용하여 응용 프로그램 A에서 응용 프로그램 B로 파일을 공유하려고합니다. 응용 프로그램 A는 응용 프로그램 B의 ContentProvider에서 insert 메서드를 호출하여 레코드를 삽입합니다. 삽입 된 데이터에는 앱 A에서 공유하려는 파일에 대한 Uri가 포함됩니다. App B의 ContentProvider는 App A에서 공유 파일을 읽으려고합니다. 파일을 공유하기 위해 의도를 사용하지 않기 때문에, 애플리케이션 (A)에 Context.grantUriPermission 호출 중이하는 판독 가능 (때때로 쓰기) 할 :FileProvider와 파일을 공유 할 때 grantUriPermission이있는 SecurityException

java.lang.SecurityException: Uid 10066 does not have permission to uri content://au.com.example.AppA.fileprovider/MyFolder/MyFileName 
at android.os.Parcel.readException(Parcel.java:1322) 
at android.os.Parcel.readException(Parcel.java:1276) 
at android.app.ActivityManagerProxy.grantUriPermission(ActivityManagerNative.java:2374) 
at android.app.ContextImpl.grantUriPermission(ContextImpl.java:1371) 
at android.content.ContextWrapper.grantUriPermission(ContextWrapper.java:400) 
at etc... 

애플리케이션 A를 가지고

mContext.grantUriPermission(MyPackageName, contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 

그러나,이 라인을 실행하는 날을 준다 (명칭 무고한 보호 변경) 매니페스트 파일의 다음 내용 :

<provider 
    android:name="android.support.v4.content.FileProvider" 
    android:authorities="au.com.example.AppA.fileprovider" 
    android:exported="false" 
    android:grantUriPermissions="true" 
    android:readPermission="au.com.example.READ_CONTENT" 
    android:writePermission="au.com.example.WRITE_CONTENT" > 
    <meta-data 
     android:name="android.support.FILE_PROVIDER_PATHS" 
     android:resource="@xml/filepaths" /> 
</provider> 

filepaths.xml이있다 : 나는 두 응용 프로그램에서 사용 권한을 정의하는 시도했습니다

<uses-permission android:name="au.com.example.READ_CONTENT" /> 
<uses-permission android:name="au.com.example.WRITE_CONTENT" /> 

: 응용 프로그램 A와 응용 프로그램 B는 모두 다음과 같은 한

<paths> 
    <files-path 
     name="MyFolder" 
     path="MyFolder/" /> 
</paths> 

. 그들은 모두 같은 디버그 서명으로 서명됩니다 : 파일의 끝

<permission 
    android:name="au.com.example.READ_CONTENT" 
    android:permissionGroup="MyGroup" 
    android:protectionLevel="signature" > 
</permission> 
<permission 
    android:name="au.com.example.WRITE_CONTENT" 
    android:permissionGroup="MyGroup" 
    android:protectionLevel="signature" > 
</permission> 

실제 경로는 다음과 같습니다

/data/data/au.com.example.AppA/files/MyFolder 

내가 난처한 상황에 빠진있어이 시점에서. 같은 응용 프로그램 내에서 방금 만든 파일에 대한 권한을 왜 부여 할 수 없는지 모르겠습니다. 그래서 내 질문은 다음과 같습니다.이 예외가 발생하는 이유는 무엇이며 어떻게 App B에 대한 사용 권한을 성공적으로 부여 할 수 있습니까?

답변

15

글쎄, 일주일이 지난 후 많은 시행 착오를 겪었을 때 대답은 사용 권한을 지정하지 않는 것 같습니다. 따라서 App A Manifest는 다음을 포함해야합니다.

<provider 
    android:name="android.support.v4.content.FileProvider" 
    android:authorities="au.com.example.AppA.fileprovider" 
    android:exported="false" 
    android:grantUriPermissions="true" > 
    <meta-data 
     android:name="android.support.FILE_PROVIDER_PATHS" 
     android:resource="@xml/filepaths" /> 
</provider> 

즉, 읽기 및 쓰기 권한을 제거했습니다. 필자의 초기 이해와 달리 달리 언급하지 않은 문서를 찾지 못하면 액세스를 제한하는 데 필요한 것이 었습니다. 그러나 나는 그들이 실제로 간섭하고 Context.grantUriPermission가 실패하는 것을 발견했습니다. 접근은 이미 제한되어 있습니다.

final long token = Binder.clearCallingIdentity(); 
try { 
    [retrieve file here] 
} finally { 
    Binder.restoreCallingIdentity(token); 
} 

을 앱의 콘텐츠 제공 업체 :

Android Permission denial in Widget RemoteViewsFactory for Content

내가 추가했다 :

이 그림을 완성하고, 내 질문의 두 번째 부분에 대답하기 위해, 나는 다음과 같은 발견 그렇지 않으면 보안 오류가 발생합니다.

+0

또한이 문제가 발생하여 매니페스트에서 읽기 권한을 제거했지만 여전히 다음 원인으로 인해 발생했습니다 : java.lang.SecurityException : Permission Denial : 프로 시저를 여는 android.support.v4.content.FileProvider ProcessRecord {40b7b968 7764 : com.google.android.gm/10018} (pid = 7764, uid = 10018)은 null 또는 null이 필요합니다. ' – StuStirling

+0

@ DiscoS2 같은 것을 보았습니다. 응용 프로그램을 제거하고 다시 설치하면 문제가 해결되었습니다. 나는 체크하지 않았지만, 어떤 종류의 매니 페스트가 계속 캐싱되고 있다고 생각합니다. – DavidsAlias

+2

시그니처 수준에서 사용 권한을 사용하지 않는 경우 응용 프로그램이 외부 위협에 노출되어 올바른 Uri를 가진 파일을 읽을 수 없습니까? – Toochka

-2

코드의 첫 번째 문제는 내 보낸 특성을 false로 설정 한 것입니다. true로 변경하십시오.

<provider 
android:name="android.support.v4.content.FileProvider" 
android:authorities="au.com.example.AppA.fileprovider" 
android:exported="true" 
android:readPermission="au.com.example.READ_CONTENT" 
android:writePermission="au.com.example.WRITE_CONTENT" > 
</provider> 

두 번째로해야 할 일은 외부 응용 프로그램 App B가 응용 프로그램 A에서 콘텐츠 공급자를 사용하는 경우입니다.그런 다음 응용 프로그램 매니페스트 파일 언급 권한에 B의 언급은 사용-허가

<permission 
android:name="au.com.example.READ_CONTENT" 
> 
</permission> 
<permission 
android:name="au.com.example.WRITE_CONTENT" 
> 
</permission> 

로 및 응용 프로그램에 나를 당신의 문제가 해결 아닌지 여부를 알려 주시기 바랍니다

<uses-permission android:name="au.com.example.READ_CONTENT" /> 
<uses-permission android:name="au.com.example.WRITE_CONTENT" /> 

로합니다. 그렇지 않으면 전체 코드를 보내주십시오. 나는 그 문제를 찾으려고 노력할 것이다. 감사합니다.

+1

나는이 문제를 해결했다. 수락 된 답변을 참조하십시오. Exported = true이면 나열된 권한을 가진 모든 응용 프로그램에 대한 액세스가 허용됩니다. 한 응용 프로그램에서 다른 응용 프로그램으로 공유하려고했습니다. – DavidsAlias

+0

임시 허가를 의미합니까 –

+3

'FileProvider'가'android : exported = "true"'를 확인하고 예외를 던집니다. – WindRider