ClassCastException: android.os.Handler$MessengerImpl cannot be cast to My - android

I have declared an handler in my service:
final Messenger messenger = new Messenger(new MusicAPIControlHandler());
public class MusicPlayerBinder extends Binder {
public MusicPlayerService getService() {
return MusicPlayerService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
public class MusicAPIControlHandler extends Handler {
#Override
public void handleMessage(Message msg) {
//
}
}
In my class which implements the ServiceConnection and which binds the service, I do the following:
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
handler = (MusicPlayerService.MusicAPIControlHandler) iBinder;
}
My problem is, I get the a ClassCastException when I try to cast the binder to my handler, which actually should be an instance of it because it´s set to the binder of the messenger.
Where am i going wrong?
I have NOT declared my service as an process

Related

The method getService() from the type TrackingService.LocalBinder is not visible

I have tracking service background as well as MainActivity when I put them in the same package I am not getting any error but when I try to seperate them in different packages also (trackingService - com.bustracker.trackingService) and (MainActivity in com.bustracker.monitoring) then I am getting at this line mService = binder.getService(); the following error The method getService() from the type TrackingService.LocalBinder is not visible
How can I fix it?
MainActivity:
package com.bustracker.monitoring;
public class MainActivity extends ActionBarActivity implements
AsyncTaskCallback {
TrackingService mService;
TrackingService mService;
boolean mBound = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.route_available);
// Start the TrackingService class.
Intent i = new Intent(this, TrackingService.class);
startService(i);
getAvialableRoutes();
System.out.println("ABC MainActivity onCreate() ");
}
private ServiceConnection mConnection = new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("ABC MainActivity onServiceConnected()");
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
//Here I am getting the error "The method getService() from the type TrackingService.LocalBinder is not visible"
mService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("ABC MainActivity onServiceDisconnected()");
mBound = false;
}
};
}
TrackingService:
package com.bustracker.trackingService;
public class TrackingService extends Service implements AsyncTaskCallback,
LocationListener {
private final IBinder mBinder = new LocalBinder();
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
detectLocation();
return START_NOT_STICKY;
}
public class LocalBinder extends Binder {
TrackingService getService() {
// Return this instance of TrackingService so clients can call public methods
return TrackingService.this;
}
}
}
The method getService() from the type TrackingService.LocalBinder is
not visible
Because getService() method is not public. declare it as public in LocalBinder to access it using binder object.

Issues when trying to bind to a service after unbinding

I've created a simple class which extends the Service class to understand how services work. But I've got a problem. I want my service to run without interruption while I'm binding and unbinding. I start the service inside activity, then I bind the activity to it, unbind and bind again. But the things after the unbinding does not go well. I don't get the output of onBind(Intent intent) and onUnbind(Intent intent) or onRebind(Intent intent) methods in the service.
public class MyService extends Service {
private final IBinder binder = new LocalBinder();
public class LocalBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
#Override
public void onCreate() {
MyActivity.log("service created");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
MyActivity.log("service started");
return 0;
}
#Override
public void onDestroy() {
MyActivity.log("service destroyed");
}
#Override
public IBinder onBind(Intent intent) {
MyActivity.log("binded");
return binder;
}
#Override
public boolean onUnbind(Intent intent) {
MyActivity.log("unbinded");
return super.onUnbind(intent);
}
#Override
public void onRebind(Intent intent) {
MyActivity.log("rebinded");
}
}

Android : how to update a interface method implemented by a class A and update from Class B?

I've declare an interface named
public interface listener {
public void onError();
}
Implemented this interface in a class A.
I've another service B which I open via startService(new Intent(this, B.class));
Now desire is, using that interface when I receive any error in class B, can be notify to class A without using Broadcast?
If your ActivityA and ServiceB are in the same process, you can use bindService(Intent intent, ServiceConnection conn, int flags) instead of startService to initiate the service. And the conn will be a inner class just like:
private ServiceConnection conn = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMyService = ((ServiceB.MyBinder) service).getService();
mMyService.setListener(new Listener() {
#Override
public void onError() {
// ...
}
});
}
#Override
public void onServiceDisconnected(ComponentName name) {
mMyService = null;
}
};
mMyService is the instance of your ServiceB.
In ServiceB, just override onBind:
public IBinder onBind(Intent intent) {
return new MyBinder();
}
and add the following class in ServiceB:
public class MyBinder extends Binder {
public ServiceB getService() {
return ServiceB.this;
}
}
in addition, add a public method:
public void setListener(Listener listener) {
this.mListener = listener;
}
so you can notify ActivityA in ServiceB like:
someMethod(){
// ...
mListener.onError();
}
ps: bindService will be like this:
this.bindService(intent, conn, Context.BIND_AUTO_CREATE);
and do not forget
protected void onDestroy() {
this.unbindService(conn);
super.onDestroy();
}
Hope it helps.

