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.
Related
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.
Use case
during a phone call, User opened some apps and the inCall UI goes behind the APP UI.I need to bring it back using adb command
What i did ?
I used below command
adb shell am start --activity-brought-to-front -n com.google.android.dialer/com.android.incallui.InCallActivity
Which resulted in error
Security exception: Permission Denial: starting Intent { flg=0x10400000 cmp=com.
google.android.dialer/com.android.incallui.InCallActivity } from null (pid=12862
, uid=2000) not exported from uid 10102
java.lang.SecurityException: Permission Denial: starting Intent { flg=0x10400000
cmp=com.google.android.dialer/com.android.incallui.InCallActivity } from null (
pid=12862, uid=2000) not exported from uid 10102
at com.android.server.am.ActivityStackSupervisor.checkStartAnyActivityPe
Is there any way to acheive the desired result using adb?
The InCallActivity activity can't be launched from other applications including launching via am start as the android:exported element of InCallActivity is set to false.
android:exported
This element sets whether the activity can be launched by components of other applications - "true" if it can be, and "false" if
not. If "false", the activity can be launched only by components of
the same application or applications with the same user ID.
If you are using intent filters, you should not set this element "false". If you do so, and an app tries to call the activity, system
throws an ActivityNotFoundException. Instead, you should prevent other
apps from calling the activity by not setting intent filters for it.
If you do not have intent filters, the default value for this element is "false". If you set the element "true", the activity is
accessible to any app that knows its exact class name, but does not
resolve when the system tries to match an implicit intent.
This attribute is not the only way to limit an activity's exposure to other applications. You can also use a permission to limit the
external entities that can invoke the activity (see the permission
attribute).
When you launch for the first time ,does the starting activity receive any intent?
If it does, where does it come from? which class starts it?
AFAIK it is Looper which is instructed by ActivityManager initiated by eg. App drawer and usually it sends intent with
action = "android.intent.action.MAIN"
and
category = "android.intent.category.LAUNCHER"
Usually there is no data (extras) attached.
You can write your own Launcher it would require do to the following:
get the list of installed packages
check if package responds to intent with fields as mentioned above.
a. If there are multiple classes which resonds to intent you need to handle all of them (add icons)
If user clicks on an icon, send intent to that package with proper intent.
I'm trying to gain information on an Activity nested within the settings menu.
Right now I can log the activity being started which gives me the message
(Logcat output): START u0 {act=android.intent.action.MAIN cmp=com.android.settings/.SubSettings (has extras)} from pid 6270
However this is clearly not what I require to create my own Intent to start this Activity.
Can anyone help me find more information on this Activity?
Many thanks.
However this is clearly not what I require to create my own Intent to start this Activity.
That activity is not exported, and so you cannot start it directly yourself via any Intent.
If Activity manager launches the MainActivity through intent-filter with action=main, and category=launcher, then which type of intent is used?
I'm confused little bit. Is it implicit intent?
An intent is an abstract description of an operation to be performed. Its most significant use is in the launching of activities.
when the user clicks on the application icon, the android system looks in the manifest file for the intent with
action="android.intent.action.MAIN"
and
category="android.intent.category.LAUNCHER".
MAIN action is the main entry point of the application.
LAUNCHER category means it should appear in the Launcher as a top-level application.
Intent is just a piece of information about intention. Intent do not starts anything. It just inform OS that there is a need to do something (i.e start app). System looks for apps able to resolve this intention, starts them and pases to them starting intent (becouse you can pass some portion of data in it).
When user clicks app icon in launcher, launcher application generates and sens intent to OS (with explicit name of desired application to start). Android creates separate DVM, main activity class, starts acrivity's life cycle with calling onCreate() and brings activity to foreground.
When the user selects your app icon from the Home screen, the system calls the onCreate() method for the Activity in your app that you've declared to be the "launcher" (or "main") activity. This is the activity that serves as the main entry point to your app's user interface.
You can define which activity to use as the main activity in the Android manifest file, AndroidManifest.xml, which is at the root of your project directory.
The main activity for your app must be declared in the manifest with an intent-filter that includes the MAIN action and LAUNCHER category(That you know probably).
If a component does not have any intent filters, it can receive only explicit intents. A component with filters can receive both explicit and implicit intents.
Therefore, activities that are willing to receive implicit intents must include "android.intent.category.DEFAULT" in their intent filters. Filters with "android.intent.action.MAIN" and "android.intent.category.LAUNCHER" settings are the exception. They mark activities that begin new tasks and that are represented on the launcher screen. They can include "android.intent.category.DEFAULT" in the list of categories, but don't need to.
For more details please refer this link:
http://developer.android.com/guide/components/intents-filters.html