android - Google API client bug, sending locations -
i want create send every few seconds message gcm. after time want remove locationupdates again. sending data intentservice of gcm use pendingintent. every time , happens lot error :
caused by:
java.lang.illegalstateexception: googleapiclient not connected yet. @ com.google.android.gms.common.internal.n.a(unknown source) @ com.google.android.gms.common.api.b.b(unknown source) @ com.google.android.gms.internal.lt.removelocationupdates(unknown source) @ com.example.task_1.location.locationupdate.stoplocationupdates(locationupdate.java:83) @ com.example.task_1.location.locationupdate.onstartcommand(locationupdate.java:52) @ android.app.activitythread.handleserviceargs(activitythread.java:2704) at android.app.activitythread.access$1900(activitythread.java:141) at android.app.activitythread$h.handlemessage(activitythread.java:1353) at android.os.handler.dispatchmessage(handler.java:99) at android.os.looper.loop(looper.java:137) at android.app.activitythread.main(activitythread.java:5103) at java.lang.reflect.method.invokenative(native method) at java.lang.reflect.method.invoke(method.java:525) at com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:737) at com.android.internal.os.zygoteinit.main(zygoteinit.java:553) at dalvik.system.nativestart.main(native method)
this code:
public class locationupdate extends service implements googleapiclient.connectioncallbacks, googleapiclient.onconnectionfailedlistener { private static final string tag = "driver"; private sharedpreferences pref; private string driverid; private googleapiclient mgoogleapiclient; private locationrequest mlocationrequest; private intent mgcmintentservice; private pendingintent mpendingintent; @override public ibinder onbind(intent arg0) { return null; } @override public int onstartcommand(intent intent, int flags, int startid) { log.e(tag, "onstartcommand"); super.onstartcommand(intent, flags, startid); boolean stopservice = false; if (intent != null) stopservice = intent.getbooleanextra("stopservice", false); if (stopservice) stoplocationupdates(); return start_sticky; } @override public void oncreate() { log.e(tag, "oncreate"); pref = getsharedpreferences("driver_app", mode_private); driverid = pref.getstring("driver_id", ""); mgoogleapiclient = new googleapiclient.builder(this) .addapi(locationservices.api).addconnectioncallbacks(this) .addonconnectionfailedlistener(this).build(); mgoogleapiclient.connect(); } @override public void ondestroy() { log.e(tag, "ondestroy"); super.ondestroy(); } public void stoplocationupdates() { if(!mgoogleapiclient.isconnected()){ mgoogleapiclient.connect(); } mgcmintentservice = new intent(this,senddataintentservice.class); mgcmintentservice.putextra("id", "fusedlocation"); mpendingintent = pendingintent.getservice(this, 0, mgcmintentservice, pendingintent.flag_cancel_current); locationservices.fusedlocationapi.removelocationupdates(mgoogleapiclient, mpendingintent); if (mgoogleapiclient.isconnected()) mgoogleapiclient.disconnect(); } @override public void onconnectionfailed(connectionresult arg0) { // todo auto-generated method stub } @override public void onconnected(bundle arg0) { // todo auto-generated method stub mlocationrequest = locationrequest.create(); mlocationrequest.setpriority(locationrequest.priority_balanced_power_accuracy); mlocationrequest.setinterval(30000); startlocationupdates(); } private void startlocationupdates() { mgcmintentservice = new intent(this,senddataintentservice.class); mgcmintentservice.putextra("id", "fusedlocation"); mpendingintent = pendingintent.getservice(this, 0, mgcmintentservice, pendingintent.flag_cancel_current); locationservices.fusedlocationapi.requestlocationupdates(mgoogleapiclient, mlocationrequest, mpendingintent); } @override public void onconnectionsuspended(int arg0) { // todo auto-generated method stub } }
anyone know how solve bug? or how fix it? searched on internet can't find anything.
the problem in stoplocationupdates()
method, not waiting api connected before call removelocationupdates()
.
one simple way fix set boolean flag when need remove location callbacks, api not connected.
add member variable:
private boolean isremoving = false;
then modify logic waits api connect before unregistering location callbacks.
in stoplocationupdates()
method:
public void stoplocationupdates() { if(!mgoogleapiclient.isconnected()){ isremoving = true; //added mgoogleapiclient.connect(); } else { mgcmintentservice = new intent(this, senddataintentservice.class); mgcmintentservice.putextra("id", "fusedlocation"); mpendingintent = pendingintent.getservice(this, 0, mgcmintentservice, pendingintent.flag_cancel_current); locationservices.fusedlocationapi.removelocationupdates(mgoogleapiclient, mpendingintent); if (mgoogleapiclient.isconnected()) mgoogleapiclient.disconnect(); } }
in onconnected()
callback:
@override public void onconnected(bundle arg0) { if (isremoving){ stoplocationupdates(); } else { // todo auto-generated method stub mlocationrequest = locationrequest.create(); mlocationrequest.setpriority(locationrequest.priority_balanced_power_accuracy); mlocationrequest.setinterval(30000); startlocationupdates(); } }
you want set flag false in startlocationupdates()
:
private void startlocationupdates() { isremoving = false; //added mgcmintentservice = new intent(this,senddataintentservice.class); mgcmintentservice.putextra("id", "fusedlocation"); mpendingintent = pendingintent.getservice(this, 0, mgcmintentservice, pendingintent.flag_cancel_current); locationservices.fusedlocationapi.requestlocationupdates(mgoogleapiclient, mlocationrequest, mpendingintent); }
also in oncreate()
:
@override public void oncreate() { log.e(tag, "oncreate"); isremoving = false; //added pref = getsharedpreferences("driver_app", mode_private); driverid = pref.getstring("driver_id", ""); mgoogleapiclient = new googleapiclient.builder(this) .addapi(locationservices.api).addconnectioncallbacks(this) .addonconnectionfailedlistener(this).build(); mgoogleapiclient.connect(); }
edit: re-start location callbacks after have been cancelled, can use onstartcommand()
method.
modify onstartcommand()
can both stop , start location updates:
@override public int onstartcommand(intent intent, int flags, int startid) { log.e(tag, "onstartcommand"); super.onstartcommand(intent, flags, startid); boolean stopservice = false; if (intent != null) { stopservice = intent.getbooleanextra("stopservice", false); } if (stopservice) { stoplocationupdates(); } else{ isremoving = false; mgoogleapiclient = new googleapiclient.builder(this) .addapi(locationservices.api).addconnectioncallbacks(this) .addonconnectionfailedlistener(this).build(); mgoogleapiclient.connect(); } return start_sticky; }
then, in order re-start location updates, call startservice()
intent has stopservice
set false:
intent = new intent(this, locationupdate.class); i.putextra("stopservice", false); startservice(i);
Comments
Post a Comment