How to open a pdf with intent in Android Q - android

I have written a code that open a file like pdf. For that I used intent like the below one:
public void openFile(Context context, File file) {
String typeFile = "application/pdf";
if (file.exists()) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), typeFile);
PackageManager pm = context.getPackageManager();
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.setType(typeFile);
Intent openInChooser = Intent.createChooser(intent, "Choose");
List<ResolveInfo> resInfo = pm.queryIntentActivities(sendIntent, 0);
if (resInfo.size() > 0) {
try {
context.startActivity(openInChooser);
} catch (Throwable throwable) {
Toast.makeText(context, "No application found which can open the file", Toast.LENGTH_SHORT).show();
// PDF apps are not installed
}
} else {
Toast.makeText(context, "No application found which can open the file", Toast.LENGTH_SHORT).show();
}
}
}
My problem is when I run this code on Android 10 and 11, the Toast in else is executed but in older versions these codes work correctly.
So what should I do to open file in Android 10 and 11?

Your app should be crashing on Android 7.0+ with a FileUriExposedException. You need to get rid of Uri.fromFile() and switch to FileProvider.
Also, you can get rid of queryIntentActivities(). You do not need it, partly because there should always be a chooser, and partly because you have the try/catch block to catch the ActivityNotFoundException if there is no chooser for some strange reason. If your reason for queryIntentActivities() is to avoid an empty chooser, stop creating a chooser — the OS will add one automatically if one is appropriate. Alternatively, for Android 11+, you will need to deal with package visibility rules to be able to call queryIntentActivities(). See this and this for more.

Related

How to open excel, doc files with intent from my app in MS-Excel or MS-Word - Android

My requirement is to download and view the Excel, Doc files in my app. So I downloaded the Excel/Doc file in phone storage and called the ACTION_VIEW Intent by passing the file path. Then I got this error saying "Try saving the file on the device and then opening it."
I can be glad if any one can suggest me another alternatives as well to open excel or doc files. Please guys i have searched a lot for this so far i didn't find the solution and i am sure that i have used proper intent for opening files.
Where My Code:
Intent intentpdf = new Intent(Intent.ACTION_VIEW);
intentpdf.setDataAndType(Uri.parse(message), "application/msword");
intentpdf.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
mactivity.startActivity(intentpdf);
} catch (ActivityNotFoundException e) {
if (!mactivity.isFinishing())
Toast.makeText(mactivity, "Install MSWord Viewer.", Toast.LENGTH_LONG).show();
}
Intent intentpdf = new Intent(Intent.ACTION_VIEW);
intentpdf.setDataAndType(Uri.parse(message), "application/vnd.ms-excel");
intentpdf.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
mactivity.startActivity(intentpdf);
} catch (ActivityNotFoundException e) {
if (!mactivity.isFinishing())
Toast.makeText(mactivity, "Install Excel Viewer.", Toast.LENGTH_LONG).show();
}
You need the flags FLAG_ACTIVITY_NO_HISTORY,FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION.
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION );
I had this exact same problem and I fixed it. The problem is most likely with your ContentProvider/FileProvider implementation. My Excel sheet opened fine in Google Sheets but I got this error in MS Excel. The fix was to return the proper content type (via the getType() method) out of your provider. Returning the wrong content type will cause the error.
Try this code to see if it helps...and if it does, you can fully implement the routine for files of all types.
#Override
public String getType(Uri uri) {
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
}
Good Luck!
Try get mime type from file
public String getMimeTypeByFile(String filePath) {
MimeTypeMap type = MimeTypeMap.getSingleton();
return type.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(filePath));
}
nothing is worked for me to open the Doc,PPT,Excel files with intent at last I find a better solution , please check the code here
if(fileType.equalsIgnoreCase("doc") || fileType.equalsIgnoreCase("docx")) {
String str = "com.microsoft.office.word";
Uri pathe = Uri.fromFile(fileN);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(pathe, "application/msword");
PackageManager packageManager = activity.getPackageManager();
if (intent.resolveActivity(packageManager) != null) {
activity.startActivity(intent.createChooser(intent, "Choose app to open document"));
}
else
{
//Launch PlayStore
try {
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id="+str)));
} catch (android.content.ActivityNotFoundException n) {
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id="+str)));
}
}
Here is the result : check the screenshot

Android - How to check if file manager is available?

My app is using a custom type of file that can be saved onto the external memory and shared.
I want to use the file picker to pick one file and load it. Here is my code :
Uri uri = Uri.fromFile("path/to/folder");
Intent intent = new Intent(Intent.ACTION_PICK, uri);
try {
startActivityForResult(Intent.createChooser(intent, "Select a file"), 123);
} catch (android.content.ActivityNotFoundException e) {
Toast.makeText(this, "Error fileChooser",Toast.LENGTH_SHORT).show();
Log.e("Dan", "onOptionsItemSelected: Error filechooser ActivityNotFoundException", e);
}
This code works absolutely perfectly on my genymotion emulator and my Nexus 4 on CyanogenMod and call the file manager to browse to the folder.
But when I try on my brand new LG G4, it doesn't work.
The biggest problem is that I get no error message, just a file picker with the good title and a message "No app can perform this action".
How to check if a file picker is available? (to provide a simple alternative if needed)
Try this:
PackageManager packageManager = getActivity().getPackageManager();
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("file/*");
List<ResolveInfo> list = packageManager.queryIntentActivities(intent,
PackageManager.GET_ACTIVITIES));
Then, check the size of the list, if it is 0, then there is no file explorer.

