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
Related
In the new Android M build, the Battery Optimization feature will stop the app on certain condition to save battery, but for the VOIPapps that need to stay alive all the time, this feature cause troubles for the developer.
Currently there is one way to bypass the optimization, which is set the app to ignore optimizations,but too many steps need to be done.
My question is, is there a way to jump to ignore optimization page of specific App, and how can I know whether my app is excluded from optimization?
WARNING: It seems Google doesn't allow apps on the Play Store to do this. See the comments below.
Based on the AndroidManifest.xml extracted from Settings.apk in the MPA44I build, it would seem you might be able to do what you want by something like the intent below.
From XML:
<intent
android:action="android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"
android:targetPackage="com.android.settings"
android:data="package:PUT_YOUR_PACKAGE_NAME_HERE" />
From code:
try {
Intent intent = new Intent(android.provider.Settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:PUT_YOUR_PACKAGE_NAME_HERE"));
startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
Note that I have not had time to verify this in practice myself but the approach is the same as I use in one of my apps to launch app-specific settings menus. Still, I hope it helps.
Google Allow this based on few conditions
Check Section "Support For Other Use Cases"
here
Also check White List Conditions
There's currently no way to effectively opt out of optimizations, as this does not affect doze mode - even if your app is on the whitelist.
See here:
https://stackoverflow.com/a/31721398/4301846
and here:
https://code.google.com/p/android-developer-preview/issues/detail?id=2225
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.
On the new Android 5.0 Lollipop a new setting was added on the Developer Options called "Use NuPlayer (beta)". My app sometimes is not working well when this setting is enabled. I'm afraid when the new version of Android gets released to the public many people would enable it and have problems with my app without knowing what is wrong.
So I wanted to display a warning message about this only if the NuPlayer setting is checked on the device. I tried looking for it on the documentation of Android but I couldn't find how to access the status of this new setting.
So the question is that, how can I check the value of this setting programatically?
Thanks
I'm cross-posting my answer from here by request:
Prevent my audio app using NuPlayer on Android Lollipop 5.x?
So, I finally found a way to safely detect wether or not NuPlayer will be used or not on Lollipop. Seems like the best strategy for now is to inform the user to open Developer Settings and enable AwesomePlayer until Google fixes NuPlayer.
Sadly, there's no good way to change this setting for the user, we can just read its value unless you're signed as a system application.
This approach checks Android's system properties values to see if the user have enabled the use of AwesomePlayer or not under Developer Settings. Since Lollipop have NuPlayer on by default, if this value is disabled, we know NuPlayer will be used.
Drop SystemProperties.java into your project for access to read the system properties, do not change its package name from android.os (it calls through to its corresponding JNI methods, so needs to stay the same).
You can now check if the phone is Lollipop/5.0, if AwesomePlayer is enabled, and act accordingly if it's not (e.g. by opening the Developer Settings):
public void openDeveloperSettingsIfAwesomePlayerNotActivated(final Context context) {
final boolean useAwesome = SystemProperties.getBoolean("persist.sys.media.use-awesome", false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !useAwesome) {
final Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
context.startActivity(intent);
}
}
Background
It might be useful for apps to allow to ask the user to answer why it was decided to uninstall them.
The problem
It seems that the Dolphin web browser app (and "everything me launcher") somehow managed to bypass it, and now it shows a webpage (on the default web browser) each time the app is being uninstalled.
This happens even if I uninstall using ADB.
As a user, I really hate it, but it's still interesting since as far as I know, apps can't get intents for the uninstallation of themselves.
Question
How could it be? How did they manage to overcome this?
Is this a hack?
Maybe the app has a background service which checks the foreground app when it's own onDestroy() callback is fired, and if the foreground app is the uninstalling activity of android Package installer, it launch a new intent for the webpage?
My guess is that they're using ACTION_PACKAGE_REMOVED.
http://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_REMOVED
Either that, or Robin Hood and Frei Tuck method, where each one listens to broadcasts events from the other.
Just a guess, but will look into it.
This might be an option: How can an app detect that it's going to be uninstalled?
Please try to get the top activity in the task via ActivityManager, and check if it is the uninstall activity.
Core code:
ComponentName topActivity = mActivityManager.getRunningTasks(1).get(0).topActivity;
String packageName = topActivity.getPackageName();
String className = topActivity.getClassName();
Log.v(TAG, "packageName" + packageName);
Log.v(TAG, "className" + className);
if ("com.android.packageinstaller".equals(packageName)
&& "com.android.packageinstaller.UninstallerActivity".equals(className)) {
//Do anything you want here
}
I am developing an application which has defined some intent filters (in the form of action strings, e.g. com.example.project.UPLOAD) for other applications to use. Consider a device that didn't have my application but with applications that use my intent filters, the Intent created will fail the action test as described in the documentation. Is there any way to prevent this happening or give a better user experience? Here are some of the approaches I can think of but don't know if there are feasible:
While installing an application that depends on another applications to handle some of the intents, suggest user to install the application that can handle the intent
Dynamically determine if the intent can be handled. If not, launch the market showing the application that can handle the intent
What is the best approach to handle this? Please provide some implementation references if possible.
Aside from mentioning it in the Marketplace, I'm not sure how you'd go about presenting messages during the application installation, as (to my knowledge) there is no supported way to execute code upon installation.
If other applications use your filters, then it's up to them to make sure your package is installed. You can't really give them anything without being installed.
They can test to see if a package is installed using the PackageManager, and adjust their logic to notify the user when they need to install your package. Example:
private boolean isInstalled(){
ComponentName comp = new ComponentName("com.yourpackagestuff", "com.yourpackagestuff.TestClass");
Intent intentName = new Intent().setComponent(comp);
List <ResolveInfo> list = ctx.getPackageManager().queryIntentActivities(intentName, PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
That's how I'd go about it, at least.
You can try calling the Intent and catch the ActivityNotFoundException if it is thrown. If it does get thrown, you know it doesn't exist so you can implement your backup code.
This solution is quicker Android check for dependent application during installation?
getPackageManager().getApplicationInfo("com.myproject", 0 );
No exception means its ok