Does Android Content Provider authority definition break the DRY rule? -
android's content provider must have:
at least 1 authority must specified.
so example in google's samples android-basicsyncadapter androidmanifest.xml there is
<provider android:name=".provider.feedprovider" android:authorities="com.example.android.basicsyncadapter" android:exported="false" /> then implement cp 1 need define same string inside cp in android-basicsyncadapter feedprovider.java content_authority
public static final string content_authority = "com.example.android.basicsyncadapter"; as have define string twice, isn't breaking dry rule - if change in 1 place, have remember change somewhere else well.
actually don't have specify authority multiple times. in our opentasks provider load authority @ runtime manifest.
the basic idea this:
context context = getcontext(); packagemanager packagemanager = context.getpackagemanager(); providerinfo providerinfo = packagemanager.getproviderinfo( new componentname(context, this.getclass()), packagemanager.get_providers | packagemanager.get_meta_data); string authority = providerinfo.authority; on android 2.2 have take efforts since method getproviderinfo not present yet.
optionally specify authority in string resource , refer manifest so:
<provider android:name=".provider.feedprovider" android:authorities="@string/authority" android:exported="false" /> in content provider load authority usual:
string authority = getcontext().getstring(r.string.authority); it's bit more difficult if content provider serves multiple authorities, that's not idea anyway.
update follow comment:
i don't see problem providing context contract.
instead of writing like
cursor c = contentprovider.query(mycontract.items.content_uri, null, null, null, null); you write
cursor c = contentprovider.query(mycontract.items.itemsuri(getcontext()), null, null, null, null); with
public final interface mycontract { // ... lots of other tables ... public final static class items { public final static string content_path = "items"; // contract definitions public final static uri itemsuri(context context) { return new uri.builder() .scheme("content") .authority(context.getstring(r.string.authority)). .path(content_path) .build(); } } there not of difference, except can more convenient when need add id:
cursor c = contentprovider.query(mycontract.items.itemuri(getcontext(), myitemid), null, null, null, null); passing context these static methods not problem since need context anyway contentresolver.
an advantage of technique code independent of actual authority , can import contentprovider library different project different authority , don't need change single line of code.
btw prefer first version (loading authority manifest) since don't need string resource in case. can inject ${applicationid} , never touch again.
the following manifest snippet guarantees authority unique each app import in:
<provider android:name=".provider.feedprovider" android:authorities="${applicationid}.myauthority" android:exported="false" />
Comments
Post a Comment