• widget的进一步使用,利用AppWidgetProvider实现桌面的时钟挂件


    1、通过上面介绍widget的基本应用外面知道,系统最多30分钟才更新挂件的内容,为了实时更新时钟我们必须自己发送广播来实现挂件内容的更新,其方法就是覆写父类AppWidgetProvider的onReceive()方法,并在注册的广播接收的intent-fliter里添加接受自己的广播。

    2、用过查看Mainfest文件知道广播接受原始只注册了android.appwidget.action.APPWIDGET_UPDATE,但是可以接收android.appwidget.action.APPWIDGET_ENABLED,android.appwidget.action.APPWIDGET_DISENABLED,猜想AppWidgetProvider里的接受者在系统里已经注册了接收这些广播,而我写的类继承它,因此也可以接收。

    3、当我去掉注册的android.appwidget.action.APPWIDGET_UPDATE只保留我自己添加的更新时间的广播时候却收不到android.appwidget.action.APPWIDGET_UPDATE等一些广播了并且在widget里找不到我定义的挂件了。猜想在系统定义了相应的规则,必须注册了的广播中含有android.appwidget.action.APPWIDGET_UPDATE,且注册的类必须继承了AppWidgetProvider才会在系统里注册一个挂件,并且继承的类可以收到AppWidgetProvider接受的广播。

    4、 当我们在存储widgetId时候数据不加static时候发现每次接收到信号时候widgetIds这个集合的size都为0,表明每次接受到广播后就重新创建了NewAppWidge这个类对象。因此在广播类中重要的数据得用static变量。

    5 广播机制:广播在mainfest里注册后,当接受到相应的广播后就会创建相应注册在receiver的类,然后由这些类的onreceiver来处理,处理后当系统内存不足的时候就会回收这个对象,然后下次收到的时候就会再次重新创建对象。

    下面给出实现的demo:

    widget类:

    package com.example.user.appwidget;
    
    import android.app.PendingIntent;
    import android.appwidget.AppWidgetManager;
    import android.appwidget.AppWidgetProvider;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    import android.widget.RemoteViews;
    import android.widget.TextView;
    
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Comparator;
    
    /**
     * Implementation of App Widget functionality.
     */
    public class NewAppWidget extends AppWidgetProvider {
    
        private final  static  String Action_UpDateTime ="android.appwidget.action.APPWIDGET_UPDATE";
        private final  static  String Action_Enable ="android.appwidget.action.APPWIDGET_ENABLED";
        private  static  ArrayList<Integer> widgetIds = new ArrayList<>();
    
        private static boolean  HasUpdateThread = false;
        Thread upWidget= null;
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
            int size = widgetIds.size();
            int [] widgetIdArray =  new int [size];
            for(int i = 0 ; i < size ; i++)
            {
                widgetIdArray[i] = widgetIds.get(i);
            }
    
            onUpdate(context , AppWidgetManager.getInstance(context) , widgetIdArray );
    
            System.out.println("收到了广播" + intent.getAction());
    
            super.onReceive(context, intent);
        }
    
        static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                                    int appWidgetId) {
            Calendar c = Calendar.getInstance();
            int hour = c.get(Calendar.HOUR_OF_DAY);
            int minute = c.get(Calendar.MINUTE);
            int seconds = c.get(Calendar.SECOND);
            CharSequence widgetText = "Time:" + hour + ":" + minute + ":" + seconds;//context.getString(R.string.appwidget_text);
            // Construct the RemoteViews object
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
            views.setTextViewText(R.id.appwidget_text, widgetText);
    
            // Instruct the widget manager to update the widget
            appWidgetManager.updateAppWidget(appWidgetId, views);
        }
    
    
        // 到达指定更新时间(new_app_widget_info.xml中指定的,大于30分钟才有效,小于30分钟会30分钟执行一次)
        // 或者向桌面添加Widget时候执行
        @Override
        public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
            // There may be multiple widgets active, so update all of them
            for (int appWidgetId : appWidgetIds)
            {
                updateAppWidget(context, appWidgetManager, appWidgetId);
                if(!widgetIds.contains((Integer)appWidgetId))
                {
                    System.out.println("不含有挂件"+appWidgetId);
                    widgetIds.add((Integer) appWidgetId);
                }
                else
                    System.out.println("含有挂件"+appWidgetId);
            }
            if (!HasUpdateThread)
            {
                System.out.println("创建了一个进程");HasUpdateThread =true;
                upWidget = new UpDateWiget(context);
                upWidget.start();
    
            }
        }
    
        //当第一个widget创建时候执行
        @Override
        public void onEnabled(Context context) {
            // Enter relevant functionality for when the first widget is created
    //        System.out.println("1111111111111111111111111111111111111111111111");
    
        }
    
        //当最后一个widget实例被删除时执行
        @Override
        public void onDisabled(Context context) {
            // Enter relevant functionality for when the last widget is disabled
        }
    
        class UpDateWiget extends Thread {
    //        public int widgetId;
            public Context context;
    
            public UpDateWiget(Context context) {
    //            this.widgetId = widgetId;
                this.context = context;
            }
    
            @Override
            public void run() {
                while (true) {
                    Intent intent = new Intent("android.appwidget.action.APPWIDGET_UPDATETIME");
    //                intent.putExtra("wigetId", widgetId);
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("发送了一条广播");
                    context.sendBroadcast(intent);
                }
            }
        }
    
    }
    

      挂件的布局文件:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#09C"
        android:padding="@dimen/widget_margin">
    
        <TextView
            android:id="@+id/appwidget_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:layout_margin="8dp"
            android:background="#09C"
            android:contentDescription="@string/appwidget_text"
            android:text="ca"
            android:textColor="#ffffff"
            android:textSize="20dp"
            android:textStyle="bold|italic" />
    
    </RelativeLayout>
    

      mainfset里注册的广播:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.user.appwidget">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    
            <receiver android:name=".NewAppWidget">
                <intent-filter>
                    <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="android.appwidget.action.APPWIDGET_UPDATETIME"/>
                </intent-filter>
    
                <meta-data
                    android:name="android.appwidget.provider"
                    android:resource="@xml/new_app_widget_info" />
            </receiver>
    
        </application>
    
    </manifest>
    

      

  • 相关阅读:
    poj1904 King's Quest
    ACM竞赛须掌握的知识 以及 2个版本的POJ推荐 @ NKOJ discuss 转载的
    poj1466
    C++23中设计模式的factory模式
    poj3667 hotel
    poj1505 Copying Books
    在linux系统中安装VSCode(Visual Studio Code)
    Spring_的jar详细说明
    java开发问题总结4Maven使用问题汇总
    线程同步之信号量(sem_init,sem_post,sem_wait)
  • 原文地址:https://www.cnblogs.com/bokeofzp/p/5968772.html
Copyright © 2020-2023  润新知