Display photo from FileProvider with Intent.ACTION_VIEW - java

I am working on a device running Android 8.1.0. I'm trying to open an image from a message attachment. I had a cache of image files working using a FileProvider a week ago and now it just stopped working without me touching the code. I'm trying to share an image from my internal app storage to Intent.ACTION_VIEW outside of my app. The photo viewer does launch, but there's a progress circle that just keeps spinning. Any suggestions? Thanks!
void launchViewer(File f) {
Uri uri = FileProvider.getUriForFile(context, "com.company.secure.provider", f);
Intent intent = new Intent(Intent.ACTION_VIEW);
String mimeType = Attachment.getMimeType(f.getName());
//TODO Test to make sure this works on all devices...
if (mimeType.startsWith("video")) {
mimeType = "video/*";
}
if (mimeType.startsWith("image")) {
mimeType = "image/*";
}
if(mimeType==null || mimeType.length()==0) {
unknownMimeType(f.getName());
return;
}
List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if(resInfoList==null || resInfoList.size()==0)
{
AlertDialog dialog = new AlertDialog.Builder(context).setTitle("Error")
.setMessage(String.format("Cannot find app to open file type(%s)",mimeType)).show();
return;
}
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
intent.setDataAndType(uri, mimeType);
context.startActivity(intent);
}

So I just had to add the following line right before starting the activity.
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
For some reason, the APK I shipped to testing that doesn't have this line in it works... but any new build does not work without this. I read that using the ResolveInfo method will only work for Lollipop and below and you will have to grant the permission directly to the intent. (Not sure how true this is). For this reason I left both permission granting methods in there to cover all bases. Thanks for all the help!

Related

Can't save photo. Camera doesn't have permission to save to this location [Only happening to Google Pixel phones]

I am currently facing an issue with Google pixel phones not letting the app save photo to a specific file location (mentioned below). I don't know if this is something to do with the scoped-storage because the app is running perfectly fine with 4000+ android 12 devices and this only happens to google pixel devices.
(content://com.au.APP_NAME/data/user/0/com.au.APP_NAME/cache/APP_NAMEPicture-Cache/1660.jpg)
private void startCameraIntent() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String filePath = FileProvider.contentUri + StorageManager.createPictureCacheFileName(getContext());
//filePath = content://com.au.APP_NAME/data/user/0/com.au.APP_NAME/cache/APP_NAMEPicture-Cache/1660.jpg
StorageManager.saveCameraCaptureImageFilePathToSharedPreferences(getContext(), filePath);
Uri fileURI = Uri.parse(filePath);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileURI);
startActivityForResult(intent, Constant.TAKE_PHOTO_FROM_CAMERA_ACTIVITY_TAG);
}

How do I remove the OK and Cancel Button on the Camera Instance for takepictureintent

How do I skip the part confirming if I want to save the image or not after taking a photo in Android Studio. I basically just want to snap...snap...snap.
Attached is my code for starting the camera activity:
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
My code for activity result OK (which I want to skip):
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
//remove bundle in has null value
//get file uri to upload to firestore Storage
File f = new File(currentPhotoPath);
Uri contentUri = Uri.fromFile(f);
myDB.insertPictureJob(JobId, currentPhotoPath);
try {
watermark(currentPhotoPath);
} catch (IOException e) {
e.printStackTrace();
}
getPictures();
imgAdap.notifyDataSetChanged();
checkStoragePermission();
//run the app
}
How do I skip the part confirming if I want to save the image or not after taking a photo in Android Studio
Use CameraX, Fotoapparat, CameraKit-Android, or another camera library and take the pictures directly within your app.
Using ACTION_IMAGE_CAPTURE delegates the request to the user's choice of camera app, out of hundreds of such apps. How those apps behave are up to those apps' developers, not you or me. And there is nothing in the ACTION_IMAGE_CAPTURE protocol for you to get multiple results back, which is implied by "snap... snap... snap...".

How to create a share button for whatsapp, facebook or others app installed in my phone

