When querying a ContentProvider on Android, one specifies the ContentProvider of interest by providing the "content URI" for that ContentProvider. What happens when multiple ContentProvider's serve that same URI, either intentionally? or maliciously?
When trying to open a pic on my phone, I've seen it prompt with apps that can "handle" the image. Will the same kind of thing happen here?
Multiple ContentProviders can't do this. The first application that registers a content provider using the element in its manifest has control over the URI pattern. I'm pretty sure that you'll get an installation error if you try to add another provider that uses the same URI pattern. Android keeps track of providers and URIs.
When you see a prompt with multiple apps for handling a file or situation, that's because the apps have specified an with a child that includes
android.intent.category.CATEGORY_ALTERNATIVE or android.intent-category.CATEGORY_SELECTED_ALTERNATVE. In essence, the app or apps are declaring themselves to be alternatives to the action specified in the child. This allows the user to have multiple choices for handling a type of data.
It makes sense to provide alternatives: a user might want to edit a picture, share it via Twitter, or e-mail it.
Note that two content providers can do the same thing, but they can't use the same URI. An app has to make a conscious choice of which one to use, or provide some mechanism of choosing between the two.
Related
Despite this being a simple question I cannot find the answer on google or stackoverflow.
When I use the following code I get this result //com.android.externalstorage.documents/tree/primary:Podcasts
var intent = new Intent(Intent.ActionOpenDocumentTree);
intent.PutExtra("android.content.extra.SHOW_ADVANCED", true);
intent.PutExtra("android.content.extra.FANCY", true);
intent.PutExtra("android.content.extra.SHOW_FILESIZE", true);
Can you help me understand the parts of my result?
How Android Storage works?
To ensure security between Android apps, Android didn't let you directly access every file within the storage system. They have something called ContentProvider.
Think of this content provider like a waiter, that your apps can ask for a certain file/folder (through Content Uri).
Content Uri will look like this: content://[Authority]/[path]/[id] is just an example of Content Uri. com.android.externalstorage.documents is an example of authority (for access to External Storage providers).
So in your case, your Uri will gain you access to the directory of Podcasts in your External Storage.
By having Uri, you can communicate between apps or service provider easily without having to pass real file every time you ask or give one. Just pass a lightweight simple Uri.
What happened in your code?
If you're wondering what happens in your code, try to look at the Reference.
It says:
Allow the user to pick a directory subtree. When invoked, the system will display the various DocumentsProvider instances installed on the device, letting the user navigate through them. Apps can fully manage documents within the returned directory.
I'm not sure what you're trying to achieve (please clarify if you can, so I can help out), but I hope my answer contains enough information.
Is it possible to add a filter to a content provider to make it accept only requests coming from a set of known application IDs?
For example, if com.domain1.app1 and com.domain2.app2 are two app that I trust I'd like to make them read my data. Any other application should be kept outside.
Something like intent filter but related to incoming request from other applications.
I know about the same signing key but it's not what I need.
If a provider's application doesn't specify any permissions, then other applications have no access to the provider's data. However, components in the provider's application always have full read and write access, regardless of the specified permissions.
As seen here.
What is the reason for content provider authorities?
How/why do I want to use them other than I HAVE to declare them in the manifest?
I've tried to do my homework on this question and cannot find a decent, cohesive discussion on this topic.
Here is the best I could find (in additi on to the four books on Android development I own):
https://stackoverflow.com/search?q=content+provider+authority
Content Providers, Authority and and URI matching
Get a list of available Content Providers
http://developer.android.com/guide/topics/manifest/provider-element.html
http://developer.android.com/guide/topics/providers/content-provider-creating.html
The Authority is used to interact with a particular content provider, that means it must be unique. That's why is a good practice to declare it as your domain name (in reverse) plus the name of the package containing the provider, that way is less likely that other developer creates an app with a content provider declaring the same authority.
You declare it in the manifest so your app and other apps (if you let them) can manipulate
data through your content provider in the form of a uri:
content://authority-name/data-in-the-provider
It works similar to domains in http urls:
http://domain-name/data-in-the-site
I am also looking for explanation and to add to answer provided by ILovemyPoncho, I hit this particular answer and I quote:
and what exactly is android:authorities asking for?
A system wide unique identifier for your provider. Or better worldwide
unique. All providers are registered with the system and they need to
be unique or the second app that wants to use the same name can't be
installed.
You use that string in the end to communicate with your provider via
an Uri like
Uri uri = Uri.parse("content://" + "your.authoritiy.string")
Let's put it this way: There is an invisible hand that facilitates your request to your app's ContentProvider.
For example:
Uri uri = mContext.getContentResolver().insert(NotifireContentProvider2.NOTE_URI, values);
Basically, what you are saying here to the Android OS is insert data given the URI containing the authority you have defined in the XML. The OS will search for this particular content provider and send the request to it. You insert method on the ContentProvider will be called and you must match the URI to handle it accordingly.
Also, what if, you're content provider is so simplistic that others have similar authority as well. I haven't encountered those two problem I mentioned but I reckon it won't be pleasant.
Authority is there to make sure that the OS understand which provider will provide the data to the requesting app and to make sure that is the provider providing it.
I have seen custom content providers for sqLite in apps, but thats about it. When should a Custom Content provider be built?
EboMike in this question says:
Other apps will be able to access your data.
You can wrap and abstract a lot of the query logic in your content provider, and limit access.
You will be able to lean on the system to allow for things like managed queries.
Remember that you can control user interacts with your data,for example you can prevent user from modifying data or you can force system to open data with explicit App and so on.
I've read Android dev guide and notice that we can implement different classes for the content provider. So,
There are many content providers or just one content provider in one Android app?
How to properly implement different content provider classes like that?
Here is what I read from the dev guide:
You implement a provider as one or more classes in an Android
application
http://developer.android.com/guide/topics/providers/content-provider-creating.html
You can implement as many as you want, as you can see from the documentation here. To register a content provider, you need to add its corresponding <provider> tag in the Android Manifest.
In most cases, however, you won't need multiple content providers. One is usually enough, as it can handle multiple tables. You should only really need more than one if you want your app to provide public access to 2+ separate data entities.
You can use (provide as well as use) as many content providers per app as you need. They need different content URIs, of course.
In addition to the uses outlined in the document (your link) you can use content providers for other purposes as accessing data storage. The content URI can have parameters, so you can use a content provider similarly to a web service.
You can create as many content providers as you want. But do you need them al?
What content provider classes do you want to implement? If you read the page very good you should have seen that it contains links to two pages:
http://developer.android.com/guide/topics/providers/content-provider-basics.html - Content Provider Basics
http://developer.android.com/guide/topics/providers/content-provider-creating.html#ContentProvider - Implementing the ContentProvider Class
I suggest you first read those pages. Google is giving some more information about Content Providers, tutorials and examples:
http://android10.org/index.php/articlesdatastorage/252-content-providers-using-and-creating-them
http://thinkandroid.wordpress.com/2010/01/13/writing-your-own-contentprovider/
http://www.vogella.com/articles/AndroidSQLite/article.html
http://about-android.blogspot.com/2010/04/content-provider-example-1.html
There is no rule as such that you have to implement only one content provider per application. If your project demands, then you can do so.
If you want to implement multiple content providers in your application package, then make sure that authorities part of each content provider is unique, to route the incoming data requests to each content providers properly.
But having too many content providers can really confuse you and not required.
The only scenario that I see to have multiple content providers is, if you are having multiple databases in your application and you want to share all those databases with outside applications. Where you can use separate content provider for each database to share it with outside world.
Hope it helps.