Sending image to Hangouts from local folder - java

I'm attempting to send an image to Hangouts from within an app I'm building.
I'm working in Xamarin for VS 2015 to do this so the code below is c# but it's not much different from the equivalent Java code so I think it's easy to follow.
What I've done is set up a button on my app which has code setting up an Intent to share an image to Hangouts. I've set the image up already in the Downloads folder on the device and hardcoded the name into the code.
Intent hangoutsShareIntent = new Intent(Intent.ActionSend);
hangoutsShareIntent.SetType("image/jpeg");
hangoutsShareIntent.SetPackage("com.google.android.talk");
string downloadsPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath;
string filePath = Path.Combine(downloadsPath, "shared.jpg");
hangoutsShareIntent.PutExtra(Intent.ExtraStream, filePath);
StartActivity(Intent.CreateChooser(hangoutsShareIntent, "Share with"));
When I run this, I get the option to select a chat in Hangouts that I want to send the content to. Upon selecting the chat, I get a blank message box and no image.
I've swapped the above code over to use text/plain and pass the filePath variable to the message. When I copy the file path into Chrome to check it, the image loads so I have to figure that the image is where I've said it is... right?
I get no errors (probably because the issue is in Hangouts rather than my app so I have nothing to debug there). Logcat shows nothing except an error I can't find much about on Google: ExternalAccountType﹕ Unsupported attribute readOnly
The only information I could find on that error implied some issue with permissions but I've made sure my app has runtime permissions checked for Read/Write using this code (which wraps the above):
if ((CheckSelfPermission(Permission.ReadExternalStorage) == (int)Permission.Granted) &&
(CheckSelfPermission(Permission.WriteExternalStorage) == (int)Permission.Granted))
NOTE: I'm running this on a HTC One M8 - no SD card but does have external storage on device. I've also added the above permissions to the manifest for earlier Android versions.
The documentation for this (here) isn't overly helpful either so any advice AT ALL here is welcome :)
Thanks!

If you use the file provider instead of sending just the URI on its own. This should get around the permission issues you are seeing.
There is a guide available here which might be useful.
Intent shareIntent = new Intent(Intent.ActionSend);
shareIntent.SetType("image/gif");
Java.IO.File file = new Java.IO.File(Android.OS.Environment.ExternalStorageDirectory + "/myimage.gif");
Android.Net.Uri fileUri = Android.Support.V4.Content.FileProvider.GetUriForFile(this, "com.myfileprovider", file);
shareIntent.SetPackage("com.google.android.talk");
shareIntent.AddFlags(ActivityFlags.GrantReadUriPermission);
shareIntent.PutExtra(Intent.ExtraStream, fileUri);
StartActivity(Intent.CreateChooser(shareIntent, "Share with"));

Related

Set image changes when I move from one fragment to another, How to keep it forever even when I restart the app?

please help I could not add code, it is throwing error , I'm new.
ActivityResultLauncher<Intent> picActivityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
Intent data = result.getData();
// your operation....
Uri pic = data.getData();
profile.setImageURI(pic);
}
}
}
It depends on the device's android version. If it's 10 or lower than that, then you can simply save the file path in the Sharedpreference so you can access it later and load the image from there (You can do it in android 10 with requestLegacyExternalStorage of course or you can go with the 2nd option which I provided below).
But, if you're writing the code for android 11 or higher, then there are only three standard ways to do it.
1. Using SAF (Storage Access Framework) :-
You can get the storage access permission of that perticular folder everytime you pick an image from there. But this is not the best option when your app is doing it multiple times. (what if it's photo editor app or social media or something like that?!)
2. Manage all files permission :-
You can go with the All files access permission but it's also too much for the small task and you also have to give clarification to google play when your app has that permission. So it's also the very last option.
3. Accessing from internal app directories - THE BEST WAY! :-
You can go with this option with almost every app!
All you have to do is just take read storage permission, access the file using file descriptor, write it to the internal app directory (it can be either external files directory or cache directory), then you'll have a lifetime access of the image. You can save the path to Sharedpreference and access it anytime.
If you want to save edited image to the gallery then it will also be easy because you already have both read and write permission to that image saved in internal app directory.
That's it. I know the answer is lengthy but it's worth it. :)

'Media not found' when trying to play video

