2017-03-13 43 views
4

是否有可能爲許多不同的應用程序使用的庫項目使用私有的(exported = false)ContentProvider?Android庫項目中的ContentProvider

問題是,即使CP未導出,它也必須具有唯一的權限。如果它不是唯一的,那麼您無法在同一部手機上安裝具有相同庫的多個應用程序(INSTALL_FAILED_CONFLICTING_PROVIDER)。

我知道我可以使用應用程序ID來定義AndroidManifest提供商這樣的:

<provider 
    android:authorities="${applicationId}.provider.test" 
    android:name=".storage.db.MyContentProvider" 
    android:exported="false" /> 

,但我不能找到一個解決方案,以生成運行時代碼的權限正確初始化一個UriMatcher。

BuildConfig.APPLICATION_ID返回庫項目的ID,而不是應用程序。 我可以嘗試從應用程序的上下文中獲取packageId,但如果應用程序使用具有不同appIds的flavor,則不是最佳解決方案。

所以我的想法來解決這個是:

  • 找到一個合適的appplicationId在我的庫代碼在運行時(也使用不同的應用程序ID口味時)
  • 找到一種方法,在適當的匹配URIs我的UriMatcher不瞭解權威。
+0

你可能會尋找一些所謂'的ProtectionLevel = signature'如果所有的應用程序都使用相同的密鑰簽名,看這裏http://stackoverflow.com/ questions/6120025/how-to-restrict-content-provider-data-across-applications and here http://stackoverflow.com/questions/23281860/how-do-i-restrict-access-to-my-contentprovider-to -only-my-apps,我沒有使用或閱讀詳細信息,但主要想法是隻允許使用相同密鑰簽名的應用訪問提供商 – Yazan

+0

我沒有擁有使用我的庫的應用,所以解決方案對應用程序開發人員應該是透明的。 – LR89

回答

3

我能夠在運行時根據找到的答案here獲得權限。該解決方案如下所示(API 9+)

private static String getAuthority(final Context appContext) throws PackageManager.NameNotFoundException { 
    final ComponentName componentName = new ComponentName(appContext, MyContentProvider.class.getName()); 
    final ProviderInfo providerInfo = appContext.getPackageManager().getProviderInfo(componentName, 0); 
    return providerInfo.authority; 
} 
0

不幸的是,唯一的方法是請求使用您的庫的應用程序的開發人員使用他們獨特的權限爲他們的AndroidManifest.xml添加標籤。