10分ごとにサーバーからデータを取得して画面に表示するAndroidウィジェットがあります。
そのウィジェットに「更新」ボタンを追加したいのですが。
ユーザーがそのボタンをクリックしたときに、サーバーから情報を取得するメソッドを実行したいと思います。
アプリケーションのボタンにイベントハンドラーを追加するのは非常に簡単ですが、ウィジェットの例を見つけることができませんでした。
ウィジェットのボタンクリックに関数を追加するためのヘルプが必要です。
質問する
58407 次
7 に答える
12
次の利点を持つ別の答えを次に示します。
- すべてのアプリ ウィジェット インスタンスを処理します (ユーザーは、画面上にさまざまな構成/サイズでウィジェットの複数のインスタンスを持っている場合があります)。すべてのインスタンスのコーディングは、公式ドキュメントで規定されているものです。Guide > App Widgets > Using the AppWidgetProvider Class を参照して、「ExampleAppWidgetProvider」のコード例まで下にスクロールします。
onReceive
効果的な呼び出しの主力コードonUpdate
(したがって、コードの重複を減らします)。- のコード
onUpdate(Context context)
は一般化されているため、任意の AppWidgetProvider サブクラスにドロップできます。
コード:
public class MyWidget extends AppWidgetProvider {
private static final String ACTION_UPDATE_CLICK =
"com.example.myapp.action.UPDATE_CLICK";
private static int mCount = 0;
private static String getMessage() {
return String.valueOf(mCount++);
}
private PendingIntent getPendingSelfIntent(Context context, String action) {
// An explicit intent directed at the current class (the "self").
Intent intent = new Intent(context, getClass());
intent.setAction(action);
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
String message = getMessage();
// Loop for every App Widget instance that belongs to this provider.
// Noting, that is, a user might have multiple instances of the same
// widget on
// their home screen.
for (int appWidgetID : appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.my_widget);
remoteViews.setTextViewText(R.id.textView_output, message);
remoteViews.setOnClickPendingIntent(R.id.button_update,
getPendingSelfIntent(context,
ACTION_UPDATE_CLICK)
);
appWidgetManager.updateAppWidget(appWidgetID, remoteViews);
}
}
/**
* A general technique for calling the onUpdate method,
* requiring only the context parameter.
*
* @author John Bentley, based on Android-er code.
* @see <a href="http://android-er.blogspot.com
* .au/2010/10/update-widget-in-onreceive-method.html">
* Android-er > 2010-10-19 > Update Widget in onReceive() method</a>
*/
private void onUpdate(Context context) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance
(context);
// Uses getClass().getName() rather than MyWidget.class.getName() for
// portability into any App Widget Provider Class
ComponentName thisAppWidgetComponentName =
new ComponentName(context.getPackageName(),getClass().getName()
);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(
thisAppWidgetComponentName);
onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (ACTION_UPDATE_CLICK.equals(intent.getAction())) {
onUpdate(context);
}
}
}
ウィジェットはこんな感じ
これはgetPendingSelfIntent
、@Kels、@SharonHaimPour、および @Erti-ChrisEelmaa の作業に基づいています。
また、Android-er > 2010-10-19 > Update Widget in onReceive() メソッド(私ではありません) にも基づいて構築されており、App Widget インスタンス ベースで onReceive から onUpdate を呼び出す方法が示されています。私はそのコードを一般化し、callOnUpdate
.
于 2014-07-22T02:48:26.603 に答える
10
protected PendingIntent getPendingSelfIntent(Context context, String action) {
Intent intent = new Intent(context, getClass());
intent.setAction(action);
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
views.setOnClickPendingIntent(R.id.Timm, getPendingSelfIntent(context,
"ham"));
URL も優先:
別の方法で解決した場合は、これを回答として提供してください
于 2013-02-10T13:14:06.997 に答える
1
では、追加のpendingIntent
属性appWidgetId
を追加して後で再利用しonReceive
、クリックしたウィジェット インスタンスを更新することもできます。
class ExampleAppWidgetProvider : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray {
appWidgetIds.forEach { appWidgetId ->
Log.e("TAG", "onUpdate $appWidgetId")
val pendingRefreshClickIntent: PendingIntent = Intent(context, javaClass).let {
it.action = ACTION_REFRESH_CLICK
it.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
return@let PendingIntent.getBroadcast(
context,
appWidgetId, // click in all instances widget will work well (base on Alireza Mirian comment in the top answer)
it,
PendingIntent.FLAG_UPDATE_CURRENT
)
}
val views = RemoteViews(
context.packageName,
R.layout.example_appwidget
)
views.setOnClickPendingIntent(R.id.button_refresh, pendingRefreshClickIntent)
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
override fun onReceive(context: Context?, intent: Intent?) {
super.onReceive(context, intent)
Log.i("TAG", "onReceive " + intent?.action)
if (intent?.action == ACTION_REFRESH_CLICK) {
val appWidgetId = intent.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID) ?: return
Log.i("TAG", "onReceive appWidgetId $appWidgetId")
val appWidgetManager = AppWidgetManager.getInstance(context)
val views = RemoteViews(context!!.packageName, R.layout.example_appwidget)
views.setTextViewText(R.id.text_data, "a " + (Math.random() * 9).roundToInt())
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
companion object {
private const val ACTION_REFRESH_CLICK = "com.example.androidwidgetbuttonclick.action.ACTION_REFRESH_CLICK"
}
}
ウィジェットの初期レイアウト
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/text_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AA"
android:textSize="20sp" />
<Button
android:id="@+id/button_refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refresh" />
</LinearLayout>
于 2021-02-17T03:47:53.743 に答える