Organizing files on sdcard into directories - android

I have images uploaded on the simulated sdcard on my emulator. I downloaded them from the browser, using the long-click on each image.
When I look at the file explorer in the DDMS perspective, I see that they are in the directory sdcard/download.
Now if I want to download some audio files and use them in an app to, say list the title of all audio files, will they go in the same directory? (I am trying to push the audio files manually from my computer to the emulator).
This doesn't seem right. Shouldn't the media files of different types (pictures, audio, video) go into different directories?
Also, thinking this through a little, how is something like this related to the physical directory on the sdcard?
Uri mMedia = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Thanks!

The correct way to access media content is via the media content providers on the device.
Content providers make it easy to access data in a unified way, whether that data is stored on disk (i.e. /sdcard/...) or in something like a SQLite database. Content providers generally expose data using a custom Android-specific content:// URI scheme.
To query content living at a given content URI (such as MediaStore.Images.Media.EXTERNAL_CONTENT_URI), use the ContentResolver class. Examples on how to use this class can be found all throughout the SDK samples and Android Open Source Project (gitweb).
Also look at the MediaScannerConnection class for information on triggering media scanning (which populates the media content providers), etc.

Related

Storage so my media/non media files are accessible by other apps

I am confused with the new app storage system in Android. I am not sure where my use case falls under and I need your help in telling me the right approach for this
My app captures images and generates pdf documents. Prior to Android 10, I used to store them in an app directory where the user can easily navigate to them through other files browsing app (like Files app on Samsung). In addition, these files can be accessed from within my app (so essentially read and write).
With the new storage, I am not sure how to accomplish the same thing. If I use the internal storage then user can't see them. If I use the media approach, well it seems it is only for Audio/video plus they will not be organized in a folder like I have them organized.
Am I missing something? How would I solve this problem?
Thank you
On an Android 11 device you can store your files in a subdirectory of the public Documents directory.
You can do that using classic File means or the media store or SAF.
Other apps can see them using SAF or the media store. Or with classic file means when requested all files access.
The user can see them using the default Files app on the device.

getting content uri of already downloaded video in android Q

i still don't understand the change made on access media files in android Q. My app downloads videos, but playing or retrieving the video gives error.
Noticed, for android Q, every media file outside of app specific folders need to be registered in the contentresolver. In which the content resolver gives a special id to that file in return. Am i right?
if so how do i register a media file in content resolver and at the same time get the uri of the media file
A good explanation on accessing, saving and opening media files on android Q will be appreciated for a better understanding
The file manipulation changes from android 9 (Q) are really confusing.
Have you read the basic documentation on data and file storage?
Basically consider your app can write and read files that it created inside internal storage or primary external storage on the folders that belongs to this app.
Reading from sdcard can be done but requires permission from the user.
Writing on sdcard can be done with limitations and is not so easy. It also requires user permission.
Media files can be handled by MediaStore api and if they are inside the folders from your app it is easier.
If you want to store Media file on other folders different from the default media folders, then it is a little more difficult.
Please, define better what are your app flows and requirements in order to be easier for someone to help.

Android sharing between apps using ContentUri

