RemoteView

常驻通知栏

Notification

//使用Notification,需要注意在android8.0以上的系统中,需要定义channel,否则无法显示通知
mBuilder = new NotificationCompat.Builder(this, CHANNEL_TOOLS);
mBuilder.setSmallIcon(R.drawable.ic_notification); // 设置顶部图标(状态栏)

//需要实现自定义的布局,需要实现RemoteView,通过setContent()方法设置
mBuilder.setContent(remoteViews);

注意点:
1. 布局尽量不要限制死高度,在不同的Room下高度过大可能导致View超出通知框范围
2. 布局背景颜色需要考虑,尽量使用透明背景色,同时布局内其他组件也尽量保证在父布局透明时能够保持正常视图
3. 不能保证透明时较好的效果,则需要统一定死背景颜色,牺牲一定的room兼容(某些room获取通知栏颜色不准,会影响动态设置背景色)

RemoteView

自定义通知栏中,需要自定义通知栏的视图时,需要使用RemoteView定义视图,代码示例

//定义RemoteView视图
RemoteView remoteViews = new RemoteViews(getPackageName(), R.layout.layout_tools_unit_normal_white);

//需要注意,在RemoteView中使用的空间有比较严格的限制,仅支持有限的几种控件
//支持控件:

//布局
FrameLayout,LinearLayout,RelativeLayout,GridLayout

//控件
AnalogClock,Button,Chronometer,ImageButton,ImageView,ProgressBar,TextView,ViewFlipper,ListView,GridView,StackView,AdapterViewFlipper,ViewStub

注意点
1. 在RemoteView中自定义控件是莫得用的
2. 在RemoteView中没法直接拿到子View对象(可以通过方法操控)

RemoteView内的控件无法直接通过findViewById来获取,所以控制RemoteView中的组件需要通过提供的方法:

例如:
setTextViewText(int viewId, CharSequence text)
setImageViewResourse(int viewId, int resId)
setTextColor(int viewId, int color)

//实际上这一些方法的实现机制是通过反射完成的,所有RemoteView的子组件都通过RemoteView调用提供的方法来操作

常驻效果

//常驻效果可以通过这行代码实现
mBuilder.setOngoing(true);


小部件

小部件是可以单独在桌面显示的内容,本质上AppWidget实现的是一个广播(BroadCastReceiver),生成一个小部件会通知我们对AppWidget的定义,然后生成相应的布局以及内容

定义小部件主体

实现小部件:继承AppWidgetProvider

public class MyAgentWidget extends AppWidgetProvider {
    
    /*
     * 核心方法,在更新的时候调用
     */
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
        //appWidgetManager:主要用来调用updataAppWidget(int appwidgetId, RemoteView view)
        //这一方法用来替换刷新appwidgetId对应的小部件的布局显示,通过RemoteView控制布局内容
        //AppWidget装载内容同样使用的是RemoteView,所以RemoteView相关的限制在小部件上也一样存在

        //appWidgetIds:小部件定义完成以后,用户可以在桌面生成多个相同的小部件,所以一个小部件update()中对应的id会是数组类型的数据

    }
    
    
    public void onEnable(Context context) {
        //小部件首次添加到桌面时调用
    }
    
    public void onDisable(Context context) {
        //小部件移除桌面时调用
    }
}

AppWidgetManager的实例可以通过getInstance()来获取,在非Widget定义部分的代码也可以对小部件的内容进行修改

//将RemoteView设置给指定的小部件替换为新的布局样式
AppWidgetManager.getInstance().updateAppWidget(new ComponentName(Context, 小部件.class), RemoteView)

小部件注册

小部件本体是一个BroadCastReceiver,那么对应的在AndroidMainfest里要进行注册

<receiver android:name=".appwidget.MyAppWidget">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data
        android:name="android.appwidget.provider"
        <!-- resource指向的xml文件是对Widget的一些基本定义 -->
        android:resource="@xml/msg_widget_mine" />
</receiver>

小部件定义

在xml文件夹下,

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialKeyguardLayout="@layout/agent_tool_widget"   <!-- 初始定义锁屏页面中布局 -->
    android:initialLayout="@layout/agent_tool_widget"           <!-- 初始定义桌面中布局 -->
    
    android:minHeight="40dp"                                    <!-- 布局最小高度 -->   
    android:minWidth="250dp"                                    <!-- 布局最小宽度 -->
    
    android:previewImage="@mipmap/ic_tools"                     <!-- 在选择小部件时展示的图片 -->
    android:updatePeriodMillis="86400000"                       <!-- 更新时间毫秒值 -->
    android:widgetCategory="home_screen"></appwidget-provider>  <!-- 相当于一个类别小部件的标识 --> 

需要注意的是:通常定义下,桌面中的一格,宽高都是40dp,但在不同的room下表现都会有差别(部分系统会在边界添加padding),所以整体父布局尽量避免使用padding,保持和桌面应用的入口相似。
只占单格的小部件样式为了更好的适配,最好只用一张图片展示



快捷方式

快捷方式的实现和小部件原理相似,同样是发送广播生成;广播发送后由系统接收,之后根据广播中包含的内容生成快捷方式;

权限申请

<!-- 快捷方式生成 -->
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<!-- 快捷方式移除 -->
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
<!-- 快捷方式读取信息 -->
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.android.launcher2.permission.READ_SETTINGS" />
<uses-permission android:name="com.android.launcher3.permission.READ_SETTINGS" />

生成快捷方式

ShortcutInfoCompat info = new ShortcutInfoCompat(Context context, String title)
    .setIcon(快捷方式图标(Bitmap,IconCompat,Drawable))
    .setShortLabel(String title)
    .setIntent(点击快捷方式发出的Intent)
    .build();
    
//生成制定快捷方式   
PendingIntent shortcutCallbackIntent = PendingIntent.getBroadCast(Context context, int type:快捷方式的唯一标识, Intent intent, PendingIntent.FLAG_UPDATE_CURRENT)
ShortcutManagerCompat.requestPinShortcut(Context context, ShortcutInfoCompat info, IntentSender intentSender)    

快捷方式点击

Intnet intent = new Intent(Context context, Class clazz);
intent.setAction(Intent.ACTION_VIEW);   //必须设置项,缺失会导致崩溃

在首页点击快捷方式后将会直接根据Intent的内容进行相应的跳转,此处的Intent可以设置FLAG来控制Activity的启动模式


关于PendingIntent的点击效果

在RemoteView中要申明点击事件需要借助PendingIntent来完成,但是有非常重要的一点在于,PendingIntent中申明的Flag是没有效果的,也就是说需要跳转到首页之类的页面时,在Intent中指定的启动模式是不会起到作用的;
如果原先的首页是standard模式(一般都设置为这个模式),那么就会在跳转是创建一个新的首页(emm....),而修改首页的launchMode也并不可取,会影响到切置后台再从图标进入时的逻辑;

对于RemoteView的点击目标最好不要直接跳转到首页,如果有必须跳转的情况,这时就需要一个中转页面来辅助跳转,因为PendingIntent无法传递launchMode,所以需要先跳转至中转页,再由中转页通过Intent来定义launchMode,通过这种方式可以做到正确的跳转

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容