I want to allow the users of my Android app to hide/unhide it when they want.
I already have the code to perform the hide/unhide actions, and the hiding works fine.
But now how can I call the unhide method to let the app back?
I mean, if the app is hidden, where can the user, let's say, "click a button" that calls the method to make the app unhide?
Here is my hide/unhide code:
// method to hide the app icon
public static void hideAppIcon(final Context context)
{
PackageManager p = context.getPackageManager();
// activity which is first time open in manifest file which is declare as <category android:name="android.intent.category.LAUNCHER" />
ComponentName componentName = new ComponentName(context, SplashActivity.class);
p.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
// method to unhide the app icon
public static void unhideAppIcon(final Context context)
{
PackageManager p = context.getPackageManager();
// activity which is first time open in manifest file which is declare as <category android:name="android.intent.category.LAUNCHER" />
ComponentName componentName = new ComponentName(context, SplashActivity.class);
p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}
Here's a way I've learned from another app. Not "hiding" the icon, instead, change the icon and label of your app. Disguise the app as some built-in apps like "Settings" or "Calculator".
Another solution (which might be closer to your need) is to add an intent-filter in your app, detecting something like phone calls. If users call a certain number, you unhide your app.
see this for more infomation.
Hope this will help.
Related
Is it possible to create an app without any activities? Without a launcher icon and without the "open" button on Play Store? Like this one https://my.pcloud.com/publink/show?code=XZUi3I7Z6yNkHyuBISL5XynlYYI8SjEJcoMk
I only need it to create a background service.
I've done some research and I haven't found anything about this. If you could just point me in a direction (or tell me it's not possible) it would be great!
Cheers!
You said you didn't want to use a translucent Activity, but that seems to be the best way to do this:
1- In your Manifest, set the Activity theme to Theme.Translucent.NoTitleBar.
2- Don't bother with a layout for your Activity, and don't call setContentView().
3- In your Activity's onCreate(), start your Service with startService().
4- Exit the Activity with finish() once you've started the Service.
In other words, your Activity doesn't have to be visible; it can simply make sure your Service is running and then exit, which sounds like what you want.
how to hide luncher icon :
PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this, com.apps.MainActivity.class); // activity which is first time open in manifiest file which is declare as <category android:name="android.intent.category.LAUNCHER" />
p.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
Hide open button couldn't be done , because we are talking about an application and not a google library
how to unhide icon :
PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this, com.apps.MainActivity.class);
p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
IMPORTANT: It's somehow tricky if you need to do something with main activity in your app when it's hidden. you will face an ActivityNotFoundException. to make it work, you should unhide icon before doing anything to your main activity and hide it again after you are finished.
I use marshmallow android.
I want inside app. Camera,Setting,internet... hide icon.
I know how to hide icon on kitkat android.
but I don't know how to hide icon on marshmallow.
how to hide app icon on android marshmallow?
use below code along with Package manager permission
PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this, com.apps.MainActivity.class); // activity which is first time open in manifiest file which is declare as <category android:name="android.intent.category.LAUNCHER" />
p.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
I am creating a launcher (kiosk) app that will be downloadable through google. When first installing this application the user has the ability of choosing which launcher (mine or the stock) will be the default. I am trying to bring this up manually if the user does not make my application the default launcher. I want the user to be forced into selecting ALWAYS instead of JUST ONCE when that dialog comes up, otherwise the dialog will continue to appear periodically with a friendly message. This is what I have attempted so far.
I created a method to check for if my application is the default
/**
* method checks to see if app is currently set as default launcher
* #return boolean true means currently set as default, otherwise false
*/
private boolean isMyAppLauncherDefault() {
final IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
filter.addCategory(Intent.CATEGORY_HOME);
List<IntentFilter> filters = new ArrayList<IntentFilter>();
filters.add(filter);
final String myPackageName = getPackageName();
List<ComponentName> activities = new ArrayList<ComponentName>();
final PackageManager packageManager = (PackageManager) getPackageManager();
packageManager.getPreferredActivities(filters, activities, null);
for (ComponentName activity : activities) {
if (myPackageName.equals(activity.getPackageName())) {
return true;
}
}
return false;
}
Then I make the attempt of launching the chooser
/**
* method starts an intent that will bring up a prompt for the user
* to select their default launcher. It comes up each time it is
* detected that our app is not the default launcher
*/
private void launchAppChooser() {
Log.d(TAG, "launchAppChooser()");
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
When I do this I am not receiving the choice between my app and the stock launcher. I tried using startActivity(Intent.createChooser(intent, "Please set launcher settings to ALWAYS")); and I get the choices between my app and the stock launcher, however, I don't get the options ALWAYS or JUST ONCE.
I can create a custom dialog for this instead of launching chooser but I need to know how to set the default app launcher programmatically. Thanks in advance!
This is actually possible with a little workaround:
Create an empty Activity that acts as a launcher called FakeLauncherActivity. Add it to your manifest as a disabled component:
<activity
android:name="com.path.to.your.FakeLauncherActivity"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Check whether your desired launcher activity is the default one (with the isMyAppLauncherDefault() from your question).
If not, offer the user to choose the preferred launcher activity like this:
public static void resetPreferredLauncherAndOpenChooser(Context context) {
PackageManager packageManager = context.getPackageManager();
ComponentName componentName = new ComponentName(context, com.path.to.your.FakeLauncherActivity.class);
packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
Intent selector = new Intent(Intent.ACTION_MAIN);
selector.addCategory(Intent.CATEGORY_HOME);
selector.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(selector);
packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, PackageManager.DONT_KILL_APP);
}
This method temporarily enables FakeLauncherActivity, which leads to a change in the set of available launcher activities, which forces Android to forget its default launcher. You will see something like...
521-735/system_process I/PackageManager﹕ Result set changed, dropping preferred activity for Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 } type null
... in your log.
The method then simply opens a launcher intent where you can see all installed launchers and the buttons "Always" / "Just once".
Finally, the method disables FakeLauncherActivity again so that it doesn't display in the list.
You could repeat that as often as you want and only let the user proceed if your desired launcher activity is set as default.
The isMyAppLauncherDefault() function in the question doesn't always work for some reason.
This code might be better for determining what is the default package for the HOME screen.
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
ResolveInfo resolveInfo = getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
String currentHomePackage = resolveInfo.activityInfo.packageName;
I want the user to be forced into selecting ALWAYS instead of JUST ONCE when that dialog comes up
That is not possible, except perhaps on rooted devices, barring some security flaw in Android.
When I do this I am not receiving the choice between my app and the stock launcher
Correct. If a default has already been chosen, this will simply launch the default.
I tried using startActivity(Intent.createChooser(intent, "Please set launcher settings to ALWAYS")); and I get the choices between my app and the stock launcher, however, I don't get the options ALWAYS or JUST ONCE.
Correct. createChooser() forces a choice, but does not allow setting a default.
Android Q (API 29) has RoleManager. Let's say your app is a Launcher.
[AndroidManifest.xml]
<activity
... />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
private val startForResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
// Perhaps log the result here.
}
}
private fun showLauncherSelection() {
val roleManager = requireActivity().getSystemService(Context.ROLE_SERVICE)
as RoleManager
if (roleManager.isRoleAvailable(RoleManager.ROLE_HOME) &&
!roleManager.isRoleHeld(RoleManager.ROLE_HOME)
) {
val intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_HOME)
startForResult.launch(intent)
}
}
When you call showLauncherSelection(), you should see a dialog similar to the following.
There are other roles, such as ROLE_BROWSER, ROLE_DIALER, ROLE_SMS, and such.
If you are implementing Google EMM solution (Dedicated Device):
https://developer.android.com/work/dpc/dedicated-devices/cookbook
// Create an intent filter to specify the Home category.
IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
filter.addCategory(Intent.CATEGORY_HOME);
filter.addCategory(Intent.CATEGORY_DEFAULT);
// Set the activity as the preferred option for the device.
ComponentName activity = new ComponentName(context, KioskModeActivity.class);
DevicePolicyManager dpm =
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
dpm.addPersistentPreferredActivity(adminName, filter, activity);
I set my activity as a default launcher to intercept home button clicks like so:
<activity
android:name=".ExampleActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
When my activity, ExampleActivity is launched, if i click the home key, I get prompted to choose. If I select make this my default and chose my activity, I am stuck In my activity as desired.
The problem is, when I leave the activity, I try to remove my activity from the default launcher, but am unsuccessful.
I have tried:
ComponentName componentName = new ComponentName(
"com.example.exampleactivity",
"com.example.exampleactivity.class");
pm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, PackageManager.DONT_KILL_APP);
And:
PackageManager pm = getActivity().getPackageManager();
ComponentName name = new ComponentName(this, "com.example.exampleactivity.class");
pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
But my designation for the home is never removed.
Does anyone have a working way to fix the above?
I only wan't the home button to be default for a specific activity, not my entire application. When I leave the activity, it should be removed and restored to default.
if it's your app that you're clearing its defaults , you can simply call :
getPackageManager().clearPackagePreferredActivities(getPackageName());
then , in order to show the dialog of choosing which launcher to use , use:
final Intent intent=new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
This solution is a clever way of doing it:
Clearing and setting the default home application
The code in onResume() basically goes like this:
ComponentName componentName = new ComponentName(MyActivity.this, FakeHome.class);
if (!isMyLauncherDefault()) {
Log.e(TAG, "MyActivity is not default home activity!");
// toggle fake activity
PackageManager pm = getPackageManager();
int flag = ((pm.getComponentEnabledSetting(componentName) == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
: PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
pm.setComponentEnabledSetting(componentName, flag, PackageManager.DONT_KILL_APP);
// start home activity to enable chooser
Intent selector = new Intent(Intent.ACTION_MAIN);
selector.addCategory(Intent.CATEGORY_HOME);
startActivity(selector);
}
and the method isMyLauncherDefault() is taken from here:
How to check if my application is the default launcher
You cannot override the behavior of the home key to suit your application; this is a design decision by Google, to ensure the user can always return to a static location. There may be some ways around this (if they still exist) but they are unintended bugs which an application should not rely on.
The short answer: you can have any key except the home key.
Have a look at the android.permission.SET_PREFERRED_APPLICATIONS permission. Also this method http://developer.android.com/reference/android/content/pm/PackageManager.html#clearPackagePreferredActivities(java.lang.String)
my app is designed to only need to be run once. As such I want to hide the icon from the launcher after the first run, but without uninstalling the app.
I have seen similar applications - they can remove their own icons from the launcher app list. How can I achieve the same results? Thank you.
PackageManager p = getPackageManager();
p.setComponentEnabledSetting(getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
Note that the icon may not be gone until the next reboot.
Hide app's icon using below code
PackageManager pkg=this.getPackageManager();
pkg.setComponentEnabledSetting(new ComponentName(this,SplashActivity.class),PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
// activity which is first time open in manifiest file which is declare as <category android:name="android.intent.category.LAUNCHER" />
Here is how to bring back the app's icon
PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this,SplashActivity.class);
p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
With Android Q (API 29) Google changed the Launcher icon visibility behaviour. Even if you disable your Launcher Activity or completely remove the
android.intent.category.LAUNCHER <intent-filter> from all your Activities, the app will appear in the launcher and open the Android OS app settings, with the exception of:
Packages that don't declare any permissions in their respective manifest files
System apps
Apps that don't contain any components inside their
respective manifest's tag
You can have an app without a launcher by NOT including an intent filter with MAIN and LAUNCHER in the declaration of the Activity in the AndroidManifest - the question then becomes how to do the first kick off.. Widget maybe ?
Hide app icon using this code:
PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this, com.apps.MainActivity.class); // activity which is first time open in manifiest file which is declare as <category android:name="android.intent.category.LAUNCHER" />
p.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
and bring it back, with this:
PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this, com.apps.MainActivity.class);
p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
NOTE: This will not work for Android 10