diff options
author | Roman Birg <roman@cyngn.com> | 2014-04-10 11:55:53 -0700 |
---|---|---|
committer | Roman Birg <roman@cyngn.com> | 2014-04-10 11:56:43 -0700 |
commit | 8202614dfec7f47f24f82148143a4f33bfa9d288 (patch) | |
tree | a396030b7c7e7ad0f7093a186e87a68ea97a8367 | |
parent | 4cc937ce3ad35156ad2c49e1dc1071d4d8b13ed4 (diff) | |
download | android_packages_apps_LockClock-8202614dfec7f47f24f82148143a4f33bfa9d288.tar.gz android_packages_apps_LockClock-8202614dfec7f47f24f82148143a4f33bfa9d288.tar.bz2 android_packages_apps_LockClock-8202614dfec7f47f24f82148143a4f33bfa9d288.zip |
LockClock: add a content provider for weather
Change-Id: I9117232cacbb9683e4f48ce741e8d86a4e49c618
Signed-off-by: Roman Birg <roman@cyngn.com>
4 files changed, 214 insertions, 0 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index b0d65de..8cf49ad 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -23,6 +23,8 @@ android:minSdkVersion="16" android:targetSdkVersion="19" /> + <permission android:name="com.cyanogenmod.lockclock.permission.READ_WEATHER" /> + <!-- Weather --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> @@ -94,6 +96,21 @@ android:permission="android.permission.BIND_REMOTEVIEWS"> </service> + <provider + android:name=".weather.WeatherContentProvider" + android:authorities="com.cyanogenmod.lockclock.weather.provider" + android:exported="true" + android:readPermission="com.cyanogenmod.lockclock.permission.READ_WEATHER" /> + <reciever + android:name=".weather.ExternalWeatherUpdateReceiver" + android:exported="true" + android:permission="com.cyanogenmod.lockclock.permission.READ_WEATHER"> + <intent-filter> + <action android:name="com.cyanogenmod.lockclock.action.FORCE_WEATHER_UPDATE" /> + <action android:name="com.cyanogenmod.lockclock.action.REQUEST_WEATHER_UPDATE" /> + </intent-filter> + </reciever> + </application> </manifest> diff --git a/src/com/cyanogenmod/lockclock/weather/ExternalWeatherUpdateReceiver.java b/src/com/cyanogenmod/lockclock/weather/ExternalWeatherUpdateReceiver.java new file mode 100644 index 0000000..bf2e59e --- /dev/null +++ b/src/com/cyanogenmod/lockclock/weather/ExternalWeatherUpdateReceiver.java @@ -0,0 +1,20 @@ +package com.cyanogenmod.lockclock.weather; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +public class ExternalWeatherUpdateReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if("com.cyanogenmod.lockclock.action.FORCE_WEATHER_UPDATE".equals(action)) { + context.startService(new Intent("com.cyanogenmod.lockclock.action.FORCE_WEATHER_UPDATE").setClass(context, WeatherUpdateService.class)); + } else if ("com.cyanogenmod.lockclock.action.REQUEST_WEATHER_UPDATE".equals(action)) { + context.startService(new Intent().setClass(context, WeatherUpdateService.class)); + } + } + +} diff --git a/src/com/cyanogenmod/lockclock/weather/WeatherContentProvider.java b/src/com/cyanogenmod/lockclock/weather/WeatherContentProvider.java new file mode 100644 index 0000000..dec65f1 --- /dev/null +++ b/src/com/cyanogenmod/lockclock/weather/WeatherContentProvider.java @@ -0,0 +1,175 @@ + +package com.cyanogenmod.lockclock.weather; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.Context; +import android.content.UriMatcher; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.net.Uri; +import android.util.Log; + +import com.cyanogenmod.lockclock.misc.Preferences; +import com.cyanogenmod.lockclock.weather.WeatherInfo.DayForecast; + +public class WeatherContentProvider extends ContentProvider { + + public static final String TAG = WeatherContentProvider.class.getSimpleName(); + private static final boolean DEBUG = false; + + static WeatherInfo sCachedWeatherInfo; + + private static final int URI_TYPE_EVERYTHING = 1; + private static final int URI_TYPE_CURRENT = 2; + private static final int URI_TYPE_FORECAST = 3; + + private static final String COLUMN_CURRENT_CITY_ID = "city_id"; + private static final String COLUMN_CURRENT_CITY = "city"; + private static final String COLUMN_CURRENT_CONDITION = "condition"; + private static final String COLUMN_CURRENT_TEMPERATURE = "temperature"; + private static final String COLUMN_CURRENT_HUMIDITY = "humidity"; + private static final String COLUMN_CURRENT_WIND = "wind"; + private static final String COLUMN_CURRENT_TIME_STAMP = "time_stamp"; + + private static final String COLUMN_FORECAST_LOW = "forecast_low"; + private static final String COLUMN_FORECAST_HIGH = "forecast_high"; + private static final String COLUMN_FORECAST_CONDITION = "forecast_condition"; + + private static final String[] PROJECTION_DEFAULT_CURRENT = new String[] { + COLUMN_CURRENT_CITY_ID, + COLUMN_CURRENT_CITY, + COLUMN_CURRENT_CONDITION, + COLUMN_CURRENT_TEMPERATURE, + COLUMN_CURRENT_HUMIDITY, + COLUMN_CURRENT_WIND, + COLUMN_CURRENT_TIME_STAMP + }; + + private static final String[] PROJECTION_DEFAULT_FORECAST = new String[] { + COLUMN_FORECAST_LOW, + COLUMN_FORECAST_HIGH, + COLUMN_FORECAST_CONDITION, + }; + + private static final String[] PROJECTION_DEFAULT_EVERYTHING = new String[] { + COLUMN_CURRENT_CITY_ID, + COLUMN_CURRENT_CITY, + COLUMN_CURRENT_CONDITION, + COLUMN_CURRENT_TEMPERATURE, + COLUMN_CURRENT_HUMIDITY, + COLUMN_CURRENT_WIND, + COLUMN_CURRENT_TIME_STAMP, + + COLUMN_FORECAST_LOW, + COLUMN_FORECAST_HIGH, + COLUMN_FORECAST_CONDITION, + }; + + public static final String AUTHORITY = "com.cyanogenmod.lockclock.weather.provider"; + + private static final UriMatcher sUriMatcher; + static { + sUriMatcher = new UriMatcher(URI_TYPE_EVERYTHING); + sUriMatcher.addURI(AUTHORITY, "weather", URI_TYPE_EVERYTHING); + sUriMatcher.addURI(AUTHORITY, "weather/current", URI_TYPE_CURRENT); + sUriMatcher.addURI(AUTHORITY, "weather/forecast", URI_TYPE_FORECAST); + } + + private Context mContext; + + @Override + public boolean onCreate() { + mContext = getContext(); + sCachedWeatherInfo = Preferences.getCachedWeatherInfo(mContext); + return true; + } + + @Override + public Cursor query( + Uri uri, + String[] projection, + String selection, + String[] selectionArgs, + String sortOrder) { + + final int projectionType = sUriMatcher.match(uri); + final MatrixCursor result = new MatrixCursor(resolveProjection(projection, projectionType)); + + WeatherInfo weather = sCachedWeatherInfo; + if (weather != null) { + // current + result.newRow() + .add(COLUMN_CURRENT_CITY, weather.getCity()) + .add(COLUMN_CURRENT_CITY_ID, weather.getId()) + .add(COLUMN_CURRENT_CONDITION, weather.getCondition()) + .add(COLUMN_CURRENT_HUMIDITY, weather.getFormattedHumidity()) + .add(COLUMN_CURRENT_WIND, weather.getFormattedWindSpeed() + + " " + weather.getWindDirection()) + .add(COLUMN_CURRENT_TEMPERATURE, weather.getFormattedTemperature()) + .add(COLUMN_CURRENT_TIME_STAMP, weather.getTimestamp().toString()); + + // forecast + for (DayForecast day : weather.getForecasts()) { + result.newRow() + .add(COLUMN_FORECAST_CONDITION, day.getCondition(mContext)) + .add(COLUMN_FORECAST_LOW, day.getFormattedLow()) + .add(COLUMN_FORECAST_HIGH, day.getFormattedHigh()); + } + return result; + } else { + if (DEBUG) Log.e(TAG, "sCachedWeatherInfo is null"); + } + return null; + } + + private String[] resolveProjection(String[] projection, int uriType) { + if (projection != null) + return projection; + switch (uriType) { + default: + case URI_TYPE_EVERYTHING: + return PROJECTION_DEFAULT_EVERYTHING; + + case URI_TYPE_CURRENT: + return PROJECTION_DEFAULT_CURRENT; + + case URI_TYPE_FORECAST: + return PROJECTION_DEFAULT_FORECAST; + } + } + + @Override + public String getType(Uri uri) { + return null; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + return null; + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + return 0; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + return 0; + } + + public static void updateCachedWeatherInfo(Context context, WeatherInfo info) { + if (DEBUG) Log.e(TAG, "updateCachedWeatherInfo()"); + if(info != null) { + if (DEBUG) Log.e(TAG, "set new weather info"); + sCachedWeatherInfo = WeatherInfo.fromSerializedString(context, info.toSerializedString()); + } else { + if(DEBUG) Log.e(TAG, "nulled out cached weather info"); + sCachedWeatherInfo = null; + } + context.getContentResolver().notifyChange( + Uri.parse("content://" + WeatherContentProvider.AUTHORITY + "/weather"), null); + } + +} diff --git a/src/com/cyanogenmod/lockclock/weather/WeatherUpdateService.java b/src/com/cyanogenmod/lockclock/weather/WeatherUpdateService.java index f38c046..d073d8c 100755 --- a/src/com/cyanogenmod/lockclock/weather/WeatherUpdateService.java +++ b/src/com/cyanogenmod/lockclock/weather/WeatherUpdateService.java @@ -26,6 +26,7 @@ import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.location.LocationProvider; +import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.IBinder; @@ -249,6 +250,7 @@ public class WeatherUpdateService extends Service { long interval = 30 * 60 * 1000; scheduleUpdate(mContext, interval, false); } + WeatherContentProvider.updateCachedWeatherInfo(mContext, result); Intent finishedIntent = new Intent(ACTION_UPDATE_FINISHED); finishedIntent.putExtra(EXTRA_UPDATE_CANCELLED, result == null); |