To transmit data to other applications I've been using implicit intents as in examples below:
Intent intent = new Intent();
intent.setAction("com.example.OpenURL");
intent.putExtra("URL_TO_OPEN", url_string);
sendOrderedBroadcastAsUser(intent);
Intent intent = new Intent();
intent.setAction("com.example.CreateUser");
intent.putExtra("Username", uname_string);
intent.putExtra("Password", pw_string);
sendBroadcast(intent);
Intent intent = new Intent();
intent.setAction("com.example.BackupUserData");
intent.setData(file_uri);
intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
sendBroadcast(intent);
But this behavior is not recommended anymore in Android 5.0
http://developer.android.com/about/versions/android-5.0-changes.html
Binding to a Service
The Context.bindService() method now requires an explicit Intent, and throws an exception if given an implicit intent. To ensure your app is secure, use an explicit intent when starting or binding your Service, and do not declare intent filters for the service.
From android source code more precisely "ContextImpl" class :
private void validateServiceIntent(Intent service) {
if (service.getComponent() == null && service.getPackage() == null) {
if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
IllegalArgumentException ex = new IllegalArgumentException(
"Service Intent must be explicit: " + service);
throw ex;
} else {
Log.w(TAG, "Implicit intents with startService are not safe: " + service
+ " " + Debug.getCallers(2, 3));
}
}
}
How can I deal with this ?
Yes, when running in a device with Android 5.0 this code will either show a warning (if your app's targetSdkVersion
is < 21) or crash outright (if targeting Lollipop itself). Check the source code for validateServiceIntent()
in ContextImpl.java
:
This code is dangerous as it might allow a malicious receiver to register itself and intercept (or alter) these calls.
The most reasonable alternative is probably to specify the package name of the app you want to call, by using Intent.setPackage()
. When done this way, the intent is no longer implicit, and it will work. For example:
intent.setPackage("com.example.app");
Of course, if the receiver is inside your app, there are easier alternatives (but that does not seem to be the case, from your description of the issue).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With