NickUnuchek
NickUnuchek

Reputation: 12857

How to bind Service if it's in another process?

Manifest:

 <service android:name="com.example.MainService" android:process=":main_service"/>

Trying to bind service in Activity:

public class MainActivity extends Activity {
    MainService mMainService;

    private boolean mBound;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        bindService(intentForMainService, mConnection, Context.BIND_AUTO_CREATE)
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className,
                                       IBinder service) {
            MainService.MainServiceBinder binder = (MainService.MainServiceBinder) service;//HERE IS EXCEPTION
            mMainService = (MainService) binder.getService();
            mBound = true;
        }

        public void onServiceDisconnected(ComponentName className) {
            mMainService = null;
            mBound = false;
        }
    };

    @Override
    protected void onStop() {
        doUnbindService();
        super.onStop();
    }

    void doUnbindService() {
        if (mBound) {
          unbindService(mConnection);
        }
    }
}

Error:

    FATAL EXCEPTION: main
 Process: com.hos.android, PID: 9001
   java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.example.service.main.MainService$MainServiceBinder
   at com.example.ui.base.BaseServiceActivity$1.onServiceConnected(MainActivity.java:34)
   at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1335)
   at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1352)
   at android.os.Handler.handleCallback(Handler.java:739)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:158)
   at android.app.ActivityThread.main(ActivityThread.java:7224)

But when I delete this android:process=":main_service" all works properly

Upvotes: 6

Views: 8875

Answers (2)

Roma Darvish
Roma Darvish

Reputation: 267

I think so if you do it will be good

Frist of all create Servic

public class MyService extends Service {

MyReceiver receiver = new MyReceiver();
@Override
public void onCreate() {
    super.onCreate();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    receiver.startAlarm(this);
    return START_STICKY;
}

@Override
public void onStart(Intent intent, int startId) {
    receiver.startAlarm(this);
}

}

after start alarm listen to alarm create BroadcastReceiver

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(final Context context, Intent intent) { 
        Log.e("Receiver", "end alarm")
    }
}


public void setAlarm(Context context) {
    AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent i = new Intent(context, BootReceiver.class);
    PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
    am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 10, pi); // Millisec * Second * Minute
}

public void cancelAlarm(Context context) {
    Intent intent = new Intent(context, BootReceiver.class);
    PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarmManager.cancel(sender);
}

add manifest this

<service android:name=".MyService"
        android:enabled="true"
        android:process=":my_service"/>

    <receiver
        android:name="MyReceiver"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.parse.push.intent.RECEIVE" />
            <action android:name="com.parse.push.intent.DELETE" />
            <action android:name="com.parse.push.intent.OPEN" />
        </intent-filter>
    </receiver>

Upvotes: -2

CommonsWare
CommonsWare

Reputation: 1006869

Step #1: Write an AIDL file that describes the interface to be exported by the service that clients can bind to. For the purposes of this answer, I will call this interface Foo, and so the AIDL file would be Foo.aidl. Note that if the client and service are in separate Android Studio modules that both need the same Foo.aidl content.

Step #2: Have your service's binder extend Foo.Stub and override the methods on Foo.Stub, instead of extending IBinder.

Step #3: In your client, in onServiceConnected(), convert the raw binder to a Foo instance via Foo.Stub.asInterface(service), and Foo has the client side of the AIDL-defined API.

This pair of sample projects illustrates this, where in my case the client and the service are in separate apps.

Upvotes: 15

Related Questions