I'm working on a program which needs to show list file in ListView. I got this list with path_of_files. But this is what i want to ask: when i clicked on an item, how can user open it? I think i want a popup let user choose which program user want to open it.
For example: I have a path: /sdcard/file.xls. When user clicked in, a popup shows some application like: Microsoft Excel, Google Spreadsheet (I only want to work with xls - and it only works with it, still ok). How can i do it?
File sdCardRoot = Environment.getExternalStorageDirectory();
File yourDir = new File(sdCardRoot, "directory");
for (File f : yourDir.listFiles()) {
if (f.isFile()) {
String name = f.getName();
Long lastModified = f.lastModified();
if (name.toLowerCase().contains(".xls"))
fileObjList.add(new FileObj(0,name,lastModified));
}
}
This is my code to get filename and file path.
First , set a listener to your listView Items . And inside the handler callback you can do something likebelow to open up excels :
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(path, "application/vnd.ms-excel");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(intent);
}
catch (ActivityNotFoundException e) {
Toast.makeText(context, "No Application Available to View Excel", Toast.LENGTH_SHORT).show();
}
Related
I've been trying to figure out a way to open the Android File Manager directly in my app's Documents directory so the user can select a JSON file among several without requiring the user to go search for the file path /storage/emulated/0/Android/data/com.company.app/files/Documents/. So far, I can make the "go find it yourself" tactic work, but not the "take the user to the directory for them" approach. Here's what I've tried:
// this is the "go find it yourself" approach that I've used:
String filename = this.getResources().getString(R.string.ExportImportFileNameString);
File directory = this.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
Uri dirPathUri = Uri.fromFile(directory);
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
Intent.createChooser(intent, "Open in...");
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, directory);
startActivityForResult(intent, IMPORT_REQUEST);
When my onActivityComplete handler is called for IMPORT_REQUEST I see the returned data looks like dat=content://com.lge.filemanager.FileProvider/storage/emulated/0/Android/data/com.company.app/files/Documents/SelectedFile.json flg=0x1 }
I've tried to invoke two different combinations of intent.setDataAndType instead of intent.setTypefollowing and that fails to let me select anything:
// This setDataAndType setup does not allow the user to open File Manager, nor navigate to the app Documents:
intent.setDataAndType(dirPath2, "application/json");
// This allows opening of File Manager but returns immediately without allowing the user to select a file, and returns a null data pointer:
intent.setDataAndType(dirPath2, "*/*");
Note that I've tried creating the intent object with ACTION_OPEN_DOCUMENT, ACTION_GET_CONTENT, and ACTION_VIEW with the similar result.
If I only have one file, I know I can have the app simply open a stream reader for a known file name as such:
File directory = this.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
File importFile = new File(directory, filename);
try
{
fis = new FileInputStream (importFile);
InputStreamReader inputStreamReader =
new InputStreamReader(fis, StandardCharsets.UTF_8);
...
However, that doesn't allow me the flexibility that I desire to allow a user to select from multiple files. Can anyone illuminate what's going on here and how to correct the situation.
Based on Commonsware feedback, here's what I have for the solution to this question:
//--------------
// Get the documents location for this app
File directory = this.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
File desiredFilePath = new File(directory.toString());
try{
// read all pathnames for files and directory
File[] allFilesInDirectory = desiredFilePath.listFiles();
// prepare array to place all path strings into
ArrayList<String> filesInDirectoryArray = new ArrayList<String>();
// retrieve each pathname file array
// but someone could simply use the "path" object instead
for(File path:allFilesInDirectory){
if (path != null){
// put all file paths into string array
filesInDirectoryArray.add(path.getPath());
// could discriminate based on file extension, if so desired
}
}
// send file path array for processing
ProcessDocuments(filesInDirectoryArray);
}catch(SecurityException e){
e.printStackTrace();
}
Recently I am developing a file sharing application and I created a GridView, where the downloaded files are being shown. From this View, I would like to be able to open the default application through an intent, to open the whole file. Currently I am testing the app with only image files. All the files are downloaded to the external public directory this way:
File externalFolder = new File(Environment.getExternalStorageDirectory(), "My application");
if(!externalFolder.exists()){
externalFolder.mkdir();
}
...
File folder = new File(externalFolder, "Images");
if(!folder.exists()){
folder.mkdir();
}
...
String filename = folder.getAbsolutePath() + "/" + fileToDownload.getName() + "." + fileToDownload.getExtension();
FileOutputStream fos = new FileOutputStream(filename);
When the file is downloaded, I scan it with MediaScannerConnection.scanFile. The scan is successful, the picture is visible among other files in Photos app.
After the file is downloaded, I am able to extract a thumbnail in the adapter of the GridView, so I surely have a valid path to the file.
And where the fun begins: I tried to set an onClickListener to the GridView items in the adapter to be able to open the picture in Photos app this way:
listItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
if(new File(current.getPath()).exists()){
Log.e("path", "valid");
}else{
Log.e("path", "invalid");
}
Log.e("path", Uri.parse("content://"+current.getPath()).toString());
intent.setDataAndType(Uri.parse("content://"+current.getPath()), "image/*");
getContext().startActivity(intent);
}
});
The Intent is created successfully, I get the following in the log:
E/path: valid
E/path: content:///storage/emulated/0/My application/Images/best_picture_ever.jpeg
I have the option to choose among apps to open. When I select the app, it fails to open the image, like when it does not exist. All the 5 applications.
I tested this on my device with Oreo, and on two emulated devices with Nougat and Lollipop, all of them behaves the same way.
What am I doing wrong?
What am I doing wrong?
You are not creating a valid Uri. You cannot put content:// in front of arbitrary things and have a useful Uri, any more than you can put https:// in front of arbitrary things and have a usable URL.
Use FileProvider to serve up this file.
I'm new to android and having a headache trying to do this scenario:
I'm creating a backup of my database, which is exists in a path like this:
String dbPath = "data/data/" + c.getPackageName() + "/databases/" + DatabaseHelper.DATABASE_NAME;
I'm copying current database file to another in same directory with a custom extension, something like this:
String backupName = "data/data/" + a.getBaseContext().getPackageName() + "/databases/MyDB_" + MyTools.GenerateDateNow() + ".mydb";
then i use a recycler view and an adapter to loop through files inside the folder, and get my custom created files
i also have a button inside the recycler view, which will restore the created backup.
everything up till now is alright and works fine.
what i want to do next is the problem:
i need to share these backups with other people ( if user decides to ), and to do that, i have used Intents to send a user selected backup file to all apps which work with files ( gmail, whatsapp, ...):
holder.btnShare.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
Intent myIntent = new Intent(Intent.ACTION_SEND);
myIntent.setType("file/*");
Uri fileUri = Uri.fromFile(file);
myIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
Intent chooserIntent = Intent.createChooser(myIntent, "Share With...");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
chooserIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
v.getContext().startActivity(chooserIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
});
the selected file will be picked and sent to the chooserIntent, but it seems like the chooserIntent has no permission to access it, i guess it's something simple that I'm missing
My app involves downloading a few csv files and then choosing one of them to perform some functions. After the user downloads the required files, a spinner must display the files that have been downloaded. On selecting the required file, it must link to another activity where the path of the file chosen is the FileName. Is this possible using a spinner and how do I go about it?
File selected = new File("/storage/emulated/0/Download/");
String item_ext = "";
try {
item_ext = selected.getName().substring(selected.getName().lastIndexOf("."));
} catch (StringIndexOutOfBoundsException e) {
item_ext = "";
}
if(item_ext.equalsIgnoreCase(".csv")) {
Intent txtIntent = new Intent();
txtIntent.setAction(android.content.Intent.ACTION_VIEW);
txtIntent.setDataAndType(Uri.fromFile(selected), "text/csv");
Toast.makeText(MainActivity.this, "Success", Toast.LENGTH_SHORT).show();
try {
startActivity(txtIntent);
} catch(ActivityNotFoundException e) {
txtIntent.setType("text/*");
startActivity(txtIntent);
}
}
Since my application requirement mainly dealt with downloaded files, I linked the app to Downloads folder. By clicking on the file of interest, the path for the file was obtained. This link helped to get the absolute path and was suitably modified for the purpose.
I download a pdf file to internal storage and then programmatically create buttons that take them to an action view. I can listFiles[] and Toast that they are there but the pdf viewer says file does not exist or file can not be viewed.
These are the main components of the write to internal storage during download.
private File file;
file = new File(mContext.getFilesDir(), filename+".pdf");
// Output stream to write file in internal storage
OutputStream output = new BufferedOutputStream(new FileOutputStream(file));
Then in another activity I get the filenames from the database and create a table with buttons
// ....Inside a for loop .....
Button c3 = new Button(this);
c3.setText("view");
c3.setId(p.getPosterID());
c3.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
File pdfFile = getBaseContext().getFileStreamPath(filename+".pdf");
if (pdfFile.exists()){
Uri path = Uri.fromFile(pdfFile);
//================================================================================
Log.d("path: ", path.toString());
//this will log: file:///data/data/com.myapp.posterviewer/files/5453b54b83b5f.pdf
//================================================================================
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path, "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try{
startActivity(pdfIntent);
}
catch(ActivityNotFoundException e){
Toast.makeText(ListPosters.this, "No Application Available", Toast.LENGTH_LONG).show();
}
}
else{
Toast.makeText(ListPosters.this, "The file does not exist", Toast.LENGTH_LONG).show();
}
}
});
Am I generating the path right with Uri path?
I am not able to see the files from windows explorer when in the app folder either.
But all my checks say file is exists and I thought that would be in the app root folder.
Internal Storage Only Visible to your Application. The OutSide Application(Pdf Viewer) Cannot Access it. Save you Pdf file in External Storage and then open it via Pdf Viewer