How to start an activity in an android Application from the Library - android

I have an Android application in Android Studio. And I've added a library into the application. The button, view, and activities are defined in the library. When I click on the button, I need to navigate to the activity defined in the application.
Usually, to navigate to another page, we used the intent, like this:
Intent intent = new Intent(MainActivity.this, Activity.class);
startActivity(intent);
But this is not a sufficient method to call the activity of the application from the library.
The problem is that the library and the application are independent; they have different packages. So the activity in the application cannot be recognized by the library.
How do I handle communication between the library and the application?

The normal way for doing this is to do this:
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.my.package","com.my.package.activity.ActivityName");
startActivity(intent);
This is an explicit reference to an activity within your library. You should ensure that when starting this Activity that you catch the ActivityNotFoundException as this can happen when the Activity does not exist in the system.
Ideally when building this Intent you should insure that you can resolve it by using PackageManager APIs.
However you should try to avoid hardcoding packages, but when it comes to a library, sometimes you don't have a choice.
Also one thing to note is that within the library you need to ensure that the Activity is exported so that you can access it outside of your application.
android:exported
Whether or not 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. The
default value depends on whether the activity contains intent filters.
The absence of any filters means that the activity can be invoked only
by specifying its exact class name. This implies that the activity is
intended only for application-internal use (since others would not
know the class name). So in this case, the default value is "false".
On the other hand, the presence of at least one filter implies that
the activity is intended for external use, so the default value is
"true".
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).
Ref
http://developer.android.com/guide/topics/manifest/activity-element.html

Include the activity in AndroidManifest.xml.
To access an activity from any other project the easiest way is to
pass the whole class name (including package, e.g;
"com.myproject.MainActivitiy")
Calling from your library :
Intent intent= new Intent("com.myproject.MainActivitiy");
startActivity(intent);
And in your project manifest declare it like this
<activity
android:name="com.myproject.MainActivitiy"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.myproject.MainActivitiy" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

In this case, Intent can be used by providing the full class name including the package.
Let us suppose your current Activity class is MainActivity.java with package name com.app.myproject.
And you want to navigate to another Activity with class named Activity.java that is in another package com.app.external.
Include com.app.external.Activity.java in the manifest of your current project/library.
<activity
android:name="com.app.external.Activity"
android:label="#string/title_activity_login"
android:screenOrientation="portrait">
</activity>
And your Intent should be like this -
Intent intent = new Intent(MainActivity.this, com.app.external.Activity.class);
startActivity(intent);

In this case use Implicit Intent
Inside library Activity TESTActivity :
Intent intent = new Intent();
intent.setAction("com.myapp.myimplicit_action");
startActivity(intent);
and here is my manifest file declaration for some activity say 'ImplicitActivity' with the same action
<activity android:name=".ImplicitActivity">
<intent-filter>
<action android:name="com.myapp.myimplicit_action" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

Related

Beginning an application while no starting activity set

I would like to launch my application and check the connectivity state in application's onCreate method then decide which activity to start! I know that I could finish() a default MAIN/LAUNCHER activity before to setLayout while starting another if it's relevant but that seems messy to me!
So, I would like to know if it is possible to start an application whose doesn't manifest an activity with action.MAIN / category.LAUNCHER? I tried this way but it doesn't work! I mean the application seems to start but no activity is shown!
(This is not a sample from my real code, I'm not at home right now! Some arguments and stuff may be missing but I think you get the point!)
public class MyApp extends Application {
onCreate() {
Intent intent = new Intent(this, MyActivity.class);
intent.setFlags(Intent.NEW_TASK);
this.startActivity(intent);
}
}
Also, the first activity of my application may be an AlertDialog and I'm wondering if I can start one while no activity is started or if I'm forced to set an activity's theme with #android:style/Theme.Dialog?
I tried the same as for the above example but same result : logcat saying application alive while no printing at all...
Tell me if I'm not clear enough and in which way! I'm not an english speaker and I'm not used to ask in forums!
You will have to go this way:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.some_empty_or_loading_view); //optional probably, not sure
//TODO: check whatever you want
if(condition) {
startActivity(this, SomeActivity.class);
} else {
startActivity(this, AnotherActivity.class);
}
finish();
}
}
Specify Your App's Launcher Activity
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 that includes the MAIN action and LAUNCHER category. For example:
<activity android:name=".MainActivity" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Note: When you create a new Android project with the Android SDK tools, the default project files include an Activity class that's declared in the manifest with this filter.
If either the MAIN action or LAUNCHER category are not declared for one of your activities, then your app icon will not appear in the Home screen's list of app

