【问题标题】:Trouble with my widget service我的小部件服务出现问题
【发布时间】:2023-03-26 18:24:01
【问题描述】:

过去一天左右我一直在开发一个 appwidget,我认为我已经正确地遵循了一切,但由于某种原因,我的更新服务似乎无法正常工作。

让我过去我的代码,我很抱歉它有点。但这就是启动和运行小部件所需要的。

MyWidgetProvider:

 public class MyWidgetProvider extends AppWidgetProvider {

private static final String LOG = "$AppWidgetProvider";

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

    Log.i(LOG, "onUpdate method called");

    // Get all ids
    ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);
    int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

    // Build the intent to call the service
    Intent intent = new Intent(context.getApplicationContext(), UpdateWidgetService.class);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

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

我的 XML 提供程序

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/widget_layout"
    android:minHeight="200dp"
    android:minWidth="144dp"
    android:widgetCategory="home_screen"
    android:configure="widget.AppWidgetConfigureActivity"
    android:updatePeriodMillis="5000" >
</appwidget-provider>

清单文件:

<!-- Widget -->
    <receiver
        android:name="widget.MyWidgetProvider"
        android:icon="@drawable/fsk"
        android:label="FSK Widget" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>

        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/app_widget_provider_info" />
    </receiver>
   <!-- Services -->
    <service android:name=".widget.UpdateWidgetService" >
    </service>

我的 AppWidgetConfiguration 类:

public class AppWidgetConfigureActivity extends Activity {

public String TAG = "AppWidgetConfigureActivity";
private View emptyView;
private View noDevices;
private int appWidgetId;
public static MyDevicesSpinnerAdapter myDeviceAdapter;
private Spinner myDevicesSpinner;
private Spinner updateFreqSpinner;
private Button configureButton;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (!isLoggedIn()) {
        Intent intent = new Intent(AppWidgetConfigureActivity.this, LoginActivity.class);
        intent.putExtra("Source", "widgetConfig");
        startActivity(intent);
    }
    getWidgetId();
    setTitle(R.string.title_activity_app_widget_configure);
    setContentView(R.layout.activity_app_widget_configure);

    Intent cancelResultValue = new Intent();
    cancelResultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    setResult(RESULT_CANCELED, cancelResultValue);
    myDevicesSpinner = (Spinner) findViewById(R.id.widget_configure_devices_spinner);
    updateFreqSpinner = (Spinner) findViewById(R.id.widget_configure_updateFreq_spinner);
    myDeviceAdapter = new MyDevicesSpinnerAdapter(AppWidgetConfigureActivity.this);
    myDevicesSpinner.setAdapter(myDeviceAdapter);

    getMyDevices();
    populateFreqSpinner();
    configureButton = (Button) findViewById(R.id.widget_configure_configure_button);
    iAgreeCheckBox = (CheckBox) findViewById(R.id.widget_configure_iAgree_checkbox);

}

    private void getWidgetId() {
    Intent intent = getIntent();
    Bundle extras = intent.getExtras();
    if (extras != null) {
        appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
    }
}


public void onConfigureClicked(View view) {

    SaveWidgetConfiguration();

    // Update the View
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(AppWidgetConfigureActivity.this);
    RemoteViews views = new RemoteViews(AppWidgetConfigureActivity.this.getPackageName(), R.layout.widget_layout);
    appWidgetManager.updateAppWidget(appWidgetId, views);

    // End the config
    Intent resultValue = new Intent();
    resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    setResult(RESULT_OK, resultValue);
    finish();
}   

/**
 * Saves the configs of the widget
 */
private void SaveWidgetConfiguration() {

    int deviceTypeId = 0;
    int deviceId = 0;
    String hashedPasscode = "";
    int updateFreq = 30000;

    SharedPreferences prefs = AppWidgetConfigureActivity.this.getSharedPreferences("prefs", 0);
    SharedPreferences.Editor edit = prefs.edit();
    edit.putInt("Widget_DeviceTypeId:" + appWidgetId, deviceTypeId);
    edit.putInt("Widget_DeviceId:" + appWidgetId, deviceId);
    edit.putString("Widget_Passcode:" + appWidgetId, hashedPasscode);
    edit.putInt("Widget_UpdateFreq:" + appWidgetId, updateFreq);
    edit.commit();
}
}

