2015-05-05 5 views
0

Я создаю приложение, которое поможет идти в ногу со своей вкладкой в ​​баре, пока вы находитесь в городе. У меня есть функция, в которой пользователь может установить сигнализацию близости (Geofence), чтобы напомнить им закрыть свою вкладку, если они покинут панель без закрытия. Сначала отображается карта, затем маркер помещается в местоположение пользователя, а затем вокруг маркера отображается геозонность 100 метров. Местоположение пользователя регулярно обновляется, поэтому оно работает на фоновом потоке.Остановить GPS и отключить GoogleApiClient

Моя проблема заключается в том, что когда пользователь закрывает свою вкладку, я хочу прекратить отключать службы местоположения, которые приложение использует с помощью нажатия кнопки. Этот щелчок кнопки происходит в отдельном Управлении, из которого запускается служба карты и геолокации. Любая помощь будет принята с благодарностью!

PS - Я попытался включить как можно больше кода, поэтому, пожалуйста, простите мой беспорядок.

Карта начинается от addBtn в этой деятельности:

public class Alarm extends ActionBarActivity { 
public static String TAG = "lstech.aos.debug"; 

static public boolean geofencesAlreadyRegistered = false; 
Button addBtn, lobbyBtn, startTabBtn, settingsBtn; 
boolean mapOpen = false; 
double latitude, longitude = 0.0; 
protected GoogleMap map; 
ActionBar actionBar; 
Fragment f; 
FragmentManager fragmentManager; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.alarm_layout); 

    actionBar = getSupportActionBar(); 
    actionBar.hide(); 

    addBtn = (Button) findViewById(R.id.add_geo_button); 
    startTabBtn = (Button) findViewById(R.id.calculator_button); 
    lobbyBtn = (Button) findViewById(R.id.lobby_button); 
    settingsBtn = (Button) findViewById(R.id.settings_button); 

    TinyDB tinydb = new TinyDB(this); 
    mapOpen = tinydb.getBoolean("mapOpen"); 

    if (mapOpen) 
     addBtn.setText(R.string.view_map_button); 
    else 
     addBtn.setText(R.string.set_gps_alert); 

    fragmentManager = getSupportFragmentManager(); 
    f = fragmentManager.findFragmentByTag("uniqueTag"); 

    // SET MAP MARKER AND GEOFENCE 
    addBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      // create a map instance if one doesn't exist 
      if (f == null) { 
       fragmentManager 
         .beginTransaction() 
         .replace(android.R.id.content, new MapFragment(), 
           "uniqueTag").commit(); 

      } // keep instance of map if it's already showing 
      else { 
       fragmentManager.beginTransaction() 
         .replace(android.R.id.content, f, "uniqueTag") 
         .commit(); 
      } 

      fragmentManager.executePendingTransactions(); 

      startService(new Intent(getApplicationContext(), 
        GeolocationService.class)); 
     } 
    }); 

Класс GeoLocationService устанавливает местонахождение и Geofence объект:

public class GeolocationService extends Service implements ConnectionCallbacks, 
    OnConnectionFailedListener, LocationListener, ResultCallback<Status> { 
// TinyDB saved value handles: (boolean)"mapReady" 
LocationListener listener; 
private static final long GEOFENCE_EXPIRATION_IN_HOURS = 12; 
private static final long RADIUS = 100; 
public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS = GEOFENCE_EXPIRATION_IN_HOURS 
     * DateUtils.HOUR_IN_MILLIS; 
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000; 
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS/5; 
protected GoogleApiClient mGoogleApiClient; 
public static GoogleApiClient mGoogleApiClientStatic; 
protected LocationRequest mLocationRequest; 
private PendingIntent mPendingIntent; 
List<Geofence> mGeofenceList; 
static public List<Geofence> mGeofenceListPass; 
SimpleGeofence simpleGeo; 
static public SimpleGeofence geoFence; 
Location mLocation, newLocation; 
Intent intent; 
public static LocationManager mlocManager; 
public static LocationListener mlocListener; 
public static android.location.LocationListener mlocListenerProvider; 
public static PendingIntent pendingIntent; 
public static ConnectionCallbacks connCallbacks; 
public static OnConnectionFailedListener connFailedListener; 

// ON START 
// *********** 
@Override 
public void onStart(Intent intent, int startId) { 
    buildGoogleApiClient(); 
    mGoogleApiClient.connect(); 
    mGoogleApiClientStatic = mGoogleApiClient; 
    mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
    mlocListener = this; 
    mlocListenerProvider = new android.location.LocationListener() { 

     @Override 
     public void onLocationChanged(Location arg0) { 
      // TODO Auto-generated method stub 
     } 

     @Override 
     public void onStatusChanged(String provider, int status, 
       Bundle extras) { 
      // TODO Auto-generated method stub 
     } 

     @Override 
     public void onProviderEnabled(String provider) { 
      // TODO Auto-generated method stub 
     } 

     @Override 
     public void onProviderDisabled(String provider) { 
      // TODO Auto-generated method stub 
     } 
    }; 

    mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0L, 
      0f, mlocListenerProvider); 
} 

