Android 小部件在一段时间后停止工作?
Android widget stops working after a while?
我有一个带小部件的手电筒应用程序。该小部件用于打开和关闭手电筒,不显示 main activity 或任何内容。然而,几个小时后,小部件什么也不做。我的意思是,如果您单击它,什么也不会发生。
我有两个 类 来完成这个 Provider
和 Receiver
.
Provider:
public class WidgetProvider extends AppWidgetProvider {
@
Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Intent receiver = new Intent(context, FlashlightWidgetReceiver.class);
receiver.setAction("COM_FLASHLIGHT");
receiver.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, receiver, 0);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.appwidget_layout);
views.setOnClickPendingIntent(R.id.imageButton, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, views);
}
}
Receiver:
public class FlashlightWidgetReceiver extends BroadcastReceiver {
private static boolean isLightOn = false;
private static Camera camera;
MediaPlayer mp;@
Override
public void onReceive(Context context, Intent intent) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout);
if (isLightOn) {
views.setImageViewResource(R.id.imageButton, R.drawable.btn_switch_off);
mp = MediaPlayer.create(context, R.raw.light_switch_off);
} else {
views.setImageViewResource(R.id.imageButton, R.drawable.btn_switch_on);
mp = MediaPlayer.create(context, R.raw.light_switch_on);
}
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@
Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.release();
}
});
mp.start();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
appWidgetManager.updateAppWidget(new ComponentName(context, WidgetProvider.class),
views);
if (isLightOn) {
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
isLightOn = false;
}
} else {
camera = Camera.open();
if (camera == null) {
Toast.makeText(context, "No Camera!", Toast.LENGTH_SHORT).show();
} else {
Camera.Parameters param = camera.getParameters();
param.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
try {
camera.setParameters(param);
camera.startPreview();
isLightOn = true;
} catch (Exception e) {
Toast.makeText(context, "No Flash!", Toast.LENGTH_SHORT).show();
}
}
}
}
}
Setup:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:maxWidth="40dp"
android:maxHeight="40dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/appwidget_layout"
android:resizeMode="horizontal|vertical">
</appwidget-provider>
更新:减少更新间隔使小部件更频繁地刷新,所以如果它卡住了,它会在 30 分钟后再次运行,然后它可能会在某个时候再次冻结。
更新 2:更改日期会立即冻结小部件,直到它被刷新。
更新 3: 更改日期会以某种方式重新启动启动器,每当启动器重新启动时,小部件都会冻结 30 分钟。
寻找这个post,我想这个问题在这里得到了解释the dark side of app widgets
好的伙计们,我终于有时间一劳永逸地解决这个问题:)
我为提供程序创建了更多方法,而不是在 onUpdate 中做所有事情,需要一个重要方法:
public static PendingIntent buildButtonPendingIntent(Context context) {
Intent intent = new Intent();
intent.setAction("COM_FLASHLIGHT");
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
当使用下面的代码点击小部件时,通过接收器调用此方法:
private void turnFlash(Context context) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout);
views.setOnClickPendingIntent(R.id.imageButton, WidgetProvider.buildButtonPendingIntent(context));
}
就是这样,别再打嗝了!
我有一个带小部件的手电筒应用程序。该小部件用于打开和关闭手电筒,不显示 main activity 或任何内容。然而,几个小时后,小部件什么也不做。我的意思是,如果您单击它,什么也不会发生。
我有两个 类 来完成这个 Provider
和 Receiver
.
Provider:
public class WidgetProvider extends AppWidgetProvider {
@
Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Intent receiver = new Intent(context, FlashlightWidgetReceiver.class);
receiver.setAction("COM_FLASHLIGHT");
receiver.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, receiver, 0);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.appwidget_layout);
views.setOnClickPendingIntent(R.id.imageButton, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, views);
}
}
Receiver:
public class FlashlightWidgetReceiver extends BroadcastReceiver {
private static boolean isLightOn = false;
private static Camera camera;
MediaPlayer mp;@
Override
public void onReceive(Context context, Intent intent) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout);
if (isLightOn) {
views.setImageViewResource(R.id.imageButton, R.drawable.btn_switch_off);
mp = MediaPlayer.create(context, R.raw.light_switch_off);
} else {
views.setImageViewResource(R.id.imageButton, R.drawable.btn_switch_on);
mp = MediaPlayer.create(context, R.raw.light_switch_on);
}
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@
Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.release();
}
});
mp.start();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
appWidgetManager.updateAppWidget(new ComponentName(context, WidgetProvider.class),
views);
if (isLightOn) {
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
isLightOn = false;
}
} else {
camera = Camera.open();
if (camera == null) {
Toast.makeText(context, "No Camera!", Toast.LENGTH_SHORT).show();
} else {
Camera.Parameters param = camera.getParameters();
param.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
try {
camera.setParameters(param);
camera.startPreview();
isLightOn = true;
} catch (Exception e) {
Toast.makeText(context, "No Flash!", Toast.LENGTH_SHORT).show();
}
}
}
}
}
Setup:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:maxWidth="40dp"
android:maxHeight="40dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/appwidget_layout"
android:resizeMode="horizontal|vertical">
</appwidget-provider>
更新:减少更新间隔使小部件更频繁地刷新,所以如果它卡住了,它会在 30 分钟后再次运行,然后它可能会在某个时候再次冻结。
更新 2:更改日期会立即冻结小部件,直到它被刷新。
更新 3: 更改日期会以某种方式重新启动启动器,每当启动器重新启动时,小部件都会冻结 30 分钟。
寻找这个post,我想这个问题在这里得到了解释the dark side of app widgets
好的伙计们,我终于有时间一劳永逸地解决这个问题:)
我为提供程序创建了更多方法,而不是在 onUpdate 中做所有事情,需要一个重要方法:
public static PendingIntent buildButtonPendingIntent(Context context) {
Intent intent = new Intent();
intent.setAction("COM_FLASHLIGHT");
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
当使用下面的代码点击小部件时,通过接收器调用此方法:
private void turnFlash(Context context) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout);
views.setOnClickPendingIntent(R.id.imageButton, WidgetProvider.buildButtonPendingIntent(context));
}
就是这样,别再打嗝了!