在app小部件中复制onUpdate

时间:2014-03-20 02:07:56

标签: android android-intent android-appwidget

我正在尝试编写一个应用小部件来显示一些时间相关的文本,并且每分钟更新一次。为了测试我的想法,我首先写了一个简单的 - 只是为了在小部件中以hh:mm显示时间。如果屏幕关闭,没有必要显示它,所以我使用两个接收器,一个用于屏幕开/关,另一个用于time_tick。屏幕关闭时,它会取消注册time_tick接收器。屏幕打开时,再次注册。第一次添加到HOME时效果很好。 Logcat还显示了小部件提供程序接收的预期意图:启用,更新(一次),update_options等。两个接收器也按预期工作。

但是在重新启动之后(断电然后再打开),小部件仍然在那里并且显示正确的时间一次,但是它有3个问题:

  1. logcat显示收到了2个更新意图,尽管它们都运行良好。意图是启用,更新,更新(再次)和没有update_options
  2. 重启后显示正确的时间,没有接收器工作。显示的时间保持不变,屏幕上没有任何记录。
  3. onDeleted只能清除共享首选项,然后在取消注册步骤失败,除非接收者未注册。
  4. 这是我的代码(我使用了一个小部件配置,但它没有做任何事情,所以我只是跳过它,日志也跳过了)。请帮忙。

    清单:

        <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.senderj.testwidget2"
        android:versionCode="1"
        android:versionName="1.0" >
    
    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="19" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity android:name="com.senderj.testwidget2.HelloWidgetConfig" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
            </intent-filter>
        </activity>
        <receiver
            android:name="com.senderj.testwidget2.HelloWidget"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/hello_widget_provider" />
        </receiver>
    </application>
    

    HelloWidget(provider)

        public class HelloWidget extends AppWidgetProvider {
        static final boolean debug = true;
        static final String ME = "TestWidget2";
        static final String CURRTEXT = "CurrText";
        static int[] thisAppWidgetIds;
        static ScreenReceiver sr;
        static IntentFilter scrFil;
        static HelloReceiver hr;
        static IntentFilter helloFil;
    
        @Override
        public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
            thisAppWidgetIds = appWidgetIds;
            hr = new HelloReceiver(thisAppWidgetIds);
            helloFil = new IntentFilter();
            helloFil.addAction(Intent.ACTION_TIME_TICK);
            context.getApplicationContext().registerReceiver(hr, helloFil);
            sr = new ScreenReceiver(thisAppWidgetIds, hr);
            scrFil = new IntentFilter();
            scrFil.addAction(Intent.ACTION_SCREEN_ON);
            scrFil.addAction(Intent.ACTION_SCREEN_OFF);
            context.getApplicationContext().registerReceiver(sr, scrFil);
            refreshMyWidget(context, appWidgetManager, appWidgetIds);
            super.onUpdate(context, appWidgetManager, appWidgetIds);
        }//end onUpdate
        public static void updateMyWidget(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
            SharedPreferences prefs = context.getSharedPreferences(ME, Context.MODE_PRIVATE);
            SharedPreferences.Editor spe = prefs.edit();
            String old_str = prefs.getString(CURRTEXT, "");
            String newText = addOne(old_str);
            spe.putString(CURRTEXT, newText);
            spe.commit();
            RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
            remoteViews.setTextViewText(R.id.widget_textview, String.format("TIME = %s", newText));
        }//end updateMyWidget
    
        public static void refreshMyWidget(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
            SharedPreferences prefs = context.getSharedPreferences(ME, Context.MODE_PRIVATE);
            SharedPreferences.Editor spe = prefs.edit();
            String old_str = prefs.getString(CURRTEXT, "");
            String newText = String.format("%tR", new java.util.Date());
            spe.putString(CURRTEXT, newText);
            spe.commit();
            RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
            remoteViews.setTextViewText(R.id.widget_textview, String.format("TIME = %s", newText));
        }//end refreshMyWidget
    
        private static String addOne(String ss) {
            String[] arry = ss.split(":");
            int hh = Integer.parseInt(arry[0]);
            int mm = Integer.parseInt(arry[1]);
            if (++mm >59) {
                mm = 0;
                hh++;
            }//end if 
            return String.format("%02d:%02d", hh, mm);
        }//end addOne
    
        @Override
        public void onDeleted(Context context, int[] appWidgetIds) {
            SharedPreferences.Editor prefs = context.getSharedPreferences(ME, Context.MODE_PRIVATE).edit();
            prefs.clear();
            prefs.commit();
            //the following 2 failed with receiver not registered
            context.getApplicationContext().unregisterReceiver(hr);
            context.getApplicationContext().unregisterReceiver(sr);
            super.onDeleted(context, appWidgetIds);
        }//end onDeleted
    }//end HelloWidget
    

    HelloWidget xml

    <?xml version="1.0" encoding="utf-8"?>
    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
        android:configure="com.senderj.testwidget2.HelloWidgetConfig"
        android:initialLayout="@layout/main"
        android:minHeight="40dp"
        android:minWidth="110dp"
        android:updatePeriodMillis="86400000" 
        android:widgetCategory="home_screen"
    >
    </appwidget-provider>
    

    ScreenReceiver

        public class ScreenReceiver extends BroadcastReceiver {
        static final boolean debug = true;
        static final String ME = "TestWidget2";
        static int[] thisAppWidgetIds;
        static HelloReceiver hr;
    
        public ScreenReceiver() {
        }
        public ScreenReceiver(int[] widgetIds, HelloReceiver helloReceiver) {
            hr = helloReceiver;
            thisAppWidgetIds = widgetIds;
        }
    
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (action.equals(Intent.ACTION_SCREEN_ON)) {
                AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                HelloWidget.refreshMyWidget(context, appWidgetManager, thisAppWidgetIds);
                hr = new HelloReceiver(thisAppWidgetIds);
                IntentFilter helloFil = new IntentFilter();
                helloFil.addAction(Intent.ACTION_TIME_TICK);
                context.getApplicationContext().registerReceiver(hr, helloFil);
            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                context.getApplicationContext().unregisterReceiver(hr);
            }//end if action.equals
    }//end onReceive
    }//end ScreenReceiver
    

    HelloReceiver

        public class HelloReceiver extends BroadcastReceiver {
        static final boolean debug = true;
        static final String ME = "TestWidget2";
        static int[] thisAppWidgetIds;
    
        public HelloReceiver() {
        }
    
        public HelloReceiver(int[] widgetIds) {
              thisAppWidgetIds = widgetIds;
        }
    
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (action.equals(Intent.ACTION_TIME_TICK)) {
                AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                HelloWidget.updateMyWidget(context, appWidgetManager, thisAppWidgetIds);
            }//end if action.equals
        }//end onReceive
    }//end HelloReceiver
    

0 个答案:

没有答案