我的 UpdateWidget 服务:

public class UpdateWidgetService extends Service {

private static final String LOG = "$widgetUpdateService";   

@Override
public void onStart(Intent intent, int startId) {

    Log.i(LOG, "Called and started");

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());
    int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);

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

    for (int appWidgetId : allWidgetIds) {
        // create some random data
        RemoteViews remoteView = getView(this, appWidgetId, allWidgetIds);
        appWidgetManager.updateAppWidget(appWidgetId, remoteView);
    }
    stopSelf();
    super.onStart(intent, startId);
}

private RemoteViews getView(Context context, int appWidgetId, int[] allWidgetIds) {
    WidgetPrefs prefs = getWidgetConfiguration(context, appWidgetId);
    switch (prefs.deviceTypeId) {
    case 8: {
        int number = (new Random().nextInt(100));

        RemoteViews remoteViews = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.widget_layout);
        Log.w("WidgetExample", String.valueOf(number));
        // Set the text
        remoteViews.setTextViewText(R.id.widget_textview_gpscoords, "Random: " + String.valueOf(number));
        // Register an onClickListener
        Intent clickIntent = new Intent(this.getApplicationContext(), MyWidgetProvider.class);
        clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
        clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.widget_button_dissarm, pendingIntent);
    }
        break;
    case 10: {
    }
        break;
    default: {
        // Error
    }
    }

    return null;
}

/**
 * Gets the preferences of the widget
 */
private WidgetPrefs getWidgetConfiguration(Context context, int appWidgetId) {

    WidgetPrefs wPrefs = new WidgetPrefs();
    SharedPreferences prefs = context.getSharedPreferences("prefs", 0);
    wPrefs.deviceTypeId = prefs.getInt("Widget_DeviceTypeId:" + appWidgetId, wPrefs.deviceTypeId);
    wPrefs.deviceId = prefs.getInt("Widget_DeviceId:" + appWidgetId, wPrefs.deviceId);
    wPrefs.hashedPasscode = prefs.getString("Widget_Passcode:" + appWidgetId, wPrefs.hashedPasscode);
    wPrefs.updateFreq = prefs.getInt("Widget_UpdateFreq:" + appWidgetId, wPrefs.updateFreq);
    return wPrefs;
}

/**
 * Holder class to store widget preferences
 * 
 */
private class WidgetPrefs {
    public int deviceTypeId = -1;
    public int deviceId = -1;
    public String hashedPasscode = "";
    public int updateFreq = 30000;
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

}

现在我遇到的问题是,我的服务中的所有断点或日志永远不会被命中或不会出现在我的 logcat 中,当我添加小部件时,它会为我提供我设置的配置活动和它然后显示小部件。但如果我点击它或任何东西。我从来没有从我的服务中获得任何活动?

我错过了什么?

【问题讨论】:

    标签: android android-widget android-service android-broadcast


    【解决方案1】:

    您的 UpdateWidgetService.getView() 方法中似乎存在 2 个问题。


    1)

    您使用以下代码在您的小部件上注册一个点击监听器:

    // Register an onClickListener
    Intent clickIntent = new Intent(this.getApplicationContext(), MyWidgetProvider.class);
    clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
    clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
    

    当小部件被点击时,它会为你的MyWidgetProvider 类广播一个意图——这不是一个活动。

    将其替换为您要启动的活动的名称。


    2)

    就在该代码下方,您可以像这样设置PendingIntent

    PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0,
        clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    

    问题是您使用PendingIntent.getBroadcast() 发送一般广播。

    您应该改为使用PendingIntent.getActivity() 来设置启动活动。像这样的:

    PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
        clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    

    当然,还要确保你的活动在你的清单文件中注册,否则它不会启动。


    顺便说一句,我看到您的 MyWidgetProvider.onUpdate() 方法尝试同时更新所有小部件,而不是单独更新每个小部件。我有一个与您使用相同代码的类似问题的答案,您可能会觉得它很有趣:

    在另一个答案中,我提供了一个非常简单的小部件演示应用程序的链接,您可以从中学习有用的信息:

    【讨论】:

      猜你喜欢
      • 2017-03-27
      • 1970-01-01
      • 2020-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多