How to delay onServiceConnected call

I'm implementing Service that establishes TCP connection with server and then allows clients to pass messages through this connection. Clients connect to service with bindService call. As a result onServiceConnected called in clients ServiceConnection object. The problem is that onServiceConnected called right after return from bindService, but my Service was not established connection with server at this moment. Can I somehow delay onServiceConnected call while connection was not established? If it is not possible please suggest some good pattern for my case. Thank you.
You should do it as follows:
Service code:
class MyService implements Service {
private boolean mIsConnectionEstablished = false;
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
public MyService getService() {
// Return this instance of LocalService so clients can call public
// methods
return MyService.this;
}
}
public interface OnConnectionEstablishedListener {
public void onConnectionEstablished();
}
private OnConnectionEstablishedListener mListener;
#Override
public void onCreate() {
super.onCreate();
new Thread( new Runnable() {
#Override
void run() {
//Connect to the server here
notifyConnectionEstablished();
}
}).start();
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private void notifyConnectionEstablished() {
mIsConnectionEstablished = true;
if(mListener != null) {
mListener.onConnectionEstablished();
}
}
public void setOnConnectionEstablishedListener(
OnConnectionEstablishedListener listener) {
mListener = listener
// Already connected to server. Notify immediately.
if(mIsConnectionEstablished) {
mListener.onConnectionEstablished();
}
}
}
Activity code:
class MyActivity extends Activity implements ServiceConnection,
OnConnectionEstablishedListener {
private MyService mService;
private boolean mBound;
#Override
public void onCreate() {
super.onCreate();
//bind the service here
Intent intent = new Intent(this, MyService.class);
bindService(intent, this, BIND_AUTO_CREATE);
}
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
mService.setOnConnectionEstablishedListener(this);
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
#Override
public void onConnectionEstablished() {
// At this point the service has been bound and connected to the server
// Do stuff here
// Note: This method is called from a non-UI thread.
}
}

android bind service to activity

I have seen several similar examples here but can't seem to get my service to bind with activity.
I am getting the error
"android.os.binderproxy cannot be cast to IC_CommissaryService".
My service looks like this:
public class IC_CommissaryService extends Service
{
#Override
public IBinder onBind(Intent intent)
{
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder
{
IC_CommissaryService getService()
{
return IC_CommissaryService.this;
}
}
public int onStartCommand(Intent intent, int flags, int startId)
{
}
private boolean SendOrderToServer(int orderID)
{
/* do stuff*/
}
}
and my activity looks like this:
public class SubmitOrders extends Activity
{
IC_CommissaryService ICservice;
#Override
public void onCreate(Bundle savedInstanceState)
{
Intent serviceintent = new Intent(this, IC_CommissaryService.class);
serviceintent.putExtra("binded", true);
bindService(serviceintent, mConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mConnection = new ServiceConnection()
{
#Override
public void onServiceConnected(ComponentName className, IBinder service)
{
Log.e("TEST", "SERVICE CONNECTED");
try
{
ICservice =(IC_CommissaryService.LocalBinder)service).getService();
for(int i = 0; i < Submitorders.size(); i++)
{
ICservice.SendOrderToServer(Submitorders.get(i).intValue());
}
}
catch(Exception ex)
{
Log.e("Error", "Error connecting service: " + ex.getMessage());
}
}
#Override
public void onServiceDisconnected(ComponentName className)
{
}
};
}
I am getting the error in my activity on the line ICservice =(IC_CommissaryService.LocalBinder)service).getService();
I think I have done the same as people already suggested in other posts so any help please?
thanks
I had the same kind of problem. I just figured it out today. Please look at the parts annotated with <<===== below. I hope it helps.
public class PracticeServiceBindingActivity extends ListActivity {
private MyService.MyBinder service; <<====
....
private ServiceConnection connection = new ServiceConnection( ){
public void onServiceConnected (ComponentName name, IBinder service) {
setService(MyService.MyBinder) service; <<====
....
}
}
public void onCreate(....) {
...
public MyService.MyBinder getService(){ <<=====
return service;
}
public void setService(MyService.MyBinder service) { <<=====
this.service = service;
}
}
}
Quote from the Bound Services documentation:
If your service is private to your own application and runs in the
same process as the client (which is common), you should create your
interface by extending the Binder class and returning an instance of
it from onBind().
Remove the android:process attribute in in AndroidManifest.ml to make the service run in the same process. I had the same problem today it did the trick.
These are the abstract classes that I use to solve this problem:
https://gist.github.com/frenchie4111/6086c6e4327d7936364a
Just extend both these classes with your service and activity (You can change the fragment from a fragment to an activity with ease). And make sure that in your service/fragment onCreate you set the serviceClass like so:
public void onCreate( Bundle savedInstance ) {
super.onCreate( savedInstance );
this.serviceClass = IC_CommissaryService.class;
}

Categories

Resources