diff --git a/clients/android/NewsBlur/AndroidManifest.xml b/clients/android/NewsBlur/AndroidManifest.xml index 2865b4558..15a9aacd4 100644 --- a/clients/android/NewsBlur/AndroidManifest.xml +++ b/clients/android/NewsBlur/AndroidManifest.xml @@ -137,9 +137,16 @@ + + + + + + @@ -150,7 +157,13 @@ - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/clients/android/NewsBlur/res/layout/newsblur_widget_item.xml b/clients/android/NewsBlur/res/layout/newsblur_widget_item.xml new file mode 100644 index 000000000..3509b8411 --- /dev/null +++ b/clients/android/NewsBlur/res/layout/newsblur_widget_item.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/clients/android/NewsBlur/res/xml/newsblur_appwidget_info.xml b/clients/android/NewsBlur/res/xml/newsblur_appwidget_info.xml new file mode 100644 index 000000000..5d37a410a --- /dev/null +++ b/clients/android/NewsBlur/res/xml/newsblur_appwidget_info.xml @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/clients/android/NewsBlur/src/com/newsblur/activity/ConfigureWidgetActivity.java b/clients/android/NewsBlur/src/com/newsblur/activity/ConfigureWidgetActivity.java new file mode 100644 index 000000000..aa97ccb18 --- /dev/null +++ b/clients/android/NewsBlur/src/com/newsblur/activity/ConfigureWidgetActivity.java @@ -0,0 +1,46 @@ +package com.newsblur.activity; + +import android.appwidget.AppWidgetManager; +import android.content.Intent; +import android.os.Bundle; +import android.widget.RemoteViews; + +import com.newsblur.R; + +public class ConfigureWidgetActivity extends NbActivity { + private int appWidgetId; + + @Override + protected void onCreate(Bundle bundle) { + super.onCreate(bundle); + + Intent intent = getIntent(); + Bundle extras = intent.getExtras(); + if (extras != null) { + appWidgetId = extras.getInt( + AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + } + + // set result as cancelled in the case that we don't finish config + Intent resultValue = new Intent(); + resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + setResult(RESULT_CANCELED, resultValue); + //todo update all the data + } + + + private void saveWidget(){ + //update widget + AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this); + RemoteViews views = new RemoteViews(getPackageName(), + R.layout.newsblur_widget); + appWidgetManager.updateAppWidget(appWidgetId, views); + + + Intent resultValue = new Intent(); + resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + setResult(RESULT_OK, resultValue); + finish(); + } +} diff --git a/clients/android/NewsBlur/src/com/newsblur/widget/NewsBlurWidgetProvider.java b/clients/android/NewsBlur/src/com/newsblur/widget/NewsBlurWidgetProvider.java new file mode 100644 index 000000000..67c492001 --- /dev/null +++ b/clients/android/NewsBlur/src/com/newsblur/widget/NewsBlurWidgetProvider.java @@ -0,0 +1,72 @@ +package com.newsblur.widget; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.widget.RemoteViews; + +import com.newsblur.R; + +public class NewsBlurWidgetProvider extends AppWidgetProvider { + public static String ACTION_OPEN_STORY = "ACTION_OPEN_STORY"; + public static String EXTRA_ITEM_ID = "EXTRA_ITEM_ID"; + + /** + * Called to update at regular interval + */ + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + // update each of the app widgets with the remote adapter + for (int i = 0; i < appWidgetIds.length; ++i) { + + // Set up the intent that starts the StackViewService, which will + // provide the views for this collection. + Intent intent = new Intent(context, WidgetRemoteViewsService.class); + // Add the app widget ID to the intent extras. + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); + intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); + // Instantiate the RemoteViews object for the app widget layout. + RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.newsblur_widget); + // Set up the RemoteViews object to use a RemoteViews adapter. + // This adapter connects + // to a RemoteViewsService through the specified intent. + // This is how you populate the data. + rv.setRemoteAdapter(R.id.widget_list, intent); + + // The empty view is displayed when the collection has no items. + // It should be in the same layout used to instantiate the RemoteViews + // object above. + rv.setEmptyView(R.id.widget_list, R.id.empty_view); + + // + // Do additional processing specific to this app widget... + // + // This section makes it possible for items to have individualized behavior. + // It does this by setting up a pending intent template. Individuals items of a collection + // cannot set up their own pending intents. Instead, the collection as a whole sets + // up a pending intent template, and the individual items set a fillInIntent + // to create unique behavior on an item-by-item basis. + Intent toastIntent = new Intent(context, NewsBlurWidgetProvider.class); + // Set the action for the intent. + // When the user touches a particular view, it will have the effect of + // broadcasting TOAST_ACTION. + toastIntent.setAction(NewsBlurWidgetProvider.TOAST_ACTION); + toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); + intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); + PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + rv.setPendingIntentTemplate(R.id.stack_view, toastPendingIntent); + + + appWidgetManager.updateAppWidget(appWidgetIds[i], rv); + } + + + super.onUpdate(context, appWidgetManager, appWidgetIds); + } + + +} diff --git a/clients/android/NewsBlur/src/com/newsblur/widget/WidgetRemoteViewsService.java b/clients/android/NewsBlur/src/com/newsblur/widget/WidgetRemoteViewsService.java new file mode 100644 index 000000000..6f4393b91 --- /dev/null +++ b/clients/android/NewsBlur/src/com/newsblur/widget/WidgetRemoteViewsService.java @@ -0,0 +1,66 @@ +package com.newsblur.widget; + +import android.appwidget.AppWidgetManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.widget.RemoteViews; +import android.widget.RemoteViewsService; + +import com.newsblur.R; + +public class WidgetRemoteViewsService extends RemoteViewsService { + @Override + public RemoteViewsFactory onGetViewFactory(Intent intent) { + return new WidgetRemoteViewsFactory(this.getApplicationContext(), intent); + } +} + +class WidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { + private Context context; + private int appWidgetId; + public WidgetRemoteViewsFactory(Context context, Intent intent) { + this.context = context; + appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + } + /** + * The system calls onCreate() when creating your factory for the first time. + * This is where you set up any connections and/or cursors to your data source. + * + * Heavy lifting, + * for example downloading or creating content etc, should be deferred to onDataSetChanged() + * or getViewAt(). Taking more than 20 seconds in this call will result in an ANR. + */ + @Override + public void onCreate() { + //TODO + } + + @Override + public RemoteViews getViewAt(int position) { + // Construct a remote views item based on the app widget item XML file, + // and set the text based on the position. + RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.newsblur_widget_item); + rv.setTextViewText(R.id.newsblur_widget_item, widgetItems.get(position).text); + + + + // Next, set a fill-intent, which will be used to fill in the pending intent template + // that is set on the collection view in StackWidgetProvider. + Bundle extras = new Bundle(); + extras.putInt(NewsBlurWidgetProvider.EXTRA_ITEM_ID, position); + Intent fillInIntent = new Intent(); + fillInIntent.putExtras(extras); + // Make it possible to distinguish the individual on-click + // action of a given item + rv.setOnClickFillInIntent(R.id.newsblur_widget_item, fillInIntent); + return rv; + } + + + @Override + public void onDataSetChanged() { + // fetch any new data + } +}