No Activity found to handle Intent (activity was declared in application manifest)

I believe I have read all of the similar questions (of which there are many).
Most of them simply said to make sure the activity is (properly) declared in the application's AndroidManifest.xml (done) and that your requested intent and declared intent filters both contain the default category, Intent.CATEGORY_DEFAULT (done).
I am in the process of moving some activities that were in an application project into a library project (that the application references). They were referenced explicitly (by class name), and I'm now trying to refer to them implicitly (via action name, data mime type, and category). Unfortunately, my attempt to start the activity is generating the exception with the detail message in the subject line.
Here is the activity declaration in the application's androidmanifest.xml (within the application node):
<activity android:name="com.everyscape.android.panoramaui.ESPhotoViewActivity" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="com.everyscape.android.panoramaui.action.VIEW_WORLDTAG"/>
<data android:mimeType="#string/IMAGE_MIME_TYPE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
Here's the code that attempts to launch that activity:
Context context = this.getContext();
Intent intent = new Intent(ESViewWorldTagActivity.ACTION_VIEW_WORLDTAG);
intent.addCategory(Intent.CATEGORY_DEFAULT);
Uri uri = Uri.parse(dataURL);
intent.setDataAndType(uri, dataMimeType);
intent.putExtra(ESPhotoViewActivity.EXTRA_WORLDTAG_TITLE, title);
intent.putExtra(ESPhotoViewActivity.EXTRA_WORLDTAG_ID, worldTagId);
intent.putExtra(ESPhotoViewActivity.EXTRA_PANORAMA_ID,panoID);
intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
context.startActivity(intent);
In the past - I started the activity by using an explicit intent.
This is the first time I am using an implicit intent.
I don't want to use an explicit intent - because I want the application to be able to override the activity that is used (and the code to launch the activity is in a library - it is not supposed to be application specific).
Here is the exception that I am getting:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.everyscape.android.panoramaui.action.VIEW_WORLDTAG cat=[android.intent.category.DEFAULT] dat=http://ugc.everyscape.com//WT2/BF/EWW-Q-0A1E.JPG typ=image/* flg=0x8 (has extras) }
How can I diagnose and resolve this exception?
Thanks,
Chuck

Start Activity Using Custom Action

I am looking to start an activity in my app using a custom action. I have found a few answers but everything I try it throws java.lang.RuntimeException saying No Activity found to handle Intent { act=com.example.foo.bar.YOUR_ACTION }.
This is the activity in my manifest file:
<activity
android:name=".FeedbackActivity" >
<intent-filter>
<action android:name="com.example.foo.bar.YOUR_ACTION" />
</intent-filter>
</activity>
And this is how I'm starting the activity:
Intent intent = new Intent("com.example.foo.bar.YOUR_ACTION");
startActivity(intent);
Any help would be greatly appreciated.
I think what you need is to add a default category to your intent-filter,
eg.
<activity
android:name=".FeedbackActivity" >
<intent-filter>
<action android:name="com.example.foo.bar.YOUR_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
see this answer for more info.
I think you are creating your intent wrong. Try like this:
String CUSTOM_ACTION = "com.example.foo.bar.YOUR_ACTION";
//Intent i = new Intent(this, FeedBackActivity.class); // <--- You might need to do it this way.
Intent i = new Intent();
i.setAction(CUSTOM_ACTION);
startActivity(i);
Just add and intent-filter category as Default.
Implicit intent works perfectly and in many cases its better to use a implicit intent with Intent-action to call a service/Activity than using class-name.
Before startActivty() / startService() with proper context you cane use this method 'queryIntentActivities(Intent intent, int flags)' from package manager class.
It helps the ActivityManager (responsible for launching activities) to check whether the Android system is getting any match with you Intent.
If it doesn't it returns a list size 0 or else >0.
By this you can also check if your app is getting the call,and in this case even if your app is not installed / has got some problem, it will not crash but will throw a warning in Log. Users will face no big trouble apart from app not being launched.
(users will never forgive you if tour app crashes).
Hope this will help !!!
Happy Coding. :)
I faced the same problem when trying to launch the activity residing in the dynamic feature module and starting through action String as the Activity is not resolvable by name at compile time.
So I set the action but the activity crashes every time (No Activity found to handle intent bla bla.. ) until I set the correct package name.
Context c = getApplicationContext();// flag would be require Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag
Intent i = new Intent(action_string);
i.setPackage(context.getPackageName());//this did the trick actually
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
In the Manifest : add catrgory default to the intent filters
from google docs:
<category android:name="android.intent.category.DEFAULT"/>
Note: In order to receive implicit intents, you must include the CATEGORY_DEFAULT category in the intent filter. The methods startActivity() and startActivityForResult() treat all intents as if they declared the CATEGORY_DEFAULT category. If you do not declare it in your intent filter, no implicit intents will resolve to your activity.

