Java tutorial
/* * Copyright (c) 2014 Yehezkel (Zack) Yovel * * 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 zack.yovel.clear.controller.background; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.location.Location; import android.os.Bundle; import android.preference.PreferenceManager; import android.text.TextUtils; import android.util.Log; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesClient; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.location.LocationClient; import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationRequest; import org.joda.time.DateTime; import java.io.FileNotFoundException; import zack.yovel.clear.R; import zack.yovel.clear.infrastructure.networking.geocoding.GeoCoderTask; import zack.yovel.clear.infrastructure.networking.geocoding.LatLng; import zack.yovel.clear.infrastructure.networking.weather.WeatherApiClientFactory; import zack.yovel.clear.infrastructure.networking.weather.WeatherApiClientInterface; import zack.yovel.clear.infrastructure.persist.AWeatherPersistAgent; import zack.yovel.clear.infrastructure.persist.IWeatherPersist; import zack.yovel.clear.util.Constants; public class UserPresentReceiver extends BroadcastReceiver implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener, GeoCoderTask.OnAddressReady { private static final String TAG = "UserPresentReceiver"; private LocationClient locationClient; private Context context; private SharedPreferences preferences; private boolean locationUpdateRequired; @Override public void onReceive(Context context, Intent intent) { this.context = context; initLocationServices(); preferences = PreferenceManager.getDefaultSharedPreferences(context); long lastPersistedWeatherReport = -1;//invalid, will require an update try { IWeatherPersist weatherReportPersistenceAgent = AWeatherPersistAgent.getInstance(); lastPersistedWeatherReport = weatherReportPersistenceAgent.getLastReportTime(context); } catch (FileNotFoundException e) { // do nothing here, the workflow will lead to triggering an update anyway. } DateTime lastUpdate = new DateTime(lastPersistedWeatherReport); if (lastUpdate.plusHours(1).isBeforeNow()) { boolean needCurrentLocation = preferences.getBoolean(Constants.Keys.PREF_MY_LOCATION, true); if (!needCurrentLocation) { String latlng = preferences.getString(Constants.Keys.PREF_LATLNG, null); if (null != latlng) { update(context, latlng); } else { findCurrentLocation(); } } else { findCurrentLocation(); } } } private void initLocationServices() { int available = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context); if (available == ConnectionResult.SUCCESS) { locationClient = new LocationClient(context, this, this); locationClient.connect(); } } private void update(Context context, String latlng) { WeatherApiClientInterface client = WeatherApiClientFactory.getInstance(); client.makeAsyncRequest(context, latlng); } @Override public void onConnected(Bundle bundle) { if (locationUpdateRequired) { requestCurrentLocation(); } } private void requestCurrentLocation() { Location lastLocation = locationClient.getLastLocation(); if (lastLocation != null) { setNewLocation(lastLocation); } else { LocationRequest request = LocationRequest.create(); request.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); int expirationDuration = 30 * 1000; request.setExpirationDuration(expirationDuration); request.setInterval(1000); request.setNumUpdates(1); locationClient.requestLocationUpdates(request, this); } } private void findCurrentLocation() { if (locationClient.isConnected()) { requestCurrentLocation(); } else { this.locationUpdateRequired = true; } } private void setNewLocation(Location location) { String latlng = location.getLatitude() + "," + location.getLongitude(); update(context, latlng); GeoCoderTask geoCoderTask = new GeoCoderTask(context, this); geoCoderTask.execute(new LatLng(location)); } @Override public void onDisconnected() { Log.d(TAG, "Disconnected from location services."); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.d(TAG, "Connection to location services failed with error code: " + connectionResult.getErrorCode()); } @Override public void onLocationChanged(Location location) { setNewLocation(location); } @Override public void onAddressReady(String address) { if (TextUtils.isEmpty(address)) { address = context.getString(R.string.app_name); } SharedPreferences.Editor editor = preferences.edit(); editor.putString(Constants.Keys.PREF_LOCATION_NAME, address); editor.putBoolean(Constants.Keys.PREF_MY_LOCATION, true); editor.commit(); } }