【问题标题】:widget delay and timeout小部件延迟和超时
【发布时间】:2013-10-24 07:57:39
【问题描述】:

这是一个非常笼统的问题。我用小部件制作了一个手电筒应用程序, 它有效,但是:

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

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>

【问题讨论】:

  • 这个问题太笼统了,无法在这里解决
  • 仍然没有解决主要问题。我将发布一个代码...

标签: android android-intent service android-widget


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您可以通过使用AlarmManager 替换刷新间隔android:updatePeriodMillis 来为您想要的每个间隔发出警报。 愿这个link 对你有所帮助。

    【讨论】:

    • 我按照帖子中的建议将 android:updatePeriodMillis 设置为 0,但仍然是在小部件没有响应之后的一天。一天后 logcat 显示:InputDispatcher - 将触摸传递到当前输入目标:action:0x0
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    相关资源
    最近更新 更多