Android: Binding to a remote service - android

I'm building a remote service and a client application targetted at API 24 executing on a Nexus 6P device. I have a remote service that automatically starts at boot. Here are the code fragments:
Remote Service Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="a.b.c">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name=".MyService" >
<intent-filter>
<action android:name="a.b.c.MY_INTENT" />
</intent-filter>
</service>
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Remote Service
package a.b.c;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service
{
#Override
public IBinder onBind(Intent intent) {
return null;
// EDIT: see StackOverflow answers/comments below:
// Returning an IBinder here solves the problem.
// e.g. "return myMessenger.getBinder()" where myMessenger
// is an instance of Android's Messenger class.
}
#Override
public void onCreate() {
super.onCreate();
}
}
Remote Broadcast Receiver
package a.b.c;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent serviceIntent = new Intent(context, MyService.class);
context.startService(serviceIntent);
}
}
}
Remote Activity
(Android Studio insists on there being an Activity)
package a.b.c;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
public class MyActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
}
}
I then have a separate project to implement a client activity in a different package that attempts to bind to the remote service. Here are the code fragments:
Client Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="x.y.z">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".ClientActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Client Activity
package x.y.z;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
public class ClientActivity extends AppCompatActivity
{
private final String TAG = "ClientActivity";
private ServiceConnection mMyServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "ServiceConnection onServiceConnected");
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "ServiceConnection onServiceDisconnected");
}
};
private boolean isServiceRunning(String className) {
ActivityManager manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo serviceInfo : manager.getRunningServices(Integer.MAX_VALUE)) {
if (className.equals(serviceInfo.service.getClassName())) {
return true;
}
}
return false;
}
private void bindMyService() {
Intent intent = new Intent("a.b.c.MY_INTENT");
intent.setPackage("a.b.c");
bindService(intent, mMyServiceConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
if (isServiceRunning("a.b.c.MyService")) {
bindMyService();
}
else {
Log.e(TAG, "Service is not running");
}
}
}
The "isServiceRunning" function returns true so I know that a.b.c.MyService is running. The bindService function seems to succeed (no errors in Logcat) but the onServiceConnected callback is never executed.
How do I bind to a.b.c.Myservice from x.y.z.ClientActivity in Android target SDK 24?
Thanks!

I see at least 2 problems here:
You are using an "implicit" Intent in the call to bindService() (ie: you haven't specified the component explicitly). This should throw an exception if you are targeting API 21 or higher. You should use an "explicit" Intent (ie: specify the package name and class name of the Service).
Your Service returns null from onBind(). This means that clients will not be able to bind to the Service, because you aren't returning an IBinder that the client can then use to call methods on the Service. Try to find a how-to or some example code for how to use bound Services.

Related

Problems with BroadcastReceiver and Service

I have a MainActivity which do nothing and one class called BootCompletedIntentReceiver which extends BroadcastReciever and one more class with name MyServices which extends Service. All I want to do is autorun my app after device turns on which is handled by BootCompletedIntentReceiver and after that it starts a Service which shows a toast 8 times. But when i reboot my device nothing happens. I have tried my best to solve this. Can any one help me to find where i am getting stuck
Here is my BootCompletedIntentReceiver code:
package com.anshuman.myapplication;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class BootCompletedIntentReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent pushIntent = new Intent(context, MyService.class);
context.startService(pushIntent);
}
}
}
And here is MyService class:
package com.anshuman.myapplication;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;
public class MyService extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
int a=2;
while (a<10) {
Toast.makeText(this, "onStartCommand", Toast.LENGTH_LONG).show();
a++;
}
return Service.START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
And my androidManifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.anshuman.myapplication">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<receiver android:name=".BootCompletedIntentReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService"/>
</application>
Code is working fine problem is that only my xiaomi device is not working with this code.

Android BroadcastReceiver, auto run service after reboot of device

Hello i am writing an application, which is when the phone reboot, the service will auto start instead of click on the application.
Here is my code for
BootCompleteReceiver.java
package com.example.newbootservice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class BootCompleteReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, MsgPushService.class);
context.startService(service);
}
}
MsgPushService.java
package com.example.newbootservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MsgPushService extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return Service.START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroy", Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
MainActivity.java (not sure whether i need this)
package com.example.newbootservice;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(getBaseContext(), MsgPushService.class));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.newbootservice"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<service android:name=".MsgPushService"/>
<receiver android:name=".BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I want the service to be started automatically after reboot instead of starting it manually.
You forgot about the permissions
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Though all the above answers were correct, however from Android Oreo they put some limitation on Background Services.
Check Background Execution Limits to know more about background limits in Android O.
You can't start a Service directly from BroadCastReceiver when the application is in the background.
However, you can start a foreground service from the receiver by calling startForegroundService() or use JobIntentService as there is no such limitation with JobIntentService.
Use this code on your Broadcast Receiver class:
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent service = new Intent(context, MsgPushService.class);
context.startService(service);
}
also try these permissions,it may help you .ifyou are using htc phones then these permissions are required
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>

Android. Reboot my BroadCast receiver. Not working.