// ON DESTROY 
// ************* 
@Override 
public void onDestroy() { 
    super.onDestroy(); 

    if (mGoogleApiClient.isConnected()) 
     mGoogleApiClient.disconnect(); 
} 

// REGISTER GEOFENCES 
// ********************* 
protected void registerGeofences(Location location) { 
    if (Alarm.geofencesAlreadyRegistered) 
     return; 

    Log.d(Alarm.TAG, "Registering Geofences"); 

    String geoId = "geoId"; 
    simpleGeo = new SimpleGeofence(geoId, location.getLatitude(), 
      location.getLongitude(), RADIUS, 
      GEOFENCE_EXPIRATION_IN_MILLISECONDS, 
      Geofence.GEOFENCE_TRANSITION_ENTER 
        | Geofence.GEOFENCE_TRANSITION_DWELL 
        | Geofence.GEOFENCE_TRANSITION_EXIT); 

    // mGeofenceList.add(new Geofence.Builder() 

    HashMap<String, SimpleGeofence> geofences = SimpleGeofenceStore 
      .getInstance().getSimpleGeofences(); 

    GeofencingRequest.Builder builder = new GeofencingRequest.Builder(); 

    for (Map.Entry<String, SimpleGeofence> item : geofences.entrySet()) { 
     SimpleGeofence sg = item.getValue(); 
     sg.setLatitude(simpleGeo.getLatitude()); 
     sg.setLongitude(simpleGeo.getLongitude()); 
     builder.addGeofence(sg.toGeofence()); 

     SimpleGeofenceStore store = SimpleGeofenceStore.getInstance(); 
     store.setLatLong(simpleGeo.getLatitude(), simpleGeo.getLongitude()); 
     // Log.d(Alarm.TAG, sg.getLatitude() + " " + sg.getLongitude()); 
    } 

    TinyDB tinydb = new TinyDB(getApplicationContext()); 
    tinydb.putBoolean("mapReady", false); 

    GeofencingRequest geofencingRequest = builder.build(); 

    mPendingIntent = requestPendingIntent(); 
    pendingIntent = mPendingIntent; 

    LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, 
      geofencingRequest, mPendingIntent).setResultCallback(this); 

    Alarm.geofencesAlreadyRegistered = true; 
} // end registerGeofences() 

// REQUEST PENDING INTENT 
// ************************* 
private PendingIntent requestPendingIntent() { 

    if (null != mPendingIntent) 
     return mPendingIntent; 

    Intent intent = new Intent(this, GeofenceReceiver.class); 
    return PendingIntent.getService(this, 0, intent, 
      PendingIntent.FLAG_UPDATE_CURRENT); 

} // end requestPendingIntent() 

// START LOCATION UPDATES 
// ************************* 
protected void startLocationUpdates() { 
    LocationServices.FusedLocationApi.requestLocationUpdates(
      mGoogleApiClient, mLocationRequest, this); 
} // end startLocationUpdates() 

// STOP LOCATION UPDATES 
// ************************ 
protected void stopLocationUpdates() { 
    LocationServices.FusedLocationApi.removeLocationUpdates(
      mGoogleApiClient, this); 
} // end stopLocationUpdates() 

// ON CONNECTED 
// *************** 
@Override 
public void onConnected(Bundle connectionHint) { 
    Log.i(Alarm.TAG, "Connected to GoogleApiClient"); 
    startLocationUpdates(); 
} // end onConnected(Bundle connectionHint) 

// ON LOCATION CHANGED 
// ********************** 
@Override 
public void onLocationChanged(Location location) { 
    Log.d(Alarm.TAG, "new location : " + location.getLatitude() + ", " 
      + location.getLongitude() + ". " + location.getAccuracy()); 
    broadcastLocationFound(location); 

    if (!Alarm.geofencesAlreadyRegistered) 
     registerGeofences(location); 

} // end onLocationChanged(Location location) 

// ON CONNECTION SUSPENDED 
// ************************** 
@Override 
public void onConnectionSuspended(int cause) { 
    Log.i(Alarm.TAG, "Connection suspended"); 
    mGoogleApiClient.connect(); 
} // end onConnectionSuspended(int cause) 

// ON CONNECTION FAILED 
// *********************** 
@Override 
public void onConnectionFailed(ConnectionResult result) { 
    Log.i(Alarm.TAG, 
      "Connection failed: ConnectionResult.getErrorCode() = " 
        + result.getErrorCode()); 
} // end onConnectionFailed(ConnectionResult result) 

// BUILD GOOGLE API CLIENT 
// ************************** 
protected synchronized void buildGoogleApiClient() { 
    Log.i(Alarm.TAG, "Building GoogleApiClient"); 

    mlocListener = this; 
    connCallbacks = this; 
    connFailedListener = this; 

    mGoogleApiClient = new GoogleApiClient.Builder(this) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .addApi(LocationServices.API).build(); 

    createLocationRequest(); 
} // end buildGoogleApiClient() 

