0

这是一个很笼统的问题。我用小部件制作了一个手电筒应用程序,它可以工作,但是:

  1. 闪光灯工作正常,但图标更改图像延迟。按下图标后,手电筒会打开,但图像会在大约 0.4 秒后更改。(通过较小的图像解决)

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);
        }
    }   
}

当前服务类

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);
        }
    }
}

提供者信息.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>

小部件布局.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>
4

2 回答 2

1

我还为闪光灯制作了一个应用程序,它工作正常,并且图像更改没有时间延迟。因此,除非您不发布代码,否则很难猜测问题的原因。

对于第二个问题,您必须!!! FAILED BINDER TRANSACTION !!!在您的小部件冻结时遇到。这是许多开发人员面临的一个长期存在的问题。但是您可以通过使用小部件中使用的小尺寸(内存)图像来避免,因为 Binder 只能占用小于 1.5 的小内存MB.我也遇到了同样的问题,在这里检查一下。Nobody was able to answer it

于 2013-10-24T10:23:03.070 回答
0

android:updatePeriodMillis您可以通过使用 AlarmManager 来替换刷新间隔,以提醒您想要的每个间隔。愿此链接对您有所帮助。

于 2013-10-24T10:18:42.240 回答