我的小部件服务有问题

时间:2014-04-24 13:05:19

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

过去一天左右我一直在研究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中,当我添加小部件它给我配置活动时我设置了它然后它显示小部件。但如果我点击它或任何东西。我从来没有从我的服务中获得任何活动?

我错过了什么?

1 个答案:

答案 0 :(得分: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()方法试图同时更新所有小部件,而不是自己更新每个小部件。我对使用与您相同的代码的类似问题有一个答案,您可能会觉得它很有趣:

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