6

StackViewが含まれているAppWidgetがあります。AppWidgetに加えて、ユーザーがAppWidgetをホーム画面に追加したときに開始されるサービスがあります。このサービスは2時間ごとに新しいデータをポーリングします。サービスが新しいデータを見つけたら、AppWidgetにアラートを送信し、そのデータをRemoteViewsService(RemoteViewsFactoryがあります)に渡して、新しいデータに必要なビューを作成できるようにする必要があります。

現在、サービスが新しいデータを検出すると、新しいデータが検出されたことをAppWidgetにブロードキャストし、そのデータをインテント内の整数の配列として渡します。

AppWidgetProviderのonReceiveメソッドがそのデータを引き出し、次にAppWidgetのRemoteViewに渡される新しいインテントを設定するプロセスを実行します。以下のサンプルコード:

public void onReceive( Context context, Intent intent )
{
    int[] appWidgetIds = appWidgetManager.getAppWidgetIds( new ComponentName( context,  SampleAppWidgetProvider.class ) );

    int[] sampleData = intent.getIntArrayExtra( Intent.EXTRA_TITLE );
    for ( int i = 0; i < appWidgetIds.length; i++ )
    {
        // RemoteViewsFactory service intent
        Intent remoteViewsFactoryIntent = new Intent( context, SampleAppWidgetService.class );
        remoteViewsFactoryIntent.putExtra( AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i] );
        remoteViewsFactoryIntent.setData( Uri.parse( remoteViewsFactoryIntent.toUri( Intent.URI_INTENT_SCHEME ) ) );
        remoteViewsFactoryIntent.putExtra( Intent.EXTRA_TITLE, sampleData );

        RemoteViews rv = new RemoteViews( context.getPackageName(), R.layout.widget_layout );

        // Sync up the remoteviews factory
        rv.setRemoteAdapter( appWidgetIds[i], R.id.sample_widget, remoteViewsFactoryIntent );           
        rv.setEmptyView( R.id.sample_widget, R.id.empty_view );

        appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
    }

    super.onUpdate( context, appWidgetManager, appWidgetIds );
}

これは初めて動作します。データはRemoteViewsService/RemoteViewsFactoryによって表示されます。後続の新しいデータは、そのファクトリのサービスがすでに実行されているため、RemoteViewsFactoryのコンストラクタにヒットしません。

データを更新するにはどうすればよいですか?onDataSetChangedを使用する必要があるように感じますが、AppWidgetのonReceiveから渡したインテントにアクセスするにはどうすればよいですか?

これを適切に行う方法についての洞察をいただければ幸いです。ありがとう。

4

4 に答える 4

5

RemoteViewsFactory に渡される整数配列に対する私の解決策は、BroadcastReceiver を使用して解決されました。RemoteViewsFactory を拡張して BroadcastReceiver (具体的には onReceive) を実装し、ファクトリのコンストラクターでアプリケーションに登録しました (これは、onDestroy での登録を解除したことも意味します)。これで、AppWidgetProvider の onReceive にある整数配列を使用してインテントをブロードキャストし、RemoteViewsFactory 内で受け取ることができました。

AppWidgetManager の notifyAppWidgetViewDataChanged も必ず呼び出して、RemoteViewsFactory が以前に使用していたデータが無効になったことを認識し、新しい整数配列を提示して新しい RemoteView を作成するようにしてください。

于 2011-09-13T16:03:09.043 に答える
3

上記の Steve のソリューションを arne.jans などの利益のためにさらに詳しく説明するために、Steven のソリューションを次のように実装しました。

  • StackRemoteViewsFactoryを独自のクラス ファイルに抽出する
  • で拡張するBroadcastReceiver
  • データが必要なときにクラスもアクセスできるonReceive()静的変数に新しいデータを保存するメソッドを実装するStackRemoteViewsFactorygetViewAt
  • メソッドですべてのウィジェットの をIntent呼び出すことができるように、 を介してすべてのウィジェット ID を渡します。notifyAndUpdateonReceive()
  • 最後に、レシーバーの標準定義を AndroidManifest.xml に追加しました。
于 2012-06-16T04:19:26.803 に答える
1

もう 1 つの方法は、ファイル システムまたは sqlite データベースを使用することです。

AppWidgetProvider で:

 File file = new File(context.getCacheDir(), "filename that service also knows");
 writeFile(file, "my content");  // impl. not shown; uses BufferedWriter.java

RemoteViewsService で:

 File file = new File(context.getCacheDir(), "filename that service also knows");
 if (file.exists()) {
     // handle params contained within file
     file.delete(); // clear for next run
 } 
于 2013-12-02T23:09:02.217 に答える