// CREATE LOCATION REQUEST 
// ************************** 
protected void createLocationRequest() { 
    mLocationRequest = new LocationRequest(); 
    mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS); 
    mLocationRequest 
      .setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS); 
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
} // end createLocationRequest() 

// ON BIND 
// ********** 
@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 

// BROADCAST LOCATION FOUND 
// *************************** 
public void broadcastLocationFound(Location location) { 
    Intent intent = new Intent(
      "com.diligencedojo.tabsitter.geolocation.service"); 
    intent.putExtra("latitude", location.getLatitude()); 
    intent.putExtra("longitude", location.getLongitude()); 
    intent.putExtra("done", 1); 
    // // 
    sendBroadcast(intent); 
} // end broadcastLocationFound(Location location) 

// ON RESULT 
// ************ 
public void onResult(Status status) { 
    if (status.isSuccess()) { 
     Toast.makeText(getApplicationContext(), 
       getString(R.string.geofences_added), Toast.LENGTH_SHORT) 
       .show(); 

     TinyDB tinydb = new TinyDB(getApplicationContext()); 
     tinydb.putBoolean("mapReady", true); 
    } else { 
     Alarm.geofencesAlreadyRegistered = false; 
     String errorMessage = getErrorString(this, status.getStatusCode()); 
     Toast.makeText(getApplicationContext(), errorMessage, 
       Toast.LENGTH_SHORT).show(); 
    } 
} // end onResult(Status status) 

// GET ERROR STRING 
// ******************* 
public static String getErrorString(Context context, int errorCode) { 
    Resources mResources = context.getResources(); 

    switch (errorCode) { 
    case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE: 
     return mResources.getString(R.string.geofence_not_available); 
    case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES: 
     return mResources.getString(R.string.geofence_too_many_geofences); 
    case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS: 
     return mResources 
       .getString(R.string.geofence_too_many_pending_intents); 
    default: 
     return mResources.getString(R.string.unknown_geofence_error); 

    } // end switch (errorCode) 
} // end getErrorString(Context context, int errorCode) 

} // end GeolocationService Class 

MapFragment где фактическая карта, маркер, и геозонность:

public class MapFragment extends Fragment { 
protected SupportMapFragment mapFragment; 
protected GoogleMap map; 
protected Marker myPositionMarker; 
Double latitude, longitude = 0.0; 
Integer transition = 0; 
float radius = 0; 
long expiration = 0; 
Handler handler; 
HashMap<String, SimpleGeofence> geofences; 
Button lobbyBtn, startTabBtn, settingsBtn; 
private Bundle savedState = null; 
Context mContext; 
boolean mapOpen = false; 
public static BroadcastReceiver mReceiver; 
public static FragmentActivity fAct; 

private BroadcastReceiver receiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     Bundle bundle = intent.getExtras(); 

     if (bundle != null) { 
      int resultCode = bundle.getInt("done"); 

      if (resultCode == 1) { 
       latitude = bundle.getDouble("latitude"); 
       longitude = bundle.getDouble("longitude"); 

       updateMarker(latitude, longitude, context); 
      } // end if (resultCode == 1) 

     } // end if (bundle != null) 
    } // end onReceive(Context context, Intent intent) 
}; // end BroadcastReceiver receiver = new BroadcastReceiver() 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    setRetainInstance(true); 
    setHasOptionsMenu(true); 

    super.onCreate(savedInstanceState); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    View rootView = inflater.inflate(R.layout.fragment_map, container, 
      false); 

    mapFragment = SupportMapFragment.newInstance(); 

    FragmentTransaction fragmentTransaction = getChildFragmentManager() 
      .beginTransaction(); 
    fragmentTransaction.add(R.id.map_container, mapFragment); 
    fragmentTransaction.commit(); 

    startTabBtn = (Button) rootView.findViewById(R.id.calculator_button); 
    lobbyBtn = (Button) rootView.findViewById(R.id.lobby_button); 
    settingsBtn = (Button) rootView.findViewById(R.id.settings_button); 

    lobbyBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent toLobby = new Intent(v.getContext(), Lobby.class); 
      startActivity(toLobby); 
     } 
    }); 

    startTabBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent toCalc = new Intent(v.getContext(), CurrentTab.class); 
      startActivity(toCalc); 
     } 
    }); 

    settingsBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent toCalc = new Intent(v.getContext(), StartTab.class); 
      startActivity(toCalc); 
     } 
    }); 

    return rootView; 
} // end onCreateView 

// ON PAUSE 
// *********** 
@Override 
public void onPause() { 
    super.onPause(); 
    fAct = getActivity(); 
    getActivity().unregisterReceiver(receiver); 
} 

// ON RESUME 
// ************ 
@Override 
public void onResume() { 
    super.onResume(); 

    if (mapFragment != null) { 

     if (map != null) 
      map.animateCamera(CameraUpdateFactory.zoomTo(15)); 

     mapFragment.getMapAsync(new OnMapReadyCallback() { 

      @Override 
      public void onMapReady(GoogleMap googleMap) { 
       map = googleMap; 
       map.animateCamera(CameraUpdateFactory.zoomTo(15)); 

      } // end onMapReady(GoogleMap googleMap) 

     }); // end mapFragment.getMapAsync(new OnMapReadyCallback() 
    } // end if (mapFragment != null) 

    mReceiver = receiver; 

    getActivity().registerReceiver(
      receiver, 
      new IntentFilter(
        "com.diligencedojo.tabsitter.geolocation.service")); 
} // end onResume() 

