次の方法を使用して、ライブラリ内に ContentProvider をパッケージ化し、実行時に ContentProvider の権限を設定して、ContentProvider 権限の競合なしで複数のプロジェクトに含めることができます。これが機能するのは、実際の「権限」が ContentProvider クラスではなく AndroidManifest に由来するためです。
基本的な ContentProvider 実装から始めます..AUTHORITY、CONTENT_URI、および UriMatcher は静的ですが、「最終」ではありません....
public class MyContentProvider extends ContentProvider {
public static String AUTHORITY = "com.foo.bar.content";
public static Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
protected static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
次に、「attachInfo」メソッドをオーバーライドして、ContentProvider が最初に初期化されるときに、AndroidManifest から収集された ProviderInfo を使用して ContentProvider が呼び出されるようにします。これは、可能性のあるクエリが行われる前に発生します。ほとんどの場合、最初の Application クラスのセットアップ中に発生します。この機会を利用して、ContentProvider ライブラリを使用しているアプリケーションによって提供されるように、AUTHORITY、CONTENT_URI、および UriMatcher を「実際の」値にリセットします。
@Override
public void attachInfo(Context context, ProviderInfo info) {
super.attachInfo(context, info);
AUTHORITY = info.authority;
CONTENT_URI = Uri.parse("content://" + AUTHORITY);
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, AlarmTable.TABLENAME, ALARMS);
uriMatcher.addURI(AUTHORITY, AttributeTable.TABLENAME, ATTRIBUTES);
uriMatcher.addURI(AUTHORITY, DeepLinkTable.TABLENAME, DEEPLINKS);
uriMatcher.addURI(AUTHORITY, NotificationTable.TABLENAME, NOTIFICATIONS);
uriMatcher.addURI(AUTHORITY, MetaDataTable.TABLENAME, RESOURCE_METADATA);
uriMatcher.addURI(AUTHORITY, ResourceTable.TABLENAME, RESOURCES);
uriMatcher.addURI(AUTHORITY, ResourceAttributeTable.TABLENAME, RESOURCES_ATTRIBUTES);
uriMatcher.addURI(AUTHORITY, ResourceTagTable.TABLENAME, RESOURCES_TAGS);
uriMatcher.addURI(AUTHORITY, TagTable.TABLENAME, TAGS);
uriMatcher.addURI(AUTHORITY, UserTagTable.TABLENAME, USER_TAGS);
uriMatcher.addURI(AUTHORITY, UserTable.TABLENAME, USERS);
uriMatcher.addURI(AUTHORITY, CUSTOM, RAW);
}
Application が開始されると、ContentProvider は Application クラスとともに実際にインスタンス化されるため、必要なすべてのパッケージ情報にアクセスできます。ProviderInfo オブジェクトには、AndroidManifest で提供される情報が含まれます...最終的なアプリケーションに含まれるリスト。
<provider android:authorities="com.foo.barapp.content"
android:name="com.foo.bar.MyContentProvider"/>
Authority はデフォルト値ではなく「com.foo.barapp.content」で書き換えられ、UriMatcher はデフォルト値ではなくアプリケーションの値に更新されます。「AUTHORITY」に依存するクラスは更新された値にアクセスするようになり、UriMatcher は「com.foo.barapp.content」の着信クエリを適切に区別します。
これをサンプル アプリケーションと androidTest パッケージの両方で同時にテストしたところ、正しく動作することがわかりました。