How to start a bound service via intent without class - android

I'm trying to start a bound (eventually remote) Android Service via an Intent. If I create the Intent with a reference to the Service class (see variable ii below) it works. If I create the Intent using Strings for the classname, bindService fails.
Ultimately I'm aiming to have a 2nd application access my service which will not have the Service class within it (that's how remote service things work...? isn't it?) - hence the desire to create the Intent without the reference to the class object.
//this Intent works
Intent ii = new Intent(this, MyService.class);
//this Intent doesn't
Intent i = new Intent();
i.setClassName("com.ghee", "MyService");
boolean b = bindService(ii,
mSvcConn,
Context.BIND_AUTO_CREATE);
if(!b) {
Log.d(TAG, "bindService returned false...");
}
If it helps, here's the majority of the manifest:
<application android:icon="#drawable/icon">
<activity android:name=".MyActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="com.ghee.MyService" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService"
android:exported="true"
android:process=":remote">
</service>
</application>

You need to specify the full path of the class, not just its name. This seems counter-intuitive, because you're already specifying the package in parameter 1, but....oh well.
Try this:
i.setClassName("com.ghee", "com.ghee.MyService");

Related

Unable to start intent service via IMPLICIT intent

AndroidManifest.xml
<application android:name=".MyApplication"
android:icon="#drawable/icon"
android:label="#string/app_name"
>
<service android:name=".MyService"
android:exported="true">
<intent-filter>
<action android:name="android.service.myapp.MyService.actionA"/>
<action android:name="android.service.myapp.MyService.actionB"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
</application>
If I use the following code, my service is launched:
Intent intent = new Intent(context, MyService.class);
intent.setAction("android.service.myapp.MyService.actionA");
context.startService(intent);
But my service is not started if I launch it with this code:
Intent intent = new Intent("android.service.myapp.MyService.actionA");
context.startService(intent);
It is insecure to use an "implicit" Intent to start or bind with a Service. Starting with Lollipop, bindService() requires an explicit Intent (your first example where you specify the Context and Class for the Service.) The behavior of startService() is undefined for implicit Intents used to start a service. From the documentation on startService():
The Intent should contain either contain the complete class name of a specific service implementation to start or a specific package name to target. If the Intent is less specified, it log a warning about this and which of the multiple matching services it finds and uses will be undefined.
If you use the explicit form, you can completely remove the <intent-filter> from the manifest: it is not needed. If you need to specify some type of work to be done by the service via the Intent, consider using a extra within the Intent.

How to start an Intent for an Application Context

I found almost the same question:How to start an Intent if context is not Activity Context but Application Context
but I faild to do it when using https://stackoverflow.com/a/9238105/6593395
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("android.intent.action.BOOT_COMPLETED".equals(action)) {
Intent applicationIntent = new Intent(context, myCamApplication.class);
applicationIntent.setAction(myCamApplication.class.getName());
applicationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(applicationIntent);
the error log:
Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.fenchtose.asyncamera/com.eason.mycamera.myCamApplication}; have you declared this activity in your AndroidManifest.xml?
I have registered this myCamApplication class as my application class inside AndroidManifest.xml
<application
android:name=".myCamApplication"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<receiver
android:name=".BootComplete"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity
android:name=".myCam"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
So, Anyone could help?
You can not start an Application class. You can only start an Activity.
Change your code from e.g.:
Intent applicationIntent = new Intent(context, myCamApplication.class);
to
Intent applicationIntent = new Intent(context, myCam.class);
Try to create an other Activity and add it to your Manifest.xml and see if there's any error do not forget to add this code <activity android:name=".yourSecondActivity" /> and start a new Intent
The problem here is that you don't understand basic principles. In android you have only 4 components: Activity, Service, ContentProvider, BroadcastReceiver. So in your manifest you declare that you have Application (name, attributes...) and inside the application you have Activities, Services, Receivers, ContentProviders.
Your application is not your Application class. So to start your application you should start default activity:
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//because we use Application context
startActivity(intent);
P.S. Your Application class will start automatically. Lifecycle of application is following:
Start of Application class -> Start of Component(service, activity..) -> Stop of Component(service...) -> Stop of Application class
P.S.S.
There is no need to check the action in onReceive - it will be there for the only reason:
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>

