Can't bind to Service - android

I have an aidl file defined as follows:
package com.erbedo.callalert;
interface RemoteCallAlert {
void notifyCallEnded();
}
The service is:
package com.erbedo.callalert;
public class CallAlert extends Service {
Filter callListener;
private final RemoteCallAlert.Stub mBinder = new RemoteCallAlert.Stub() {
#Override
public void notifyCallEnded() throws RemoteException {
// TODO
}
};
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "CallAlert Created", Toast.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "CallAlert Destroyed", Toast.LENGTH_LONG).show();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Toast.makeText(this, "CallAlert Started", Toast.LENGTH_LONG).show();
callListener = new Filter();
TelephonyManager tm =
(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(this.callListener, PhoneStateListener.LISTEN_CALL_STATE);
}
public void callEnded() {
// TODO
}
}
and the Activity that has to bind to the service is:
package com.erbedo.callalert;
public class DummyStart extends Activity {
Filter callListener;
RemoteCallAlert mService;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
Log.d("CONNECT","OK");
}
public void onServiceDisconnected(ComponentName className) {
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout l = new LinearLayout(this);
setContentView(l);
this.startService(new Intent(this, CallAlert.class));
}
}
The onServiceConnected isn't called. Am I missing something obvious?

startService() does not use a ServiceConnection. bindService() does.

Intent intent = new Intent(CallAlert.class.getName());
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

The onServiceConnected isn't called.
For binding with the service you need to call bindService(). It provide the persistence connection, and after connection establishment onServiceConnected() is called.
Second point:-
If you are using AIDL IPC mechanism then I think you need the communication between 2 diff processes/Application. Here you need to have same copy of .aidl file in both service and Activity side in same PACKAGE. Then you need to modify little bit in your Activity side..
you can find here
http://www.zestofandroid.blogspot.com/

Related

Service: starting a bound service

I'm kind of confused with bound services. I read Can anybody explain what is difference between unbound and bound service in android this post and based on that I'm trying out a sample. I created a Service and binding it to My activity as shown below
public class MyService extends Service {
private static final String TAG = "MyService";
MyBinder mMyBinder = new MyBinder();
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand: ");
// start long running operation
return super.onStartCommand(intent, flags, startId);
}
#Override
public boolean onUnbind(Intent intent) {
Log.d(TAG, "onUnbind: ");
return super.onUnbind(intent);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: ");
return mMyBinder;
}
public class MyBinder extends Binder {
public MyService getService(){
return MyService.this;
}
}
}
Activity is
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
MyService.MyBinder mMyBinder;
private Connect mConn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, MyService.class);
mConn = new Connect();
bindService(intent, mConn, BIND_AUTO_CREATE);
}
public class Connect implements ServiceConnection {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected: ");
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected: ");
}
}
}
The service 'onStartCommand' is not called when I call bindService(intent, mConn, BIND_AUTO_CREATE);
should I call startService after binding? binding will not start the service?
If I already have a service which is started using startService and running , and I'm bindind the same service in some other activity, what happens if activity goes out of scope?

Service killed before starting loop

