Can't open Activity from other module - android

I've added a reference to a new module and try to open an Activity from it.
It throws an Exception that says:
android.content.ActivityNotFoundException: Unable to find explicit
activity class{
com.giljulio.imagepicker.ui/com.giljulio.imagepicker.ui.ImagePickerActivity
};
have you declared this activity in your AndroidManifest.xml?
Do I need to add anything else beside reference the new module?

You have to define in gradle dependencies(in module where you want to call another module activity):
dependencies{
...
compile project(':yourModuleName')
...
}
After adding this sync the gradle and now can you use the activity in the module.

User like this. This will help you
Intent intent = null;
try {
intent = new Intent(this,
Class.forName("ir.test.testlibary1.HelloWorldActivity"));
startActivity(intent);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

Ok, so I am a few years late.
The issue is not that you don't have the gradle dependency as #arpit suggested, it seems you report a runtime exception. Also, what #Aman suggested will help with the handling the exception, it will just not help you start the activity.
If understood correctly, you have a multi-module app (let's say A-app module and B-lib module) and need to call another lib-module(C) from one B.
If that is the case, you need to declare that library's activity(C) in your module's(B) Manifest.xml, inside the tag.
If it has not already been setup, you also need to enable manifest merger.

Related

IllegalArgumentException from Activity#startActivity(Intent)

The Android#startActivity(Intent) is specified to throw android.content.ActivityNotFoundException if there was no Activity found to run the given Intent.
I therefore have code like
try {
// Try to start activity provided by external app:
startActivity(intent);
} catch (ActivityNotFoundException e) {
// [...] Inform user about external app needed
// for this functionality to work.
}
which catches ActivityNotFoundException to handle the case where the external app is not installed.
However, from the Crashes & ANRs section of the Google Play Developer Console I'm starting to get crashes as IllegalArgumentException: Unknown component com.example.package/com.example.package.Activity. Should code invoking startActivity() be ready to handle that exception as well? Is this a framework bug (or documentation error)?
This exception generally arises when you haven't declared it in your manifest file. So, try doing it
Somewhere inside your application tag do this
<activity
android:name="Your_Activity_Name"
android:theme="Whatever your theme is"
</activity>
If its any other issue please let me know.
You can use this code to check it. This is the better approach then handling exception
List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
if (list.size() > 0)
{
// start your activity
}

Calling an Application Activity from a Library Project in Android

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.

How to start main activity from a library?

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.

Way to find if an Activity Exists in android

I want to test if the Activity by name "test" exists or not in the appliaction. May be using Manifest file before calling startActivity or in its catch block for the following:
Starting an Activity with Intent and SetClassName
So say:
if(test.exists){
Activity is registered and start it
}
else{
create Activity and add it in manifset programmatically, as this would be a dynamic Activity
}
We cant add activities in manifeast file programmatically even if you get it from JSON response.
And if you are launching the native Activity we usually dont add them at all to manifeast file but for certain things we need to add permission to use them in our app.
use forName instead..
something like this..
try {
Class<?> act = Class.forName("TestActivity");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
// do what you wish if not exist
}
Manifest and so do other xmls present in apk cannot be modified.So yoou may have to re-use your components and you you can use fragments for that(if i understand your requirements correctly). or simply reuse a activity,
Checking the presence of Activity can be done easily .

Using an Android library project Activity within another project

I have an Android library project that I would like to use from within another Android project.
The library has a Activity declared in its AndroidManifest. When I try the following within the second project:
Intent intent = new Intent(this, ReaderActivity.class);
startActivity(intent);
I get the following exception:
java.lang.RuntimeException: Unable to start activity ComponentInfo{br.com.digitalpages.reader.demo/br.com.digitalpages.reader.demo.ReaderDemoActivity}: android.content.ActivityNotFoundException: Unable to find explicit activity class {br.com.digitalpages.reader.demo/br.com.digitalpages.reader.ReaderActivity}; have you declared this activity in your AndroidManifest.xml?
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
...
Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {br.com.digitalpages.reader.demo/br.com.digitalpages.reader.ReaderActivity}; have you declared this activity in your AndroidManifest.xml?
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1404)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1378)
...
How can I open the Activity from the another project?
EDIT:
By users answers I added the following line into my second project
<uses-library android:name="br.com.digitalpages.reader" android:required="true" />
But it's still doesn't works
I believe you must include the <activity> in your own AndroidManifest.xml -- I don't think it gets picked up from a library. I don't have my reference for that handy.
Update: It's official solution. From the doc:
Declaring library components in the manifest file
In the manifest file of the application project, you must add
declarations of all components that the application will use that are
imported from a library project. For example, you must declare any
<activity>, <service>, <receiver>, <provider>, and so on, as well as
<permission>, <uses-library>, and similar elements.
Declarations should reference the library components by their
fully-qualified package names, where appropriate.
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
intent.setComponent(new ComponentName("packagename//ex-com.hello",
"classname//ex-com.hello.ExampleActivity"));
startActivity(intent);
And make sure in library you have declared the activities. You don't need to declare the library activities in your current project's manifest.
did you add to the manifest?
http://developer.android.com/guide/topics/manifest/uses-library-element.html
This works:
In your library, put your custom Activity:
public class MyLibraryActivity extends ListActivity { ... }
No need to put it into a manifest.
In your calling Android project, create an empty (dummy) wrapper:
public class MyActivity extends MyLibraryActivity { }
and add reference to this class to your manifest:
<activity android:name="my_package.MyActivity" ... />
I am aware that the question is quite old but I think this might help people like me that came up with the same problem.
Using Eclipse, the best way to share code and activities among libraries is probably the one that can be found in the android documentation here:
Managing Projects from Eclipse with ADT
When using an activity inside the library, the activity should be declared only inside the manifest of library.
The activity can be started from the main app like this:
Intent intent = new Intent();
intent.setClassName(this, "com.duna.remotelocklibrary.activities.MainRemoteActivity");
startActivity(intent);
I tried to start the library's activity like the following code, but i warn you: it doesn't work
Intent intent = new Intent();
intent.setClassName("com.duna.remotelocklibrary", "com.duna.remotelocklibrary.activities.MainRemoteActivity");
startActivity(intent);
you should import just the code of the activity ( not the manifest too ) , and then , declare your Activity ( of the library ) , in the manifest of your second project
You don't need to explicitly add activity in your main project's manifest if you have already added the activity in your library's manifest by using the following code when starting library's activity.
For Kotlin
val myIntent = Intent(activityContext, ActivityToLaunch::class.java)
// Needed to set component to remove explicit activity entry in application's manifest
myIntent.component = ComponentName(activityContext, PickerActivity::class.java)
activityContext.startActivity(myIntent, PICKER_REQUEST_CODE)
For Java
Intent myIntent = new Intent(activityContext, PickerActivity.class);
// Needed to set component to remove explicit activity entry in application's manifest
final ComponentName component = new ComponentName(activityContext, PickerActivity.class);
myIntent.setComponent(component);
activityContext.startActivity(myIntent, REQUEST_CODE);

Categories

Resources