I wanted to know the best approach to passing information from an app to another app on the same devices in android.
For example:
I open google apps and I share a document with my App A.
Google App generated an intent and sends a content URI. From my
understanding, the content uri contains information about the file
(filename, file size, mimetype) and the ability to extract the
content which is located in the cache of the google app on the
device.
When App A opens, it reads the content URI. Ideally, it
should be able to extract the information from the content uri and
then render the image. What this means is that App A will display the image shared. In this example, google app shares a docement, and App A wants to open and display the document within it's own app.
The confusing part
From searching the web, it seems that some people actually try to
extract the file path from the content URI. This requires that you
have permission to access another app's cache or storage space
within the device. Let's say this is possible. It also makes some
assumptions that it's possible to extract the file path.
After reading some articles:
https://commonsware.com/blog/2016/03/14/psa-file-scheme-ban-n-developer-preview.html
https://commonsware.com/blog/2014/07/04/uri-not-necessarily-file.html
https://commonsware.com/blog/2016/03/15/how-consume-content-uri.html
it seems that, ideally you should never assume that you can extract the file path and that google has made some updates that makes this not possible.
Work around:
Eventhough i'm not able to extract the file path from the
contentUri, I'm able to read the bytes of what the contentUri is
pointing to. So I could save it to a file that is relevant to the
local cache of App A and pass that path along to get render or pass
the bytes back. This refers to App A displaying the content. That is passing the path or bytes and let's make the assumption that it knows how to display it given that information.
Question:
The work around does not seem ideal because technically you are
save the file again on the device. There are two locations with the
same content ( google app storage and App A's storage). You also
have to manage when to delete the App A's file that you created.
This doesn't really seem ideal and was wondering what the best
approach would be? Or is this the expected flow?
Also I don't know
if it's ideal to pass the bytes back up vs. just a file path.
Update
To be more specific, the app i'm creating is a hybrid where i'm using cordova plugin to interact with a web app. The web app has methods to process or display the shared document based on file path. So ideally I want to keep it consistent with just reading the file path so that the other platforms that the web app supports does not break.
Any advice appreciated,
D
Eventhough i'm not able to extract the file path from the contentUri, I'm able to read the bytes of what the contentUri is pointing to.
Correct. This is not significantly different than how you use an HTTPS URL, where you also do not have direct filesystem access to the content (in that case, resident on a different server).
So I could save it to a file that is relevant to the local cache of App A and pass that path along to get render or pass the bytes back.
Or, just consume the bytes. Again, drawing an analogy to an HTTPS URL, there is no requirement to save those bytes to disk to use them.
The work around does not seem ideal because technically you are save the file again on the device. There are two locations with the same content ( google app storage and App A's storage). You also have to manage when to delete the App A's file that you created.
Then do not save the file again on the device, and simply use the stream of bytes. Again, this is not significantly different than using an HTTPS URL.
This doesn't really seem ideal and was wondering what the best approach would be?
Do not write the bytes to disk. Just use them.
So ideally I want to keep it consistent with just reading the file path so that the other platforms that the web app supports does not break.
Your choices are:
Improve the Web app code, such that a local file path is one possible source of the data, or
Suffer the problems with making copies of that data
After all, bear in mind that the Uri you are given via ACTION_SEND does not have to be a content Uri. It could very easily be an http or https Uri.

Accessing music files into my application programmatically

How can I access music files in the device into my application programmatically?
Another approach could be to use the MediaStore content provider to find your music: http://developer.android.com/reference/android/provider/MediaStore.html.
There's a DATA field in the MediaColumns that holds the data stream for the media file.
Google has an example of reading images from the MediaStore a bit more than half way down this page: http://developer.android.com/guide/topics/providers/content-providers.html. You should be able to adopt the code to read music without too much trouble, I think.
EDIT: Google has re-written the documentation on content providers. The example I referred to above doesn't seem to exist any longer. But once you have an URI for your media, you should be able to get an Input stream by using:
InputStream is = getContentResolver().openInputStream(uri);
Depending on where your files are stored you can use:
Environment.getExternalStorageDirectory();
or:
Environment.getDataDirectory();
Both will give you the root path to their respective data. i.e. getExternalStorageDirectory() will gives me /mnt/sdcard/ on my Evo 4G since my SD card is registered as external storage for the device.
After that you have to know where your files are and make your way to that folder.

Show a list of files

I would like to show a list of files in the Android phone.
For example, i would like my app to be able to list all images stored in the phone, i dont want a gallery view, just a simple list.
I would also like to be able to show all the audio files
any help would be appreciated
Thanks
I'm assuming you mean on external storage. Read up on Data Storage, which will tell you the correct way to go about navigating the file-system.
If you're using API Level 8 or
greater, use getExternalFilesDir() to
open a File that represents the
external storage directory where you
should save your files. This method
takes a type parameter that specifies
the type of subdirectory you want,
such as DIRECTORY_MUSIC and
DIRECTORY_RINGTONES (pass null to
receive the root of your application's
file directory). This method will
create the appropriate directory if
necessary. By specifying the type of
directory, you ensure that the
Android's media scanner will properly
categorize your files in the system
(for example, ringtones are identified
as ringtones and not music). If the
user uninstalls your application, this
directory and all its contents will be
deleted.
If you're using API Level 7 or lower,
use getExternalStorageDirectory(), to
open a File representing the root of
the external storage.
For standard/common media types such as Music, video and images in the internal memory, there are respective ContentProviders in the system that manage them. If you want to build list of such items you should consider querying respective ContentProviders (Google for MediaStore Provider).
However, if you want to build an exhaustive list of all the files in a particular directory, internal or external, you can use File#listFiles() API as was suggested by Fredley above.

Categories

Resources