Java tutorial
/** * Copyright 2017-today Manuel de la Pea * * 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 es.mdelapenya.uned.master.is.ubicomp.sensors.activities.location; import android.Manifest; import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.location.Location; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.telephony.TelephonyManager; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; import es.mdelapenya.uned.master.is.ubicomp.sensors.activities.BaseAndroidBusRegistrableActivity; import es.mdelapenya.uned.master.is.ubicomp.sensors.interactors.SensorsInteractor; import es.mdelapenya.uned.master.is.ubicomp.sensors.interactors.SensorsMetricInteractor; import es.mdelapenya.uned.master.is.ubicomp.sensors.pojo.Metric; import es.mdelapenya.uned.master.is.ubicomp.sensors.pojo.SensorMetric; import es.mdelapenya.uned.master.is.ubicomp.sensors.util.SpeedConverter; import java.util.Date; import java.util.UUID; /** * @author Manuel de la Pea */ public class BaseGeoLocatedActivity extends BaseAndroidBusRegistrableActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { @Override public void onConnected(Bundle bundle) { lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient); LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, GPS_REQUEST, this); } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { } @Override public void onConnectionSuspended(int i) { } @Override public void onLocationChanged(Location location) { Location currentLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient); double speed = 0; if (lastLocation != null) { speed = Math .sqrt(Math.pow(currentLocation.getLongitude() - lastLocation.getLongitude(), 2) + Math.pow(currentLocation.getLatitude() - lastLocation.getLatitude(), 2)) / (currentLocation.getTime() - lastLocation.getTime()); if (currentLocation.hasSpeed()) { speed = currentLocation.getSpeed(); } this.speed = new Float(speed); lastLocation = currentLocation; Metric metric = new SensorMetric(uniqueDeviceId, "sensors-android", currentLocation.getLatitude(), currentLocation.getLongitude(), SpeedConverter.convertToKmsh(this.speed), "speed", "km/h", new Date().getTime()); SensorsInteractor sensorsInteractor = new SensorsMetricInteractor(metric); new Thread(sensorsInteractor).start(); } } protected float getSpeed() { return speed; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode != REQUEST_CODE_RECOVER_PLAY_SERVICES) { return; } if (resultCode == RESULT_OK) { if (!googleApiClient.isConnecting() && !googleApiClient.isConnected()) { googleApiClient.connect(); } } else if (resultCode == RESULT_CANCELED) { Toast.makeText(this, "Google Play Services must be installed.", Toast.LENGTH_SHORT).show(); finish(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initializeGooglePlayServices(); if (uniqueDeviceId == null) { uniqueDeviceId = getUniqueDeviceId(); } } @Override protected void onPause() { if (googleApiClient != null) { googleApiClient.disconnect(); } super.onPause(); } @Override protected void onResume() { super.onResume(); if (googleApiClient != null) { googleApiClient.connect(); } } private void checkRuntimePermission(String permission) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) { // Show an expanation to the user *asynchronously* -- don't block // this thread waiting for the user's response! After the user // sees the explanation, try again to request the permission. } else { ActivityCompat.requestPermissions(this, new String[] { permission }, PERMISSION_REQUEST_READ_FINE_LOCATION); // PERMISSION_REQUEST_READ_FINE_LOCATION is an // app-defined int constant. The callback method gets the // result of the request. } } } private void checkRuntimePermissions() { String[] permissions = { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.INTERNET, Manifest.permission.READ_PHONE_STATE }; for (String permission : permissions) { checkRuntimePermission(permission); } } private String getUniqueDeviceId() { TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); final String deviceId = telephonyManager.getDeviceId(); final String simSerialNumber = telephonyManager.getSimSerialNumber(); final String androidId = android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID); UUID deviceUuid = new UUID(androidId.hashCode(), ((long) deviceId.hashCode() << 32) | simSerialNumber.hashCode()); return deviceUuid.toString(); } private void initializeGooglePlayServices() { checkRuntimePermissions(); GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance(); int checkGooglePlayServices = googleApiAvailability.isGooglePlayServicesAvailable(this); if (checkGooglePlayServices != ConnectionResult.SUCCESS) { /* * google play services is missing or update is required * return code could be * SUCCESS, * SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, * SERVICE_DISABLED, SERVICE_INVALID. */ Dialog errorDialog = googleApiAvailability.getErrorDialog(this, checkGooglePlayServices, REQUEST_CODE_RECOVER_PLAY_SERVICES); errorDialog.show(); return; } googleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this) .addOnConnectionFailedListener(this).addApi(LocationServices.API).build(); } private static final LocationRequest GPS_REQUEST = LocationRequest.create().setInterval(10000) .setFastestInterval(3000).setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); private static final int PERMISSION_REQUEST_READ_FINE_LOCATION = 1111; private static int REQUEST_CODE_RECOVER_PLAY_SERVICES = 200; private GoogleApiClient googleApiClient; private Location lastLocation; private float speed; private String uniqueDeviceId; }