android - Use of GoogleApiClient hanging app -
in app have 4 5 fragments , fragment needed googleapiclient object current location , other related things.
so, using googleapiclient below :
first implementing as :
implements googleapiclient.connectioncallbacks, googleapiclient.onconnectionfailedlistener declaration :
private googleapiclient mgoogleapiclient; in side oncreate() of fragment :
if (!constant.checkpermission(mcontext, manifest.permission.access_fine_location)) { constant.requestpermission(getactivity(), manifest.permission.access_fine_location, 101); } else { if (constant.isonline(mcontext)) { buildgoogleapiclient(); locationupdate(); } else { constant.displaytoast(mcontext, getresources().getstring(r.string.msg_internet)); } } buiding below :
private synchronized void buildgoogleapiclient() { if (mgoogleapiclient == null || !mgoogleapiclient.isconnected()) { mgoogleapiclient = new googleapiclient.builder(getactivity()) .addapi(locationservices.api) .addapi(places.geo_data_api) .addapi(places.place_detection_api) .enableautomanage(getactivity(), mapfragment.this) .addconnectioncallbacks(this) .addonconnectionfailedlistener(this) .build(); } } onconnected method:
@override public void onconnected(@nullable bundle bundle) { try { if (activitycompat.checkselfpermission(mcontext, manifest.permission.access_fine_location) != packagemanager.permission_granted && activitycompat.checkselfpermission(mcontext, manifest.permission.access_coarse_location) != packagemanager.permission_granted) { return; } mlastlocation = locationservices.fusedlocationapi.getlastlocation(mgoogleapiclient); } catch (exception e) { e.printstacktrace(); } } getlocation() method:
private void getlocation() { try { if (activitycompat.checkselfpermission((activity) mcontext, manifest.permission.access_fine_location) != packagemanager.permission_granted && activitycompat.checkselfpermission((activity) mcontext, manifest.permission.access_coarse_location) != packagemanager.permission_granted) { return; } else { mlocationmanager = (locationmanager) mcontext .getsystemservice(location_service); // getting gps status boolean isgpsenabled = mlocationmanager .isproviderenabled(locationmanager.gps_provider); // getting network status boolean isnetworkenabled = mlocationmanager .isproviderenabled(locationmanager.network_provider); if (!isgpsenabled && !isnetworkenabled) { // no network provider enabled } else { if (prefrences.checkpref(mcontext, zipcode)) { getlatlongfromzipcode(); } else { if (isnetworkenabled) { if (!prefrences.checkpref(mcontext, near_me_search)) { mlocationmanager.requestlocationupdates( locationmanager.network_provider, 0, 0, this); if (mlocationmanager != null) { mlocation = mlocationmanager .getlastknownlocation(locationmanager.network_provider); if (mlocation != null) { mcurrentlatitude = mlocation.getlatitude(); mcurrentlongitude = mlocation.getlongitude(); } else if (mlastlocation != null) { mcurrentlatitude = mlastlocation.getlatitude(); mcurrentlongitude = mlastlocation.getlongitude(); } else { constant.displaytoast(mcontext, "location not fetched. try again."); } } } } else if (isgpsenabled) { if (!prefrences.checkpref(mcontext, near_me_search)) { if (mlocation == null) { mlocationmanager.requestlocationupdates( locationmanager.gps_provider, 0, 0, this); if (mlocationmanager != null) { mlocation = mlocationmanager .getlastknownlocation(locationmanager.gps_provider); if (mlocation != null) { mcurrentlatitude = mlocation.getlatitude(); mcurrentlongitude = mlocation.getlongitude(); } else if (mlastlocation != null) { mcurrentlatitude = mlastlocation.getlatitude(); mcurrentlongitude = mlastlocation.getlongitude(); } else { constant.displaytoast(mcontext, "location not fetched. try again."); } } } } } loadservicedata(); } } } } catch (exception e) { e.printstacktrace(); } } locationupdate() method, in getlocation() method calling :
private void locationupdate() { try { mlocationrequest = locationrequest.create(); mlocationrequest.setpriority(locationrequest.priority_high_accuracy); mlocationrequest.setinterval(5 * 1000); mlocationrequest.setfastestinterval(1 * 1000); locationsettingsrequest.builder builder = new locationsettingsrequest.builder() .addlocationrequest(mlocationrequest); // ************************** builder.setalwaysshow(true); // key ingredient // ************************** if (mgoogleapiclient != null) { pendingresult<locationsettingsresult> result = locationservices.settingsapi .checklocationsettings(mgoogleapiclient, builder.build()); result.setresultcallback(new resultcallback<locationsettingsresult>() { @override public void onresult(locationsettingsresult result) { final status status = result.getstatus(); final locationsettingsstates state = result .getlocationsettingsstates(); switch (status.getstatuscode()) { case locationsettingsstatuscodes.success: // location settings satisfied. client can // initialize location // requests here. try { if (constant.isonline(mcontext)) { getlocation(); } else constant.displaytoast(mcontext, mcontext.getresources().getstring(r.string.msg_internet)); } catch (exception e) { e.printstacktrace(); } break; case locationsettingsstatuscodes.resolution_required: // location settings not satisfied. // fixed showing user // dialog. try { status.startresolutionforresult((activity) mcontext, location_get_code); } catch (intentsender.sendintentexception e) { e.printstacktrace(); } break; case locationsettingsstatuscodes.settings_change_unavailable: // location settings not satisfied. however, have // no way fix // settings won't show dialog. constant.displaytoast(mcontext, "location change issue."); break; } } }); } } catch (exception e) { e.printstacktrace(); } } onactivityresult() below :
@override public void onactivityresult(int requestcode, int resultcode, intent data) { super.onactivityresult(requestcode, resultcode, data); if (requestcode == location_get_code) { switch (resultcode) { case activity.result_ok: try { getlocation(); } catch (exception e) { e.printstacktrace(); } break; case activity.result_canceled: // user asked change settings, chose not toast.maketext(mcontext, "please, turn on gps , try again", toast.length_long).show(); break; default: break; } } runtime.getruntime().gc(); } onstop() method :
@override public void onstop() { try { if (mgoogleapiclient != null && mgoogleapiclient.isconnected()) { mgoogleapiclient.stopautomanage(getactivity()); mgoogleapiclient.disconnect(); } super.onstop(); } catch (exception e) { e.printstacktrace(); } } onstart() method :
@override public void onstart() { try { super.onstart(); if (mgoogleapiclient != null) { mgoogleapiclient.connect(); } } catch (exception e) { e.printstacktrace(); } } ondestroy() method :
@override public void ondestroy() { try { super.ondestroy(); if (mgoogleapiclient != null) { mgoogleapiclient.stopautomanage(getactivity()); mgoogleapiclient.disconnect(); } } catch (exception e) { e.printstacktrace(); } } now, issue when navigating 1 fragment fragment app stucks or hang 2 3 seconds.
what might issue ? thanks.
this happening because in each fragment doing same thing again , again. connecting in onstart() , disconnecting in onstop(). onstart() of second fragment called before onstop() of first fragment.
instead of using googleapiclient in each fragment, move single class , connect , disconnect activity.
i have implemented locationupdater own purpose. @ code, if think can use it.
locationfinder.class
import com.google.android.gms.common.connectionresult; import com.google.android.gms.common.api.googleapiclient; import com.google.android.gms.common.api.pendingresult; import com.google.android.gms.common.api.resultcallback; import com.google.android.gms.common.api.status; import com.google.android.gms.location.locationlistener; import com.google.android.gms.location.locationrequest; import com.google.android.gms.location.locationservices; import com.google.android.gms.location.locationsettingsrequest; import com.google.android.gms.location.locationsettingsresult; import com.google.android.gms.location.locationsettingsstatuscodes; import com.google.android.gms.maps.model.latlng; /** * created bhuvanesh on 8/21/2017. */ @suppresswarnings("missingpermission") public class locationfinder implements locationlistener, googleapiclient.connectioncallbacks, googleapiclient.onconnectionfailedlistener { public static final string tag = "locationfinder"; private static final string broadcast_gps_req = "locationfinder.gps_req"; private static final string key_gps_req = "key.gps.req"; private static final int gps_request = 2301; private fragmentactivity activity; private findertype findertype; private googleapiclient googleapiclient; private locationrequest locationrequest; private long updateinterval; private long fastestinterval; private gpsrequestlistener gpsrequestlistener; private locationupdatelistener locationupdatelistener; public locationfinder(fragmentactivity activity, findertype findertype) { this.activity = activity; this.findertype = findertype; } private void connectgoogleapiclient() { googleapiclient = new googleapiclient.builder(activity) .addapi(locationservices.api).addconnectioncallbacks(this) .addonconnectionfailedlistener(this).build(); googleapiclient.connect(); } private void createlocationrequest() { locationrequest = locationrequest.create(); locationrequest.setpriority(locationrequest.priority_high_accuracy); locationrequest.setinterval(updateinterval); locationrequest.setfastestinterval(fastestinterval); } private broadcastreceiver receiver = new broadcastreceiver() { @override public void onreceive(context context, intent intent) { int intextra = intent.getintextra(key_gps_req, 0); switch (intextra) { case activity.result_ok: locationservices.fusedlocationapi.requestlocationupdates(googleapiclient, locationrequest, locationfinder.this); gpsrequestlistener.gpsturnedon(); break; case activity.result_canceled: gpsrequestlistener.gpsnotturnedon(); } } }; public void gpsrequestcallback(gpsrequestlistener gpsrequestlistener) { this.gpsrequestlistener = gpsrequestlistener; localbroadcastmanager.getinstance(activity).registerreceiver(receiver, new intentfilter(broadcast_gps_req)); } public void find(locationupdatelistener listener) { this.locationupdatelistener = listener; createlocationrequest(); connectgoogleapiclient(); } private void find() { locationsettingsrequest.builder builder = new locationsettingsrequest.builder() .addlocationrequest(locationrequest); builder.setalwaysshow(true); pendingresult<locationsettingsresult> result = locationservices.settingsapi.checklocationsettings(googleapiclient, builder.build()); result.setresultcallback(new resultcallback<locationsettingsresult>() { @override public void onresult(@nonnull locationsettingsresult locationsettingsresult) { status status = locationsettingsresult.getstatus(); switch (status.getstatuscode()) { case locationsettingsstatuscodes.success: locationservices.fusedlocationapi.requestlocationupdates(googleapiclient, locationrequest, locationfinder.this); break; case locationsettingsstatuscodes.resolution_required: try { status.startresolutionforresult(activity, gps_request); } catch (intentsender.sendintentexception e) { e.printstacktrace(); } break; case locationsettingsstatuscodes.settings_change_unavailable: log.d(tag, "no gps hardware"); break; } } }); } public void stopfinder() { locationservices.fusedlocationapi.removelocationupdates(googleapiclient, this); activity.unregisterreceiver(receiver); googleapiclient.disconnect(); } @override public void onconnected(@nullable bundle bundle) { log.d(tag, "googleapiclient: connected"); find(); } @override public void onconnectionsuspended(int i) { log.d(tag, "googleapiclient: onconnectionsuspended") } @override public void onconnectionfailed(@nonnull connectionresult connectionresult) { log.d(tag, "googleapiclient: onconnectionfailed") } @override public void onlocationchanged(location location) { if (findertype != findertype.track) stopfinder(); locationupdatelistener.onlocationupdate(new latlng(location.getlatitude(), location.getlongitude())); } public void setgpsrequestlistener(gpsrequestlistener gpsrequestlistener) { this.gpsrequestlistener = gpsrequestlistener; } public static void onrequestresult(activity activity, int requestcode, int resultcode) { if (requestcode == gps_request) { intent intent = new intent(broadcast_gps_req); intent.putextra(key_gps_req, resultcode); localbroadcastmanager.getinstance(activity).sendbroadcast(intent); } } public enum findertype { // update current gps location once. gps, //it update user location continuously. track } interface locationupdatelistener { void onlocationupdate(latlng latlng); } interface gpsrequestlistener { void gpsturnedon(); void gpsnotturnedon(); } } in activity:
locationfinder finder = new locationfinder((fragmentactivity) getactivity(), locationfinder.findertype.track); finder.config(5000, 5000); finder.find(this); you should implement locationfinder.locationupdatelistener in fragment. location update in callback method.
void onlocationupdate(latlng latlng); if want turn on gps , callback after process have this.
finder.gpsrequestcallback(new gpsrequestlistener() { @override public void gpsturnedon() { } @override public void gpsnotturnedon() { } }); in activity onactivityresult() should this.
@override protected void onactivityresult(int requestcode, int resultcode, intent data) { super.onactivityresult(requestcode, resultcode, data); locationfinder.onrequestresult(this, requestcode, resultcode); } note: have location permission before use this.
Comments
Post a Comment