When i use Activity in camel case it gives error but works fine in upper case spelled

Hy! Expets i have two activities
1- MainActivity
2- Startup
I am starting my MainActivity activity through new intent after starting Startup activity using Thread. but when when i call new intent by passing MainActivity spelled in camel case and within inten-filter tag <action android:name="com.example.test.MainActivity" as shown below
Thread timer =new Thread(){
public void run(){
try{
sleep(5000);
}catch(InterruptedException e){
e.printStackTrace();
}finally{
Intent startUpIntent = new Intent("com.example.test.MainActivity");
startActivity(startUpIntent);
}
}
};
and here is AndroidMaifest.xml File code
<activity
android:name="com.example.test.Startup"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.newboston.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.example.test.MainActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
it gives error.
But when I use code as
Intent startUpIntent = new Intent("com.example.test.MainActivity");
AndroidManifest.xml code
<intent-filter>
<action android:name="com.example.test.MainActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
then it works fine as i want.
I want to know reason to use Upper case spelled instead of camel case.???
Thanx...
You probably want to be defining an intent for a specific component:
Intent startUpIntent = new Intent(Startup.this, MainActivity.class);
Then you don't need to bother with an <intent-filter> for MainActivity in your manifest.
There are a number of action constants defined in the Intent class. Some of them are:
ACTION_MAIN: Start up as the initial activity of a task, with no data input and no returned output.
ACTION_CALL: Initiate a phone call.
ACTION_EDIT: Display data for the user to edit.
To use ACTION MAIN in your manifest, you will replace the ACTION_ part with android.intent.action.. Since they are constants defined in a class you are using, they need to be used as defined.
For example, the following two declarations are not the same. They define and instantiate two different variables:
int myVariable = 1;
int MYVARIABLE = 1;
So, you cannot write:
<action android:name="android.intent.action.MAIN" />
as
<action android:name="android.intent.action.main" />
or anything other that the former.
From the android developers resource page on <action>:
To assign one of [standard actions defined in the Intent class] to
this attribute, prepend "android.intent.action." to the string that
follows ACTION_. For example, for ACTION_MAIN, use
"android.intent.action.MAIN" and for ACTION_WEB_SEARCH, use
"android.intent.action.WEB_SEARCH".
To read up more on this:
Intent
action

How to launch a certain activity of an Android app

I would like to launch, from my app, two specific activities A_Activity and B_Activity from apps Aapp and Bapp
I inserted two buttons and in the two OnClickListener I wrote
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction("com.Acompany.Aapp.A_Activity");
ctx.startActivity(intent);
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction("com.Bcompany.Bapp.B_Activity");
ctx.startActivity(intent);
Moreover I added to AndroidManifest.xml the following lines
<activity
android:name="com.Acompany.Aapp.A_Activity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.Acompany.Aapp.A_Activity" />
</intent-filter>
</activity>
<activity
android:name="com.Bcompany.Bapp.B_Activity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.Bcompany.Bapp.B_Activity" />
</intent-filter>
</activity>
But my app crashes and in the logcat I read "No Activity found to handle Intent"
Where is my mistake?
EDIT: More precisely the two activities are not in my own app
More precisely the two activities are not in my own app
You should investigate target app's manifest file first, to check if these activities are available to others by being exported or offering publicly accessible intent filters. It looks you may simply be not allowed to do what you attempt to.
Try like this. For your home activity(first launch activity) do like this in your manifest file.xml
<activity
android:name="com.Acompany.LaunchHomeActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.Acompany.LaunchHomeActivity" />
</intent-filter>
</activity>
<activity android:name="com.Acompany.Aapp.A_Activity">
</activity>
<activity android:name="com.Bcompany.Bapp.B_Activity">
</activity>
don't include <intent-filter> to all activities
Intent intent = new Intent(myFirstClass.this, MySecondClassA.class);
startActivity(intent);
Class B
Intent intent = new Intent(myFirstClass.this, MySecondClassB.class);
startActivity(intent);

ActivityNotFoundException?