How to open certain path in the Samsung Android My Files Programmatically

I'm using the following code to allow the user to access My Files from a Samsung android device. I'm trying to open certain path in the My Files when the user press the button. Right now it will open the default path. Can you tell me if it is possible to pass the path through when open My Files from Android? Below is the code that I use. Can you give me the code that will open My Files into certain Path? Thank you in advance for your help.
public void AccessingFiles(View view) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
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", "*/*");
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();
}
}
For anyone looking for the solution to the same question this is how I open My Files pointed at a certain path:
File folder = new File(""); // construct the path
Intent fmIntent = new Intent(Intent.ACTION_MAIN);
fmIntent.setComponent(new ComponentName("com.sec.android.app.myfiles", "com.sec.android.app.myfiles.MainActivity"));
fmIntent.setData(Uri.parse(folder.toString()));
To be noted that fmIntent.setData(Uri.fromFile(folder)) did not work for me.
The solution is tested with My Files 1.19.0 and this is how I came to it:
I created a custom Launcher;
My Files can create home screen shortcuts to a specific path;
When the install shortcut intent was sent to my launcher I dumped its contents so that I can use them to create my fmIntent from the above code snippet.

Is it possible to programmatically check if any file explorer is present on my Android device?

I'm trying to import a file into my application, below is the code :
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath());
intent.setDataAndType(uri, "*/*");
startActivityForResult(Intent.createChooser(intent, "Select File"),
REQUESTCODE);
What i want is that before firing the intent i want to programatically check whether any File explorer is present on my device or not? If yes then fire the intent but if no then i want to redirect user to Play store to download one, as it is mandatory for selecting a file. Is this feature possible to implement? Kindly enlighten me on this. Thanks in advance.
You can check if the file explorer is present or not using the below code, If not then ask user to download the app.
PackageManager packageManager = getActivity().getPackageManager();
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("file/*");
List<ResolveInfo> list = packageManager.queryIntentActivities(intent,
PackageManager.GET_ACTIVITIES));
if (list.size > 0) {
// File explore is present (Size tells how many file explorers are present)
} else {
// Not present
// Just pointing to this app - https://play.google.com/store/apps/details?id=com.rhmsoft.fm
// You can choose whichever you need
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.rhmsoft.fm")));
} catch (android.content.ActivityNotFoundException e) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=com.rhmsoft.fm")));
}
}

Android: How to open a specific folder via Intent and show its content in a file browser?

