Android小部件在一段时间后无法响应

时间:2012-02-10 14:17:43

标签: android widget

我开发了一个带小部件的简单手电筒。但是经过一段时间后,由于一些奇怪的原因,小部件没有响应,添加一个新的 - 一切正常,旧的应该被删除。

public class XFlashLightAppWidgetProvider extends AppWidgetProvider {

/** Action name for updating widget receiver */
private static final String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {
    // Loop through all widgets of this application
    for (int i = 0; i < appWidgetIds.length; i++) {
        // Creating intent to send to the widget broadcast receiver
        // with update action
        Intent intent = new Intent(context,
                XFlashLightAppWidgetProvider.class);
        intent.setAction(ACTION_WIDGET_RECEIVER);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
                0, intent, 0);

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

        // When user click on the widget - send broadcast intent to the
        // widget
        // broadcast receiver for enabling or disabling flashlight and
        // updating widgets
        views.setOnClickPendingIntent(R.id.widgetLampImage, pendingIntent);

        // When user added new widget on his device - checking flashlight
        // and if flashlight is enabled - changing widget icon
        if (CameraHelper.isTorchFlashMode()) {
            views.setImageViewResource(R.id.widgetLampImage,
                    R.drawable.widget_on);
        }

        // Update each widget of the application
        appWidgetManager.updateAppWidget(appWidgetIds[i], views);
    }
    super.onUpdate(context, appWidgetManager, appWidgetIds);
}

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    // Check whether the device supports flash on the camera and the
    // receiver
    // received correct action
    if (CameraHelper.checkCameraFlashLightHadrware(context)
            && (action.equals(ACTION_WIDGET_RECEIVER)
                    || action.equals(XFlashLightActivity.ACTION_WIDGET_ON) || action
                        .equals(XFlashLightActivity.ACTION_WIDGET_OFF))) {
        RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.appwidget);

        // Checking action name, if action name equals
        // "ActionReceiverWidget" -
        // enable or disable flashlight and update widget icon, else if
        // action name
        // equals "ActionReceiverOn" or "ActionReceiverOff" - change widget
        // icon only
        if (action.equals(ACTION_WIDGET_RECEIVER)) {
            if (!CameraHelper.isTorchFlashMode()) {
                CameraHelper.initializeCameraFlash();
                views.setImageViewResource(R.id.widgetLampImage,
                        R.drawable.widget_on);
            } else {
                CameraHelper.releaseCamera();
                views.setImageViewResource(R.id.widgetLampImage,
                        R.drawable.widget_off);
            }
        } else if (action.equals(XFlashLightActivity.ACTION_WIDGET_ON)) {
            views.setImageViewResource(R.id.widgetLampImage,
                    R.drawable.widget_on);
        } else if (action.equals(XFlashLightActivity.ACTION_WIDGET_OFF)) {
            views.setImageViewResource(R.id.widgetLampImage,
                    R.drawable.widget_off);
        }

        // Update each widget of the application
        AppWidgetManager appWidgetManager = AppWidgetManager
                .getInstance(context);
        int[] appWidgetIds = appWidgetManager
                .getAppWidgetIds(new ComponentName(context,
                        XFlashLightAppWidgetProvider.class.getName()));
        for (int i = 0; i < appWidgetIds.length; i++) {
            appWidgetManager.updateAppWidget(appWidgetIds[i], views);
        }
    }
    super.onReceive(context, intent);
  }
}

2 个答案:

答案 0 :(得分:1)

当面向内存不足的情况时,Android会停止您的主页小部件。然后它将在自动清理RAM后重新启动主窗口小部件。但是这一次,你的家庭小部件将从最后一个小部件获得不同的pid,因此无法响应广播。

我认为您应该检查您的应用是否有内存泄漏。 此外,您还可以使用alarmManager尝试不同的工具。将所有onUpdate()移动到alarmReceiver。

见这个。 Updating app widget using AlarmManager

或尝试更新服务。

答案 1 :(得分:0)

感谢Zhenghong Wang。 相反, AppWidgetProvider 中的 onReceive 方法我已经使用了该服务

public class WidgetUpdateService extends Service {

    @Override
    public void onStart(Intent intent, int startId) {
        Context context = getApplicationContext();
        String action = intent.getAction();

        if (CameraHelper.checkCameraFlashLightHadrware(context)
            && (action.equals(XFlashLightAppWidgetProvider.ACTION_WIDGET_RECEIVER)
                    || action.equals(XFlashLightActivity.ACTION_WIDGET_ON) || action
                        .equals(XFlashLightActivity.ACTION_WIDGET_OFF))) {
            RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.appwidget);

            if (action.equals(XFlashLightAppWidgetProvider.ACTION_WIDGET_RECEIVER)) {
                if (!CameraHelper.isTorchFlashMode()) {
                    CameraHelper.initializeCameraFlash();
                    views.setImageViewResource(R.id.widgetLampImage,
                        R.drawable.widget_on);
                } else {
                     CameraHelper.releaseCamera();
                    views.setImageViewResource(R.id.widgetLampImage,
                        R.drawable.widget_off);
                }
            } else if (action.equals(XFlashLightActivity.ACTION_WIDGET_ON)) {
                views.setImageViewResource(R.id.widgetLampImage,
                    R.drawable.widget_on);
            } else if (action.equals(XFlashLightActivity.ACTION_WIDGET_OFF)) {
                views.setImageViewResource(R.id.widgetLampImage,
                    R.drawable.widget_off);
            }

            AppWidgetManager appWidgetManager = AppWidgetManager
                .getInstance(context);
            int[] appWidgetIds = appWidgetManager
                .getAppWidgetIds(new ComponentName(context,
                        XFlashLightAppWidgetProvider.class.getName()));
            for (int i = 0; i < appWidgetIds.length; i++) {
                appWidgetManager.updateAppWidget(appWidgetIds[i], views);
            }
        }
        super.onStart(intent, startId);
    }

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

}