I am getting an ActivityNotFoundException in the following code:
Main.java
Intent intent = new Intent();
intent.setAction("com.test.app.TEST");
startActivity(intent); // ActivityNotFoundException
Manifest.xml
<activity android:name=".MainActivity" android:theme="#android:style/Theme.Dialog">
<intent-filter>
<action android:name="com.test.app.TEST" />
</intent-filter>
</activity>
I've had this issue too, as perfectly concisely described by jpahn.
the period at the front did not give any help to me.
even with exactly this (a copy of the original question including edits), I would still get ActivityNotFoundException.
Main.java
Intent intent = new Intent();
intent.setAction("com.test.app.TEST");
startActivity(intent); // ActivityNotFoundException
Manifest.xml
<activity android:name=".MainActivity" android:theme="#android:style/Theme.Dialog">
<intent-filter>
<action android:name="com.test.app.TEST" />
</intent-filter>
</activity>
This was resolved, after much trial-and-error, by simply adding this to the intent-filter in the manifest:
<category android:name="android.intent.category.DEFAULT" />
So the final manifest file contained:
<activity android:name=".MainActivity" android:theme="#android:style/Theme.Dialog">
<intent-filter>
<action android:name="com.test.app.TEST" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
I got this error after moving an activity class from one package to another.
Clean build solved it (Project -> Clean).
Be sure to declare your activity in the manifest.xml within the aplication:
<application>
<activity android:name=".YourNewActivity"/>
</application>
To start the new Activity:
Intent intent = new Intent(main.this, YourNewActivity.class);
startActivity(intent);
Where main stands for the current activity,
Add a . (dot) before your activity name in Android Manifest. So it should be android:name=".WordsToSpeakMainActivity"
I have some addition to the #Tom Pace answer. The answer is completely right, but to make it more clear:
ActivityNotFoundException occurs because of absence of
<category android:name="android.intent.category.DEFAULT" />
Because when Android OS see this in the manifest file, understands that this activity can receive intent.
The point ActivityNotFoundException thrown is that, when activity(intent-creator-activity) tries to create intent for other activity(intent-receiver-activity), Android OS sees there is intent for receiver activity but receiver activity does not receive anyone. Then Android OS returns null or empty intent to intent-creator-activity. And startActivity throws that exception.
I have found a code from android developers to avoid this exception:
// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(chooser);
}
Android Developers: Intent Filters
To be safe you can also call your new activity like this:
Intent intent = new Intent();
intent.setClass(this, THECLASSNAME);
startActivity(intent); //
However, you must add the activity to the androidmanifest - and write a . in front of it, e.g.
<activity android:name=".YOURACTIVITYNAME"></activity>
There two types of intents in android framework,
1-Implicit intents that you are using,
<activity android:name=".MainActivity" android:theme="#android:style/Theme.Dialog">
<intent-filter>
<action android:name="com.test.app.TEST" />
</intent-filter>
</activity>
just add one line in intent filter
<intent-filter>
<action android:name="com.test.app.TEST" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
2- Explicit Intents
Intent i=new Intent(CurrentActivity.this,WhereWeWantToGoActivity.class);
startActivity(i);
To launch an activity by a string definition, use:
Intent intent = new Intent();
intent.setComponent(
new ComponentName("com.app", "com.app.activity.TheActivity"));
startActivity(intent);
At the very top of your AndroidManifest.xml, you'll see the package attribute
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.example"
and then, in the activity tag, you'll see the name attribute:
<activity
android:name=".Something"
Make sure that the package name and activity name, when joined together, make the full package specification of your Activity i.e.
com.android.example + .Something = com.android.example.Something
Otherwise, you'll get a ActivityNotFoundException.
I found a solution to this problem... I´m using 2 modules in a android studio project, the thing here is that I needed to add the activity to the main manifest file
<activity android:name="com.HeadApp.ARTry.UnityPlayerActivity"
android:clearTaskOnLaunch="false" android:label="#string/app_name"
android:screenOrientation="portrait"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
/>
I had that in the unity activity manifest, I just copied the activity and paste it in the main manifest and that was it, hope it helps, eve been struggling a lot with this for the past 3 weeks

Categories

Resources