How to update android app with hidden icon - android

I use this code for hiding icon:
PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this, MainActivity.class);
p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
It works fine, but when I try to update my application, I get this error:
Error while executing: am start -n "../..main.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -D
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=../.main.MainActivity launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } }
Error type 3
Error: Activity class {../..main.MainActivity} does not exist.
Error while Launching activity
How can I hide icon and still available application update (without uninstall/install in a manual way)?

This is a design problem I think. You need to prevent MainActivity getting launched when it is disabled. If you are forced for some reason to start your MainActivty after updating, just enable your MainActivity first. You can set MainActivity enabled state to false in the Manifest and make it enabled whenever you need for example in onCreate method of the application class, in a service or in a broadcast receiver. Disabling MainActivity in the Manifest probably prevent it to be launched by default and might be the thing you need. It is all based on your need of how and when you want your MainActivity to get disabled and enabled again. For a final comment as you probably know an app doesn't need an activity - with action main or not - to get started.

just remove android.intent.category.LAUNCHER from the Activity and there will be no launcher icon - while it still can be launched, due to android.intent.action.MAIN. If you really need a launcher icon, which can be hidden & shown, simply add one proxy Activity, which has no other purpose than providing the launcher and then start the actual Activity... so that one still can start it directly, no matter if that proxy Activity had been disabled, whether or not.

Related

Android start activity of second app having no icon from first app

I am having two apps. First app has an activity from which I want to launch an activity from the second app. I am using the following code:
Intent launchIntent = m_context.getPackageManager().getLaunchIntentForPackage(m_packageName);
if (launchIntent != null) {
m_context.startActivity(launchIntent);
}
This code is working very fine to launch the activity from the second app but I want to have the second application without any icon. I am using following code in MainActivity of the second application to remove icon:
PackageManager p = getPackageManager();
//Removing app icon
ComponentName componentName = new ComponentName(this, com.tools.html2pdf.MainActivity.class);
p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
This code successfully removes the launcher icon but then activity from my first application is unable to launch the activity from second app.
Can any one help me in this regard? I want to launch activity of an app having no icon from activity of another application.
When you disable the component like you have done, that component can't be launched in any way. However, interesting thing is that other components (non-disabled activities) of your second application are still launchable.
So, you can create an alias of your MainActivity in the second application which will be used for your purpose. Let's call alias as MainActivityAlias.
From your first application, call the intent on MainActivity. The code for disabling the component will be executed and nothing will open. However, the icon will be gone because this component is disabled and everything related to this component (i.e icon) is gone too.
Now, call the intent on MainActivityAlias just after above intent in the first application. This is just a copy of MainActivity but it does not have any code for disabling and thus, it is enabled and launchable.
Some Side Notes :
1) Both activities should have an <intent-filter> with android.intent.action.MAIN.
2) Your MainActivity should be the launcher activity and thus should have android.intent.category.LAUNCHER in the manifest.
3) Inside MainActivity, you have to check where the call is coming from. If the call is from the first application, then execute the code to disable icon which you mentioned in the question. If the call is coming from launcher icon, then open MainActivityAlias using intent. You can know where the call is coming from like this.
Note - This is just an idea. I have not tested it.
If you don't want the second app to have an app icon, just remove the <intent-filter> with ACTION=MAIN and CATEGORY=LAUNCHER for the root Activity in the second app. When the app is installed, if there is no <intent-filter> with ACTION=MAIN and CATEGORY=LAUNCHER, there will be no app icon shown.
Your app can still launch the second app, but not with the method you've described, since Android doesn't know which is the "launch" Activity. Assuming you know the package and class name of the Activity you want to launch in the second app, you can launch it like this:
Intent launchIntent = new Intent();
launchIntent.setClassName("second.package.name", "fully.qualified.class.name.of.MainActivity");
// add and Intent flags if necessary here
launchIntent.addFlags(Intent.FLAG_ACTIVITY_...);
startActivity(launchIntent);

How to override default call screen?

