Android ACTION_VIEW Multiple Images - android

I have between one and three photos I'd like my app to display. I won't know until runtime exactly how many photos are downloaded from the Internet.
I can't figure out how to create an Intent to display the photos. Right now I'm caching them on the sdcard under a folder I create by doing something like (sans error checking):
final File externalDirectory = Environment.getExternalStorageDirectory();
final String folder = externalDirectory.getAbsolutePath() + "/Android/data/" + packageName + "/files/";
This was explained in the Android Developer Reference.
I can get one photo to display by doing the following:
final Uri uri = Uri.fromFile(file);
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "image/*");
Util.startActivity(this, intent);
Where file is the file of a saved photo.
If it helps, I could save the images to any location available to my app, however I would prefer to not have the photos show up listed with the user's other personal photos as that may be annoying.
The Image Viewer has a menu option "Slideshow", so it must know about multiple photos.
I could create my own Image Viewer, but that seems like extra work and beyond what I would I reasonably expect. Even if I did this, I would like the user to be able to install a 3rd party Image Viewer and get a better experience with pan, zoom, share, ...
I tried using the directory of the cached photo files to create the Uri, but the Image Viewer shows a black page. If I pass in the file, it shows just that one file and no others.
I know this must be possible because I can see use the Gallery app and show the photos if I manually select the folder. Everytime I research this issue, the comments say it's not possible to show multiple images.
I suspect there's some magic incantation, but what?

I think your goal is out of your control. If the viewer app is designed to handle mutiple images or a directory, you may ask it to show as you want, but you are defined to the viewer's pattern.
I have installed a third-party image viewer called QuickPic. I just tested your code snippet and the system popped up a chooser dialog to let me select the app to show the images in the folder. If I select native gallery, what I see is just an empty folder, while the Quickpic works as I want.
PS: I tell my app the Uri of the folder this way:
intent.setDataAndType(Uri.fromFile(new File("//mnt/sdcard/test/")), MimeTypeMap.getSingleton().getMimeTypeFromExtension("png"));

Related

How to open media browser directly to photo gallery?

