I am launching a third party app (AppC) using startActivity() and getPackageManager().getLaunchIntentForPackage() API:
Intent i = getPackageManager().getLaunchIntentForPackage(packageName);
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
and when I return from that app some features of my application stop working until I manually clear data of my application. If I use a different 3rd party app (AppK) - everything works just fine.
Is it possible that AppC does something to my application's data? What could cause such behavior?
Is it possible that AppC does something to my application's data?
Probably not. The author of AppC probably does not know you exist, let alone to exploit any security holes in your app to do "something to [your] application's data".
What could cause such behavior?
Bugs in your app. Bear in mind that your process may terminate after starting this other activity.
AppC was deleting files in the shared (Downloads) folder, which my app relied upon.
Related
There are apps (such as https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher) that are free, but whose paid features can be enabled by buying another app (in this case, this one https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher.prime)
How does this work?
My guess is that the free apps launches an explicit Intent and can detect if the app is present via a try/catch structure. The downside of this is that this could be easily circunvented by someone who creates an app with the same package name and specifies all possible Intent filters.
Is this how it works, or is it some other way?
There are various ways to do that. One way is to query a content provider which will be protected with a special permission.
I have released quite long ago on Github a library which helps doing this: Android Unlocker Library.
That's a good option if you are dealing with devices outside the Google ecosystem, however, from a developer experience, in-app purchases offer a much better user experience (and thus drive more sales) according to me.
The easiest way is to use startActivityForResult(...) from app A against an Activity of app B, that must be configured with an IntentFilter in order to be used from an outer app. Inside the B called activity you can also check who's calling with getCallingActivity(). You can find an example here.
Before starting the Activity, you can test that B is installed (using the PackageManager) or you can just start the activity and catch the Exception.
In the called Activity, you can check the signature of the calling package using the PackageManager.checkSignature(String,String) method. Pass the package name of A and B and if the signature matches, execute the logic.
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
Hi guys this is just my first post,
is it possible to access an activity which is in Phone.apk in a non-rooted phone?
I've tried something like this
Intent i = new Intent(Intent.ACTION_MAIN);
i.setClassName("com.android.phone", "com.android.phone.PhoneApp");
startActivity(i);
but my app always stops unexpectedly.
There is no activity named com.android.phone.PhoneApp in the Android firmware, let alone in the Android SDK.
Moreover, you should not be attempting to start activities in the com.android package, as they are not part of the Android SDK and may or may not exist on any given device or Android version.
I would like to require that a user type a password before being allowed to uninstall/remove my application. How can I implement this functionality?
You could do this by:
The first time your app is installed, install a separate application/package ("watcher").
The only classes "watcher" contains is a BroadcastReceiver that listens for ACTION_PACKAGE_REMOVED
Add a BroadcastReceiver to your application that also listens for ACTION_PACKAGE_REMOVED
When a intent is broadcast to one of your receivers, check if the other component is still installed. If is isn't (the user just uninstalled it), prompt for the password - if it's wrong, reinstall the other component. If it's right, uninstall yourself.
You can exec logcat and get the start activity intent information.
You will find that before the uninstall activity is displayed, there is
a text msg such as:
Starting activity: Intent { act=android.intent.action.DELETE dat=package:com.comodo.pimsecure cmp=com.android.packageinstaller/.UninstallerActivity }
then you can pop a activity ask for password now.
It is possible. you can do it with DeviceAdminReceiver api. (i don't no how)
This is a hard problem. I can think of at least one non-evil use-case for it.
e.g. Stolen Phone Recovery app - you wish to deter ne'er-do-wells from uninstalling the app.
In this case, I can think of two sensible assumptions which would stop me implementing what you're looking for:
the thief is unaware of your app, so will not try to uninstall it.
the thief is aware of your app, and switch it off until he can get it to an iron box* to re-install the OS.
* For the uninitiated: an iron box will prevent the device sending or receiving electromagnetic signals.
Of course, this answer amounts to You Ain't Going To Need It, though I suspect you have already thought this through.
Protect installing/uninstalling apps by password makes Android more secure from malware/viruses. Your Android become as secure as iPhone.
How it works:
Automatic apps installing is prompted to user. You can search the app name. If not secure, Block it.
Root access is prompted to user. Too many ads is an indicator that access is dangerous.