// DISPLAY GEOFENCE 
// ******************* 
protected void displayGeofences() { 
    geofences = SimpleGeofenceStore.getInstance().getSimpleGeofences(); 

    // set circle around marker 
    for (Map.Entry<String, SimpleGeofence> item : geofences.entrySet()) { 
     SimpleGeofence sg = item.getValue(); 

     CircleOptions circleOptions1 = new CircleOptions() 
       .center(new LatLng(sg.getLatitude(), sg.getLongitude())) 
       .radius(sg.getRadius()).strokeColor(Color.BLACK) 
       .strokeWidth(2).fillColor(0x500000ff); 

     map.addCircle(circleOptions1); 
    } 

} // end displayGeofences() 

// CREATE MARKER 
// **************** 
protected void createMarker(Double latitude, Double longitude, 
     Context context) { 
    LatLng latLng = new LatLng(latitude, longitude); 

    myPositionMarker = map.addMarker(new MarkerOptions().position(latLng)); 
    map.moveCamera(CameraUpdateFactory.newLatLng(latLng)); 
    // display the geofence after the marker is placed to ensure that the 
    // map is being displayed successfully 
    displayGeofences(); 

    // save the state of the map (if it's open or not) 
    TinyDB tinydb = new TinyDB(context); 
    tinydb.putBoolean("mapOpen", true); 
    tinydb.putDouble("latitude", latitude); 
    tinydb.putDouble("longitude", longitude); 
} 

// UPDATE MARKER 
// **************** 
protected void updateMarker(Double latitude, Double longitude, 
     Context context) { 
    if (myPositionMarker == null) 
     createMarker(latitude, longitude, context); 

    LatLng latLng = new LatLng(latitude, longitude); 
    myPositionMarker.setPosition(latLng); 
    map.moveCamera(CameraUpdateFactory.newLatLng(latLng)); 
} 

// ON CREATE OPTIONS MENU 
// ************************* 
@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    super.onCreateOptionsMenu(menu, inflater); 
    inflater.inflate(R.menu.menu_map, menu); 
} 

// ON OPTIONS SELECTED 
// ********************** 
@Override 
public boolean onOptionsItemSelected(MenuItem item) { 

    return super.onOptionsItemSelected(item); 
} 

} // end MapFragment Class 

Деятельность CloseTab где я хочу остановить любой сервис GPS, который использует приложение. Я пробовал много разных подходов, так что нести свой код.

public class CloseTab extends Activity { 
Button numDrinksBtn, estBillBtn, avgCostBtn, tipAmtBtn, totBillBtn, 
     dismissBtn; 
TextView tipExpl; 
int currDrinkTotal = 0; 
double currTabTotal, currTipTotal, tipAmt = 0.0; 
boolean isSobriety, isSaver, isCount = false; 
GoogleApiClient mGoogleApiClient; 
SimpleGeofence sg; 
LocationListener mlocListener; 
LocationManager locationManager; 
android.location.LocationListener mlocListenerProvider; 
PendingIntent mPendingIntent; 
ConnectionCallbacks mConnCallbacks; 
OnConnectionFailedListener mConnFailedListener; 
BroadcastReceiver mReceiver; 
FragmentActivity fAct; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.close_tab_layout); 

    numDrinksBtn = (Button) findViewById(R.id.num_drinks_amout); 
    estBillBtn = (Button) findViewById(R.id.est_bill_amout); 
    avgCostBtn = (Button) findViewById(R.id.avg_cost_amout); 
    tipExpl = (TextView) findViewById(R.id.tip_expl_text); 
    tipAmtBtn = (Button) findViewById(R.id.total_tip_amount); 
    totBillBtn = (Button) findViewById(R.id.total_bill_amout); 
    dismissBtn = (Button) findViewById(R.id.dismiss_button); 

    getSavedValues(); // populate view with saved values 

    // DISMISS BUTTON 
    dismissBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      mGoogleApiClient = GeolocationService.mGoogleApiClientStatic; 
      if (mGoogleApiClient.isConnected()) { 
       mlocListener = GeolocationService.mlocListener; 
       locationManager = GeolocationService.mlocManager; 
       mlocListenerProvider =      GeolocationService.mlocListenerProvider; 
       mPendingIntent = GeolocationService.pendingIntent; 
       mConnCallbacks = GeolocationService.connCallbacks; 
       mConnFailedListener = GeolocationService.connFailedListener; 
       LocationServices.FusedLocationApi.removeLocationUpdates(
         mGoogleApiClient, mlocListener); 
       LocationServices.GeofencingApi.removeGeofences(
         mGoogleApiClient, mPendingIntent); 
       locationManager.removeUpdates(mlocListenerProvider); 
       mGoogleApiClient 
         .unregisterConnectionCallbacks(mConnCallbacks); 
       mGoogleApiClient 
         .unregisterConnectionFailedListener(mConnFailedListener); 
       // mGoogleApiClient.stopAutoManage(f); 
       // mReceiver.abortBroadcast(); 
       // fAct = MapFragment.fAct; 
       // mGoogleApiClient.stopAutoManage(fAct); 
       // mReceiver = MapFragment.mReceiver; 
       // fAct.unregisterReceiver(mReceiver); 
       mGoogleApiClient.disconnect(); 
      } 

      turnGPSOff(); 

      Intent intent = new Intent(
        "android.location.GPS_ENABLED_CHANGE"); 
      intent.putExtra("enabled", false); 
      sendBroadcast(intent); 

      ActivityManager am = (ActivityManager) getSystemService(Activity.ACTIVITY_SERVICE); 
      am.killBackgroundProcesses("com.diligencedojo.tabsitter"); 
      am.getRunningServices(100).clear(); 
      am.getRunningAppProcesses().clear(); 

      // clear all saved values 
      TinyDB tinydb = new TinyDB(getApplicationContext()); 
      tinydb.clear(); 

      finish(); 
      startActivity(getIntent()); 

      Intent toLobby = new Intent(v.getContext(), Lobby.class); 
      startActivity(toLobby); 
     } 
    }); 

} // end onCreate 

