Android - Provider authority in the application project

The android library project contains several providers whose credentials are defined in the class of contracts:

public static final String CONTENT_AUTHORITY = "my.com.library.providers.tester"; private static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY); 

Now there are many application projects that use this library project. The problem that I am currently facing is that for each application project I need to have a separate branch in the library project for each application just to have unique content. This creates some version control problems (for example, propagating signs / bug fixes from one branch to each other branch, etc.). Instead, I would like to delegate responsibility for determining the content permissions for the application project. Is there any way to do this?

+17
java android android-contentprovider android-library
May 28 '12 at 10:11
source share
2 answers

An application is the only thing absolutely necessary to know about permissions, as it declares a <provider> in a manifest with the android:authorities attribute.

Therefore, in principle, it should β€œjust work” while you remove all authorization-specific logic from the provider, for example:

  • those static data members (which now go to the hosting application)
  • UriMatcher (scan something yourself without checking credentials, but focusing on the rest of Uri )

If for some reason you are absolutely sure that your provider should know your credentials, the application will have to provide this to the provider before the provider is used for real work. Possible ways to do this:

  • Since a ContentProvider is a natural singleton, assign it to a static data member, and then grant it a privilege string using a custom method from the user class Application (since the providers are initialized first, so this should work)

  • If you only support API level 11+, use the Application class call() call() to

    to grant ContentProvider authority
  • Suppose the only real calls (e.g. query() , insert() ) are valid and just lazily initialize your power based on what goes into the first Uri you see

+21
May 28 '12 at 22:39
source share

I know that this is an old topic, but today I encountered this problem, and we are developing for quite some time, therefore we were not ready to go through all the statics in the Content Provider Contract and change them, also because our content provider and database generated a Mechanoid plug-in for Eclipse (Yes, I am also an author! :))

The solution I came across was to add a static initializer to our generated contract, which uses reflection to find the class and uses the static field CONTENT_AUTHORITY if it exists, if it does not return to default:

 public class QuxContract { public static final String CONTENT_AUTHORITY = initAuthority(); private static String initAuthority() { String authority = "com.example.app.data.qux"; try { ClassLoader loader = QuxContract.class.getClassLoader(); Class<?> clz = loader.loadClass("com.example.app.data.QuxContentProviderAuthority"); Field declaredField = clz.getDeclaredField("CONTENT_AUTHORITY"); authority = declaredField.get(null).toString(); } catch (ClassNotFoundException e) {} catch (NoSuchFieldException e) {} catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } return authority; } private static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY); // ... 

Now, in each project that refers to the library project, its own privileges can be granted:

 package com.example.app.data; public class QuxContentProviderAuthority { public static final String CONTENT_AUTHORITY = "com.example.app.data.baz"; } 

Also, be sure to also change the credentials in the manifest.

+23
Jan 29 '13 at 20:56
source share



All Articles