2

編集:アプリ4.xデバイスをインストールしましたが、問題はありません。問題は3.xデバイスでのみ発生します。

デバイスでユーザー設定が変更されたときに、AppWidgetを手動で更新しようとしています。そのために、次のようなコードを使用します。

ComponentName thisWidget = new ComponentName(this, MyAppWidget.class); 
AppWidgetManager manager = AppWidgetManager.getInstance(this); 
manager.updateAppWidget(thisWidget, updateViews);

コードでlogcatにいくつかのデバッグ文字列を記録したため、結果としてAppWidgetonUpdateメソッドが呼び出されていることがわかります。ただし、AppWidget自体は画面上で変更されません。

ここに興味深い部分があります。デバイスを回転させてホーム画面を強制的に更新すると(PORTRAITからLANDSCAPEに、またはその逆)、最終的にAppWidgetが更新されます。ただし、デバイスを回転してもonUpdateメソッドが呼び出されることはないため、AppWidgetは以前の更新で提供されたRemoteViewを使用している必要があります。

更新を処理するときにAppWidgetのホーム画面を強制的に再描画する方法を誰かに説明してもらえますか?

使ってます<uses-sdk android:minSdkVersion="11" />

public void onUpdate(Context context, AppWidgetManager appWidgetManager,
  int[] appWidgetIds) {

  // Get all ids
  ComponentName thisWidget = new ComponentName(context, MyProvider.class);
  int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
  // Build the intent to call the service
  Intent intent = new Intent(context.getApplicationContext(), MyService.class);
  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

  RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.appwidget_layout);

  appWidgetManager.updateAppWidget(appWidgetIds, views);

  // Update the widgets via the service
  context.startService(intent);
}

そして私のサービス:

@Override
public void onStart(Intent intent, int startId) {
    Log.i(LOG, "Called");

    this.appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());

    this.allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);

    ComponentName thisWidget = new ComponentName(getApplicationContext(), MyProvider.class);
    int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
    Log.w(LOG, "From Intent" + String.valueOf(allWidgetIds.length));        
    Log.w(LOG, "Direct" + String.valueOf(allWidgetIds2.length));
    config = getResources().getConfiguration();

    for (int widgetId : allWidgetIds) {
        //do things like starting ASYNCs (couple of them) to fetch data from server
        //and set an adapter for the gridview
    }   

    Intent intentOpen = new Intent(getApplicationContext(), MainFragmentActivity.class);
    PendingIntent open = PendingIntent.getActivity(getApplicationContext(), 0, intentOpen, 0);
    remoteViews.setOnClickPendingIntent(R.id.widget_whole, open);
    remoteViews.setViewVisibility(R.id.widgetProgress, View.GONE);
    appWidgetManager.updateAppWidget( thisWidget, remoteViews );    
    Log.d(LOG, "sent!!");       
}
stopSelf();

super.onStart(intent, startId); }
4

2 に答える 2

0

これはランチャー アプリのバグのように思えます。AppWidgetManagerを呼び出すたびupdateAppWidgetに、新しいレイアウトが受信され、ランチャーはこの新しいレイアウトでウィジェットを再描画します。

画面が回転onUpdateし、updateAppWidget呼び出されていないときに、ランチャーが新しいレイアウトでウィジェットを再描画するという事実は、AppWidgetManagerがその新しいレイアウトを既に正常に受け取っていることを意味します。

画面が回転すると、ランチャーは強制的にすべてを再描画し (Activity が再作成されます)、それが新しいレイアウトを表示する理由です。

そして、このバグはおそらく Android 4.0 以降で修正されています。

于 2014-03-25T18:45:18.647 に答える
-1

invalidate()ウィジェットのビューを呼び出してみます。これを呼び出すと、システムはビューを強制的に再描画します。

于 2012-10-09T14:28:53.887 に答える