How to start a service in android using nested class when mobile is switched ON?
I have the package contains nested class.
package Name
com.android
MainActivity
BroadCastReceiver
I am trying to reboot my BroadCast receiver. But it doesn't work (getting Failed). I don't know if the reason is, because of any problems for nested classes.
<receiver android:name="ConnectionReceiver"></receiver>
<receiver android:name="com.android.MainActivity .BroadCastReceiver ">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="onchip.automobile.caraccessory1"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<receiver
android:name=".Onchip_BroadcastReceiver">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
<service
android:name=".Onchip_BackgroundService">
<intent-filter >
<action android:name="onchip.automobile.caraccessory1.BACKGROUND_SERVICE" />
</intent-filter>
</service>
</application>
</manifest>
Onchip_BroadcastReceiver.java
package onchip.automobile.caraccessory1;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class Onchip_BroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent serviceIntent = new Intent("onchip.automobile.caraccessory1.BACKGROUND_SERVICE");
context.startService(serviceIntent);
}
}
Onchip_BackgroundService.java
package onchip.automobile.caraccessory1;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.IBinder;
import android.widget.Toast;
public class Onchip_BackgroundService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Onchip_BackgroundService Created", Toast.LENGTH_LONG).show();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Toast.makeText(this, "Onchip_BackgroundService Started", Toast.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Onchip_BackgroundService Destroyed", Toast.LENGTH_LONG).show();
}
}
R u having BroadcastReceiver as nested class. if yes dont do this.
1)if you have receiver as nested class, register it in activity dynamically, do not register in manifest
2) if you are registering it in manifest , make separate class for Receiver.

android service problem

i have a problem with a simple service. the service should run "automatically", as i already know if boot completet.
i've found a simple example and my code is the same but it doesnt work, there is nothing in the log. here is the example [Start Service at Boot][1]
package com.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MainService extends Service
{
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public void onCreate()
{
Log.v("StartServiceAtBoot", "StartAtBootService Created");
}
#Override
public void onStart(Intent intent, int startId)
{
Log.v("StartServiceAtBoot", "StartAtBootService -- onStart()");
}
#Override
public void onDestroy()
{
Log.v("StartServiceAtBoot", "StartAtBootService Destroyed");
}
}
[1]: http://www.androidcompetencycenter.com/2009/06/start-service-at-boot/
here the braodcast receiver for the Boot-completed Action:
package com.service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MainServiceReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED))
{
Log.i("Test", "Test");
Intent i = new Intent();
i.setAction("com.service.MainService");
context.startService(i);
}
}
}
and here the manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.service"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses- permission>
<application android:icon="#drawable/icon" android:label="#string/app_name">
<service android:name="com.service.MainService">
<intent-filter>
<action android:name="android.action.intent.BOOT_COMPLETED">
</action>
</intent-filter>
</service>
<receiver android:name="com.service.MainServiceReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED">
</action>
<category android:name="android.intent.category.HOME">
</category>
</intent-filter>
</receiver>
</application>
in the android error log there is always this error:
9009 Applications Change Receiver updating1 application packageName = com.service....
please help me i think its a little thing but I dont see the mistake.
Thank you
In your code:
Intent i = new Intent();
i.setAction("com.service.MainService");
context.startService(i);
But at in manifest you have not declared intent-filter to receive this action.
You only need startSerice by call:
startService(new Intent(MainServiceReceiver .this,MainService.class));
If you have any problem, please add my yahoo or skype :fsoft_duonghv

Broadcast receiver not working

I am trying to test Broadcast receiver for outgoing calls. Please help.
Here is my CallCounter class:
package com.callout;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
public class CallCounter extends PhoneStateListener {
public void onCallStateChanged(int state, String incomingNumber) {
switch(state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.d("Tony+++++++++++","Outgoing Call finished");
// Call Finished -> stop counter and store it.
// callStop=new Date().getTime();
Context c = getApplicationContext();
c.stopService(new Intent(c,ListenerContainer.class));
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d("++++++++++++++++Tony","Outgoing Call Starting");
// Call Started -> start counter.
// This is not precise, because it starts when calling,
// we can correct it later reading from call log
// callStart=new Date().getTime();
break;
}
}
private Context getApplicationContext() {
// TODO Auto-generated method stub
return this.getApplicationContext();
}
}
Here is myReceiver
package com.callout;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class myReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
Log.d("T+++++++++++++++++ony","In mYRecieverrr");
context.startService(new Intent(context,ListenerContainer.class));
}
}
}
Here is myService:
package com.callout;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
public class ListenerContainer extends Service {
public class LocalBinder extends Binder {
ListenerContainer getService() {
Log.d("Tony","OKKK HEREEEEEEEEEEEEEeEEEEE");
return ListenerContainer.this;
}
}
#Override
public void onStart(Intent intent, int startId) {
TelephonyManager tManager =(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
CallCounter callCounter=new CallCounter();
tManager.listen(callCounter,PhoneStateListener.LISTEN_CALL_STATE);
Log.d("To++++++++++++++ny","Call COUNTER Registered");
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
}
And this is the manifest file if i m missing some permission:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.callout"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".CallCounter"
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=".myReceiver"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:enabled="true" android:name=".ListenerContainer" />
<receiver android:name=".myReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
</application>
</manifest>
Please point out my mistake.
You must add the following permission to your manifest since your are registering a phonestatelistener.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
It looks like your receiver is missing an attribute in the manifest file :
http://developer.android.com/guide/topics/manifest/receiver-element.html
Look at the exported attribute, it should be set tot true to receive broadcast from other apps.
Regards,
Stéphane
There's a working solution with full source here that meets your requirements
https://www.codeproject.com/articles/548416/detecting-incoming-and-outgoing-phone-calls-on-and

Categories

Resources