I have a weird problem, I am playing a video file from local storage, if the video name is "test#.mp4" it does not work and shows "media not found" toast, if it's "test.mp4", it works fine, no idea where is the problem.
basically if the name has "#" anywhere, the video does not play.
Here is my code
String item = names.get(itemPosition); // file name eg. test#.mp4
Uri uri = Uri.parse(context.getExternalFilesDir(null).getAbsolutePath() + "/MyFiles/"+item); // path to file
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
intent.setDataAndType(uri, "video/*");
context.startActivity(intent);
The answer is that I needed to use FileProvider, I have no idea why my earlier method was working and sometimes not.Also because the original documentation is so confusing, I used this answer, I took a look at the actual Uri and everything made sense now! android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()

How to open a file in external storage from an application? (Android)

I've added a button to my application which is supposed to open the download folder of the phone, and from there you should be able to click on files that were stored there, from the same app. Right now im saving some data there.
Problem is; I cant open the saved files in the folder.
I can see the files stored right there, but when I press one of them you immediatley go back to the app and not the file that you pressed.
Is there something I'm missing? Are you not supposed to open files stored in external storage from another app?
I've tried adding permissions in manifest and checkSelfpermission for checks in runtime, but with no success.
Here's the button for opening download folder:
private void openSavedLocation(){
if (ContextCompat.checkSelfPermission(ExportAndImport.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(ExportAndImport.this, new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
Uri uri = Uri.parse(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath());
intent.setDataAndType(uri, "text/xml");
startActivity(Intent.createChooser(intent, "Open Folder"));}
I can open the file perfectly when Im opening it outside the app, not via this "createChooser". What could i be missing?
Any help is appreciated.
but when I press one of them you immediatley go back to the app and not the file that you pressed
That is what your code does. ACTION_GET_CONTENT says "let the user pick a piece of content". It does not say "open that piece of content in some other app". There is no single Intent action for saying "let the user pick a piece of content, then open that piece of content in some other app".
Is there something I'm missing?
If you want to try to open the XML in some other app:
Use startActivityForResult(), not startActivity(), for your ACTION_GET_CONTENT request (and get rid of the createChooser() bit)
Override onActivityResult() to get the result of the user's choice
If the user chose something (i.e., you get RESULT_OK in onActivityResult()), create an ACTION_VIEW Intent wrapped around the Uri that you get from the Intent passed into onActivityResult(), and call startActivity() on the ACTION_VIEW Intent
If, instead, your objective is to open this XML in your app, you would:
Use startActivityForResult(), not startActivity(), for your ACTION_GET_CONTENT request (and get rid of the createChooser() bit)
Override onActivityResult() to get the result of the user's choice
If the user chose something (i.e., you get RESULT_OK in onActivityResult()), get the Uri of the content from the Intent passed into onActivityResult(), then use ContentResolver to do something useful with that Uri (e.g., openInputStream() to read in the content)
Here's the button for opening download folder
ACTION_GET_CONTENT uses the MIME type. It will not necessarily honor your supplied starting Uri.

How to start file browser app from Android application?

I have an App that is started from "share via" menu and get the list of the selected files as an input. Now, what I would like to do is to let the user be able to run file browsing app from my App and then get back the results.
I know for example that I can start phonebook and obtain the choosen contact(s) with following code:
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
So the question is: is there a similar way to run the file browser and to get in return a list of all files selected?
EDIT: the "possible duplicated post" is actually only partially similar, as it ask how to start the file manager inside a specific path, and by the way hasn't an accepted answer. What I really need, if it is possible, is to start the file manager (if there is one) to a specific path and then get in return the selected files.
thank you all very much
Cristiano

Android: How to open an unknown file type

I am developing a file explorer app in android.
How to handle files with unknown extensions? When I try to open such kind of file, its throwing ActivityNotFound exception. But I want the system to pop up list of apps so that we can manually choose an application to open it.
Can anyone help me here?
I am starting activity to open the file by binding the file and its extension to the intent.
Intent intent = new Intent(Intent.ACTION_VIEW);
MimeTypeMap mime = MimeTypeMap.getSingleton();
String ext = file.getName().substring(file.getName().lastIndexOf(".") + 1);
String type = mime.getMimeTypeFromExtension(ext);
intent.setDataAndType(Uri.fromFile(new File(file.toString())), type);
try
{
startActivity(intent);
}
catch(Exception e){}
ActivityNotFound is thrown when no application is registered that can handle specific file type. This means that the list of apps you want to show will be empty.
The most appropriate way to deal with he situation is to catch ActivityNotFound exception and show a toast notifying the user there are no appropriate applications to open the file.
All android browsers proceed in this manner.
I will leave this link here, that targets the same problem and has a little more detail to it (second answer, read comments): Launching an Activity based on a file in android

Categories