I am trying to share file with email clients and Google Drive. Now, in following code, only Google drive is opening and email clients are not opening at all. I can provide equivalent Java code of following code if required
val photoURI: Uri = FileProvider.getUriForFile(this, "com.emerson.oversight.com.emerson.oversight.provider",
File(this.cacheDir.path + "/SensorReport.pdf"))
val emailIntent = Intent(Intent.ACTION_SENDTO)
emailIntent.data = Uri.parse("mailto:")
emailIntent.putExtra(Intent.EXTRA_STREAM, photoURI)
emailIntent.putExtra(Intent.EXTRA_EMAIL, "asd#dsa.dsa")
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "dsadsada")
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
val driveIntent = Intent()
driveIntent.`package`= "com.google.android.apps.docs"
driveIntent.action = Intent.ACTION_VIEW
val fileID = File(this.cacheDir.path + "/SensorReport.pdf")
val url = "https://docs.google.com/file/d/" + fileID
driveIntent.data = Uri.parse(url)
val openInChooser = Intent.createChooser(driveIntent, getString(R.string.share_using))
openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayListOf(emailIntent))
startActivity(openInChooser)
Please help
You were almost there, the only missing piece in the puzzle is the getPackageManager().queryIntentActivities method that will return all activities that can handle your email intent. With the ResolveInfo returned you can build an intent for each email option to be displayed in the chooser. Then you can pass the array of those intents as Intent.EXTRA_INITIAL_INTENTS. You could even exclude certain packages if you like here. So the final part of your code would look something like this:
val openInChooser = Intent.createChooser(driveIntent, getString(R.string.share_using))
val emailOptionIntents = mutableListOf<Intent>()
val resInfo = getPackageManager().queryIntentActivities(emailIntent, 0)
if (!resInfo.isEmpty()) {
for (resolveInfo in resInfo) {
val emailOptionIntent = Intent(Intent.ACTION_SENDTO)
emailOptionIntent.data = Uri.parse("mailto:")
emailOptionIntent.putExtra(Intent.EXTRA_STREAM, photoURI)
emailOptionIntent.putExtra(Intent.EXTRA_EMAIL, "asd#dsa.dsa")
emailOptionIntent.putExtra(Intent.EXTRA_SUBJECT, "dsadsada")
emailOptionIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
emailOptionIntent.`package` = resolveInfo.activityInfo.packageName
emailOptionIntents.add(emailOptionIntent)
}
}
openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, emailOptionIntents.toTypedArray())
startActivity(openInChooser)
Related
I'm trying to share image with third party apps in android. I'm able to share image with all device except Xiaomi(Android 12) & OnePlus Node (Android 11).
val shareIntent = Intent()
shareIntent.action = Intent.ACTION_SEND
shareIntent.putExtra(Intent.EXTRA_TEXT, shareText)
shareIntent.putExtra(Intent.EXTRA_STREAM,imageUri)
shareIntent.type = "image/*"
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
context.startActivity(Intent.createChooser(shareIntent, "Share using"))
Shows toast message --> this file is not supported.
val file = File(path, "${System.currentTimeMillis()}.png")
file.outputStream().use {
imageBitmap!!.compress(Bitmap.CompressFormat.PNG,100, it)
}
var imageUri = FileProvider.getUriForFile(
context,
BuildConfig.APPLICATION_ID + ".fileprovider",
file )
I have multiple email account installed on Android. But when I launch the Intent I see only three of them. I've added also the browsers installed. But still I can see only three options. Is there a way to show all the options available?
This is the code I'm using:
fun openEmailPicker(){
val packageManager = activity.packageManager
val resInfoEmail = extractResInfoFromIntent("mailto:", packageManager)
val resInfoBrowser = extractResInfoFromIntent("http://www.gmail.com", packageManager)
if (resInfoEmail.size > 0) {
val openInChooser = buildHeader(resInfoEmail, packageManager)
val emailIntents = createIntentLIst(1, resInfoEmail, packageManager)
val browserIntents = createIntentLIst(0, resInfoBrowser, packageManager)
browserIntents.addAll(emailIntents)
openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, browserIntents.toTypedArray())
startActivity(openInChooser)
}
}
private fun buildHeader(resInfo: MutableList<ResolveInfo>, packageManager: PackageManager): Intent {
val resolveInfo = resInfo[0]
val intentChooser = packageManager.getLaunchIntentForPackage(resolveInfo.activityInfo.packageName)
return Intent.createChooser(intentChooser, getString(R.string.select_to_open_email))
}
private fun createIntentLIst(from: Int, resInfo: MutableList<ResolveInfo>, packageManager: PackageManager): MutableList<LabeledIntent> {
val intentList: MutableList<LabeledIntent> = ArrayList()
for (index in from until resInfo.size) {
extractLabelToLabeledIntent(resInfo, index, packageManager, intentList)
}
return intentList
}
private fun extractLabelToLabeledIntent(resInfo: MutableList<ResolveInfo>, i: Int, pm: PackageManager, intentList: MutableList<LabeledIntent>) {
val resolveInfo = resInfo[i]
val packageName = resolveInfo.activityInfo.packageName
val intent = pm.getLaunchIntentForPackage(packageName)
intentList.add(LabeledIntent(intent, packageName, resolveInfo.loadLabel(pm), resolveInfo.icon))
}
private fun extractResInfoFromIntent(URI: String, packageManager: PackageManager): MutableList<ResolveInfo> {
val emailIntent = Intent(Intent.ACTION_VIEW, Uri.parse(URI))
return packageManager.queryIntentActivities(emailIntent, 0)
}
You misunderstand what account and what application is. When you fire the intent, you get the list of the applications that can handle that intent. No matter how many separate accounts or whatever are created within these application. Once you got an application open, then you can select the account and the address -- you don't get a separate icon for every account within the same application in the intent chooser dialog.
You may get a list of the applications that are capable to handle your intent with queryIntentActivities() to receive a list of activities.
Official doc for App Chooser: https://developer.android.com/training/basics/intents/sending
I think those mail clients don't have action intent,
Any way you can add them manually by adding their package names something similar to this
List<Intent> targetedShareIntents = new ArrayList<Intent>();
Intent shareInent = new Intent(Intent.ACTION_SEND);
shareInent.setType("text/plain");
List<ResolveInfo> resInfo = activity.getPackageManager().queryIntentActivities(shareInent, 0);
// put the name of the packages you want in this ArrayList
ArrayList<String> wantedPackage = new ArrayList<>();
if (!resInfo.isEmpty()) {
for (ResolveInfo info : resInfo) {
Intent targetedShare = new Intent(android.content.Intent.ACTION_SEND);
targetedShare.setType("text/plain");
String infoPackageName = info.activityInfo.packageName.toLowerCase();
if (wantedPackage.contains(infoPackageName)) {
targetedShare.putExtra(Intent.EXTRA_TEXT, "put your text here");
targetedShare.setPackage(info.activityInfo.packageName.toLowerCase());
targetedShareIntents.add(targetedShare);
resPackageNames.add(infoPackageName);
}
}
Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0), "Chooser title");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{}));
startActivity(chooserIntent);
}
You can show the email clients in the chooser dialog but I don't think those clients would perform the action you desire since they lack the intent handling.
I'm trying to make a button in my app when user click on it, it'll open a specific URI in file manager but the best I could've done is that the button opens recent tab in default file manager.
Please, if it's possible, suggest me a code which opens a chooser for user to choose between his file manager applications and when user chose, that file manager opens in specific URI that I defined in my code.
Here is my code:
val intent = Intent(Intent.ACTION_GET_CONTENT)
val uri = Uri.parse(
//my path
)
intent.data = uri
intent.type = "*/*"
startActivity(Intent.createChooser(intent, "Open folder"))
Also one of the users suggested me to use INITIAL_URI I've did it like this but didn't work :
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
val uri = Uri.parse(
//my path
)
intent.data = uri
intent.type = "*/*"
intent.putExtra("android.provider.extra.INITIAL_URI", uri)
intent.putExtra("android.content.extra.SHOW_ADVANCED", true)
startActivity(Intent.createChooser(intent, "Open folder"))
suggest me a code which opens a chooser for user to choose between his file manager applications and when user chose, that file manager opens in specific URI that I defined in my code
That has never been a pattern in Android app development. There is no standard Intent action for what you seek that is likely to be implemented by much of anything, let alone a significant number of file manager apps.
fun openNewTabWindow(urls: String, context : Context) {
val uris = Uri.parse(urls)
val intents = Intent(Intent.ACTION_VIEW, uris)
val myV = Bundle()
myV.putBoolean("new_window", true)
intents.putExtras(myV)
context.startActivity(intents)
}
Instagram allows a single image or video to be uploaded programmatically from an Android app via Android Intents. I have been able to do this successfully. What I want to know is it possible for Instagram to handle multiple images using Intents? Not much to no information on this unfortunately. The following is my last attempt which opens Instagram briefly then closes with a toast message saying "Unable to load image".
Have tried both Intent.ACTION_SEND and Intent.ACTION_SEND_MULTIPLE
val fileUris = ArrayList<Uri>()
val newFile = File("/data/user/0/com.myapp.android/files/media/961087022.jpg")
val contentUri = getUriForFile(this, "com.myapp.fileprovider", newFile)
grantUriPermission("com.instagram.android", contentUri, FLAG_GRANT_READ_URI_PERMISSION)
fileUris.add(contentUri)
val newFile2 = File("/data/user/0/com.myapp.android/files/media/961146948.jpg")
val contentUri2 = getUriForFile(this, "com.myapp.fileprovider", newFile2)
grantUriPermission("com.instagram.android", contentUri2, FLAG_GRANT_READ_URI_PERMISSION)
fileUris.add(contentUri2)
val shareIntent = Intent(Intent.ACTION_SEND)
shareIntent.type = "image/*"
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, fileUris)
shareIntent.`package` = "com.instagram.android"
startActivity(Intent.createChooser(shareIntent, "Share to"))
I was looking on how to share multiple video files to instagram stories.. I couldn't find how to do it reading the facebook documentation.
Instead i set the intent to send multiple files and set the intent package to "com.instagram.android", and surprisingly it worked..
Intent share = new Intent(Intent.ACTION_SEND_MULTIPLE) ;
share.setType("video/*");
share.putExtra(Intent.EXTRA_SUBJECT, "abc");
share.putExtra(Intent.EXTRA_TITLE, "abcd");
ArrayList<Uri> files = new ArrayList<Uri>();
for (String path : filesToSend) {
File myFiles = new File(path);
Uri doneUri = FileProvider.getUriForFile(Objects.requireNonNull(getApplicationContext()),
BuildConfig.APPLICATION_ID + ".provider", myFiles);
files.add(doneUri);
}
share.setPackage("com.instagram.android");
share.putParcelableArrayListExtra(Intent.EXTRA_STREAM, files);
startActivity(share);
Hope, this helps!!
I'm trying to share an image/jpg stored in the raw resource folder of my application, but the Intent seems not to find the image resource and sends nothing.
Here is my code for sending (in Kotlin):
val current = filePaths!![mViewPager!!.currentItem]
val uri = Uri.parse("android.resource://" + getPackageName() + "/" + current.resourceId)
val shareIntent : Intent = Intent()
shareIntent.setAction(Intent.ACTION_SEND)
shareIntent.putExtra(Intent.EXTRA_STREAM, uri)
shareIntent.setType("image/*")
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)))
I also tried to send the Uri this way:
val uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + File.pathSeparator + File.separator + File.separator + getPackageName() + "/raw/" + filename)
but it doesn't work either. Can somebody help me?
The Uri passed via EXTRA_STREAM needs to be a content Uri. And while some apps supporting ACTION_SNED are more flexible, few will handle the almost-completely-unused android.resource scheme.
Implement a ContentProvider to serve your content, and use a Uri for that content in your Intent. Also, use a concrete MIME type in your Intent — this is your content, so you know what the MIME type is.
After 3 days of headaches i finally solved... what i've done was just save the image resource and then serve it:
val current = filePaths!![mViewPager!!.currentItem]
val imagePath = File(Environment.getExternalStorageDirectory(), "_temp")
if(!imagePath.exists())
imagePath.mkdirs()
val imageToShare = File(imagePath, "share.jpeg")
if(imageToShare.exists())
imageToShare.delete()
imageToShare.createNewFile()
val out = FileOutputStream(imageToShare)
val imageToSave = utils.createBitmap(current.resourceId)
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out)
out.flush()
out.close()
val uri = Uri.fromFile(imageToShare)
val shareIntent : Intent = Intent()
shareIntent.setAction(Intent.ACTION_SEND)
shareIntent.putExtra(Intent.EXTRA_STREAM, uri)
shareIntent.setType("image/jpeg")
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)))
:)