Java tutorial
/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.geofence; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.text.TextUtils; import android.text.format.DateUtils; import com.example.android.geofence.GeofenceUtils.REMOVE_TYPE; import com.example.android.geofence.GeofenceUtils.REQUEST_TYPE; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.location.Geofence; import java.util.ArrayList; import java.util.List; import org.apache.cordova.api.CallbackContext; import org.apache.cordova.api.CordovaPlugin; import org.json.JSONArray; import org.json.JSONException; /** * UI handler for the Location Services Geofence sample app. * Allow input of latitude, longitude, and radius for two geofences. * When registering geofences, check input and then send the geofences to Location Services. * Also allow removing either one of or both of the geofences. * The menu allows you to clear the screen or delete the geofences stored in persistent memory. */ public class DGGeofencing extends CordovaPlugin { /* * Use to set an expiration time for a geofence. After this amount * of time Location Services will stop tracking the geofence. * Remember to unregister a geofence when you're finished with it. * Otherwise, your app will use up battery. To continue monitoring * a geofence indefinitely, set the expiration time to * Geofence#NEVER_EXPIRE. */ private static final long GEOFENCE_EXPIRATION_IN_HOURS = 1200; private static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS = GEOFENCE_EXPIRATION_IN_HOURS * DateUtils.HOUR_IN_MILLIS; // Store the current request private REQUEST_TYPE mRequestType; // Store the current type of removal private REMOVE_TYPE mRemoveType; // Store a list of geofences to add List<Geofence> mCurrentGeofences; // Add geofences handler private GeofenceRequester mGeofenceRequester; // Remove geofences handler private GeofenceRemover mGeofenceRemover; /* * Internal lightweight geofence objects for geofence 1 and 2 */ private SimpleGeofence mUIGeofence1; // An intent filter for the broadcast receiver private IntentFilter mIntentFilter; // Store the list of geofences to remove private List<String> mGeofenceIdsToRemove; public static CallbackContext cbContext; @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { if (action.equalsIgnoreCase("initCallbackForRegionMonitoring")) { cbContext = callbackContext; } else if (action.equalsIgnoreCase("startMonitoringRegion")) { // Create an intent filter for the broadcast receiver mIntentFilter = new IntentFilter(); // Action for broadcast Intents that report successful addition of geofences mIntentFilter.addAction(GeofenceUtils.ACTION_GEOFENCES_ADDED); // Action for broadcast Intents that report successful removal of geofences mIntentFilter.addAction(GeofenceUtils.ACTION_GEOFENCES_REMOVED); // Action for broadcast Intents containing various types of geofencing errors mIntentFilter.addAction(GeofenceUtils.ACTION_GEOFENCE_ERROR); // All Location Services sample apps use this category mIntentFilter.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES); // Instantiate the current List of geofences mCurrentGeofences = new ArrayList<Geofence>(); // Instantiate a Geofence requester mGeofenceRequester = new GeofenceRequester(this.cordova.getActivity()); // Instantiate a Geofence remover mGeofenceRemover = new GeofenceRemover(this.cordova.getActivity()); // Attach to the main UI //setContentView(R.layout.activity_main); /* * Record the request as an ADD. If a connection error occurs, * the app can automatically restart the add request if Google Play services * can fix the error */ mRequestType = GeofenceUtils.REQUEST_TYPE.ADD; /* * Check for Google Play services. Do this after * setting the request type. If connecting to Google Play services * fails, onActivityResult is eventually called, and it needs to * know what type of request was in progress. */ if (!servicesConnected()) { return false; } /* * Create a version of geofence 1 that is "flattened" into individual fields. This * allows it to be stored in SharedPreferences. */ double lat = Double.valueOf(args.getString(1)); double lng = Double.valueOf(args.getString(2)); float radius = Float.valueOf(args.getString(3)); mUIGeofence1 = new SimpleGeofence("1", // Get latitude, longitude, and radius from the UI lat, lng, radius, // Set the expiration time GEOFENCE_EXPIRATION_IN_MILLISECONDS, // Only detect entry transitions Geofence.GEOFENCE_TRANSITION_ENTER); /* * Add Geofence objects to a List. toGeofence() * creates a Location Services Geofence object from a * flat object */ mCurrentGeofences.add(mUIGeofence1.toGeofence()); // Start the request. Fail if there's already a request in progress try { // Try to add geofences mGeofenceRequester.addGeofences(mCurrentGeofences); } catch (UnsupportedOperationException e) { // Notify user that previous request hasn't finished. } } return true; } /* * Handle results returned to this Activity by other Activities started with * startActivityForResult(). In particular, the method onConnectionFailed() in * GeofenceRemover and GeofenceRequester may call startResolutionForResult() to * start an Activity that handles Google Play services problems. The result of this * call returns here, to onActivityResult. * calls */ @Override public void onActivityResult(int requestCode, int resultCode, Intent intent) { // Choose what to do based on the request code switch (requestCode) { // If the request code matches the code sent in onConnectionFailed case GeofenceUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST: switch (resultCode) { // If Google Play services resolved the problem case Activity.RESULT_OK: // If the request was to add geofences if (GeofenceUtils.REQUEST_TYPE.ADD == mRequestType) { // Toggle the request flag and send a new request mGeofenceRequester.setInProgressFlag(false); // Restart the process of adding the current geofences mGeofenceRequester.addGeofences(mCurrentGeofences); // If the request was to remove geofences } else if (GeofenceUtils.REQUEST_TYPE.REMOVE == mRequestType) { // Toggle the removal flag and send a new removal request mGeofenceRemover.setInProgressFlag(false); // If the removal was by Intent if (GeofenceUtils.REMOVE_TYPE.INTENT == mRemoveType) { // Restart the removal of all geofences for the PendingIntent mGeofenceRemover.removeGeofencesByIntent(mGeofenceRequester.getRequestPendingIntent()); // If the removal was by a List of geofence IDs } else { // Restart the removal of the geofence list mGeofenceRemover.removeGeofencesById(mGeofenceIdsToRemove); } } break; // If any other result was returned by Google Play services default: // Report that Google Play services was unable to resolve the problem. } // If any other request code was received default: // Report that this Activity received an unknown requestCode break; } } /** * Verify that Google Play services is available before making a request. * * @return true if Google Play services is available, otherwise false */ private boolean servicesConnected() { // Check that Google Play services is available int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this.cordova.getActivity()); // If Google Play services is available if (ConnectionResult.SUCCESS == resultCode) { // Continue return true; // Google Play services was not available for some reason } else { return false; } } /** * Define a Broadcast receiver that receives updates from connection listeners and * the geofence transition service. */ public class GeofenceSampleReceiver extends BroadcastReceiver { /* * Define the required method for broadcast receivers * This method is invoked when a broadcast Intent triggers the receiver */ @Override public void onReceive(Context context, Intent intent) { // Check the action code and determine what to do String action = intent.getAction(); // Intent contains information about errors in adding or removing geofences if (TextUtils.equals(action, GeofenceUtils.ACTION_GEOFENCE_ERROR)) { handleGeofenceError(context, intent); // Intent contains information about successful addition or removal of geofences } else if (TextUtils.equals(action, GeofenceUtils.ACTION_GEOFENCES_ADDED) || TextUtils.equals(action, GeofenceUtils.ACTION_GEOFENCES_REMOVED)) { handleGeofenceStatus(context, intent); // Intent contains information about a geofence transition } else if (TextUtils.equals(action, GeofenceUtils.ACTION_GEOFENCE_TRANSITION)) { handleGeofenceTransition(context, intent); // The Intent contained an invalid action } else { } } /** * If you want to display a UI message about adding or removing geofences, put it here. * * @param context A Context for this component * @param intent The received broadcast Intent */ private void handleGeofenceStatus(Context context, Intent intent) { } /** * Report geofence transitions to the UI * * @param context A Context for this component * @param intent The Intent containing the transition */ private void handleGeofenceTransition(Context context, Intent intent) { /* * If you want to change the UI when a transition occurs, put the code * here. The current design of the app uses a notification to inform the * user that a transition has occurred. */ } /** * Report addition or removal errors to the UI, using a Toast * * @param intent A broadcast Intent sent by ReceiveTransitionsIntentService */ private void handleGeofenceError(Context context, Intent intent) { } } }