I am new in android development. My service killed before starting loop..
I started service from another activity like MainActivity
package com.example.ch_m_usman.sharedtasklist.Services;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
public class ReminderService extends IntentService {
public ReminderService() {
super("Reminder Service");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.e("check","")
//Loop does not start.
for (int i=0;i<5;i++){
Log.e("Inside for","");
}
}
}
//How to use loop in intent service
Use below code:
public class TaskConfirm extends IntentService {
private final IBinder mBinder = new LocalBinder();
public TaskConfirm() {
super("TaskConfirm");
setIntentRedelivery(true);
}
#Override
public void onCreate() {
super.onCreate();
//Initilise your objects here like below...
taskIdList=new ArrayList<String>();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
return super.onStartCommand(intent, flags, startId);
}
#Override
protected void onHandleIntent(Intent intent) {
// get intent data here like below if required......
if (intent != null) {
String taskId=intent.getStringExtra("taskId");
}
// apply your loop here .......
for (int i=0;i<5;i++){
Log.e("Inside for","");}
}
public class LocalBinder extends Binder {
public TaskConfirm getService() {
return TaskConfirm.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
Start service like below from your activity :
Intent serviceIntent = new Intent(context, TaskConfirm.class);
// put some extra data if required
serviceIntent.putExtra("taskId","1");
startService(serviceIntent);
If you want to access this service in other activity then bind that activity to service:
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, TaskConfirm.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
TaskConfirm.LocalBinder binder = (TaskConfirm.LocalBinder) service;
mService = binder.getService();
mBound = true;
// do your task on service-connected...
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};

Accessing a variable of a Service

I have an Android Activity called Main that calls a Service called MainService as follows:
Intent intent = new Intent(this, MainService.class);
if(MainService.getInstance() == null){
Log.d(TAG, "Calling MainService");
startService(intent);
}
MainService maintains a variable during its lifetime that I wish to access in Main later on. How do I do this?
Thanks.
You can bind the service and can have the service instance forever. Below sample code will help you:-
Service Class
public class MusicService extends Service {
MyBinder binder=new MyBinder();
MusicService services;
static Context context;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return binder;
}
#Override
public void onCreate() {
super.onCreate();
context=getApplicationContext();
MediaPlayer mPlayer = MediaPlayer.create(getApplicationContext(), R.raw.yaar);
mPlayer.start();
}
public class MyBinder extends Binder
{
public MusicService getServiceSystem()
{
return MusicService.this;
}
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
Activity
public class MainActivity extends AppCompatActivity {
MusicService services;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ServiceConnection connection=new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.MyBinder binderr=(MusicService.MyBinder)service;
services=binderr.getServiceSystem();
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
};
Intent intent= new Intent(this, MusicService.class);
startService(intent);
}
}
You can then use service anywhere you need in activity. Hope it helps.
Yes, you can access variables inside service, but for that you have to bind to this service first. After that, use accessors for getting or setting variables or call any other method of the service.
See https://developer.android.com/guide/components/bound-services.html

Is it possible to use AIDL without binding service to the activity

I've implemented and aidl file as follows:
interface ITaskService{
void addGetNamesJob();
void addUploadJob();
}
I then in my service have done the following:
#Override
public IBinder onBind(Intent intent) {
return new ITaskService.Stub() {
#Override
public void addBeerNamesJob() throws RemoteException {
jobManager.addJobInBackground(new GetNamesTask());
}
#Override
public void addUploadJob() throws RemoteException {
jobManager.addJobInBackground(new UploadRatingTask(wifi, twitter, TWITTER_CONSUMER, TWITTER_CONSUMER_SECRET, /*ctx,*/ accessToken, accessTokenSecret ));
}
};
}
then in my main activity the service is bound as follows:
private void initService() {
Log.i(TAG, "initService()" );
mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
service = ITaskService.Stub.asInterface((IBinder)iBinder);
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
bound = false;
service = null;
}
};
if(service == null){
Intent it = new Intent();
it.setAction("com.company.taskservice");
bindService(it, mServiceConnection, Context.BIND_AUTO_CREATE);
bound = true;
}
}
private void releaseService() {
if(bound && mServiceConnection!=null && service!=null){
unbindService(mServiceConnection);
}
bound = false;
service = null;
Log.d(TAG, "releaseService(): unbound.");
}
This all works perfectly, I can call on the methods in the service via the interface. However, what I would like to do now is on device boot is start the service, which I written like this:
public class DeviceBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent ratingUpload = new Intent(context, RatingUploaderService.class);
//Toast.makeText(context, "------------->>>>DEVICE BOOT RECEIVER CALLED ---- CONNECTED", Toast.LENGTH_LONG).show();
context.startService(ratingUpload);
}
}
}
I don't want the service to die if the app is A. sent to the background or B. killed. So if it's possible to start the service on boot, it will run independently of the application. However, can I through my aidl file access the methods without binding and if so can someone show me how?
thanks in advance

Not able to get binder object from Service

I am receiving a boot completed intent in my BootReceiver class and start a service when I receive that intent.
#Override
public void onReceive(Context arg0, Intent arg1) {
Intent myIntent = new Intent(arg0, BootService.class);
arg0.startService(myIntent);
}
The service is started normally and now, I want to use the binder object within the service . Here is the service code.
public class BootService extends Service implements IBinder{
private IBinder binder;
public class LocalBinder extends Binder {
IBinder getService() {
return BootService.this;
}
}
#Override
public void onCreate() {
super.onCreate();
Log.d("BootService", "onCreate()");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("BootService", "onStartCommand()");
binder = new LocalBinder().getService();
//This doesn't seem to work
//I wana use this binder object here
return START_STICKY;
}
.....
}
I am not sure if this is the correct way to get a binder.
Any help is much appreciated!!
In ur Acivity
#Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(getApplicationContext(), MyService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
unbindService(mConnection);
}
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(getApplicationContext(), "Service disconnected", 1000).show();
mBindr = false;
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(getApplicationContext(), "Service connected", 1000).show();
LocalBinder mLocalBinder = (LocalBinder) service;
myService = mLocalBinder.getSrvice();
mBindr = true;
}
};
Update your code
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class BootService extends Service {
private IBinder binder = new LocalBinder();
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return binder;
}
public class LocalBinder extends Binder {
BootService getService() {
return BootService.this;
}
}
#Override
public void onCreate() {
super.onCreate();
Log.d("BootService", "onCreate()");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("BootService", "onStartCommand()");
//binder = new LocalBinder().getService();
//This doesn't seem to work
//I wana use this binder object here
return START_STICKY;
}
.....
}

Categories

Resources