// automatic turn off the gps 
public void turnGPSOff() { 
    Context ctx = getApplicationContext(); 
    // CloseTab.this 
    String provider = Settings.Secure.getString(ctx.getContentResolver(), 
      Settings.Secure.LOCATION_PROVIDERS_ALLOWED); 

    if (provider.contains("gps")) { // if gps is enabled 
     // Toast.makeText(getApplicationContext(), 
     // "in->provider.contains(gps)", Toast.LENGTH_SHORT).show(); 

     final Intent poke = new Intent(); 
     poke.setClassName("com.android.settings", 
       "com.android.settings.widget.SettingsAppWidgetProvider"); 
     poke.addCategory(Intent.CATEGORY_ALTERNATIVE); 
     poke.setData(Uri.parse("3")); 
     ctx.sendBroadcast(poke); 
     // CloseTab.this.sendBroadcast(poke); 
    } 
} 
.......... 

Эти классы, которые я использую для моего геозоны:

SimpleGeofence класса

public class SimpleGeofence { 
private final String id; 
private double latitude; 
private double longitude; 
private final float radius; 
private long expirationDuration; 
private int transitionType; 
private int loiteringDelay = 60000; 

public SimpleGeofence(String geofenceId, double latitude, double longitude, 
     float radius, long expiration, int transition) { 
    this.id = geofenceId; 
    this.latitude = latitude; 
    this.longitude = longitude; 
    this.radius = radius; 
    this.expirationDuration = expiration; 
    this.transitionType = transition; 
} 

public String getId() { 
    return id; 
} 

public void setLatitude(Double mLat) { 
    this.latitude = mLat; 
} 

public double getLatitude() { 
    return latitude; 
} 

public void setLongitude(Double mLong) { 
    this.longitude = mLong; 
} 

public double getLongitude() { 
    return longitude; 
} 

public float getRadius() { 
    return radius; 
} 

public void setExpirationDuration(long mExpirationDuration) { 
    this.expirationDuration = mExpirationDuration; 
} 

public long getExpirationDuration() { 
    return expirationDuration; 
} 

public int getTransitionType() { 
    return transitionType; 
} 

public Geofence toGeofence() { 
    Geofence g = new Geofence.Builder().setRequestId(getId()) 
      .setTransitionTypes(transitionType) 
      .setCircularRegion(getLatitude(), getLongitude(), getRadius()) 
      .setExpirationDuration(expirationDuration) 
      .setLoiteringDelay(loiteringDelay).build(); 
    return g; 
} 

} // end SimpleGefence Class 

SimpleGeofenceStore Класс

public class SimpleGeofenceStore { 
private static final long GEOFENCE_EXPIRATION_IN_HOURS = 12; 
private static final long RADIUS = 100; 
public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS = GEOFENCE_EXPIRATION_IN_HOURS 
     * DateUtils.HOUR_IN_MILLIS; 
protected HashMap<String, SimpleGeofence> geofences = new HashMap<String, SimpleGeofence>(); 
private static SimpleGeofenceStore instance = new SimpleGeofenceStore(); 
private double latitude; 
private double longitude; 

public static SimpleGeofenceStore getInstance() { 
    // mContext = context; 
    return instance; 
} 

public void setLatLong(Double mLat, Double mLong) { 
    this.latitude = mLat; 
    this.longitude = mLong; 
} 

public Double getLatitude() { 
    return latitude; 
} 

public Double getLongitude() { 
    return longitude; 
} 

private SimpleGeofenceStore() { 

    geofences.put("My House", new SimpleGeofence("My House", getLatitude(), 
      getLongitude(), RADIUS, GEOFENCE_EXPIRATION_IN_MILLISECONDS, 
      Geofence.GEOFENCE_TRANSITION_ENTER 
        | Geofence.GEOFENCE_TRANSITION_DWELL 
        | Geofence.GEOFENCE_TRANSITION_EXIT)); 

} 

public HashMap<String, SimpleGeofence> getSimpleGeofences() { 
    return this.geofences; 
} 

} // end SimpleGeofenceStore Class 
+0

