One user of my app reports that after upgrading to Android 10 my app on his device stopped displaying an image.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setType("image/*");
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setData(scannedUri);
startActivity(intent);
I have "targetSdkVersion 28" so the new Scoped Storage rules should not be operating.
Still I put "compileSdkVersion 29" and included in the Manifest file:
android:requestLegacyExternalStorage="true"
Still all my user has is an empty screen, while he could see an image before Android 10:
I had the same issue, and the combination of
<external-path name="pics" path="/" /> (used with FileProvider)
and
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
solved it for me (I am on SDK version 28).
Just wanted to say thank you for asking this question and providing the READ_URI_PERMISSION flag code, without that I couldn't get it working and I tried like 10 different things!
i think problem of image extension .jpeg,.jpg or other....
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setType("image/jpeg");
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setData(scannedUri);
startActivity(intent);
If you pass Uri like this way, For example
Uri imageUri = Uri.parse("http://www.android.com");
Intent imageIntent = new Intent(Intent.ACTION_VIEW, imageUri);
By default, the system determines the appropriate MIME type required by an intent based on the Uri data that's included.
Setting the MIME type further specifies which kinds of activities should receive the intent.
For instance, If you want to display an image using the ACTION_VIEW Intent, you should specify a MIME type of image/*. This stop (someone) from doing something in apps that can "view" other types of data (like a map app) from being triggered by the intent.
I hope it'll help you.
Related
I am trying to open a pdf with existing installed pdf apps such as Google PDF Viewer. But the PDF screen shows blank.
I created an intent and used ACTION_VIEW filter but when I open in Google PDF it shows just blank screen nothing else even name of the file in Google PDF is not visible only document id (content-provider://..../document/122 <- this id) is shown
String filePath = "content://com.android.providers.downloads.documents/document/346";
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(filePath), "application/pdf");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
mActivity.startActivity(Intent.createChooser(intent, "select an app to open this file"));
setFlags will replace all previous flags on intent. So use addFlags instead -
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
also check if you have long term access to content URI. After Android 4.3 you'll need to ask for persistent permission using takePersistableUriPermission() on content uri you get. Also you'll need to change ACTION_VIEW to ACTION_OPEN_DOCUMENT where you are getting the URI you mentioned for takePersistableUriPermission() to work.
Read below articles for more clarification -
- About Using ACTION_OPEN_DOCUMENT
- How to use new Storage Access Framework to access/modify/create a file
i have a little problem, I need show the images/videos form a specific folder via default gallery, but when i throw the intent, the gallery not shows only files from the folder that i pass to te data intent, the gallery shows all images to the device. The code that i use is:
Uri selectedUri = Uri.parse(Environment.getExternalStorageDirectory().toString() + "/DCIM/folder/");
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setData(selectedUri);
intent.setType("image/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
I need show the images/videos form a specific folder via default gallery
That is not possible. There are thousands of device models. These ship with hundreds of different "default gallery" apps. None of them have to have some sort of API to allow you to request that they view some directory's worth of images.
Activities responding to ACTION_VIEW with a MIME type of image/* will expect that the Uri points to a single image. There is no MIME type for a directory, and there is no requirement that any gallery app honor such a MIME type even if one existed.
I tried picking a file from the internal or external storage with the code below:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("file/*");
startActivityForResult(intent, 1);
Of course it has onActivityResult method, and it's not the problem. It works fine in the modern phones or phones that have file manager installed. But the old one with no file manager throws
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.GET_CONTENT typ=file/* }
I tried switching to ACTION_PICK but no luck. I also tried intent.setType("*/*");, it didn't crash but the popup ask for action (videos, contacts,...) which is not true. I just want to pick any file not just a specified type.
I don't want to use any other file manager just to pick a file. Is there anyway I can get through this?
I believe that having the error explained, makes the solution much easier. So let me explain it to you:
You're starting an implicit intent. That means it's an intent that you know what you want to happen (use select a file) and you don't care which application will do it.
The error you're encountering is simply the system telling you (the developer), that there's no application installed that is capable of doing it (neither system nor 3rd party). There's simply no one capable of handling the action you want.
So you have two options from what I can see:
try-catch the error
.
try {
startActivityForResult(intent, 1);
} catch (ActivityNotFoundException e) {
// maybe you should show a toast to the user here?
Toast.makeText(context, "You need to install a file picker", Toast.LENGTH_SHORT).show();
// or maybe redirect to a 3rd party app that you know works
startIntent(new Intent(Uri.parse("https://play.google.com/... some app
}
you can find a library or code to pick the file from inside your own app: http://bit.ly/1N1fZbO
Below code section should work for you!
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("*/*");
Intent intent = Intent.createChooser(chooseFile, "Choose a file");
startActivityForResult(intent, ACTIVITY_CHOOSE_FILE);
What's your Android version? Some android maybe not released with such activity.
In my Android app, I use the following code to launch an image picker:
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/jpg");
startActivityForResult(intent, INTENT_PICK_IMAGE);
But unfortunately, the system gallery activity that is called by this also display videos. Is there a way to prevent this?
I use this to only allow image types:
intent.setType("image/*");
Edit: setType() is based on MIME type, not file extension (See here: http://developer.android.com/reference/android/content/Intent.html#setType(java.lang.String))
I don't know if you have seen the amazing Mytrack update, but it allow to send a kml file to Google Earth app and display it inside the Google app (if installed, of course).
The source code is there: http://code.google.com/p/mytracks/source/browse/
but I cannot find the way to achieve such a thing.
I think I found something here: http://code.google.com/r/jshih-mytracks3/source/browse/MyTracks/src/com/google/android/apps/mytracks/io/file/SaveActivity.java?spec=svn5178eb75934b7f0c4c23ec26b7d79a0787de18b8&r=5178eb75934b7f0c4c23ec26b7d79a0787de18b8
else if (playTrack) {
Intent intent = new Intent()
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(GOOGLE_EARTH_TOUR_FEATURE_ID, KmlTrackWriter.TOUR_FEATURE_ID)
.setClassName(GOOGLE_EARTH_PACKAGE, GOOGLE_EARTH_CLASS)
.setDataAndType(Uri.fromFile(new File(savedPath)), GOOGLE_EARTH_KML_MIME_TYPE);
startActivity(intent);
The hardcoded way gives this code:
Intent intent = new Intent()
.addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra("com.google.earth.EXTRA.tour_feature_id","tour")
.setClassName("com.google.earth", "com.google.earth.EarthActivity")
.setDataAndType(Uri.fromFile(new File("/sdcard/test.kml")),
"application/vnd.google-earth.kml+xml");
startActivity(intent);
But the above code simply displays the path with the same result than this code:
Intent mapIntent = new Intent(Intent.ACTION_VIEW);
Uri uri1 = Uri.parse("file:///sdcard/test.kml");
mapIntent.setData(uri1);
startActivity(Intent.createChooser(mapIntent, "Sample"));
My objective is to get the same result, with a "play" button.
You need to specify the URI to your KML file AND the KML MIME type, as follows.
File file = new File(Environment.getExternalStorageDirectory(), "sample_tour.kml");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.google-earth.kml+xml");
intent.putExtra("com.google.earth.EXTRA.tour_feature_id", "my_track");
startActivity(intent);
This is presently undocumented, but we're looking to fix this.
Be sure to use Intent::setDataAndType and not Intent::setData and Intent::setType separately (they each override the other).
"my_track" is a reference to your placemark id. The intent extra automatically starts the tour.
<Placemark id="my_track">
<gx:Track>
...
</gx:Track>
</Placemark>
Is it possible to use a link instead of a kml from disk?
Something like this:
intent.setDataAndType(Uri.parse("http://sites.cyclingthealps.com/other/downloads/doc.kml"), "application/vnd.google-earth.kml+xml");
Thanks
If you are targeting Android N, you are not allowed to send a file:// intent anymore. Use the instructions at android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData() , and add the Intent.FLAG_GRANT_READ_URI_PERMISSION flag.
File KML = new File("/sdcard/doc.kml");
Intent i = getPackageManager().getLaunchIntentForPackage("com.google.earth");
i.setDataAndType(Uri.fromFile(KML), "xml");
startActivity(i);
source: http://enladodelbien.blogspot.com/2015/06/kmlkmz-to-google-earth.html