I thought this would be easy but as it turns out unfortunately it's not.
What I have:
I have a folder called "myFolder" on my external storage (not sd card because it's a Nexus 4, but that should not be the problem). The folder contains some *.csv files.
What I want:
I want to write a method which does the following: Show a variety of apps (file browsers) from which I can pick one (see picture). After I click on it, the selected file browser should start and show me the content of "myFolder". No more no less.
My question:
How exactly do I do that? I think I came quite close with the following code, but no matter what I do - and I'm certain that there must be something I didn't get right yet - it always opens only the main folder from the external storage.
public void openFolder()
{
File file = new File(Environment.getExternalStorageDirectory(),
"myFolder");
Log.d("path", file.toString());
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setDataAndType(Uri.fromFile(file), "*/*");
startActivity(intent);
}
This should help you:
Uri selectedUri = Uri.parse(Environment.getExternalStorageDirectory() + "/myFolder/");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(selectedUri, "resource/folder");
if (intent.resolveActivityInfo(getPackageManager(), 0) != null)
{
startActivity(intent);
}
else
{
// if you reach this place, it means there is no any file
// explorer app installed on your device
}
Please, be sure that you have any file explorer app installed on your device.
EDIT: added a shantanu's recommendation from the comment.
LIBRARIES:
You can also have a look at the following libraries https://android-arsenal.com/tag/35 if the current solution doesn't help you.
I finally got it working. This way only a few apps are shown by the chooser (Google Drive, Dropbox, Root Explorer, and Solid Explorer). It's working fine with the two explorers but not with Google Drive and Dropbox (I guess because they cannot access the external storage). The other MIME type like "*/*" is also possible.
public void openFolder(){
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath()
+ File.separator + "myFolder" + File.separator);
intent.setDataAndType(uri, "text/csv");
startActivity(Intent.createChooser(intent, "Open folder"));
}
Here is my answer
private fun openFolder() {
val location = "/storage/emulated/0/Download/";
val intent = Intent(Intent.ACTION_VIEW)
val myDir: Uri = FileProvider.getUriForFile(context, context.applicationContext.packageName + ".provider", File(location))
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
intent.setDataAndType(myDir, DocumentsContract.Document.MIME_TYPE_DIR)
else intent.setDataAndType(myDir, "*/*")
if (intent.resolveActivityInfo(context.packageManager, 0) != null)
{
context.startActivity(intent)
}
else
{
// if you reach this place, it means there is no any file
// explorer app installed on your device
CustomToast.toastIt(context,context.getString(R.string.there_is_no_file_explorer_app_present_text))
}
}
Here why I used FileProvider - android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()
I tested on this device
Devices: Samsung SM-G950F (dreamltexx), Os API Level: 28
Intent chooser = new Intent(Intent.ACTION_GET_CONTENT);
Uri uri = Uri.parse(Environment.getDownloadCacheDirectory().getPath().toString());
chooser.addCategory(Intent.CATEGORY_OPENABLE);
chooser.setDataAndType(uri, "*/*");
// startActivity(chooser);
try {
startActivityForResult(chooser, SELECT_FILE);
}
catch (android.content.ActivityNotFoundException ex)
{
Toast.makeText(this, "Please install a File Manager.",
Toast.LENGTH_SHORT).show();
}
In code above, if setDataAndType is "*/*" a builtin file browser is opened to pick any file, if I set "text/plain" Dropbox is opened. I have Dropbox, Google Drive installed. If I uninstall Dropbox only "*/*" works to open file browser. This is Android 4.4.2. I can download contents from Dropbox and for Google Drive, by getContentResolver().openInputStream(data.getData()).
Thread is old but I needed this kind of feature in my application and I found a way to do it so I decided to post it if it can help anyone in my situation.
As our device fleet is composed only by Samsung Galaxy Tab 2, I just had to find the file explorer's package name, give the right path and I succeed open my file explorer where I wanted to. I wish I could use Intent.CATEGORY_APP_FILES but it is only available in API 29.
Intent intent = context.getPackageManager().getLaunchIntentForPackage("com.sec.android.app.myfiles");
Uri uri = Uri.parse(rootPath);
if (intent != null) {
intent.setData(uri);
startActivity(intent);
}
As I said, it was easy for me because our clients have the same device but it may help others to find a workaround for their own situation.
this code will work with OI File Manager :
File root = new File(Environment.getExternalStorageDirectory().getPath()
+ "/myFolder/");
Uri uri = Uri.fromFile(root);
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setData(uri);
startActivityForResult(intent, 1);
you can get OI File manager here : http://www.openintents.org/en/filemanager
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, DocumentsContract.Document.MIME_TYPE_DIR);
startActivity(intent);
Will open files app home screen
Today, you should be representing a folder using its content: URI as obtained from the Storage Access Framework, and opening it should be as simple as:
Intent i = new Intent(Intent.ACTION_VIEW, uri);
startActivity(i);
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("text/csv");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult(Intent.createChooser(intent, "Select a File to Upload"), 0);
} catch (android.content.ActivityNotFoundException ex) {
ex.printStackTrace();
}
then you just need to add the response
public void onActivityResult(int requestCode, int resultCode, Intent data){
switch (requestCode) {
case 0: {
//what you want to do
//file = new File(uri.getPath());
}
}
}
You seem close.
I would try to set the URI like this :
String folderPath = Environment.getExternalStorageDirectory()+"/pathTo/folder";
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
Uri myUri = Uri.parse(folderPath);
intent.setDataAndType(myUri , "file/*");
startActivity(intent);
But it's not so different from what you have tried.
Tell us if it changes anything ?
Also make sure the targeted folder exists, and have a look on the resulting Uri object before to send it to the intent, it may not be what we are expected.
File temp = File.createTempFile("preview", ".png" );
String fullfileName= temp.getAbsolutePath();
final String fileName = Uri.parse(fullfileName)
.getLastPathSegment();
final String filePath = fullfileName.
substring(0,fullfileName.lastIndexOf(File.separator));
Log.d("filePath", "filePath: " + filePath);
fullfileName:
/mnt/sdcard/Download_Manager_Farsi/preview.png
filePath:
/mnt/sdcard/Download_Manager_Farsi

Categories

Resources