просто прекратите обслуживание и прекратите все сервисы Google Play, связанные с onDestroy службы – tyczj

+0

Основываясь на моем коде в классе GeolocationService, что еще я должен останавливать в onDestroy()?Я просто попытался удалить обновления из диспетчера местоположений и отменить ожидающее его намерение. – stormyBrain

+0

Кроме того, чтобы я смог запустить onDestroy() в GeolocationService, вызвав функцию finish() в операции CloseTab? – stormyBrain

ответ

0

Чтобы отключить услуги и процессы местоположение на кнопку нажмите на другую активность, я выполнил следующие шаги. Сначала я определил переменные местоположения в GeolocationServices.java как общедоступные и статические. Это позволяет вам получить доступ к ним в других действиях. Затем я поместил логическую переменную «tabClosed» вокруг всего, что потенциально могло бы повторно подключить GoogleApiClient после того, как оно было отключено. Я не совсем уверен, что мне это нужно.

GeolocationServices.java

public class GeolocationService extends Service implements ConnectionCallbacks, 
    OnConnectionFailedListener, LocationListener, ResultCallback<Status> { 
// TinyDB saved value handles: (boolean)"mapReady" 
LocationListener listener; 
private static final long GEOFENCE_EXPIRATION_IN_HOURS = 12; 
private static final long RADIUS = 100; 
public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS = GEOFENCE_EXPIRATION_IN_HOURS 
     * DateUtils.HOUR_IN_MILLIS; 
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000; 
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS/5; 
// protected GoogleApiClient mGoogleApiClient; 
public static GoogleApiClient mGoogleApiClient; 
protected LocationRequest mLocationRequest; 
// private PendingIntent mPendingIntent; 
public static PendingIntent mPendingIntent; 
List<Geofence> mGeofenceList; 
SimpleGeofence simpleGeo; 
Location mLocation, newLocation; 
public static LocationManager mlocManager; 
public static LocationListener mlocListener; 
public static ConnectionCallbacks connCallbacks; 
public static OnConnectionFailedListener connFailedListener; 
public static ResultCallback<Status> mGeoCallback; 

// ON START 
// *********** 
@Override 
public void onStart(Intent intent, int startId) { 
    TinyDB tinydb = new TinyDB(getApplicationContext()); 
    boolean tabClosed = tinydb.getBoolean("tabClosed"); 

    if (!tabClosed) { 
     buildGoogleApiClient(); 
     mGoogleApiClient.connect(); 
    } 
} 

// ON DESTROY 
// ************* 
@Override 
public void onDestroy() { 
    // super.onDestroy(); 

    if (mGoogleApiClient.isConnected()) { 
     mGoogleApiClient.disconnect(); 
     mlocManager.removeUpdates(mPendingIntent); 
     mlocManager.removeProximityAlert(mPendingIntent); 
     mPendingIntent.cancel(); 
    } 

    super.onDestroy(); 
} 

// REGISTER GEOFENCES 
// ********************* 
protected void registerGeofences(Location location) { 
    if (Alarm.geofencesAlreadyRegistered) 
     return; 

    Log.d(Alarm.TAG, "Registering Geofences"); 

    String geoId = "geoId"; 
    simpleGeo = new SimpleGeofence(geoId, location.getLatitude(), 
      location.getLongitude(), RADIUS, 
      GEOFENCE_EXPIRATION_IN_MILLISECONDS, 
      Geofence.GEOFENCE_TRANSITION_ENTER 
        | Geofence.GEOFENCE_TRANSITION_DWELL 
        | Geofence.GEOFENCE_TRANSITION_EXIT); 

    // // 
    HashMap<String, SimpleGeofence> geofences = SimpleGeofenceStore 
      .getInstance().getSimpleGeofences(); 

    GeofencingRequest.Builder builder = new GeofencingRequest.Builder(); 

    for (Map.Entry<String, SimpleGeofence> item : geofences.entrySet()) { 
     SimpleGeofence sg = item.getValue(); 
     sg.setLatitude(simpleGeo.getLatitude()); 
     sg.setLongitude(simpleGeo.getLongitude()); 
     builder.addGeofence(sg.toGeofence()); 

     SimpleGeofenceStore store = SimpleGeofenceStore.getInstance(); 
     store.setLatLong(simpleGeo.getLatitude(), simpleGeo.getLongitude()); 
     // Log.d(Alarm.TAG, sg.getLatitude() + " " + sg.getLongitude()); 
    } 

    TinyDB tinydb = new TinyDB(getApplicationContext()); 
    tinydb.putBoolean("mapReady", false); 

    GeofencingRequest geofencingRequest = builder.build(); 

    mPendingIntent = requestPendingIntent(); 

    mGeoCallback = this; 

    LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, 
      geofencingRequest, mPendingIntent).setResultCallback(
      mGeoCallback); 

    Alarm.geofencesAlreadyRegistered = true; 
} // end registerGeofences() 

