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.
Related
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);
If the intent filters are to resolve implicit intents, then why does
the MainActivity(which is the very first activity that is run when
app is launched) has an intent filter?
Who send an implicit intent to it?
What if the sent implicit intent doesn't have proper data ?
Well, how does the system know which activity is the main activity? It isn't the name- the system doesn't care about the name. Its the activity with the intent filter that says its the main activity.
It can also have other intent filters to launch it any other way you may want. For example, you may have an intent filter to launch it via a deep link.
As for proper data- if launched from the app list or homescreen, it won't have any data. Its on the programmer of the app to make sure that it can do something that makes sense in that case.
It has CATEGORY_LAUNCHER and ACTION_MAIN .
android.intent.action.MAIN means that this activity is the entry point of the application, i.e. when you launch the application, this activity is created.
CATEGORY_LAUNCHER tells that your activity should be displayed in the top-level launcher.
https://developer.android.com/reference/android/content/Intent.html#ACTION_MAIN
Launcher sends implicit intent to it. This is how launcher knows which activity is to be opened on click.
If you send improper data it will not open your activity. For ex:
If you try to start your main activity using implicit intent only in startActivity then it will not start because there is CATEGORY_DEFAULT associated with it. You need to add one more intent_filter to your activity to resolve the intents.
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
I have two activities with exactly same intent filters and I would like to start one of them depending on the condition.
ActivityA should be started by the user when he/she gets the Intent delivered by Android OS to the "Complete action using" list and now the user navigates to ActivityB, so now presently the user is in ActivityB.
So when the user does the same action, I don't want the Android OS to pop again the same "Complete action List" with ActivityA but I want the activity A be replaced now by Activity B.(That is the action changes then the ActivityB is in foreground).
Is this possible?
Use an Intent action in conjunction with Intent extras to figure out where the Intent needs to resolve.
So, for example, you can set some sort of flag and if a specific flag is set (your extra) make it go to ActivityB if it is not... or the other way; no extra show ActivityA if there is an extra go to ActivityB.
That is a real simple example, there are many other ways of dealing with what you are trying to accomplish.
Look into Intents and Intent Filters http://developer.android.com/guide/topics/intents/intents-filters.html and Activity http://developer.android.com/reference/android/app/Activity.html
Also this is a good read as well, http://developer.android.com/guide/topics/fundamentals.html
My boss asked me to prove that my application behaves properly when summoned by another application (dunno why he asked that).
So I have two apps here, one launches a second one. How I launch the specific app I want? Using Intent launch seemly any generic app that reaches a certain goal, not the app I really want.
Give this a try.
Intent secondIntent = new Intent();
secondIntent.setAction(Intent.ACTION_MAIN);
secondIntent.setClassName("com.example", "com.example.YourSecondApp");
startActivity(secondIntent);
I should point out that com.example should be the package of your second application (the one you want to call) and com.example.YourSecondapp is the class name where you have your onCreate() method.
Intent secondApp = new Intent("com.test.SecondApp");
startActivity(secondApp);
Check out for more examples
http://developer.android.com/resources/faq/commontasks.html#opennewscreen
Create one Intent using the following code
Explicit Intent
When you know the particular component(activity/service) to be loaded
Intent intent = new Intent();
intent.setClass("className/package name");
start<Activity/Service>(intent);
Imlicit Intent
When we do not have the idea which class to load and we know the Action to be perform by the launched application we can go with this intent.
Action needs to set, and the Android run time fallows the intent Resolution technique and list out(one or more components) the components to perform the action. from the list out components (if more than one), user will get the chance to launch his chosen application