java - Implementing geofencing in a tabbed activity -
im new android development. followed basic tutorial geofencing on geofencing on tutsplus. created app geofencing. im trying implement geofencing in swipe tabbed activity, don't know if possible. have 3 java class default main activity tabbed activity, fragment , geofence handler class.
below fragment class
import android.manifest; import android.app.pendingintent; import android.content.context; import android.content.intent; import android.content.sharedpreferences; import android.content.pm.packagemanager; import android.graphics.color; import android.location.location; import android.net.uri; import android.os.bundle; import android.support.annotation.nonnull; import android.support.annotation.nullable; import android.support.v4.app.fragment; import android.support.v4.app.fragmenttransaction; import android.support.v4.content.contextcompat; import android.util.log; import android.view.layoutinflater; import android.view.menu; import android.view.menuinflater; import android.view.menuitem; import android.view.view; import android.view.viewgroup; import android.widget.textview; import com.google.android.gms.common.connectionresult; import com.google.android.gms.common.api.googleapiclient; import com.google.android.gms.common.api.resultcallback; import com.google.android.gms.common.api.status; import com.google.android.gms.location.geofence; import com.google.android.gms.location.geofencingrequest; 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.maps.cameraupdate; import com.google.android.gms.maps.cameraupdatefactory; import com.google.android.gms.maps.googlemap; import com.google.android.gms.maps.mapfragment; import com.google.android.gms.maps.onmapreadycallback; import com.google.android.gms.maps.supportmapfragment; import com.google.android.gms.maps.model.bitmapdescriptorfactory; import com.google.android.gms.maps.model.circle; import com.google.android.gms.maps.model.circleoptions; import com.google.android.gms.maps.model.latlng; import com.google.android.gms.maps.model.marker; import com.google.android.gms.maps.model.markeroptions; /** * simple {@link fragment} subclass. * activities contain fragment must implement * {@link third.onfragmentinteractionlistener} interface * handle interaction events. * use {@link third#newinstance} factory method * create instance of fragment. */ public class third extends supportmapfragment implements googleapiclient.connectioncallbacks, googleapiclient.onconnectionfailedlistener, locationlistener, onmapreadycallback, googlemap.onmapclicklistener, googlemap.onmarkerclicklistener, resultcallback<status>{ // todo: rename parameter arguments, choose names match // fragment initialization parameters, e.g. arg_item_number private static final string arg_param1 = "param1"; private static final string arg_param2 = "param2"; // todo: rename , change types of parameters private string mparam1; private string mparam2; private onfragmentinteractionlistener mlistener; private static final string tag = mainactivity.class.getsimplename(); private googlemap map; private googleapiclient googleapiclient; private location lastlocation; private mapfragment mapfragment = (mapfragment) getfragmentmanager().findfragmentbyid(r.id.map); private static final string notification_msg = "notification msg"; // create intent send notification public static intent makenotificationintent(context context, string msg) { intent intent = new intent( context, mainactivity.class ); intent.putextra( notification_msg, msg ); return intent; } public third() { // required empty public constructor } /** * use factory method create new instance of * fragment using provided parameters. * * @param param1 parameter 1. * @param param2 parameter 2. * @return new instance of fragment first. */ // todo: rename , change types , number of parameters public static third newinstance(string param1, string param2) { third fragment = new third(); bundle args = new bundle(); args.putstring(arg_param1, param1); args.putstring(arg_param2, param2); fragment.setarguments(args); return fragment; } @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); if (getarguments() != null) { mparam1 = getarguments().getstring(arg_param1); mparam2 = getarguments().getstring(arg_param2); } sethasoptionsmenu(true); // initialize googlemaps initgmaps(); // create googleapiclient creategoogleapi(); } @override public void oncreateoptionsmenu(menu menu, menuinflater inflater) { inflater.inflate(r.menu.menu_a, menu); super.oncreateoptionsmenu(menu, inflater); } @override public boolean onoptionsitemselected(menuitem item) { switch ( item.getitemid() ) { case r.id.geofence: { startgeofence(); return true; } case r.id.clear: { cleargeofence(); return true; } } return super.onoptionsitemselected(item); } // create googleapiclient instance private void creategoogleapi() { log.d(tag, "creategoogleapi()"); if ( googleapiclient == null ) { googleapiclient = new googleapiclient.builder( ) .addconnectioncallbacks( ) .addonconnectionfailedlistener( ) .addapi( locationservices.api ) .build(); } } @override public void onstart() { super.onstart(); // call googleapiclient connection when starting activity googleapiclient.connect(); } @override public void onstop() { super.onstop(); // disconnect googleapiclient when stopping activity googleapiclient.disconnect(); } private final int req_permission = 999; // check permission access location private boolean checkpermission() { log.d(tag, "checkpermission()"); // ask permission if wasn't granted yet return (contextcompat.checkselfpermission(this, manifest.permission.access_fine_location) == packagemanager.permission_granted ); } // asks permission private void askpermission() { log.d(tag, "askpermission()"); } // verify user's response of permission requested @override public void onrequestpermissionsresult(int requestcode, @nonnull string[] permissions, @nonnull int[] grantresults) { log.d(tag, "onrequestpermissionsresult()"); super.onrequestpermissionsresult(requestcode, permissions, grantresults); switch ( requestcode ) { case req_permission: { if ( grantresults.length > 0 && grantresults[0] == packagemanager.permission_granted ){ // permission granted getlastknownlocation(); } else { // permission denied permissionsdenied(); } break; } } } // app cannot work without permissions private void permissionsdenied() { log.w(tag, "permissionsdenied()"); // todo close app , warn user } // initialize googlemaps private void initgmaps(){ mapfragment.getmapasync(this); } // callback called when map ready @override public void onmapready(googlemap googlemap) { log.d(tag, "onmapready()"); map = googlemap; map.setonmapclicklistener(this); map.setonmarkerclicklistener(this); } @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { // inflate layout fragment return inflater.inflate(r.layout.fragment_first, container, false); } // todo: rename method, update argument , hook method ui event public void onbuttonpressed(uri uri) { if (mlistener != null) { mlistener.onfragmentinteraction(uri); } } @override public void onattach(context context) { super.onattach(context); if (context instanceof onfragmentinteractionlistener) { mlistener = (onfragmentinteractionlistener) context; } else { throw new runtimeexception(context.tostring() + " must implement onfragmentinteractionlistener"); } } @override public void ondetach() { super.ondetach(); mlistener = null; } @override public void ondestroy() { super.ondestroy(); fragment f = (fragment) getfragmentmanager().findfragmentbyid(r.id.map); if (f != null) { getfragmentmanager().begintransaction().remove(f).commit(); } } @override public void onconnected(@nullable bundle bundle) { } @override public void onconnectionsuspended(int i) { log.w(tag, "onconnectionsuspended()"); } @override public void onconnectionfailed(@nonnull connectionresult connectionresult) { log.w(tag, "onconnectionfailed()"); } @override public void onmapclick(latlng latlng) { log.d(tag, "onmapclick("+latlng +")"); markerforgeofence(latlng); } @override public boolean onmarkerclick(marker marker) { log.d(tag, "onmarkerclicklistener: " + marker.getposition() ); return false; } private locationrequest locationrequest; // defined in mili seconds. // number in extremely low, , should used debug private final int update_interval = 1000; private final int fastest_interval = 900; // start location updates private void startlocationupdates(){ log.i(tag, "startlocationupdates()"); locationrequest = locationrequest.create() .setpriority(locationrequest.priority_high_accuracy) .setinterval(update_interval) .setfastestinterval(fastest_interval); if ( checkpermission() ) locationservices.fusedlocationapi.requestlocationupdates(googleapiclient, locationrequest, this); } @override public void onlocationchanged(location location) { log.d(tag, "onlocationchanged ["+location+"]"); lastlocation = location; writeactuallocation(location); } // last known location private void getlastknownlocation() { log.d(tag, "getlastknownlocation()"); if ( checkpermission() ) { lastlocation = locationservices.fusedlocationapi.getlastlocation(googleapiclient); if ( lastlocation != null ) { log.i(tag, "lasknown location. " + "long: " + lastlocation.getlongitude() + " | lat: " + lastlocation.getlatitude()); writelastlocation(); startlocationupdates(); } else { log.w(tag, "no location retrieved yet"); startlocationupdates(); } } else askpermission(); } private void writeactuallocation(location location) { markerlocation(new latlng(location.getlatitude(), location.getlongitude())); } private void writelastlocation() { writeactuallocation(lastlocation); } private marker locationmarker; private void markerlocation(latlng latlng) { log.i(tag, "markerlocation("+latlng+")"); string title = latlng.latitude + ", " + latlng.longitude; markeroptions markeroptions = new markeroptions() .position(latlng) .title(title); if ( map!=null ) { if ( locationmarker != null ) locationmarker.remove(); locationmarker = map.addmarker(markeroptions); float zoom = 14f; cameraupdate cameraupdate = cameraupdatefactory.newlatlngzoom(latlng, zoom); map.animatecamera(cameraupdate); } } private marker geofencemarker; private void markerforgeofence(latlng latlng) { log.i(tag, "markerforgeofence("+latlng+")"); string title = latlng.latitude + ", " + latlng.longitude; // define marker options markeroptions markeroptions = new markeroptions() .position(latlng) .icon(bitmapdescriptorfactory.defaultmarker(bitmapdescriptorfactory.hue_orange)) .title(title); if ( map!=null ) { // remove last geofencemarker if (geofencemarker != null) geofencemarker.remove(); geofencemarker = map.addmarker(markeroptions); } } // start geofence creation process private void startgeofence() { log.i(tag, "startgeofence()"); if( geofencemarker != null ) { geofence geofence = creategeofence( geofencemarker.getposition(), geofence_radius ); geofencingrequest geofencerequest = creategeofencerequest( geofence ); addgeofence( geofencerequest ); } else { log.e(tag, "geofence marker null"); } } private static final long geo_duration = 60 * 60 * 1000; private static final string geofence_req_id = "my geofence"; private static final float geofence_radius = 500.0f; // in meters // create geofence private geofence creategeofence( latlng latlng, float radius ) { log.d(tag, "creategeofence"); return new geofence.builder() .setrequestid(geofence_req_id) .setcircularregion( latlng.latitude, latlng.longitude, radius) .setexpirationduration( geo_duration ) .settransitiontypes( geofence.geofence_transition_enter | geofence.geofence_transition_exit ) .build(); } // create geofence request private geofencingrequest creategeofencerequest( geofence geofence ) { log.d(tag, "creategeofencerequest"); return new geofencingrequest.builder() .setinitialtrigger( geofencingrequest.initial_trigger_enter ) .addgeofence( geofence ) .build(); } private pendingintent geofencependingintent; private final int geofence_req_code = 0; private pendingintent creategeofencependingintent() { log.d(tag, "creategeofencependingintent"); if ( geofencependingintent != null ) return geofencependingintent; intent intent = new intent( this, geofencetrasitionservice.class); return pendingintent.getservice(this, geofence_req_code, intent, pendingintent.flag_update_current ); } // add created geofencerequest device's monitoring list private void addgeofence(geofencingrequest request) { log.d(tag, "addgeofence"); if (checkpermission()) locationservices.geofencingapi.addgeofences( googleapiclient, request, creategeofencependingintent() ).setresultcallback(this); } @override public void onresult(@nonnull status status) { log.i(tag, "onresult: " + status); if ( status.issuccess() ) { savegeofence(); drawgeofence(); } else { // inform fail } } // draw geofence circle on googlemap private circle geofencelimits; private void drawgeofence() { log.d(tag, "drawgeofence()"); if ( geofencelimits != null ) geofencelimits.remove(); circleoptions circleoptions = new circleoptions() .center( geofencemarker.getposition()) .strokecolor(color.argb(50, 70,70,70)) .fillcolor( color.argb(100, 150,150,150) ) .radius( geofence_radius ); geofencelimits = map.addcircle( circleoptions ); } private final string key_geofence_lat = "geofence latitude"; private final string key_geofence_lon = "geofence longitude"; // saving geofence marker prefs mng private void savegeofence() { log.d(tag, "savegeofence()"); sharedpreferences sharedpref = getpreferences( context.mode_private ); sharedpreferences.editor editor = sharedpref.edit(); editor.putlong( key_geofence_lat, double.doubletorawlongbits( geofencemarker.getposition().latitude )); editor.putlong( key_geofence_lon, double.doubletorawlongbits( geofencemarker.getposition().longitude )); editor.apply(); } // recovering last geofence marker private void recovergeofencemarker() { log.d(tag, "recovergeofencemarker"); sharedpreferences sharedpref = getpreferences( context.mode_private ); if ( sharedpref.contains( key_geofence_lat ) && sharedpref.contains( key_geofence_lon )) { double lat = double.longbitstodouble( sharedpref.getlong( key_geofence_lat, -1 )); double lon = double.longbitstodouble( sharedpref.getlong( key_geofence_lon, -1 )); latlng latlng = new latlng( lat, lon ); markerforgeofence(latlng); drawgeofence(); } } // clear geofence private void cleargeofence() { log.d(tag, "cleargeofence()"); locationservices.geofencingapi.removegeofences( googleapiclient, creategeofencependingintent() ).setresultcallback(new resultcallback<status>() { @override public void onresult(@nonnull status status) { if ( status.issuccess() ) { // remove drawing removegeofencedraw(); } } }); } private void removegeofencedraw() { log.d(tag, "removegeofencedraw()"); if ( geofencemarker != null) geofencemarker.remove(); if ( geofencelimits != null ) geofencelimits.remove(); } /** * interface must implemented activities contain * fragment allow interaction in fragment communicated * activity , potentially other fragments contained in * activity. * <p> * see android training lesson <a href= * "http://developer.android.com/training/basics/fragments/communicating.html" * >communicating other fragments</a> more information. */ public interface onfragmentinteractionlistener { // todo: update argument type , name void onfragmentinteraction(uri uri); } }
i following errors in fragment: cannot resolve method 'getpreferences'
private mapfragment mapfragment = (mapfragment) getfragment().findfragmentbyid(r.id.map)
inconvertible types; cannot cast 'android.support.v4.app.fragment' 'com.google.android.gms.maps.mapfragment'
the helper class
public class geofencetrasitionservice extends intentservice { private static final string tag = geofencetrasitionservice.class.getsimplename(); public static final int geofence_notification_id = 0; public geofencetrasitionservice() { super(tag); } @override protected void onhandleintent(intent intent) { geofencingevent geofencingevent = geofencingevent.fromintent(intent); // handling errors if ( geofencingevent.haserror() ) { string errormsg = geterrorstring(geofencingevent.geterrorcode() ); log.e( tag, errormsg ); return; } int geofencetransition = geofencingevent.getgeofencetransition(); // check if transition type of interest if ( geofencetransition == geofence.geofence_transition_enter || geofencetransition == geofence.geofence_transition_exit ) { // geofence triggered list<geofence> triggeringgeofences = geofencingevent.gettriggeringgeofences(); string geofencetransitiondetails = getgeofencetrasitiondetails(geofencetransition, triggeringgeofences ); // send notification details string sendnotification( geofencetransitiondetails ); } } private string getgeofencetrasitiondetails(int geofencetransition, list<geofence> triggeringgeofences) { // id of each geofence triggered arraylist<string> triggeringgeofenceslist = new arraylist<>(); ( geofence geofence : triggeringgeofences ) { triggeringgeofenceslist.add( geofence.getrequestid() ); } string status = null; if ( geofencetransition == geofence.geofence_transition_enter ) status = "entering "; else if ( geofencetransition == geofence.geofence_transition_exit ) status = "exiting "; return status + textutils.join( ", ", triggeringgeofenceslist); } @requiresapi(api = build.version_codes.jelly_bean) private void sendnotification(string msg ) { log.i(tag, "sendnotification: " + msg ); // intent start main activity intent notificationintent = third.makenotificationintent( getapplicationcontext(), msg ); taskstackbuilder stackbuilder = taskstackbuilder.create(this); stackbuilder.addparentstack(third.class); stackbuilder.addnextintent(notificationintent); pendingintent notificationpendingintent = stackbuilder.getpendingintent(0, pendingintent.flag_update_current); // creating , sending notification notificationmanager notificatiomng = (notificationmanager) getsystemservice( context.notification_service ); notificatiomng.notify( geofence_notification_id, createnotification(msg, notificationpendingintent)); } // create notification private notification createnotification(string msg, pendingintent notificationpendingintent) { notificationcompat.builder notificationbuilder = new notificationcompat.builder(this); notificationbuilder .setsmallicon(r.drawable.ic_action_location) .setcolor(color.red) .setcontenttitle(msg) .setcontenttext("geofence notification!") .setcontentintent(notificationpendingintent) .setdefaults(notification.default_lights | notification.default_vibrate | notification.default_sound) .setautocancel(true); return notificationbuilder.build(); } private static string geterrorstring(int errorcode) { switch (errorcode) { case geofencestatuscodes.geofence_not_available: return "geofence not available"; case geofencestatuscodes.geofence_too_many_geofences: return "too many geofences"; case geofencestatuscodes.geofence_too_many_pending_intents: return "too many pending intents"; default: return "unknown error."; } } }
the tabbed activity returns 3 tabs, other 2 tabs empty. can use multiple maps in tabbed activity. , guidance best android development practices highly appreciated
Comments
Post a Comment