I want to launch my customized screen when user dials any number from my android app instead of default caller screen.
Generally speaking, in order to know how to override any default Activity, first you need to know the structure of the Intent that can launch the Activity.
Determining the structure of the Intent
Open Android Monitor (aka Logcat)
Filter the log to only show those matching the string "ActivityManager"
Launch the Activity that you want to override. In your case, launch the call screen
If the Activity can be overridden, you should see a log entry with "START...", copy that entry so that you don't lose it in the log. On my device, this entry was:
START u0 {act=android.intent.action.CALL dat=tel:xxxxxxxxxxx flg=0x10000000 cmp=com.android.server.telecom/.CallActivity (has extras)} from uid 10088 on display 0
This Intent is made up of
act - The Intent action
dat - The Intent data
cmp - The Intent component
Now you need to check if this Intent can launch the default dialer without specifying the component.
Checking if a default Activity can be overridden
adb shell
am start -a android.intent.action.CALL -d tel:xxxxxxxxxxx (fill in the number you want to test with)
If it launches the dialer, then, voila. You should be able to create an IntentFilter for your application, setting the action and the data appropriately. Then, the next time the user tries to make a call, it will ask the user which app they want to use.

How to hide an app and give it the right to be access from another app?

I hope anyone can help me or give me a clear solution,
I have an app that I don't want to be opened directly from the user, so I need to hide its icon.
and in the other hand, I want to access this application from another app (App2), so I wrote this code in the function of onClick of a certain button of App2:
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(package name of the first app );
startActivity(launchIntent);
Before hiding the App1 , everything was working perfectly No errors but after hiding it using the following code, it crashes:
PackageManager packageManager = this.getPackageManager();
ComponentName componentName = new ComponentName(this,FingerActivity.class);
packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
and the following error appear in Android Studio:
Starting: Intent { act=android.intent.action.MAIN
cat=[android.intent.category.LAUNCHER]
cmp=com.neurotec.samples.multibiometric/.fingers.FingerActivity }
Error type 3 Error: Activity class
{com.neurotec.samples.multibiometric/com.neurotec.samples.multibiometric.fingers.FingerActivity}
does not exist.
any idea?
any idea?
You disabled the component. You cannot start the component from any other app.
I have an app that I don't want to be opened directly from the user, so I need to hide its icon.
The simplest way for it to not have an icon is for you to not give it an icon. Change your <intent-filter> for that activity to be something custom for you, rather than having it have the MAIN/LAUNCHER values that causes home screens to put an icon for it in the launcher.

setComponentEnabledSetting causes an exception,it may kill current app?

i am willing to disable one activity from another activity by following codes,but it causes a problem: kill current app.
the SDK version is 4.0 .
#Override
public void onCreate(Bundle savedInstanceState) {
PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(newComponentName(this,
"com.xxx.launcher.desktop.testActivity"),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
is it lack of sth to be set?
You should take a look at http://developer.android.com/reference/android/content/pm/PackageManager.html#DONT_KILL_APP
You have to be a little careful when you use PackageManager.DONT_KILL_APP, as it can lead to undefined behavior. Especially if the activity is trying to disable itself. It should be fine if you're targeting another Activity, but I'm guessing the Activity you're trying to clear is in the
It looks like your call to ComponentName is incorrect.
You will probably want to call new ComponentName(this.getApplicationContext(), testActivity.class). Or you can use new ComponentName("com.xxx.launcher.desktop","com.xxx.launcher.desktop.testActivity"), where the first argument is the package in the AndroidManifest.xml file, and the second being the full path to the ComponentName. Take a look at the following SO question for information on setting up a ComponentName: When to use which constructor for ComponentName in Android? for more information.
I had the same problem as the OP.
I noticed, at the top of the Run window in Android Studio, that it wasn't trying to launch my default launcher activity, SplashActivity, but another launcher activity within my app:
Launching 'app' on samsung SM-J320FN.
$ adb shell am start -n "com.example/com.example.NotMyDefaultLauncherActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
My app exited unceremoniously when it later attempted to disable NotMyDefaultLauncherActivity (via packageManager.setComponentEnabledSetting(...).
The solution for me was to go into Run > Edit Configurations... > Android App > app, where I changed the launch activity from DefaultActivity to (what should have been the default, as it was the first one listed in my manifest) com.example.SplashActivity.

Disable activity from another activity?

I am using the following code to remove my app from the launcher:
if (!dialercode.getText().toString().equals("")) {
getPackageManager().setComponentEnabledSetting(
getComponentName(),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
However, that also stops that activity being launched through other means (secret code).
So, I have setup a separate Launcher activity that will be disabled instead (all the Launcher activity does is launch the main activity).
However, I don't know how to go about disabling the Launcher.java activity via the main activity - IE how do I get the component name for the Launcher activity when I'm in a different activity?
I discovered the solution, instead of using getComponentName() use:
new ComponentName(context, Activity.class) where Activity is the name of the Activity you wish to disable. You can use this in any activity in your application.

Categories

Resources