Load real data into the 1x1 Today widget, moving our work to an IntentService
This commit is contained in:
@@ -116,10 +116,12 @@
|
||||
android:label="@string/title_widget_today" >
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
<action android:name="com.example.android.sunshine.app.ACTION_DATA_UPDATED" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.appwidget.provider"
|
||||
android:resource="@xml/widget_info_today" />
|
||||
</receiver>
|
||||
<service android:name=".widget.TodayWidgetIntentService" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -52,6 +52,8 @@ import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class SunshineSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
public final String LOG_TAG = SunshineSyncAdapter.class.getSimpleName();
|
||||
public static final String ACTION_DATA_UPDATED =
|
||||
"com.example.android.sunshine.app.ACTION_DATA_UPDATED";
|
||||
// Interval at which to sync with the weather, in seconds.
|
||||
// 60 seconds (1 minute) * 180 = 3 hours
|
||||
public static final int SYNC_INTERVAL = 60 * 180;
|
||||
@@ -338,6 +340,7 @@ public class SunshineSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
WeatherContract.WeatherEntry.COLUMN_DATE + " <= ?",
|
||||
new String[] {Long.toString(dayTime.setJulianDay(julianStartDay-1))});
|
||||
|
||||
updateWidgets();
|
||||
notifyWeather();
|
||||
}
|
||||
Log.d(LOG_TAG, "Sync Complete. " + cVVector.size() + " Inserted");
|
||||
@@ -350,6 +353,14 @@ public class SunshineSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateWidgets() {
|
||||
Context context = getContext();
|
||||
// Setting the package ensures that only components in our app will receive the broadcast
|
||||
Intent dataUpdatedIntent = new Intent(ACTION_DATA_UPDATED)
|
||||
.setPackage(context.getPackageName());
|
||||
context.sendBroadcast(dataUpdatedIntent);
|
||||
}
|
||||
|
||||
private void notifyWeather() {
|
||||
Context context = getContext();
|
||||
//checking the last update and notify if it' the first of the day
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.sunshine.app.widget;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.IntentService;
|
||||
import android.app.PendingIntent;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import com.example.android.sunshine.app.MainActivity;
|
||||
import com.example.android.sunshine.app.R;
|
||||
import com.example.android.sunshine.app.Utility;
|
||||
import com.example.android.sunshine.app.data.WeatherContract;
|
||||
|
||||
/**
|
||||
* IntentService which handles updating all Today widgets with the latest data
|
||||
*/
|
||||
public class TodayWidgetIntentService extends IntentService {
|
||||
private static final String[] FORECAST_COLUMNS = {
|
||||
WeatherContract.WeatherEntry.COLUMN_WEATHER_ID,
|
||||
WeatherContract.WeatherEntry.COLUMN_SHORT_DESC,
|
||||
WeatherContract.WeatherEntry.COLUMN_MAX_TEMP
|
||||
};
|
||||
// these indices must match the projection
|
||||
private static final int INDEX_WEATHER_ID = 0;
|
||||
private static final int INDEX_SHORT_DESC = 1;
|
||||
private static final int INDEX_MAX_TEMP = 2;
|
||||
|
||||
public TodayWidgetIntentService() {
|
||||
super("TodayWidgetIntentService");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
// Retrieve all of the Today widget ids: these are the widgets we need to update
|
||||
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
|
||||
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(this,
|
||||
TodayWidgetProvider.class));
|
||||
|
||||
// Get today's data from the ContentProvider
|
||||
String location = Utility.getPreferredLocation(this);
|
||||
Uri weatherForLocationUri = WeatherContract.WeatherEntry.buildWeatherLocationWithStartDate(
|
||||
location, System.currentTimeMillis());
|
||||
Cursor data = getContentResolver().query(weatherForLocationUri, FORECAST_COLUMNS, null,
|
||||
null, WeatherContract.WeatherEntry.COLUMN_DATE + " ASC");
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
if (!data.moveToFirst()) {
|
||||
data.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract the weather data from the Cursor
|
||||
int weatherId = data.getInt(INDEX_WEATHER_ID);
|
||||
int weatherArtResourceId = Utility.getArtResourceForWeatherCondition(weatherId);
|
||||
String description = data.getString(INDEX_SHORT_DESC);
|
||||
double maxTemp = data.getDouble(INDEX_MAX_TEMP);
|
||||
String formattedMaxTemperature = Utility.formatTemperature(this, maxTemp);
|
||||
data.close();
|
||||
|
||||
// Perform this loop procedure for each Today widget
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
int layoutId = R.layout.widget_today_small;
|
||||
RemoteViews views = new RemoteViews(getPackageName(), layoutId);
|
||||
|
||||
// Add the data to the RemoteViews
|
||||
views.setImageViewResource(R.id.widget_icon, weatherArtResourceId);
|
||||
// Content Descriptions for RemoteViews were only added in ICS MR1
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||
setRemoteContentDescription(views, description);
|
||||
}
|
||||
views.setTextViewText(R.id.widget_high_temperature, formattedMaxTemperature);
|
||||
|
||||
// Create an Intent to launch MainActivity
|
||||
Intent launchIntent = new Intent(this, MainActivity.class);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, launchIntent, 0);
|
||||
views.setOnClickPendingIntent(R.id.widget, pendingIntent);
|
||||
|
||||
// Tell the AppWidgetManager to perform an update on the current app widget
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
|
||||
private void setRemoteContentDescription(RemoteViews views, String description) {
|
||||
views.setContentDescription(R.id.widget_icon, description);
|
||||
}
|
||||
}
|
||||
@@ -15,55 +15,39 @@
|
||||
*/
|
||||
package com.example.android.sunshine.app.widget;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.PendingIntent;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProvider;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.widget.RemoteViews;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.example.android.sunshine.app.MainActivity;
|
||||
import com.example.android.sunshine.app.R;
|
||||
import com.example.android.sunshine.app.Utility;
|
||||
import com.example.android.sunshine.app.sync.SunshineSyncAdapter;
|
||||
|
||||
/**
|
||||
* Provider for a widget showing today's weather.
|
||||
*
|
||||
* Delegates widget updating to {@link TodayWidgetIntentService} to ensure that
|
||||
* data retrieval is done on a background thread
|
||||
*/
|
||||
public class TodayWidgetProvider extends AppWidgetProvider {
|
||||
|
||||
@Override
|
||||
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
||||
int weatherArtResourceId = R.drawable.art_clear;
|
||||
String description = "Clear";
|
||||
double maxTemp = 24;
|
||||
String formattedMaxTemperature = Utility.formatTemperature(context, maxTemp);
|
||||
|
||||
// Perform this loop procedure for each Today widget
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
int layoutId = R.layout.widget_today_small;
|
||||
RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
|
||||
|
||||
// Add the data to the RemoteViews
|
||||
views.setImageViewResource(R.id.widget_icon, weatherArtResourceId);
|
||||
// Content Descriptions for RemoteViews were only added in ICS MR1
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||
setRemoteContentDescription(views, description);
|
||||
}
|
||||
views.setTextViewText(R.id.widget_high_temperature, formattedMaxTemperature);
|
||||
|
||||
// Create an Intent to launch MainActivity
|
||||
Intent launchIntent = new Intent(context, MainActivity.class);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, launchIntent, 0);
|
||||
views.setOnClickPendingIntent(R.id.widget, pendingIntent);
|
||||
|
||||
// Tell the AppWidgetManager to perform an update on the current app widget
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||
}
|
||||
context.startService(new Intent(context, TodayWidgetIntentService.class));
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
|
||||
private void setRemoteContentDescription(RemoteViews views, String description) {
|
||||
views.setContentDescription(R.id.widget_icon, description);
|
||||
@Override
|
||||
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager,
|
||||
int appWidgetId, Bundle newOptions) {
|
||||
context.startService(new Intent(context, TodayWidgetIntentService.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(@NonNull Context context, @NonNull Intent intent) {
|
||||
super.onReceive(context, intent);
|
||||
if (SunshineSyncAdapter.ACTION_DATA_UPDATED.equals(intent.getAction())) {
|
||||
context.startService(new Intent(context, TodayWidgetIntentService.class));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user