// REQUEST PENDING INTENT 
// ************************* 
private PendingIntent requestPendingIntent() { 
    PendingIntent tempPendingIntent = null; 

    if (null != mPendingIntent) 
     return mPendingIntent; 

    TinyDB tinydb = new TinyDB(getApplicationContext()); 
    boolean tabClosed = tinydb.getBoolean("tabClosed"); 

    if (!tabClosed) { 
     Intent intent = new Intent(this, GeofenceReceiver.class); 
     tempPendingIntent = PendingIntent.getService(this, 0, intent, 
       PendingIntent.FLAG_UPDATE_CURRENT); 
    } 

    return tempPendingIntent; 

} // end requestPendingIntent() 

// BROADCAST LOCATION FOUND 
// *************************** 
public void broadcastLocationFound(Location location) { 
    Intent intent = new Intent(
      "com.diligencedojo.tabsitter.geolocation.service"); 
    intent.putExtra("latitude", location.getLatitude()); 
    intent.putExtra("longitude", location.getLongitude()); 
    intent.putExtra("done", 1); 

    TinyDB tinydb = new TinyDB(getApplicationContext()); 
    boolean tabClosed = tinydb.getBoolean("tabClosed"); 

    if (!tabClosed) 
     sendBroadcast(intent); 

} // end broadcastLocationFound(Location location) 

// START LOCATION UPDATES 
// ************************* 
protected void startLocationUpdates() { 
    TinyDB tinydb = new TinyDB(getApplicationContext()); 
    boolean tabClosed = tinydb.getBoolean("tabClosed"); 

    if (!tabClosed) { // 
     LocationServices.FusedLocationApi.requestLocationUpdates(
       mGoogleApiClient, mLocationRequest, this); 
    } 
} // end startLocationUpdates() 

// STOP LOCATION UPDATES 
// ************************ 
protected void stopLocationUpdates() { 
    LocationServices.FusedLocationApi.removeLocationUpdates(
      mGoogleApiClient, this); 
} // end stopLocationUpdates() 

// ON CONNECTED 
// *************** 
@Override 
public void onConnected(Bundle connectionHint) { 
    Log.i(Alarm.TAG, "Connected to GoogleApiClient"); 
    startLocationUpdates(); 
} // end onConnected(Bundle connectionHint) 

// ON LOCATION CHANGED 
// ********************** 
@Override 
public void onLocationChanged(Location location) { 
    Log.d(Alarm.TAG, "new location : " + location.getLatitude() + ", " 
      + location.getLongitude() + ". " + location.getAccuracy()); 

    TinyDB tinydb = new TinyDB(getApplicationContext()); 
    boolean tabClosed = tinydb.getBoolean("tabClosed"); 

    if (!tabClosed) 
     broadcastLocationFound(location); 

    if (!Alarm.geofencesAlreadyRegistered) 
     registerGeofences(location); 

} // end onLocationChanged(Location location) 

// ON CONNECTION SUSPENDED 
// ************************** 
@Override 
public void onConnectionSuspended(int cause) { 
    Log.i(Alarm.TAG, "Connection suspended"); 

    TinyDB tinydb = new TinyDB(getApplicationContext()); 
    boolean tabClosed = tinydb.getBoolean("tabClosed"); 

    if (!tabClosed) 
     mGoogleApiClient.connect(); 

} // end onConnectionSuspended(int cause) 

// ON CONNECTION FAILED 
// *********************** 
@Override 
public void onConnectionFailed(ConnectionResult result) { 
    Log.i(Alarm.TAG, 
      "Connection failed: ConnectionResult.getErrorCode() = " 
        + result.getErrorCode()); 
} // end onConnectionFailed(ConnectionResult result) 

// BUILD GOOGLE API CLIENT 
// ************************** 
protected synchronized void buildGoogleApiClient() { 
    Log.i(Alarm.TAG, "Building GoogleApiClient"); 

    TinyDB tinydb = new TinyDB(getApplicationContext()); 
    boolean tabClosed = tinydb.getBoolean("tabClosed"); 

    if (!tabClosed) { 
     mlocListener = this; 
     connCallbacks = this; 
     connFailedListener = this; 

     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(connCallbacks) 
       .addOnConnectionFailedListener(connFailedListener) 
       .addApi(LocationServices.API).build(); 

     createLocationRequest(); 
    } 

} // end buildGoogleApiClient() 

// CREATE LOCATION REQUEST 
// ************************** 
protected void createLocationRequest() { 
    TinyDB tinydb = new TinyDB(getApplicationContext()); 
    boolean tabClosed = tinydb.getBoolean("tabClosed"); 

    if (!tabClosed) { 
     mLocationRequest = new LocationRequest(); 
     mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS); 
     mLocationRequest 
       .setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS); 
     mLocationRequest 
       .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    } 

} // end createLocationRequest() 

// ON BIND 
// ********** 
@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 