Launch Activity from another Application Android [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Android Launch an application from another application
I am having a problem and it is the following one:
I have two applications, and I want to launch one of the activities from one app by the other one......I am gonna give an example:
first app package:
"es.wul4.android.app1"
second app package:
"es.wul4.android.app2"
What I want is to launch the activity whose class is called "Identificar" from the app1
This activity is NOT the main one. I tried by doind that:
Intent intent = getPackageManager().getLaunchIntentForPackage("es.wul4.app2.Identificar");
startActivity(intent);
But what i get doing that is nothing, it tells me that the app doesn´t exists.
If i try doing that:
getPackageManager().getLaunchIntentForPackage("es.wul4.app2");
startActivity(intent);
And it launch one activity, but the main one........
How can I launch this particular Activity inside the package "es.wul4.app2.Identificar"??
Thank u very much.
What you need to use are intent-filters. Assume the activity to be launched is in the package launch.me. Inside this applications manifest all the activities (main or otherwise) will be decalred by the <activity> tag.
Assuming the activity you want to launch is inside the class file Launchme. Then a portion of your manifest will be something like:
<activity android:name="launch.me.Launchme"
android:label="#string/app_name">
<intent-filter>
<action android:name="launch.me.action.LAUNCH_IT"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
Now in the activity from where you want to launch the above activity use:(Note: This activity can be in any package anywhere. You have to make sure that both, the calling and the called packages are available on the device)
Intent i=new Intent();
i.setAction("launch.me.action.LAUNCH_IT");
startActivityForResult(i,0);
You can use other methods for starting the intent other than startActivityForResult, thats upto you.
Did you add activity inside app1s manifest?:
<activity
android:label="#string/app_name"
android:name=".Identificar" >
</activity>
I think, since both activities are in the same package that you only have to do:
startActivity(new Intent(getApplicationContext(), Identificar.class));

Changing launcher Activity name in a new application version

I have developed a new release of an application and I have changed the name of the activity which is launched.
Before the upgrade, in the manifest was:
<activity
android:name=".Splash"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
and then I only changed the name and the package of the activity and now it is:
<activity
android:name=".view.SplashActivity"
... >
...
</activity>
what happens is that after people download the application from the market, the launcher is not refreshing and it still calls to the old path to the activity.
Do you know how to solve this?
Refer Things That Cannot Change
It says,
A subtle but important aspect of what constitutes a break in compatibility is the android:name attribute of your activity, service, and receiver components. This can be surprising because we think of android:name as pointing to the private code implementing our application, but it is also (in combination with the manifest package name) the official unique public name for that component, as represented by the ComponentName class.
Changing the component name inside of an application can have negative consequences for your users. Some examples are:
If the name of a main activity of your application is changed, any shortcuts the user made to it will no longer work. A shortcut is an Intent that directly specifies the ComponentName it should run.
If the name of a service implementing a Live Wallpaper changes, then a user who has enabled your Live Wallpaper will have their wallpaper revert to the system default when getting the new version of your app. The same is true for Input Methods, Accessibility Services, Honeycomb’s new advanced Widgets, and so on.
If the name of a receiver implementing a Device Admin changes, then as with the live wallpaper example, the device admin will be disabled when the application is updated. This also applies to other kinds of receivers, such as App Widgets.
So if possible, don't change the name of components declared in the manifest, or remove any icon pointing to that component using below code.
ComponentName componentToDisable = new ComponentName("application.package.name", "packagename.ActivityClassName");
getPackageManager().setComponentEnabledSetting(componentToDisable, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
Also specify new launcher activity in manifest using <intent-filter>...</intent-filter> so that your new activity will be launched when user clicks launcher icon.
Does the activity is called correctly if you start the activity in debug mode on your phone.
If so check if you did something of the following:
you changed the whole package name
you signed it not at all or not correctly
Also you might check out http://developer.android.com/guide/publishing/publishing_overview.html
Anyway. If the application runs correctly on your debugging phone there is something wrong with your publishing parameters and you should go through the page above step by step.
If not you might check the path values, like package and name of the activity and the filters.

Categories

Resources