Starting an activity in a different application using explicit intents - android

I have written two different applications, we'll call them AppA and AppB. I am trying to start an activity in AppA from AppB using an intent. I am trying to accomplish this with an explicit intent.
In AppB, I create the intent like this:
ComponentName cn = new ComponentName("com.example.user.appa",
"appaActivity");
Intent infoIntent = new Intent();
infoIntent.setComponent(cn);
infoIntent.setAction("com.example.DO_SOMETHING");
infoIntent.putStringArrayListExtra("arrList", incInfo);
startActivity(infoIntent);
In the AndroidManifest.xml for AppA, I have included the following:
<activity
android:name=".appaActivity"
android:label="#string/title_activity">
<intent-filter>
<action android:name="com.example.DO_SOMETHING"/>
</intent-filter>
</activity>
When I try to run AppB (which is sending the Intent to AppA, I get the following error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.user.appb/com.example.user.appb.MainActivity}: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.user.appa/appaActivity}; have you declared this activity in your AndroidManifest.xml?
Since I can clearly see that I've defined appaActivity in AppA AndroidManifest.xml, can anyone tell me what I might be overlooking?

In AppB's ComponentName object, I wasn't providing the full path to the class name as I didn't realize it was necessary. Once I added that, it worked like a charm.
Corrected Component Name:
ComponentName cn = new ComponentName("com.example.user.appa",
"com.example.user.appa.appaActivity");

Related

Unable to find explicit activity class, even when i declare the intent in the manifest

I have an activity which I declare in my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.my">
<uses-sdk android:minSdkVersion="14"/>
<application>
<activity
android:name="com.my.InternalDummyActivity"
android:exported="false">
</activity>
</application>
</manifest>
I have tried without the exported=false as well
The application contains an inner library with another activity.
I try to call an explicit intent from the other activity (other namespace)
But I always get an exception:
Intent intent1 = new Intent(activity.getApplicationContext(), InternalDummyActivity.class);
activity.startActivity(intent1);
ComponentName componentName2 =
new ComponentName(
"com.my","com.my.InternalDummyActivity");
Intent intent2 = new Intent().setComponent(componentName2); //dones work
activity.startActivity(intent2);
Process: com.comp.outter, PID: 9267
android.content.ActivityNotFoundException: Unable to find explicit activity class {com.my/com.my.InternalDummyActivity}; have you declared this activity in your AndroidManifest.xml?
How can I fix this?
Try using one of the ComponentName's contructors that uses a Context, such as
ComponentName cn = new ComponentName(context,
"com.my.InternalDummyActivity");
For some reason, you can use the contructor taking two Strings only if you know the class dynamically.
Also, update your manifest as follow:
<activity
android:name=".InternalDummyActivity">
</activity>
and application package name should be in lower case only, as mentioned in Java's Naming Conventions in Oracle Docs
Package names are written in all lower case to avoid conflict with the
names of classes or interfaces
This question is possible duplicate of the thread gives below
How to call activity from a library module in android studio
Check if this is what you are looking for.

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

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>

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

Launch Main Activity with Implicit Intent in Service

I have an implicit intent in a service that sends information to my main activity, as well as to another class. I also now want that intent to launch my main activity. I've looked at the myriad posts related to this, and tried lots of different things--addCategory, setAction(MAIN; the activity's name; you name it, I've tried it...), category.DEFAULT in the manifest, and several other things that either resulted in ActivityNotFoundExceptions (most commonly) or behavior that was otherwise undesirable.
Here's where the intent is set up and the relevant part of the manifest. The receiver for the intent is registered in the main activity.
final String NEW_DOSES = "changed to protect the innocent";
Intent bluetoothBroadcast = new Intent();
several putExtra lines here
bluetoothBroadcast.setAction(NEW_DOSES);
sendBroadcast(bluetoothBroadcast);
<activity
android:name=".AsthmaAppActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Is it possible to get this intent to launch my main activity with relatively minor changes? Thanks in advance.
Yes it is possible but no with sendBroadcast(bluetoothBroadcast); sendBroadcast does not launch an activity. You must use startActivity to achieve this. For example here is what a launcher application will do in order to launch an application:
public static void LaunchApplication(Context cx, String packagename) {
PackageManager pm = cx.getPackageManager();
Intent i = pm.getLaunchIntentForPackage(ai.packageName);
if (i != null) cx.startActivity(i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
You can easily adjust the extras and the data needed in order to launch the activity. For example if your activity is named myActivity then you can go like this:
Intent i = new Intent(cx, myActivity.class);
//Put the extras and the data you want here...
//If you are launching the activity from a receiver component you must use
//i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
cx.startActivity(i);
Hope this helps...

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.

Categories

Resources