// ON RESULT 
// ************ 
public void onResult(Status status) { 
    TinyDB tinydb = new TinyDB(getApplicationContext()); 
    boolean tabClosed = tinydb.getBoolean("tabClosed"); 

    if (!tabClosed) { 

     if (status.isSuccess()) { 
      Toast.makeText(getApplicationContext(), 
        getString(R.string.geofences_added), Toast.LENGTH_SHORT) 
        .show(); 

      tinydb.putBoolean("mapReady", true); 
     } else { 
      Alarm.geofencesAlreadyRegistered = false; 
      String errorMessage = getErrorString(this, 
        status.getStatusCode()); 
      Toast.makeText(getApplicationContext(), errorMessage, 
        Toast.LENGTH_SHORT).show(); 
     } 
    } else { 
     Toast.makeText(getApplicationContext(), 
       "Tab closed, do not add geofence.", Toast.LENGTH_SHORT) 
       .show(); 
    } 

} // end onResult(Status status) 

// GET ERROR STRING 
// ******************* 
public static String getErrorString(Context context, int errorCode) { 
    Resources mResources = context.getResources(); 

    switch (errorCode) { 
    case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE: 
     return mResources.getString(R.string.geofence_not_available); 
    case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES: 
     return mResources.getString(R.string.geofence_too_many_geofences); 
    case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS: 
     return mResources 
       .getString(R.string.geofence_too_many_pending_intents); 
    default: 
     return mResources.getString(R.string.unknown_geofence_error); 

    } // end switch (errorCode) 
} // end getErrorString(Context context, int errorCode) 

} // end GeolocationService Class 

Сейчас в CloseTab.java, я восстановил переменные я объявившим открытые статические в GeolocationService.java. При отключении служб определения местоположения важно использовать то же самое ожидающее намерения, что и параметр. Сначала я удалил геозонность, затем обновил местоположение, а затем я отключил клиент google api все вместе. Наконец, я использовал stopService (намерение) для удаления любых затяжных сервисов (например, запущенных в моей MapFragment.java).

public class CloseTab extends Activity { 
Button numDrinksBtn, estBillBtn, avgCostBtn, tipAmtBtn, totBillBtn, 
     dismissBtn; 
TextView tipExpl; 
int currDrinkTotal = 0; 
double currTabTotal, currTipTotal, tipAmt = 0.0; 
boolean isSobriety, isSaver, isCount = false; 
GoogleApiClient mGoogleApiClient; 
PendingIntent mPendingIntent; 
ResultCallback<Status> mGeoCallback; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.close_tab_layout); 

    numDrinksBtn = (Button) findViewById(R.id.num_drinks_amout); 
    estBillBtn = (Button) findViewById(R.id.est_bill_amout); 
    avgCostBtn = (Button) findViewById(R.id.avg_cost_amout); 
    tipExpl = (TextView) findViewById(R.id.tip_expl_text); 
    tipAmtBtn = (Button) findViewById(R.id.total_tip_amount); 
    totBillBtn = (Button) findViewById(R.id.total_bill_amout); 
    dismissBtn = (Button) findViewById(R.id.dismiss_button); 

    getSavedValues(); // populate view with saved values 

    // DISMISS BUTTON 
    dismissBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      mGoogleApiClient = GeolocationService.mGoogleApiClient; 
      if (mGoogleApiClient.isConnected()) { 
       // Log.d("DBG", "mGoogleApiClient.isConnected()"); 

       mPendingIntent = GeolocationService.mPendingIntent; 
       mGeoCallback = GeolocationService.mGeoCallback; 

       try { // Log.d("DBG", "try hit in CloseTab"); 

        // use the same pending intent set in GeolocationService 
        // to identify the right things to disable 

        // Remove geofence 
        LocationServices.GeofencingApi.removeGeofences(
          mGoogleApiClient, mPendingIntent) 
          .setResultCallback(mGeoCallback); 
        // Remove location updates 
        LocationServices.FusedLocationApi 
          .removeLocationUpdates(mGoogleApiClient, 
            mPendingIntent); 
        // Disconnect google client 
        mGoogleApiClient.disconnect(); 

        // Remove any lingering services 
        Intent intent = new Intent(getApplicationContext(), 
          GeolocationService.class); 
        stopService(intent); 

       } catch (SecurityException securityException) { 
        // Catch exception generated if the app does not use 
        // ACCESS_FINE_LOCATION permission. 
        Log.d("DBG", "catch hit in CloseTab"); 
       } 
      } 

      // clear all saved values 
      TinyDB tinydb = new TinyDB(getApplicationContext()); 
      tinydb.clear(); 
      // tab has been closed. this is used as a condition to determine 
      // if gps should be allowed to reconnect on it's own 
      tinydb.putBoolean("tabClosed", true); 

      Intent toLobby = new Intent(v.getContext(), Lobby.class); 
      startActivity(toLobby); 
     } 
    }); 

}// end onCreate 

Надеюсь, это поможет кому-то еще.

+0

Еще одна вещь, которую я сделал, - поместить location.reset() в методы broadcastLocationFound() и onLocationChanged(), чтобы очистить местоположение. – stormyBrain

Смежные вопросы