Ok,
So I'm making a library project of UI elements. The Library has some activities which are based of ActionBarSherlock which is a backwards compatibility library for the action bar in android. In these activities I would like to have a button in the action bar which will take the user home regardless of which activity they are using in the Library project.
Some terminology. The 'library' refers to the Android UI library project I'm working on. The 'Application' refers to whatever customer a developer might be using with the Library included.
Usually, when you make an activity and you want to call another, you would do something like this.
intent = new Intent(this, WhateverMyActivityName.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Simple enough. But here's the tricky bit. Android Libraries have little to no knowledge of what application is using them. So 'WhateverMyActivityName.class' is useless as there is no way to predict what the developers application will call their activities.
I need to replace
intent = new Intent(this, WhateverMyActivityName.class);
with something like this
intent = new Intent(this, getApplication().MainActivity().getClass());
or possibly use some sort of intent action which will call the main Activity in the application (Intent.ACTION_MAIN or Intent.CATEGORY_LAUNCHER)
So in short: How do I get an applications main activity from a library project?
We can use reflection to get class object.
Class.forName("com.mypackage.myMainActivity")
Add this code in Library project to call,
try {
Intent myIntent = new Intent(this,Class.forName("com.mypackage.myMainActivity"));
startActivity(myIntent );
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
"com.mypackage.myMainActivity" is the Activity present in Main project, that we need to call from its Library project.
The application calls some method in your library providing the Intent to be invoked, or providing the Class of the activity to be invoked. Your library stores that someplace and uses it.
Your assumption that the right answer is "Intent.ACTION_MAIN or Intent.CATEGORY_LAUNCHER" may be inaccurate. For example, some apps have that be a splash screen activity (which is an issue in its own right, but that's beside the point), and that would not be where a home affordance within the app should go.
You can get the list of activities using the code mentioned in the this post. After that loop through the resolveinfo and check the intenet filter to find the activity with your desired intent action.
Related
I am using a Project A, and a library project to develop my Android app. Both of these projects have activities in them. If I am currently in Project A, then it is easy to just start an activity in the library project by just importing it. However, I'm not sure how to start an Activity in Project A if I am coming from an activity in the library project. I'm trying to make the library project independent of the package name of the Project A since I will be using it for multiple apps. Any ideas on how to do this? Thanks.
There are a few possible solutions.
The best is to register an intent filter in the Manifest entries for the activities that you wish to be accessible to your other projects. There is a great tutorial on intent filters here.
Another option would be to pass a Class to the library project, and use the Intent (Context packageContext, Class cls) constructor to create an intent to fire off and start the activity. It would be a better practice and learning experience to use intent filters, however.
Good luck!
I believe this is to be the simplest answer: you'll need an object which exists in the library, which you can extend in your project.
Imagine that your library has a LibraryApplication which your ProjectApplication extends. The LibraryActivity can call:
((LibraryApplication)getApplication()).startNewActivity(this, "goHome")
Your ProjectApplication implements this new method:
public void startNewActivity(Context context, String action) {
if("goHome".equals(action)) {
startActivity(context, ProjectHomeActivity.class);
}
}
You can add project as external library. Also you can use maven for this kind of things.
From a simple and good answer:
try {
startActivity(new Intent(this, Class.forName("com.package.HomeActivity")));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
And also is possible with this answer, using actions.
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
Let's say I create an intent to view a Google map like so:
Intent intent = new Intent("android.intent.ACTION_VIEW");
intent.setComponent(ComponentName.unflattenFromString("com.google.android.apps.maps/com.google.android.maps.MapsActivity"));
intent.addCategory(android.intent.category.LAUNCHER);
intent.setData("Your Google My Map URL HERE");
startActivity(intent);
Is there any way to customize this MapsActivity component, or just get a handle in it to control/query it at all, or would I have to start from scratch to do this?
Is there any way to customize this MapsActivity component, or just get a handle in it to control/query it at all, or would I have to start from scratch to do this?
No. You have no right to hack into other apps, any more than they have the right to hack into yours. Use MapView.
BTW, your example code there is scary. Never reference third-party apps by component name, as your code will break if that app refactors its code. Never add the LAUNCHER category to an Intent unless you are actually a launcher (e.g., a home screen). And bear in mind that this recipe is neither documented nor supported by Google.
I want to use ActivityGroup to run two activities, but the catch is that those are not necessarily Activities I wrote, for example, I may want to open a contact picker or something that was part of the system. Is this possible? Using the ndk maybe?
EDIT: I want to run both activities on-screen at the same time.
I'm not sure that i understood your question. But if you want to start an activity from another one, you can simply use:
this.startActivity(new Intent(String intent));
Were the parameter of Intent should be the component name of a registered activity, the action or a specific class of your application that you want to start.
i.e. to open a contact detail:
this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, ""+contactId)));
take a look here to have a deep view on intent
I would like to launch an app the user selects from within my application. However, I'm not sure how I'd go about doing this. I've tried this:
Intent intent = new Intent();
intent.setAction(Contacts.Intents.SHOW_OR_CREATE_CONTACT);
startActivity(intent);
But this seems to throw an error and force close my application. I also tried adding:
<action android:name="Contacts.Intents.SHOW_OR_CREATE_CONTACT"/>
in the AndroidManifest file, but to no avail.
A look at Logcat shows that it's an "IOexception - no such file or directory". A couple of questions arise from this. I read through the Android docs and noticed that the Contact.Intents class is deprecated. However, it's successor, ContactContracts is aimed at API level 5 whereas I'm targeting API level 3. Could this be the problem? Also, I've hardcoded this application into the code. Is there a way to retrieve the intents of any application the user selects so that they can be launched?
You need to pass extra information into the intent to tell Android what you want to show or create. Otherwise Android doesn't know what activity to start and (presumably in your case) throws an ActivityNotFoundException.
For a contact, you use the generic Intent.ACTION_INSERT_OR_EDIT then use the MIME type of an individual contact (Contacts.People.CONTENT_ITEM_TYPE).
For example:
Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
intent.setType(People.CONTENT_ITEM_TYPE);
intent.putExtra(Contacts.Intents.Insert.PHONE, "+1234567890");
intent.putExtra(Contacts.Intents.Insert.PHONE_TYPE, Contacts.PhonesColumns.TYPE_MOBILE);
That will bring up the contacts app, prompting you to select an existing contact to add the phone number to, or to create a new contact.
You don't need to add anything special to your manifest to start external activities. Only if you were to directly manipulate the contacts ContentProvider would you need to add the appropriate CONTACT permissions to your manifest.
I use this code for that purpose:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName("com.android.settings", "com.android.settings.Settings");
startActivity(intent);
This will launch the Settings app, you can use these also:
intent.setClassName("com.android.music", "com.android.music.MediaPlaybackActivityStarter");
intent.setClassName("com.android.contacts", "com.android.contacts.DialtactsContactsEntryActivity");
intent.setClassName("com.android.contacts", "com.android.contacts.DialtactsActivity");
The first starts the default music app, the second the contacts, and the third the dialer.
Hope this helps.
You need to pass in valid arguments to the apps you start. A lot of apps expect the data URI and / or certain extras to be valid.
Please try the following code:
Intent intent = new Intent(Contacts.Intents.SHOW_OR_CREATE_CONTACT);
this.startActivity(intent);
(sorry if there is something wrong on the syntax, I dont have android in this computer)
And remove the action from the manifest. that is not needed.
The action method is used for something else.
For more info, please look at the android site: http://developer.android.com/reference/android/content/Intent.html
Daniel
The activity you are calling should appear not only in the Manifest for its own package, but in the Manifest for the CALLING package, too.