I'd like to know if there's a way to open a file browser (system or 3rd party like Astro) to a specific path. There's not much else to say here... pretty straight-forward question.
Sounds like ACTION_GET_CONTENT is what you want. See here. The relevant bits would be:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("file/*");
startActivityForResult(intent,PICKFILE_RESULT_CODE);
On my phone (which has astro already installed), this brings up an astro dialog for /sdcard. I'm not sure what this will do on a phone with no file browser installed. I'm also unsure about whether you are able to actually specify the starting path using this method. The docs make it sound like you can't specify a starting uri for ACTION_GET_CONTENT.
EDIT: I think I understand the question better now. I thought you were wanting a picker style browser to just get a file path from the user. If you want a full blown browser to handle your uri, then this worked for me:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file:///mnt/sdcard/Music"), "*/*");
startActivity(intent);
That will probably give you quite a long list of possible handlers, but I'd bet any file manager on the system would be in the list (astro certainly is).
I don't believe that any of the manufacturer provided File Browsers provide such a thing.
Though I don't see anything glaringly wrong with the theory of doing so. I imagine you are more likely to find a 3rd party file browser with this feature, but I've never come across any of those either.
You might look in to the Open Intents OI File Manager this concept seems right up their ally, if they don't already have this feature, I bet they might consider adding it if you get in contact with them.
Here i am going to show you that how to create a BROWSE button, which when you will click, it will open up the SDCARD, you will select a File and in result you will get the File Name and File path of the selected one:
// A button which you will hit**
browse.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);
Uri startDir = Uri.fromFile(new File("/sdcard"));
startActivityForResult(intent, PICK_REQUEST_CODE);
}
});
//The function which will get the Resulted File Name and File Path
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
{
if (requestCode == PICK_REQUEST_CODE)
{
if (resultCode == RESULT_OK)
{
Uri uri = intent.getData();
if (uri.getScheme().toString().compareTo("content")==0)
{
Cursor cursor =getContentResolver().query(uri, null, null, null, null);
if (cursor.moveToFirst())
{
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);//Instead of "MediaStore.Images.Media.DATA" can be used "_data"
Uri filePathUri = Uri.parse(cursor.getString(column_index));
String file_name = filePathUri.getLastPathSegment().toString();
String file_path=filePathUri.getPath();
Toast.makeText(this,"File Name & PATH are:"+file_name+"\n"+file_path, Toast.LENGTH_LONG).show();
}
}
}
}
}
Related
I am using this code to allow the user to select multiple .csv files from their storage:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("text/comma-separated-values");
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(Intent.createChooser(intent, "Get CSV Files"), REQUEST_IMPORT_CSV);
After choosing the files it goes to onActivityResult() and so far I have done:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_IMPORT_CSV:
if (data != null) {
ClipData clipData = data.getClipData();
ArrayList<Uri> csvUris = new ArrayList<>();
if (clipData != null) {
for (int i = 0; i < clipData.getItemCount(); i++) {
clipData.getItemAt(i).getText()
csvUris.add(clipData.getItemAt(i).getUri());
}
}
else {
csvUris.add(data.getData());
}
}
break;
}
}
Is this the right way to get all the relevant Uris from the result? If seems like if the user picks one file, I get the Uri from data.getData(), and if the user picked multiple files, then it goes straight to this clipData() thing instead.
Assuming (1) is correct, how do I get the filenames of the corresponding files that the user chose? For example "chosen_file.csv" (I am not asking for the path).
Is this the right way to get all the relevant Uris from the result?
AFAIK, yes. Leastways, it has worked for me.
how do I get the filenames of the corresponding files that the user chose?
Strictly speaking, you don't. There is no requirement for the Uri to point to a file, any more than the URL to this Web page has to point to a file.
What you can do is wrap the Uri in a DocumentFile, via fromSingleUri(). Then, call getName() on the DocumentFile to get a "display name" for the content. Depending on where the user got the content from, this may be a filename-like value. It is supposed to be something user-recognizable. However, do not assume that it is a filename, as it could be something else.
I use this code to share a zip file (fzip):
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(fzip));
sendIntent.putExtra("myfilename", fzip.getPath());
sendIntent.setType("application/zip");
startActivityForResult(sendIntent, 1);
After the file is shared (copied, added to Dropbox, ...) I want to delete the original zip file because it is no longer useful.
I try to use this:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == 1) {
String myname=data.getStringExtra("myfilename");
Toast.makeText(getApplicationContext(), "created file:" + myname , Toast.LENGTH_SHORT).show();
}
}
so that after I get the file name, and since the file has been shared, I could delete it.
The zip file is copied as it should. but the app crashes. What should I do?
First, ACTION_SEND is not used with startActivityForResult(), as it does not return a result.
Second, your extra is not on the Intent passed into onActivityResult(), because those are separate Intent objects.
Third, just because control returned to you does not mean that the other application is done with your file yet. You have no good way to know when the other app is done with the file. I would recommend waiting 24 hours and deleting it then.
In my application I will have list with different file paths.
Example list:
/storage/emulated/0/Edited/myjpeg_file.JPG
/storage/emulated/0/Downloads/bill.pdf
/storage/emulated/0/Downloads/mytextfile.txt
This list is showed in list view. When I click on one entry, it should open list of supported installed applications to process it further.
When I click on entry wit .JPG then it should show apps related to that.
And If i select .pdf file it should show supported apps
And for all paths default it should show file browser such as default file manager , Es Explorer etc...
I am referring to
http://developer.android.com/training/sharing/send.html
But need the selection based on file type (txt, xml, pdf jpeg etc..).
If i select .JPG file it is not showing gallery or Es file explorer (i have it on my mobile)
In same way when I click on .pdf file it is not showing adobe reader etc..
Below is my code:
public void openFile(String minmeType, Uri uriFromPath) {
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uriFromPath);
if(minmeType.contains("text/plain")) {
shareIntent.setType("text/plain");
} else {
shareIntent.setType("image/jpeg");
}
startActivity(Intent.createChooser(shareIntent, "sending out"));
}
Above function is called from below code:
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String path = pathList[position];
Uri uriFromPath = Uri.fromFile(new File(path));
Toast.makeText(getActivity().getApplicationContext(),"Uri: "+ uriFromPath, Toast.LENGTH_LONG).show();
if(path.contains(".JPG")) {
openFile("image/*", uriFromPath);
} else {
openFile("text/plain", uriFromPath);
}
return;
}
});
Have you tried using ACTION_VIEW instead of ACTION_SEND?
ACTION_SEND implies you want to send the document to somebody else. Adobe Reader won't catch those Intents that want to do ACTION_SEND, because sending pdfs is not what they do. VIEWing them, on the other hand, is.
You also need to match the intent that the target application is filtering for.
In this case, it's pretty simple what you want to do: you want Adobe Reader to open your file. And Adobe Reader actually has the intent filter you would expect. If you look into its Manifest file, you'll see that (among others) it includes an intent filter that matches Uris with schema file, any host, and any path that ends in .pdf. If you change your openFile method to this:
public void openFile(Uri uriFromPath) {
Intent shareIntent = new Intent(Intent.ACTION_VIEW, uriFromPath);
startActivity(Intent.createChooser(shareIntent, "sending out"));
}
It will work. It should also work for most apps that handle content from files.
I would like to start an intentchooser for apps which can return any kind of file
Currently I use (which I copied from the Android email source code for file attachment)
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
Intent i = Intent.createChooser(intent, "File");
startActivityForResult(i, CHOOSE_FILE_REQUESTCODE);
But it only shows "Gallery" and "Music player" on my Galaxy S2. There is a file explorer on this device and I would like it to appear in the list. I would also like the camera app to show in the list, so that the user can shoot a picture and send it through my app.
If I install Astro file manager it will respond to that intent, too. My customers are Galaxy SII owners only and I don't want to force them to install Astro file manager given that they already have a basic but sufficient file manager.
Any idea of how I could achieve this ? I am pretty sure that I already saw the default file manager appear in such a menu to pick a file, but I can't remember in which app.
Not for camera but for other files..
In my device I have ES File Explorer installed and This simply thing works in my case..
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("file/*");
startActivityForResult(intent, PICKFILE_REQUEST_CODE);
Samsung file explorer needs not only custom action (com.sec.android.app.myfiles.PICK_DATA),
but also category part (Intent.CATEGORY_DEFAULT) and mime-type should be passed as extra.
Intent intent = new Intent("com.sec.android.app.myfiles.PICK_DATA");
intent.putExtra("CONTENT_TYPE", "*/*");
intent.addCategory(Intent.CATEGORY_DEFAULT);
You can also use this action for opening multiple files: com.sec.android.app.myfiles.PICK_DATA_MULTIPLE
Anyway here is my solution which works on Samsung and other devices:
public void openFile(String mimeType) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(mimeType);
intent.addCategory(Intent.CATEGORY_OPENABLE);
// special intent for Samsung file manager
Intent sIntent = new Intent("com.sec.android.app.myfiles.PICK_DATA");
// if you want any file type, you can skip next line
sIntent.putExtra("CONTENT_TYPE", mimeType);
sIntent.addCategory(Intent.CATEGORY_DEFAULT);
Intent chooserIntent;
if (getPackageManager().resolveActivity(sIntent, 0) != null){
// it is device with Samsung file manager
chooserIntent = Intent.createChooser(sIntent, "Open file");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { intent});
} else {
chooserIntent = Intent.createChooser(intent, "Open file");
}
try {
startActivityForResult(chooserIntent, CHOOSE_FILE_REQUESTCODE);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(getApplicationContext(), "No suitable File Manager was found.", Toast.LENGTH_SHORT).show();
}
}
This solution works well for me, and maybe will be useful for someone else.
this work for me on galaxy note
its show
contacts,
file managers installed on device,
gallery,
music player
private void openFile(Int CODE) {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("*/*");
startActivityForResult(intent, CODE);
}
here get path in onActivityResult of activity.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
String Fpath = data.getDataString();
// do somthing...
super.onActivityResult(requestCode, resultCode, data);
}
This gives me the best result:
Intent intent;
if (android.os.Build.MANUFACTURER.equalsIgnoreCase("samsung")) {
intent = new Intent("com.sec.android.app.myfiles.PICK_DATA");
intent.putExtra("CONTENT_TYPE", "*/*");
intent.addCategory(Intent.CATEGORY_DEFAULT);
} else {
String[] mimeTypes =
{"application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", // .doc & .docx
"application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation", // .ppt & .pptx
"application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", // .xls & .xlsx
"text/plain",
"application/pdf",
"application/zip", "application/vnd.android.package-archive"};
intent = new Intent(Intent.ACTION_GET_CONTENT); // or ACTION_OPEN_DOCUMENT
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
}
Turns out the Samsung file explorer uses a custom action. This is why I could see the Samsung file explorer when looking for a file from the samsung apps, but not from mine.
The action is "com.sec.android.app.myfiles.PICK_DATA"
I created a custom Activity Picker which displays activities filtering both intents.
If you want to know this, it exists an open source library called aFileDialog that it is an small and easy to use which provides a file picker.
The difference with another file chooser's libraries for Android is that aFileDialog gives you the option to open the file chooser as a Dialog and as an Activity.
It also lets you to select folders, create files, filter files using regular expressions and show confirmation dialogs.
The other answers are not incorrect. However, now there are more options for opening files. For example, if you want the app to have long term, permanent acess to a file, you can use ACTION_OPEN_DOCUMENT instead. Refer to the official documentation: Open files using storage access framework. Also refer to this answer.
I know Android cannot handle PDFs natively. However, the Nexus One (and possibly other phones) come pre-installed with QuickOffice Viewer. How would I determine whether the user has a PDF viewer installed?
Currently, the code to start the PDF download looks pretty simple:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
After the download, the user clicks on the downloaded file to invoke the viewer.
However, if there is no PDF viewer, Android reports "Cannot download. The content is not supported on the phone."
I want to determine if the user will get this message, and if so, direct them to PDF apps in the Android Market.
I have been testing this and found that the following works. First you download the file independently and store it on the device and then you go do this:
File file = new File("/sdcard/download/somepdf.pdf");
PackageManager packageManager = getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");
List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (list.size() > 0 && file.isFile()) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
I have tested this on various emulator and a rooted cyanogen phone as well as a HTC Magic. If no pdf renderer is available the list will return zero and nothing will happen.
It seems to be important to set the data type to the pdf mime type to get the correct behaviour.
If you e.g. install droidreader it will react to the intent and display the pdf.
Of course you could do the check before you download the pdf as well depending on your use case or do things like popping up alerts or redirecting do other intents for download or whatever.
Edit: I have since refactored this out into a separate method ..
public static final String MIME_TYPE_PDF = "application/pdf";
/**
* Check if the supplied context can render PDF files via some installed application that reacts to a intent
* with the pdf mime type and viewing action.
*
* #param context
* #return
*/
public static boolean canDisplayPdf(Context context) {
PackageManager packageManager = context.getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType(MIME_TYPE_PDF);
if (packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY).size() > 0) {
return true;
} else {
return false;
}
}
You can query the PackageManager to see if there's a package that can handle your Intent. Here's an example: http://www.curious-creature.org/2008/12/15/android-can-i-use-this-intent/
You will probably use asynch task to download any file.so simple way is Just add below code in post execute() method of asynch task.it will ask for choice.
FileOpener.open(context, file);
and file should contain info about filepath and filename.Example
File file = new File(Environment
.getExternalStoragePublicDirectory("/MDroid")
+ filepath + fileName );
Hope it helps