Does PlayStore send any broadcast message with "com.android.launcher.action.INSTALL_SHORTCUT" action, when it adds app shortcut to home screen before/after the app get installed?
I heard of the following method:
Add <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" /> to manifest.xml
Extend BroadcastReceiver class, then override onReceive() method
Is it true that the above 2 steps will let app get notified when Play Store add app shortcut to home screen?
Here I don't think there is any listener available to listen shortcuts directly. but you could go through some tricky way like :
1) Listen to application install using listener. you could achieve it by registering following way :
<receiver android:name=".apps.AppListener">
<intent-filter android:priority="999">
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<data android:scheme="package"/>
</intent-filter>
2) In your AppListener broadcast receiver whenever you will get it triggered, keep delay of 5 to 10 second and perform action to get all installed applications using :
List<ApplicationInfo> packs = pm.getInstalledApplications(0);
Now you have all installed packages, iterate through them and callgetLaunchIntentForPackage() on each item
If a valid intent is returned, that means it exists on launcher, else if it returns null, the package doesn't launch from home screen.
REASON : Home screens shortcuts are subset of the launcher apps :)
Related
I am trying to handle app removing.
My AndroidManifest.xml looks like this:
<uses-permission android:name="android.permission.GET_TASKS"/>
<receiver android:name=".receivers.UninstallIntentReceiver">
<intent-filter android:priority="0">
<action android:name="android.intent.action.QUERY_PACKAGE_RESTART" />
<data android:scheme="package" />
</intent-filter>
</receiver>
UninstallIntentReceiver.java
public class UninstallIntentReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// fetching package names from extras
LogUtils.i("HK_LOG " + this.getClass().getSimpleName(), "onReceive");
String[] packageNames = intent.getStringArrayExtra("android.intent.extra.PACKAGES");
if(packageNames!=null){
for(String packageName: packageNames){
if(packageName!=null && packageName.equals("com.betconstruct.sportsbookModule")){
// User has selected our application under the Manage Apps settings
// now initiating background thread to watch for activity
new UninstallActivity(context).start();
}
}
}
}
}
When apps is stopped, onReceive() method is called, but when app is running, onReceive() method is not getting called.
In this case onReceive() is called:
But in this case onReceive() is not called:
If I click on close button (from settings, pic that I show with arrow), after that onReceive() method is called.
I feel that I must guest how to handle this action, and solve this problem.
Any kind of suggestion will help me. Thanks.
I am trying to handle app removing.
I'm not sure android.intent.action.QUERY_PACKAGE_RESTART is the intent you need.
From javadocs:
Ask system services if there is any reason to restart the given package. The data contains the name of the package.
This looks like an action that's needed for system services, it doesn't even have a documentation. Also note the #hide annotation, which means that this action is not exposed to public API and you shouldn't rely on that.
The actual action you are interested in should be android.intent.action.PACKAGE_REMOVED.
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package"/>
</intent-filter>
</receiver>
If I understand your question correct, you are trying to handle an action of removing an application within the same application, meaning you expect onReceive() method of BroadcastReceiver which is in Sportsbook application to be fired as soon as user removes Sportsbook application. That's not possible, because when user uninstalls your application, all your app data, apk, classes are removed, thus there doesn't exist that receiver anymore.
If you try to detect removal of application from another application (let's say you have 2 applications, and you want to track whether user removes one of your apps), then that would make sense, and onReceive() would be called as expected.
I am developing a launcher app for android and for that i need my app to get notified for the system broadcast with actions like ACTION_PACKAGE_REMOVED, ACTION_PACKAGE_CHANGED, etc that impacts the activities available for launch with the user(to be displayed by my app).
Broadcast for package installed, package removed, package updated & package disabled/enabled are working as usual but the problem is when whole of the package is disabled like through Titanium backup or some similar app its get notified to my Broadcast receiver through system broadcast invoked having action Intent.ACTION_PACKAGE_CHANGED but when an app component like an activity is disabled individually from apps like MyAndroidTools it does not get notified to my Broadcast receiver i.e no broadcast(broadcast with Intent.ACTION_PACKAGE_CHANGED) is received from the system to my app due to disabling individual app component.
Here is my Manifest declaration of Broadcast receiver with requisite intent filter:
<receiver android:name=".LauncherBroadcastReceiver">
<intent-filter android:priority="100">
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_CHANGED"/>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
Everything is working as intented but only when whole of the package is disabled or enabled but not when a single component(say activity) is disabled or enabled.
There is definately some way of doing it as i have test checked it with some other launchers i.e. when a single component is disabled it gets reflected(disappeared in app drawer) in the launcher & vice versa for enabling the component. So those launchers are receiving this info may be some listener or broadcast.
`<receiver android:name=".LauncherBroadcastReceiver" exported="true" enabled="true">`
One probable solution(not ideal) for my problem is to get the list of disabled launchable activites in Activity onResume method and than update to reflect the changes.
To get the list of disabled launchable activities:
Query package manager for all launchable activities(including disabled ones)
Intent mainLaunchIntent = new Intent(Intent.ACTION_MAIN);
mainLaunchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
mainLaunchIntent.addFlags(PackageManager.MATCH_DISABLED_COMPONENTS);
List<ResolveInfo> activitiesInformationList = packageManager.queryIntentActivities(mainLaunchIntent, 0);
Query package manager for only enabled launchable activities
Intent mainLaunchIntent = new Intent(Intent.ACTION_MAIN);
mainLaunchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> activitiesInformationList = packageManager.queryIntentActivities(mainLaunchIntent, 0);
List(1-2) will be the list of disabled activities. I haven't tested the same since not ideal for me would like to wait for more answers but if some1 found the same helpful can use it.
I want to implement something like AppLock application is doing.
If in its settings it is set to lock applications uninstall/install, then while uninstalling any app (precisely on clicking the Uninstall button) a lock screen comes which asks for a password/pattern.
Only after entering the password user is allowed to uninstall the app.
What's that intent(or anything, I assume it to be an intent but not sure) that one get when Uninstall button is clicked?Also I dont want to make it device admin, as the app I mentioned does require to be device admin.If they can do it, then there is some way.
Please help.
I have found a way.
When you go to Settings -> Manage Apps -> Click on any app.
you get a broadcast with name of the package in extras.
When you click on the Uninstall button on that screen,
an activity is opened always name com.android.uninstaller.UnistallerActivity.
So the solution to this problem is a combined way of 1 and 2 steps mentioned above.
When ever you get the intent mentioned in first step and the extras contain the package name of your app start an activity watcher using PackageManager by which you get the top most visible activity and its package.
So now if uninstaller activity is launched then you can be sure that user wants to uninstall your app.
There after you can do necessary action to stop him to do that.
You can intercept the intent for your application uninstall. Simply put the following code in your manifest file:
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
<uses-permission android:name="android.permission.CLEAR_APP_CACHE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".UninstallActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DELETE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="package" android:pathPattern="com.package.yourapp" />
</intent-filter>
</activity>
</application>
After this you can somehow process that your application is going to be deleted, and call the package manager uninstaller.
Make it a device administrator instead. That will automatically block the user from uninstalling it. If the user tries to deactivate it from the Security > Device Administrator list in order to uninstall it, your app can then ask for the password.
try catching below intent in the broadcast reciver and fire up ur activity warning activity or processing what u want to carry on.
"android.intent.action.UNINSTALL_PACKAGE"
this intent will not given or broadcasted to same app which is about to get uninstalled
Looks like this has gone through a lot of changes. The default broadcast of PACKAGE_REMOVED doesn't work as intended. I came across this discussion, did not actually implement it, but people say it has worked for them. Do give this a try
https://groups.google.com/forum/?fromgroups=#!topic/android-developers/aX5-fMbdPR8
try this code
Please try to get the top activity in the task via ActivityManager, and check if it is the uninstall activity.
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
}
như lone
How do I build an intent and the Manifest so that I can invoke an activity with my application as an implicit intent.
The idea is that I am writing some general code that I wish to use in a number of applications.
This code is held in an Android library and is linked to the using application.
This general code opens an activity and does some work.
Once it is done (user clicks a button) it needs to transfer to an activity that is specific to this application.
As per my understanding on your questions,
You can declare your activity with specified implicit intent in your application's manifest file..
For example: If you want to make a application for view Image with your application and you have to use that application on your device which can allow other activity to view image using implicit intent action.VIEW so ,just
<activity android:label="#string/app_name" android:name=".MyImageViewerActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN">
<category android:name="android.intent.category.LAUNCHER">
</category></action></intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW">
<category android:name="android.intent.category.DEFAULT">
<data android:mimetype="image/*">
</data></category></action></intent-filter>
</activity>
In the above code we can see that intent-filter has following properties.
a. action: type for which this activity will respond for.Like this activity will respond for view action.
b. category: implicit intents are divided in categories.Like this activity is in default category.
c. data: Specify more information about intent-filter. Like this activity will handle file of mimeType “image/*”.
And when you install this application in your device and click on any image file, you will see a choice dialog that offer you to select between default application and your application. Just select your application to see the image.
For more info with example look at this What is intent filter in android?
Tutorial: Registering via Intentfilter
I think you can use intent-filters. I didn't use it for such things, but I hope that will help you.
Idea is that you can call your activity not by name, but by it's action (that is setted in intent-filter in your Manifest)
Is there any way to hide an application icon from Android applications list ? The application should be downloaded from Market and opened some GUI for configuring my application. I don't want to see any icon of my application in applications list. User should not be able to run it.
By the way I know some way:
remove this line from manifest category android:name="android.intent.category.LAUNCHER"
But it is not worked for me, because the GUI is not shown.
Thanks very much !
Removing the launcher category is correct.
Try adding android.intent.category.DEFAULT to the intent filter to be able to call the activity.
Thanks for replay.
I found a way to hide application icon from application list;
PackageManager pm = getApplicationContext().getPackageManager();
pm.setComponentEnabledSetting(getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
But in time of application reinstalling occurs error "Activity class does not exist" and it is not possible to reinstall application without uninstalling it. .... what's the problem ?
There is also variant of Launcher Pro. But this is an application. My app should be downloaded from Android Market and there is no guarantee that all users have Launcher Pro.
I want programmatically hide application icon from application list. The method with PackageManager works for me ... but there is a problem regarding reinstalling. It is important when you want to update the application from Market.
I have found a way for this to work when you reinstall the app.
Add a broadcast receiver with intent filter action android.intent.action.PACKAGE_ADDED.
In the onReceived method you must activate your disabled component :
ComponentName componentToEnable = new ComponentName(context, Your_disabled_class.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(componentToEnable, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
Complete AndroidManifest.xml for receiver:
<receiver android:name="PackageChangeReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>