Email intent no longer working in Android Lollipop - android

I have been using below code to start an Intentin Android to send an email. Prior to Android Lollipop (API level 21) this worked fine. Unfortunately, in Android Lollipop, this throws an "Unsupported Action" error.
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setType("message/rfc822");
intent.setData(Uri.parse("mailto:" + email));
startActivity(intent);
It's pretty basic, it simply passes the e-mailaddress and lets the user pick which application to use.
How should I adapt my code to make this work across api levels? My minimum API level is 16 (JellyBean).
Edit
I've included the MIME-type, as per the comments and answers.

I've got it. This was caused by not having set up an emailaccount. After setting one up in at least one email app, it works.
It's not a problem with Lollipop.

You have to add intent.setType("message/rfc822"); see this detailed answer: How can I send emails from my Android application?

From my testing, this is a problem that happens when the intent's URI (from setData()) doesn't match anything and you're running on one of the official Android emulators. This doesn't seem to happen on real devices, so it shouldn't be a real-world problem.
You can use this code to detect when this is going to happen before you launch the intent:
ComponentName emailApp = intent.resolveActivity(getPackageManager());
ComponentName unsupportedAction = ComponentName.unflattenFromString("com.android.fallback/.Fallback");
boolean hasEmailApp = emailApp != null && !emailApp.equals(unsupportedAction);
(The name of the activity that shows the "Unsupported action" action method is com.android.fallback.FallbackActivity.)

By default this intent will be consumed by Android beam, I don't expect this behavior so I believe there must be something wrong in Lollipop.

Related

Android Wear is not opening dial pad via intent

I am working on an android wear project, I am facing an issue while opening the dialing activity via intent. The problem is that Intent is opening the call history instead of the dial pad.
Code snippet
val callIntent = Intent(Intent.ACTION_DIAL)
callIntent.data = Uri.parse("tel:0526722293")
context.startActivity(callIntent)
I have checked different stack-overflow post but still facing the same issue.
Can we make calls to any number in Android Wear 2.0?
How to make a phone call using intent in Android wear?
Is there anything that, I have to do more for android wear
If you are testing the app one an emulator, try the same on a physical watch. If the issue still persists, you might want to check the following:
Do the app have required permissions
Is this specific to a device/OS version
Ref:
https://developer.android.com/guide/topics/connectivity/telecom/selfManaged#constraints
https://developer.android.com/wear/releases?hl=ko

Android 4 startActivityForResult with Intent.ACTION_EDIT always returns resultcode RESULT_CANCELED

This problem occurs with android version 4.0.3. I am adding contacts with a custom RawContacts.ACCOUNT_TYPE using the Android Contacts 2.0 API. As a second step I want to use Intent.ACTION_EDIT to edit those contacts using the following code:
Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setData(contactUri);
startActivityForResult(intent, EDIT_CONTACT_RESULT);
The Intent is opening up the android built in edit contact activity. But when I press done, it is forwarding me to a contact view activity of the currently edited contact. If I then hit the back button, I get forwarded back to my application. The Problem is that onActivityResult(); always returns RESULT_CANCELED as a result code. Any ideas how to solve this problem?
Thanks.
This happens even on "stock Android" (JB, Galaxy Nexus). It seems the only way around it is to ignore the result code and to reread the contact again regardless of it (note that the Intent data will also be null, so you'd have to the contact Uri you had used when opening the Edit Activity).
Unfortunately, a lot of manufacturers tweak their SDKs, and a lot off apps fail to implement properly this, let call it "Android Pattern" where you should return the proper RESTULT_CODE. I have also encountered a lot of similar behaviours in the Facebook,Twitter, etc applications, and even them fail to return a proper result code if the user has shared/ or cancelled the action.
I don't think there is a problem with your code, it is very likely, that the problem is in the application that you are starting, which fails in returning a proper result.
Adding the following solved a similar problem for me:
intent.putExtra("finishActivityOnSaveCompleted", true);

Launching browser on Ice Cream Sandwich

I have a program that I have made for Android 1.6 and up and I have been doing tests to ensure that the program works fine with the new Ice Cream Sandwich (Android 4).
Everything on the app works fine except that when a certain task has been performed by the user it is supposed to automatically launch the android browser. However for some reason it seems to load it up in the background and keeps my app shown which is not what I want it to do.
On every other version of android when I execute the code to launch the browser the browser comes to the top of the screen therefore causing my app to be in the background which is how I wanted it to work.
Below is the code that I have to launch the browser
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setData(Uri.parse(companyURL));
startActivity(intent);
The companyURL is a variable that I am using to parse the url to the browser.
Thanks for any help you can provide.
UPDATE
I have just discovered that if the browser is not currently running (i.e. not been loaded previously) when my app starts the browser it brings it to the front. However, once the browser has been previously loaded, when my app loads it up again, it loads it in the background.
Please try this it is working on ICS for me.
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(companyURL));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Typically you don't need the CATEGORY_BROWSABLE category. Try the following instead:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(companyURL));
startActivity(intent);
In fact, the documentation seems to suggest CATEGORY_BROWSABLE is intended to be used in the opposite direction (browser to your app):
Activities that can be safely invoked from a browser must support this category. For example, if the user is viewing a web page or an e-mail and clicks on a link in the text, the Intent generated execute that link will require the BROWSABLE category, so that only activities supporting this category will be considered as possible actions.
http://developer.android.com/reference/android/content/Intent.html#CATEGORY_BROWSABLE
Try adding FLAG_ACTIVITY_BROUGHT_TO_FRONT flag to the intent.
I'm using following code and its working fine with me even when browser is already running in the background.
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
startActivity(intent);

