Finding out all about Android Uri class - use and purpose - android

Does anyone have some helpful links to find out about Android Uri's?
For example, you get a Uri back from a "take a picture" Intent. What does a URI look like and how do you use it. Why are they used instead of filenames or file handles?
The Dev documentation on the Uri class is practically worthless. http://developer.android.com/reference/android/net/Uri.html It is only clear if you already know exactly what it is, and how to use it.
Thanks for any links.

I'd check out the content providers section
http://developer.android.com/guide/topics/providers/content-providers.html
It expalins URI's for the different content providers and how they work.

Read this post it explained what is URI and URL ? Hope it will help to you.http://javapapers.com/servlet/uri-and-url-difference/
This is a list of URIs that can be used in intents.
http://www.openintents.org/en/uris

Related

SecurityException on Android Q for acessing ExternalStorage with ACTION_OPEN_DOCUMENT_TREE

I'm trying to fetch all images from a specific folder for displaying in a recycler view, but no matter what, i get a SecurityException.
I'm currently doing it the following way:
Code for selecting folder
Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
lastRequest = REQUEST_IMAGENS;
startActivityForResult(i, REQUEST_IMAGENS);
onActivityResult
getContentResolver().takePersistableUriPermission(data.getData(),data.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
and for fetching each individual bitmap (this part specifically i tried many different variations, but all with same result)
BitmapFactory.decodeStream(xContext.getContentResolver().openInputStream(Uri.parse(stringUri + "%3A" + (archiveName + ".png"))));
I think the problem is on the last bit of code, but i really dont know what else to try.
The exception i get is:
java.lang.SecurityException: Permission Denial: reading com.android.externalstorage.ExternalStorageProvider uri content://com.android.externalstorage.documents/tree/primary%3ADownload%2FSaurus%20-%20Cadastro%20-%20Imagens%3A2171.png from pid=13239, uid=10425 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
I've retrieved the persisted permissions with getPersistedUriPermissions and it contains the following uri:
content://com.android.externalstorage.documents/tree/primary%3ADownload%2FSaurus%20-%20Cadastro%20-%20Imagens
I'm almost certan i cant manually append the file name like i did, but i dont know what i have to do instead.
I've read other posts and there are lots of different answers, but none worked and i tried almost everything i could find.
Any help is appreciated, thanks.
Edited:
The problem is i only want the user to select the folder, not all the images, and then i will search the images i want within the folder, in a loop that i omitted because its not part of the problem. All i want to know is how to open a specific file within a folder i have permissions.
Code for selecting folder
As blackapps noted, get rid of those flags, as they are useless in this context.
I think the problem is on the last bit of code
Correct. You cannot create valid document Uri values manually.
but i really dont know what else to try
What you want is not reliable. You are making assumptions about display names of documents in a tree that may not match reality. But, if you are willing to live with compatibility problems, you can do this:
Step #1: Call DocumentFile.fromTreeUri(), passing in the tree Uri that you got from onActivityResult() to give you a DocumentFile for the tree
Step #2: Call listFiles() on that DocumentFile to give you an array of DocumentFile objects representing the contents of that tree root
Step #3: Use getName() and isFile() to filter that array to the subset that match your desired naming scheme
Step #4: For those that match, call getUri() to get the Uri for those documents, which you can pass to your favorite image-loading library

getType method in contentProvider subclass

i searched a lot about this topic
but i still can't wrap my brain around it
can someone "deeply explains to me " how getType() works ? and few examples that also explains the mime and how it is used when it is returned by getType() ?
Content URIs can be used to reference content from a wide variety of contexts. The getType method allows a content consumer - which might be a component in your app, but can also be component outside your app and which doesn't know anything specifically about your app except for the content URI - to find out what type of data a content URI refers to. The content consumer needs this information to know how what to do with the content - for example, how to display it - when it resolves the content URI. So in the simplest case, if the URI content://my.app/record/1 refers to a HTML file, then the type is text/html, and if the URI content://my.app/record/2 refers to a JPEG file then the type is image/jpeg. There is no other way to infer the content type from the URI (because e.g. there's no file extensions).
Android also provides some special MIME types for indicating table data, android.cursor.item/* and android.cursor.dir/*.
This approach is designed to fit in with Android's Activity based architecture, allowing the system to open content URIs by examining the content MIME type and then choosing an Intent to open an Activity which displays the content.

Correct way of making Uri for content resolver?

Reading previous posts, I can check all the content provider there are on my system.
I was wondering what is the correct way of making Uri's for the content resolver? Do we just put the whole path like Uri.parse("content://org.company.example.sampleprovider/items"); or should we go step by step like
Uri.builder.scheme("content://");
Uri.builder.authority("org.company.example.sampleprovider");
What is the correct next step to get the items? How is the Uri.matcher used? in this whole procedure?

How to refer to an array by Uri in Android?

Programming my application would be a lot easier if I could refer to an array by URI, and use that array to inflate a list. Has anyone done this? Thanks in advance!
No, it's not possible to refer to an array using a Uri in the same way that you do using R.array.yourarray.
Technically, just to say the proper answer, you could wrap an object to parse the Uri for you and return the R.array.yourarray for you. Like a Content Provider, for example. But obviously that is just nonsense, there is no reason to create a non standard thing when the standard works just fine.
I don't think there is any scenario that would require a Uri that the standard way doesn't handle just fine.

Why use ContentProvider.getType() to get MIME type?

Looking at content providers, I'm not quite clean on the typical usage of the getType() method. The API doc says about implementing this method that
This allows [applications] to retrieve the MIME
type for a URI when dispatching
intents.
Could anyone describe a typical case where using it would be particularly useful?
For example, you're writing content provider for picture gallery. You should mention in your getType() method that you provide pictures - jpg or png. So, when one will launch image gallery, it will be able to show built-in pictures and pictures provided by your content provider.
In pseudocode the user of contentProvider do something like:
List contentProviders = getProviders();
List resultProviders;
final Type type = Type.JPG;
for (ContentProvider provider : contentProviders) {
if (type == provider.getType()) {
resultProviders.add(provider);
}
}
This is pseudocode, but I hope you will got the idea.
As I understand it, a use case could be the following:
App A contains the content provider. App B uses that content provider to retrieve all the data items from App A. The user then picks one of these (in App B) and after that an activity in App A to show/edit/delete the selected data item should be started. So App B then creates an intent, and to make sure that an activity in App A handles it, you need to set the (mime-)type of the intent to the mime-type of the uri (the show/edit/delete activities in App A has added this mime type to their intent filters).

Categories

Resources