这是一个相当普遍的问题。我用小部件制作了一个手电筒应用程序 它有效,但是:
2。一天之后,我检查小部件并且它不起作用,但是如果我再次拉动小部件就可以了。
是什么让这些事情发生?
currentprovider.class
public class CurrentProvider extends AppWidgetProvider {
public static final String WIDGETTAG = "WidgetFlashLight";
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
Log.i(WIDGETTAG, "onUpdate");
final int N = appWidgetIds.length;
// Perform this loop procedure for each App Widget that belongs to this provider
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
Log.i(WIDGETTAG, "updating widget[id] " + appWidgetId);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widgetlayout);
Intent intent = new Intent(context, CurrentService.class);
intent.setAction(CurrentService.CHANGE_CAMERA_STATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.widgetBtn, pendingIntent);
Log.i(WIDGETTAG, "pending intent set");
// Tell the AppWidgetManager to perform an update on the current App Widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
currentService.class
public class CurrentService extends Service {
public static final String CHANGE_CAMERA_STATE = "ChangeState";
public static boolean mFlashIsOn = false;
public static Camera camera;
public static Parameters params;
private static final int NOTIFICATION_EX = 1;
private NotificationManager notificationManager;
Notification notification;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStart(intent, startId);
Log.i(CurrentProvider.WIDGETTAG, "onStartCommand");
getCamera();
switchCameraState(intent);
stopSelf(startId);
return START_STICKY;
}
private void switchCameraState(Intent intent) {
Log.i(CurrentProvider.WIDGETTAG, "This is the intent " + intent);
if (intent != null){
String requestedAction = intent.getAction();
Log.i(CurrentProvider.WIDGETTAG, "This is the action " + requestedAction);
if (requestedAction != null && requestedAction.equals(CHANGE_CAMERA_STATE)){
int widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0);
AppWidgetManager appWidgetMan = AppWidgetManager.getInstance(this);
RemoteViews views = new RemoteViews(this.getPackageName(),R.layout.widgetlayout);
switchFlash(views);
appWidgetMan.updateAppWidget(widgetId, views);
Log.i(CurrentProvider.WIDGETTAG, "State updated!");
}
}
}
public void getCamera() {
if (camera == null) {
try {
camera = Camera.open();
params = camera.getParameters();
} catch (RuntimeException e) {
Log.e("Camera Error. Failed to Open. Error: ", e.getMessage());
}
}
}
public void switchFlash(RemoteViews views) {
if (camera == null || params == null) {
Log.i("camera||params","is null");
return;
}
params = camera.getParameters();
if (mFlashIsOn) {;
params.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(params);
camera.stopPreview();
views.setImageViewResource(R.id.widgetBtn, R.drawable.wi_off);
mFlashIsOn=false;
//setNotification(false);
switchNotificationOff();
}else{
params.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(params);
camera.startPreview();
views.setImageViewResource(R.id.widgetBtn, R.drawable.wi_on);
mFlashIsOn=true;
setNotification(true);
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void setNotification(boolean x){
notificationManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
int icon = R.drawable.icon;
CharSequence tickerText = "Just FlashLight";
notification = new Notification(icon, tickerText, 0);
Context context = getApplicationContext();
CharSequence contentTitle = "Just FlashLight";
CharSequence contentText = "Press to stop flashlight";
Intent notificationIntent = new Intent(this, StartScreen.class);
PendingIntent contentIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle,
contentText, contentIntent);
notificationManager.notify(NOTIFICATION_EX, notification);
}
public void switchNotificationOff( ){
if (Context.NOTIFICATION_SERVICE!=null) {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager nMgr = (NotificationManager) getApplicationContext().getSystemService(ns);
nMgr.cancel(NOTIFICATION_EX);
}
}
}
providerInfo.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="72dp"
android:minHeight="72dp"
android:updatePeriodMillis="0"
android:initialLayout="@layout/widgetlayout">
</appwidget-provider>
widgetlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="0.1dp" >
<ImageButton
android:id="@+id/widgetBtn"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_gravity="center_vertical"
android:src="@drawable/wi_off"
android:scaleType="fitXY"
android:background="@android:color/transparent"
>
</ImageButton>
</LinearLayout>
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.flashlight"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<application
android:allowBackup="true"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/AppTheme" >
<service android:name="com.flashlight.CurrentService" >
</service>
<receiver android:name="com.dimrix.flashlight.CurrentProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<category android:name="android.intent.category.DEFAULT" >
</category>
<category android:name="android.intent.category.ALTERNATIVE" >
</category>
</intent-filter>
<intent-filter>
<action android:name="com.flashlight.CurrentService" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widgetproviderinfo" />
</receiver>
<activity
android:name="com.flashlight.StartScreen"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
答案 0 :(得分:1)
我还制作了一个闪光灯的应用程序,它工作正常,图像更改没有时间延迟。所以直到您不发布代码,很难猜出问题的原因。
对于第二个问题,当你的小部件冻结时,你必须得到!!! FAILED BINDER TRANSACTION !!!
。这是许多开发人员面临的长期运行问题。但是你可以避免使用小部件中使用的小尺寸(内存)图像因为Binder可以只占用小于1.5MB的小内存。我也遇到同样的问题检查它here。Nobody was able to answer it
答案 1 :(得分:0)
您可以使用AlarmManager替换刷新间隔android:updatePeriodMillis
以警告您想要的每个间隔。
可能这link会帮助你。