I want to create an Android Gallery/Photos viewer that lets the user PICK a profile picture. Based on all the examples I looked at, this is my code for doing so.
val galleryIntent = Intent(Intent.ACTION_GET_CONTENT, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
galleryIntent.type = "image/*"
galleryIntentLauncher.launch(galleryIntent)
Unfortunately this opens to the root of some file system, but I want it to open directly to the Gallery or Google Photos or whatever is the correct location for the photo gallery on the device.
I realize this varies by manufacturer (OnePlus, Samsung, Google, etc.) and that may be the reason what I want to do is impossible, but I know I've seen other apps do it.
Is there some formal/common way of doing this (i.e. opening directly to the photo gallery instead of the root directory)?

Android 11 URI usage (file:// content://)

We have some old issues with similar words, but most of them are about converting one or the other.
What I'm looking here is the "Right" behaviour of URI usage with the new changes. Let me give some context:
Before when we get an image URI this would return file://... format.
But since the new OS permissions changes, where we should not use WRITE_EXTERNAL_STORAGE anymore we should use getUriForFile(..) that return content://... path.(Scope Storage usage Android 11 Storage FAQ)
This can be spot on some Android guides, like: taken photos guide
The "problem" is that many users got used to use the URI of a crop image (for example) to create a file of it and save it.
Now, with this changes come the question:
How should we use the URI?
Make some code to check Android version and if more than 29 we should create a new file path for the URI?
Let the URI be the path to the image (content of file) and if someone wanna save it would need to create it own file path
Something else that I don't get yet about how to use URI right.
Obs: Asking this, because of a Android Image Crop open source project handover, where we need to upgrade the permissions for Android 10/11 but now we have this content/file issue. More here
Edit:
As pointed on the comments
Code returning file:// (not valid anymore since the changes)
Uri outputFileUri = null;
outputFileUri = Uri.fromFile(
new File(context.getExternalCacheDir().getPath(),
"pickImageResult.jpeg")
);
Code returning content://
outputFileUri = FileProvider.getUriForFile(
context,
context.getPackageName() + CommonValues.authority,
File.createTempFile("pickImageResult", ".jpeg", getImage)
);
The "problem" is that many users got used to use the URI of a crop image (for example) to create a file of it and save it.
In the end, this is your library, and you need to document what any Uri that you return is suitable for. After all, a Uri could point to:
A file on the filesystem (file)
A Web resource (https, or possibly http)
An Android resource (android.resource)
An asset in the app (file://android_asset)
Some arbitrary set of bytes (content)
Your library is for image cropping. While I have not examined the implementation, I assume that it all works inside the app itself. If so, there is nothing wrong with returning a file Uri, if you want to do so. Your code is writing a file somewhere (e.g., getCacheDir() on Context). The app using your library must have access to that file, or else you would have crashed trying to write it. A Uri created via Uri.fromFile(), for that file, is perfectly fine... in that app.
Where Uri.fromFile() becomes a problem is in passing the Uri to another app. However, your library is for cropping images, not sharing content with other apps. Your job, IMHO, is to give a cropped image back to the app. What the app does with it is up to that app, subject to whatever limitations there are in the Uri that you hand over.
The two options that you seem to be considering have different issues:
Uri Source
Advantages
Disadvantages
Uri.fromFile()
Cheap, easy
Can only be used within the app itself; cannot be passed to other apps
FileProvider
Uri can be passed to other apps
Requires a library and manifest configuration; cannot readily get to the underlying file
Since IMHO an image cropper is not an image sharing solution, Uri.fromFile() seems reasonable. If the app using your library wants to turn around and share the cropped image, they would set up FileProvider themselves and use FileProvider.getUriForFile(). The only catch is that either you need to document where the file will be written or give them an option to tell you what directory to use — that information will be needed to set up the FileProvider metadata.
Someday, if you elect to change the API, you might consider returning an ordinary File instead of a Uri. That way, there is no confusion about what it represents.
But, in the end, this is all your decision. If you want to use FileProvider, or you want to upload images to your own Web server and use https, that is all up to you. However, you should document what you are doing and what the Uri represents.

Android - Get an image picked from a camera into a photo gallery

I am new to Android. This is my first question. I am testing on 4.4.4, KitKat.
I am using the Android Developers "Taking Photos Simply" code in my app.
(Taking Photos Simply Tutorial)
I want the photos taken by the user to be available to my app, but also available later in the gallery.
If I specify
File storageDir = getExternalFilesDir (null);
Then various cameras work (camera, opencamera, DSLR camera), but after I leave my app the images do not appear in the gallery.
If I specify
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
Then the behavior is the same, except for one camera app: DSLR Camera. The photo does appear in that app's camera directory which is visible using the gallery later.
I want this behavior for my app. I want the photos that the user takes to appear in a directory that they can later see using the gallery app. I don't want to create duplicate images, however.
I also want to save modified images later on to the same directory.
Thanks for any help
but after I leave my app the images do not appear in the gallery.
It may eventually. Gallery apps usually use the MediaStore, and your file may eventually be added to it. Use MediaScannerConnection and scanFile() to expedite this process.
You need to request the media scanner to scan a file and add it to the media database.Use this code.
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(mMediaUri);
sendBroadcast(mediaScanIntent);
and see ACTION_MEDIA_SCANNER_SCAN_FILE in android developer site.Here mMediaUri is the Uri of your file.

Different way to open a PDF than from current SD?

I know there are many similar questions, but I need specifics. I originally wanted my app to open PDFS within the app itself, but I have settled to send an intent activity to adobe reader. I am currently opening PDFS by looking for the file on the device itself. Is there a way I can have the PDFS in my app, and create a folder on the users device, and then look for them? or something similar? Obvisouly the user isn't going to have the PDF already installed on their device. Here is my current code.
Intent intent7 = new Intent();
intent7.setPackage("com.adobe.reader");
intent7.setDataAndType(Uri.fromFile(new File("/storage/emulated/0/Download/Auto-example.pdf")), "application/pdf");
startActivity(intent7);
Is there a way I can have the PDFS in my app, and create a folder on the users device, and then look for them?
You can put the PDF in internal storage (e.g., getFilesDir()), then use FileProvider to serve them via a ContentProvider. This sample project demonstrates serving a PDF from internal storage (copied there from assets/) and viewing it in the user's chosen PDF viewer. There is also an Android training module covering this.
With respect to the code that you have, please use ACTION_VIEW as your Intent action (e.g., pass that to the constructor) and delete the setPackage() line.

How to invoke the default file chooser picker in Android?

If you go to imgur.com from your Android device, click on Upload an Image and then on Touch here to select your images, the Android prompts you with a Choose file for upload with few options. The good thing about this picker is that even if there is no camera as an option (for older phones) you can start the camera from the Gallery application, take a picture and eventually select it from the gallery to be uploaded.
That works also for any file <input> on any website.
So my question is: how can I invoke that file picker and eventually get the path to the selected image in native Java app?
If possible I would like to filter it so it will prompt only for images and not audio files and I don't want to install any file managers since it's doable within the browser. It's hard to believe that is available only for the Browser.
I don't want to implement my own file browser or list the camera's folder within my app. I'm also just starting with Android so a complete example to get eventually the file path or an image would be awesome.
Based on the chooser that comes up, <input> would appear to be requesting an ACTION_GET_CONTENT activity, with a MIME type of */*.
If possible I would like to filter it so it will prompt only for images and not audio files
Use a MIME type of image/*.
I'm also just starting with Android so a complete example to get eventually the file path or an image would be awesome.
See: https://stackoverflow.com/a/10274699/115145

Categories

Resources