Determine whether a device could launch Android Market app or not

I just wanted to "help" my users to give feedback to my app by providing a button to launch Market. Found a working solution here, of course, which does:
Uri uri = Uri.parse("market://details?id=<mypackagename>");
Intent intent = new Intent (Intent.ACTION_VIEW, uri);
startActivity(intent);
Simple as that, thanks!
But: on my first run, I had that on my emulator. Gives an ActivityNotFoundException immediately.
Now, my question: is there a way to find out whether a call to this intent will succeed BEFORE I try it? That way I could hide the button completely to not even give the option.
Thanks for your much appreciated help!
Instead of using this URL, you can use this one:
https://market.android.com/details?id=<mypackagename>
Even if the user doesn't have the Market application, he could go to the Website.
If he has the Market application, he should have a prompt between Internet and Market.
BTW, surround your code with a try catch in case he has nothing ;o)
You can also use this method.
Instead of IMDB, use your market URL: market://details?id=<mypackagename>
The exception was thrown just because there is no Android Market on the emulators. Every Android-powered device has the Android Market, so you shouldn't worry about this exception being thrown on a real device. Hope this helps.

Kill an app / package in API 8 (Froyo)

I have an app killing feature in one of my apps but up to API 7 i always worked with restartPackage(String PackageName); but since API 8 its deprecated so I tried killBackgroundProcesses(String PackageName); but that didn't work either.
Both are methods are in the ActivityManager class
I hope someone can help me.
I have, or rather had, the same feature in one of my apps... From all the research that I have done this feature is no longer possible.
The SDK Docs state this about why the restartPackages permission was deprecated:
"This is now just a wrapper for killBackgroundProcesses(String); the previous behavior here is no longer available to applications because it allows them to break other applications by removing their alarms, stopping their services, etc."
This seems to imply that anything visible to the user can no longer be closed by SDK applications. I am very disappointed by this decision and if anyone knows of a workaround I am interested in the answer as well.
I understand that there is the potential to "break" other applications with this feature enabled, but I thought that this is what the whole permission system is for. Users know up front the permissions that the app grants and thereby know what the possible consequences are.
I don't know how many people have come to me asking me to fix the fact that they can no longer close applications in FroYo via my application.
EDIT:
The best thing I have been able to come up with is to add the ability to provide a one-click solution go to the System's Application Info page for a given application. Below is some example code that I use in my app:
public Intent getManagePkgIntent(String pkgName)
{
int osVersion = AppMode.getAndroidVersion();
Intent intent = new Intent();
if (osVersion > AppMode.FROYO_SDK_VERSION)
{
//Settings.ACTION_APPLICATION_DETAILS_SETTINGS - THIS CONSTANT ISN'T AVAILABLE UNTIL COMPILING WITH 2.3
intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.setData(Uri.fromParts("package", pkgName, null));
return intent;
}
else //FROYO And Older...
{
intent.setAction(Intent.ACTION_VIEW);
intent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
String pkgExtra = (osVersion != AppMode.FROYO_SDK_VERSION) ? "com.android.settings.ApplicationPkgName" : "pkg";
intent.putExtra(pkgExtra, pkgName);
}
if (m_pkgMgr.resolveActivity(intent, 0) == null)
return null;
return intent;
}
AppMode.getAndroidVersion() is just a static method that safely gets the Android OS version as an int (because the app also runs on 1.5)...
AppMode.FROYO_SDK_VERSION is just a static final int indicating the FroYo API level.
There is one article talked about this issue.
In android 2.2, there is still "Force Close" button in the emulator test.
So this means it still has the way to overcome the disappeared "restartpackage" function.
But I am not sure it is Public API or just only allows the System level to use. Hope the answer is the former one. :(
link text

Categories

Resources