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

Popular posts from this blog

Ansible - ERROR! the field 'hosts' is required but was not set -

customize file_field button ruby on rails -

SoapUI on windows 10 - high DPI/4K scaling issue -