I am developing an app, where I want to share the TEXT and IMAGE to other apps installed on my phone.
But when I click the share button Neither it shares TEXT nor IMAGE just empty it directs me to another app I chose for sharing.
below postDescription and postImage are my methods of model class, and I checked that am I getting values are not in a toast it gives there values properly.
Below is the code:
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_TEXT, postDescription);
Uri uri = Uri.parse(postImage);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
context.startActivity(Intent.createChooser(shareIntent, "Share With"));
So the above bunch of code was not working, then I found code through which I can share my post TEXT and IMAGE to WhatsApp only, I tried that but it shows file formate not supported inside WhatsApp.
below is the code for sharing to WhatsApp only:
Uri imgUri = Uri.parse(postImage);
Intent whatsappIntent = new Intent(Intent.ACTION_SEND);
whatsappIntent.setType("text/plain");
whatsappIntent.setPackage("com.whatsapp");
whatsappIntent.putExtra(Intent.EXTRA_TEXT, postDescription );
whatsappIntent.putExtra(Intent.EXTRA_STREAM, imgUri);
whatsappIntent.setType("image/jpeg");
whatsappIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
context.startActivity(whatsappIntent);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(context, "Whatsapp have not been installed.", Toast.LENGTH_SHORT).show();
}
I want to know how to create a share button that works fine for WhatsApp and everything or only WhatsApp will do the work for me.
By removing the package from the intent, Android should display the list of apps that can handle the type of intent.
Uri imgUri = Uri.parse(postImage); //Provide the URI to the downloaded image, not an external URL
Intent whatsappIntent = new Intent(Intent.ACTION_SEND);
whatsappIntent.setType("*/*");
whatsappIntent.putExtra(Intent.EXTRA_TEXT, postDescription );
whatsappIntent.putExtra(Intent.EXTRA_STREAM, imgUri);
if (whatsappIntent.resolveActivity(packageManager) != null) {
startActivity(whatsappIntent)
}

Android, directly open mtp folder

I'm working on a project that requires the connection of a smartphone to a tablet via a USB cable. To acces the files from the smartphone from the tablet, I am using the Android's Intent.ACTION_GET_CONTENT to retrieve the files. I am, more specifically trying to open pictures.
I know this is possible since, when I click on the notification describing the smartphone, it opens a default Android app with the base folder of the smartphone.
What I am trying to achieve is to directly open the connected smartphone's storage instead of having to switch from the tablet to storage to the smartphone's.
I know how to get the volume name of the smartphone but that hasn't helped me progress. I have checked the Uri, received from the Intent, it is something like content://com.android.mtp.documents/document/951 or content://com.android.mtp.documents/tree/1021.
I have tried to use thes Uri to open the desired folder but it didn't work.
I've tried the new StorageManager API without success.
Recently, I've focused more on trying to simply access the files from my app but using the above mentionned Uri or the mount folder (/dev/bus/usb/001/002/) leads to nothing.
I also tried the Environment.MEDIA_MOUNTED without success.
My current code it this:
Requesting permission to use the smartphone:
final UsbManager manager = (UsbManager) getActivity().getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
if (deviceList.size() > 0) {//TODO switch to 1 on USBCameraFragment
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
UsbDevice device = (UsbDevice) deviceList.values().toArray()[0];
manager.requestPermission(device, mPermissionIntent);
} else {
Toast.makeText(getContext(), "Please connect your device to the tablet.", Toast.LENGTH_SHORT).show();
}
Opening the connection and starting the Intent:
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(device != null){
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
Uri path = MediaStore.Files.getContentUri(device.getProductName());
//Uri path = Uri.parse(Environment.getExternalStoragePublicDirectory(Environment.MEDIA_MOUNTED).getAbsolutePath());
i.setDataAndType(path, "image/*");
i.addCategory(Intent.CATEGORY_OPENABLE);
MtpDevice mtpDevice = new MtpDevice(device);
UsbDeviceConnection conn = ((UsbManager) getActivity().getSystemService(Context.USB_SERVICE)).openDevice(device);
mtpDevice.open(conn);
//1.5s to make sure I have allowed the MTP connection on the smartphone.
try{Thread.sleep(1500);}catch(InterruptedException e){}
startActivityForResult(i, Constants.PICKFILE_REQUEST_CODE);
}
}
else {
Log.d(TAG, "permission denied for device: " + device);
}
}
}
}
};

Android gallery not updated after ACTION_IMAGE_CAPTURE

I'm using MediaStore.ACTION_IMAGE_CAPTURE to take a picture with MediaStore.EXTRA_OUTPUT to point to the Uri for the DCIM/Camera directory where all the other photo/video files are stored.
The photo file is successfully taken and I can see it using ES File Explorer and can view it inside my app. However it is not shown in the gallery when I use Intent.ACTION_PICK
Intent selectPictureIntent = new Intent(Intent.ACTION_PICK);
selectPictureIntent.setType("image/*");
I've read the other topics on updating the Gallery after the picture comes back using
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
and also
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, _outputMediaUri);
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
What's going on here :(
why did you use LocalBroadcastManager? LocalBroadcastManager can only send broadcast data inside of your app. Try to use
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, _outputMediaUri);
sendBroadcast(intent);
Gallery always listens to URI change. After file event broadcast to Gallery, the data stored in Gallery will be updated.
it also can problem with KITKAT build version.. for sure you can use this code:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(out); \\out is your output file
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
} else {
sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
}

Categories

Resources