怎么设置原来状态栏的权限,让替代的状态栏一直显示而不mac 终端退出root权限?

怎样才能使QQ输入法的状态栏一直在桌面上显示?_百度知道
怎样才能使QQ输入法的状态栏一直在桌面上显示?
  状态栏是跟进程相关的,可以设置QQ拼音成为系统默认输入法,状态栏会一直在设置QQ拼音成为系统默认输入法的方法是:  右键点击右下角的语言栏图标,选择设置,在“默认输入语言”中把QQ拼音设置成为默认输入法。  QQ输入法是腾讯旗下的一款全功能输入法。和其它同类输入法一样,QQ输入法也将最常用的“中/英文切换”、“全/半角切换”、“中/英文标点切换”、“软键盘”和“属性设置”等按钮布置在了主界面上,用户只要轻轻一点,便可以完成这些特殊输入。而且QQ输入法也可以添加表情,可以发表微博。经典的企鹅图标也被一并放置在了界面之中。而且,为了更好地贴合主题,输入法中的QQ,也多了一项新装备,那就是一根大大的“笔”。 掌握用户的习惯也是QQ输入法的核心因素,针对用户的上网习惯,常用词汇的收集,成为到现在网民心目中使用较方便的输入法之一。
其他类似问题
为您推荐:
提问者采纳
在语言栏右击那个图标
在默认输入法那选择QQ输入法就好了
提问者评价
谢谢你了 !
其他2条回答
盘上的 CTRL 空格 键 按 键盘上的 CTRL 空格 键,做个有头有尾的人,按 键盘上的 CTRL 空格键,聊完,有时也不能解决的
如果你的输入法状态栏隐藏了,你可以通过开始—所有程序中找到输入法的文件夹,再点击文件夹内的设置,会出现输入法的设置窗口,在外观里面看看隐藏状态栏有没有打钩,有打钩去掉它,点击确定。桌面上状态栏就出来了!
qq输入法的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁您现在的位置: &
状态栏显示QQ/微信图标
粉丝积分128278经验25098 精华1签到70天O币1883
& && && &每当系统后台挂QQ/微信时,状态栏就不显示图标和消息了。误以为是软件自动退出了?其实解决方法很简单。& && && &1.状态栏显示QQ消息:& && && &进入QQ--设置--消息通知--打开通知显示消息内容。& && && &2.状态栏显示QQ图标:& && && &(a):进入QQ--设置--辅助功能--打开系统通知栏显示QQ图标。& && && &(b):步骤a打开之后状态栏还是没有,你可以进入手机设置--安全服务--通知中心--打开QQ。& &&&& & (c):如果你的纯净后冻结了QQ,状态栏也是不会显示QQ图标和消息的。所以平常使用的时候记得勾选允许后台运行。& && && &3.微信后台状态栏显示图标:& && && &先进入微信--设置--新消息提醒--接收新消息通知,将其勾选,其余步骤可参照上面QQ所描述的方法。
本帖最后由 oppo客服 于
14:34 编辑
粉丝积分858经验333 精华0签到0天O币645
15:53 上传
来自R829T.OPPO乐园4.7.1版
粉丝积分858经验333 精华0签到0天O币645
15:53 上传
来自R829T.OPPO乐园4.7.1版
粉丝积分858经验333 精华0签到0天O币645
还是不现实啊
来自R829T.OPPO乐园4.7.1版
粉丝积分858经验333 精华0签到0天O币645
纯净后台也没有冻结,还是不行
来自R829T.OPPO乐园4.7.1版
Lv4.高中生O粉
粉丝积分491经验489 精华0签到0天O币10
Lv4.高中生O粉, 积分 491, 距离下一级还需 509 积分
哈哈,问题解决了
来自R831T.OPPO乐园4.7.1版
&解决了,谢谢&
8月11日 星期四66970人签到
风景、卡通、炫酷几何,马上来装扮你的手机吧~
十二星座的专属音乐,你最喜欢哪个呢?
换了4G流量刷刷就没了?今天卤煮就教你一键开启2G网络,再也不用但系费流量了android 状态栏(StatusBar)
android 状态栏(StatusBar)
一、SystemUI 概述
&&&&&&& 自android2.2开始
原本存在与framework-res.apk中的状态栏和下拉通知栏界面控制被分割出一个单独的apk
SystemUI.apk,
System/app文件夹中。在
SystemUI.apk
,是存在着状态栏的图标,XML
和控制文件等
,这样的分割
使我们可以更方便地去修改。
SystemUI模块中主要包含了
和Statusbar两个子模块,本文将以Statusbar为主导来向大家阐述SystemUI
Statusbar的功能作用,使用方法,模块框架,以及模块内部的重要流程。
1.1 Statusbar 的功能作用
状态栏主要用来显示一些系统图标,应用的通知图标和系统时间。Statusbar模块就是控制和管理着这些图标,以及通知信息的显示和一些系统开关的。
Ⅰ、状态栏的通知功能(包括时间,通知,系统状态等)
状态栏与Toast都可以起到通知、提醒的作用。但它们的实现原理和表现形式却完全不一样。Toast其实相当于一个Widget组件,有些类似于没有按钮的对话框。而Statusbar可与系统其它应用进行交互来显示在屏幕上方状态栏中的信息,并且Statusbar还可通过图标的显示变化来反应一些系统状态的变换,如电池电量,wifi,系统音量,闹钟等。状态栏是一种让你的应用程序或系统信息变化在不使用Activity
的情况下给用户的提醒和通知。
Ⅱ、状态栏的日期显示
&&&&&状态栏也会显示系统时间,当前日期也会在状态栏显示,只是在默认情况下日期是隐藏的,只有在点击状态栏时才会显示。
1.2 Statusbar 的使用方法
1.2.1 notification 的使用
Ⅰ、Notification主要作用和使用步骤:
Notification是看不见的程序组件(
Broadcast Receiver ,Service
和不活跃的 Activity )警示用户有需要注意的事件发生的最好途径
下面主要介绍使用方法步骤:
获取NotificationManager
获取Notification
示例,设置属性,并发送通知
Java代码 &
public&class&Main&extends&Activity&{
&&&&&&private&Button&sendBtn&,&cancelB &&&&&&private&Notification&n; &&&&&&private&NotificationManager& &&&&&&&&&&&&private&static&final&int&ID&=&1;
&&&&& &&&&&&@Override&&&&&&public&void&onCreate(Bundle&savedInstanceState)&{ &&&&&&&&&&super.onCreate(savedInstanceState); &&&&&&&&&&setContentView(R.layout.main); &&&&&&&&& &&&&&&&&&&&&&&&&&&&&sendBtn&=&(Button)this.findViewById(R.id.sendBtn); &&&&&&&&&&cancelBtn&=&(Button)this.findViewById(R.id.cancelBtn); &&&&&&&&& &&&&&&&&&&&&&&&&&&&&String&service&=&NOTIFICATION_SERVICE; &&&&&&&&&&nm&=&(NotificationManager)this.getSystemService(service); &&&&&&&&& &&&&&&&&&&&&&&&&&&&&n&=&new&Notification(); &&&&&&&&&&&&&&&&&&&&int&icon&=&R.drawable. &&&&&&&&&&&&&&&&&&&&String&tickerText&=&"Test&Notifaction"; &&&&&&&&&&&&&&&&&&&&long&when&=&System.currentTimeMillis(); &&&&&&&&& &&&&&&&&&&n.icon&=& &&&&&&&&&&n.tickerText&=&tickerT &&&&&&&&&&n.when&=& &&&&&&&&&&n.flags&=&Notification.FLAG_NO_CLEAR; &&&&&&&&&&n.flags&=&Notification.FLAG_ONGOING_EVENT; &&&&&&&&& &&&&&&&&&&&&&&&&&&&&sendBtn.setOnClickListener(sendClickListener); &&&&&&&&&&cancelBtn.setOnClickListener(cancelClickListener); &&&&&&} &&&&& &&&&&&private&OnClickListener&sendClickListener&=&new&OnClickListener()&{
&&& &&&&@Override&&&&public&void&onClick(View&v)&{ &&&&&&&&&&Intent&intent&=&new&Intent(Main.this,&Main.class);
&&&&&&&&&&PendingIntent&pi&=&PendingIntent.getActivity(Main.this,&0,&intent,&0);
&&&&&n.setLatestEventInfo(Main.this,&"My&Title",&"My&Content",&pi);
&&&&&nm.notify(ID,&n); &&&& &&&&&&&&&} &&}; &&private&OnClickListener&cancelClickListener&=&new&OnClickListener(){
&&& &&&&@Override&&&&public&void&onClick(View&v)&{ &&&&&nm.cancel(ID); &&&&} &&}; &&}&&&&&
[java] public&class&Main&extends&Activity&{&&&&&&private&Button&sendBtn&,&cancelB&&&&&&private&Notification&n;&&&&&&private&NotificationManager&&&&&&&&&&&&&private&static&final&int&ID&=&1;&&&&&&&&&&&@Override&&&&&&public&void&onCreate(Bundle&savedInstanceState)&{&&&&&&&&&&super.onCreate(savedInstanceState);&&&&&&&&&&setContentView(R.layout.main);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sendBtn&=&(Button)this.findViewById(R.id.sendBtn);&&&&&&&&&&cancelBtn&=&(Button)this.findViewById(R.id.cancelBtn);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&String&service&=&NOTIFICATION_SERVICE;&&&&&&&&&&nm&=&(NotificationManager)this.getSystemService(service);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&n&=&new&Notification();&&&&&&&&&&&&&&&&&&&&int&icon&=&R.drawable.&&&&&&&&&&&&&&&&&&&&String&tickerText&=&"Test&Notifaction";&&&&&&&&&&&&&&&&&&&&long&when&=&System.currentTimeMillis();&&&&&&&&&&&&&&&&&&&n.icon&=&&&&&&&&&&&n.tickerText&=&tickerT&&&&&&&&&&n.when&=&&&&&&&&&&&n.flags&=&Notification.FLAG_NO_CLEAR;&&&&&&&&&&n.flags&=&Notification.FLAG_ONGOING_EVENT;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sendBtn.setOnClickListener(sendClickListener);&&&&&&&&&&cancelBtn.setOnClickListener(cancelClickListener);&&&&&&}&&&&&&&&&&&private&OnClickListener&sendClickListener&=&new&OnClickListener()&{&&&&&&&@Override&&&&public&void&onClick(View&v)&{&&&&&&&&&&Intent&intent&=&new&Intent(Main.this,&Main.class);&&&&&&&&&&PendingIntent&pi&=&PendingIntent.getActivity(Main.this,&0,&intent,&0);&&&&&&&&&&n.setLatestEventInfo(Main.this,&"My&Title",&"My&Content",&pi);&&&&&&&&&&nm.notify(ID,&n);&&&&&&&&&&&&&}&&};&&private&OnClickListener&cancelClickListener&=&new&OnClickListener(){&&&&&&&@Override&&&&public&void&onClick(View&v)&{&&&&&nm.cancel(ID);&&&&}&&};&&}&&&&&
Ⅱ、步骤详解
获取NotificationManager实例
这个类主要负责将Notification在状态栏中显示出来和取消。主要包括5个函数:
void cancel(int id),
void cancel(String tag, int id) ,void cancelAll()
, void notify(int id, Notification notification),
notify(String tag, int id, Notification notification)
看看这五个函数就知道这个类的作用了。但是在初始化对象的时候要注意:
NotificationM
String service = NOTIFICATION_SERVICE;
nm = (NotificationManager)this.getSystemService(service);
获取Notification示例,设置属性,并发送通知
这个类主要是设置Notification的相关属性,初始化。
Notification n = new Notification();
Notification里面有很多属性下面选择几个常用的介绍一下(表1.1)
这个是设置通知的图标。像天气预报图标。
这个是设置来通知时的提示音。
tickerText
设置提示的文字。
来通知时振动。
设置来通知时的时间。
contentIntent
Notification的
,即点击后转向的
FLAG_NO_CLEAR
设置为这个属性那么通知栏的那个清楚按钮就不会出现
FLAG_ONGOING_EVENT
设置为这个属性那么通知就会像QQ图标一样一直在状态栏显示
DEFAULT_ALL
将所有属性设置为默认
DEFAULT_SOUND&
将提示声音设置为默认
DEFAULT_VIBRATE
将震动设置为默认
填充Notification的各个属性:
//Notification的
Intent ,即点击后转向的 Activity
Intent notificationIntent1 = new Intent(this, this.getClass());
notificationIntent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent1 = PendingIntent.getActivity(this, 0, notificationIntent1, 0);
n.contentIntent=contentIntent1;
n.icon = R.drawable.notification_
n.tickerText = "hello";
notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3");
notification.vibrate =
发送通知:
private static final int ID_NOTIFICATION = 1;
mNotificationManager.notify(ID_NOTIFICATION, notification);
通知的更新
&&如果需要更新一个通知,只需要在设置好
notification 之后,再调用setLatestEventInfo
,然后重新发送一次通知即可。
自定义通知视图
& &这部分可以参考官方文档,讲的很详细了。
AndroidSDK: docs/guide/topics/ui/notifiers/notifications.html
Notification.Builder
这个类一般用于管理Notification,动态的设置
Notification
的一些属性。即用set
问题:如何区分“正在进行的”和“通知”,谁决定一个事件是“正在进行的”还是持续的“通知”?
通过设置Notification的flag属性可以设定notification是正在进行的还是持续的notification。
FLAG_INSISTENT和FLAG_ONGOING_EVENT标志位可以让Notification成为持续的或正在进行的Notification。
.Notification
标记为ONGOING,如下面的代码所示,它就能用于表示当前正在进行的事件(如来电)。正在进行的事件与“通知”Notification区别在扩展的状态条窗口中。
notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
.持续的Notification一直重复,直到用户取消。下面的代码给出了如何设置Notification为持续的:
notification.flags = notification.flags | Notification.FLAG_INSISTENT;
持续Notification
反复重复开头的 Notification效果,直到用户取消。持续的
Notification 应该保留给如闹钟的情形,它需要及时的采取响应.
1.2.2 系统图标的增加删除
这里主要向大家介绍如何添加一个在状态栏显示的系统图标,类似于系统默认的闹钟图标,声音图标等。
文件中加资源:
.frameworks\base\core\res\res\drawalbe
中添加系统图标的图片资源
.frameworks\base\core\res\res\values\config.xml
中添加图片引用,这些
在这个string array的位置就决定了其在status
bar 上显示的位置了。我们可以从code
里面得出该结论。所以当你要调换
的顺序时,改动这个config.xml就可以了。在
StatusBarManagerService
初始化的时候就会读取config.xml下
icons 的String array。
这个文件中加代码:StatusBarPolicy.java
以闹钟为例。
StatusbarPolicy.java
中初始化所增加的系统图标
.在构造函数中
.StatusBarPolicy
调用registerReceiver
注册了感兴趣的
intent,当感兴趣的
发生时,对图标进行更新。例如,设置一个闹钟后,闹钟模块会发出一个叫做Intent.ACTION_ALARM_CHANGED的广播,然后
StatusBarPolicy
接收到此广播,继而更新状态栏上的闹钟图标。
// Alarm clock StatusBarPolicy构造方法中初始化闹钟图标
mService.setIcon("alarm_clock",R.drawable.stat_notify_alarm, 0);
mService.setIconVisibility("alarm_clock", false);
// StatusBarPolicy构造方法中注册闹钟改变广播
filter.addAction(Intent.ACTION_ALARM_CHANGED);
图标更新函数
private final void updateAlarm(Intent intent) {
boolean alarmSet = intent.getBooleanExtra(“alarmSet”, false);
mService.setIconVisibility(“alarm_clock”, alarmSet);
以上是在状态栏添加显示的系统图标的步骤。
代码执行步骤:
StatusBarManagerService.java中
StatusBarIconList mIcons = newStatusBarIconList();
&&&&&&&&& mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.config_statusBarIcons));
&&&&&&&&& StatusBarPolicy.java -- & setIcon(…)
&&&&&&&&& StatusBarManager.java-- & setIcon(…)
&&&&&&&&& StatusBarManagerService.java-- & setIcon(…)
在StatusBarService的onCreate的时候调用StatusBarManagerService中的registerStatusBar(…)
Statusbar中的控制开关会做详细的描述,这里就不在赘述。
二、模块基本布局
2.1 Statusbar 布局
Android系统顶上的状态栏是属于FrameWork的内容,在此先对
的的结构做一定描述。
StatusBar的布局文件
status_bar.xml
,文件位置:
frameworks/base/packages/SystemUI/res/layout/status_bar.xml
LinearLayout android:id="@+id/icons"我们看到的状态栏,系统默认是左边放通知图标
notificationIcons
,右边放状态图标
statusIcons
通知图标区域:&
IconMerger android:id="@+id/notificationIcons"
状态图标区域:
LinearLayout android:id="@+id/statusIcons"
LinearLayout android:id="@+id/ticker"显示。在正常情况下ticker
是不显示的,只有在
StatusBarService
收到通知时它才显示
最后一个是DateView
,它是在点击
statusbar时才显示的,默认是隐藏的
三、模块内部框架
Statusbar内部各种交互以及模块与其他应用的交互都是建立在StatusbarService之上的,其中包括
视图的创建(包括
、 TrackingView和
StatusbarExpandedView
),视图动画,系统图标(闹钟、
卡等)的加载和管理,其他应用通知信息的加载显示、更新、删除等,其他应用的远程接口控制(如当打电话时statusbar处于禁用状态的)对Android
系统其他应用的通知信息(包括图标、
、notification的布局等)的处理。SIM
卡信息的控制等。
总之StatusbarService是
的灵魂所在,是
Statusbar的核心,所有关于
的操作处理都是建立在
StatusbarService
这个基础之上的。
四、模块流程
在整个Statusbar模块中包括了多个操作流程(例如StatusbarService的启动流程),
与系统其他应用交互的处理流程(例如
对天气预报的通知的处理),还有系统图标的更新流程,
拖动时动画的绘制流程,以及远程接口的控制流程等。
4.1启动流程
4.1.1 StatusbarService的启动流程
首先,当系统进程system_press启动之后,调用系统SystemServer.java,在
SystemServer
ServerThread.run()方法时会注册
StatusBarManagerService
Java代码 &
&SPAN&style="FONT-SIZE:&x-small"&try&{ &&&&Slog.i(TAG,&"Status&Bar"); &&&&statusBar&=&new&StatusBarManagerService(context); &&&&ServiceManager.addService(Context.STATUS_BAR_SERVICE,&statusBar); &&&&}&catch&(Throwable&e)&{ &&&&Slog.e(TAG,&"Failure&starting&StatusBarManagerService",&e); &&&&} &&&&让后调用StatusBarManagerService&的systemReady2()&方法,会在systemReady2()&方法中启动StatusbarService&。 &&&&final&StatusBarManagerService&statusBarF&=&statusB &&&&if&(statusBarF&!=&null)&statusBarF.systemReady2(); &&&&public&void&systemReady2()&{ &&&&ComponentName&cn&=&ComponentName.unflattenFromString(mContext.getString(com.android.internal.R.string.config_statusBarComponent)); &&&&Intent&intent&=&new&Intent(); &&&&intent.setComponent(cn); &&&&Slog.i(TAG,&"Starting&service:&"&+&cn); &&&&mContext.startService(intent); &&&&}&&/SPAN&&&
[java] try&{&span&style="font-size:10"&&span&style="font-size:10"&&&&&Slog.i(TAG,&"Status&Bar");&&&&statusBar&=&new&StatusBarManagerService(context);&&&&ServiceManager.addService(Context.STATUS_BAR_SERVICE,&statusBar);&&&&}&catch&(Throwable&e)&{&&&&Slog.e(TAG,&"Failure&starting&StatusBarManagerService",&e);&&&&}&&&&让后调用StatusBarManagerService&的systemReady2()&方法,会在systemReady2()&方法中启动StatusbarService&。&&&&final&StatusBarManagerService&statusBarF&=&statusB&&&&if&(statusBarF&!=&null)&statusBarF.systemReady2();&&&&public&void&systemReady2()&{&&&&ComponentName&cn&=&ComponentName.unflattenFromString(mContext.getString(com.android.internal.R.string.config_statusBarComponent));&&&&Intent&intent&=&new&Intent();&&&&intent.setComponent(cn);&&&&Slog.i(TAG,&"Starting&service:&"&+&cn);&&&&mContext.startService(intent);&&&&}&&/span&&/span&&&
注:在SystemUI模块的SystemUiApp.java的onCreate方法中也会startService,这是当Statusbar意外退出而导致StatusbarService停止服务时会重新启动StatusbarService
4.1.2系统图标初始化流程
在启动StatusBarService后,StatusbarService会调用一个makeStatusBarView的方法,在里面将创建StatusBarView在创建StatusbarView的过程中会加载系统图标。
在启动StatusbarService的过程中会创建StatusBarPolicy的对象,StatusBarPolicy.java主要负责状态栏显示策略的管理(如状态栏的图标什么时候显示,在什么位置显示等)。StatusBarPolicy的构造函数中初始化了很多系统图标(如电池信息图标,闹钟图标,声音图标,信号栏图标等)。。默认时有很多图标是不显示的,需要显示时再进行更新。
图标初始化,以电池电量显示为例,大概关键步骤如下:
通过BroadcastReceiver机制,StatusBarPolicy中注册的mIntentReceiver收到BatteryService广播的ACTION_BATTERY_CHANGED事件触发;
调用updateBattery(intent)开始更新电池状态栏;
从intent中解析需要的字段,调用StatusBarManager的setIcon()。StatusBarManager是客户端使用的状态栏管理类;
通过IBinder机制跨进程调用StatusBarManagerService的setIcon()。StatusBarManagerService派生于IStatusBarService.Stub,是状态栏管理的服务端,是具体实现;
StatusBarManagerService有一个mIcons成员,这个list成员在StatusBarManagerService创建时加载。StatusBarManagerService的setIcon()过程中,会又"battery"字段获得在mIcons中的索引,再由包名、图片id和等级创建StatusBarIcon实例,并将这个实例更新StatusBarIconList中所获得索引对应项;
调用CommandQueue的setIcon()。CommandQueue派生于IStatusBar.Stub,有一个内部接口Callbacks,这个接口的实现就是StatusBarService。CommandQueue、StatusBarService和StatusBarManager属于同一个进程,而StatusBarManagerService是一个系统级服务,它们之间必然需要通过IBinder进程间通信;
CommandQueue用于处理状态栏、通知相关的请求,内部维护了一个事件队列,setIcon()会创建一个OP_SET_ICON的massege,发送给Handler处理;
CommandQueue内部也有一个StatusBarIconList实例,这个实例是由StatusBarService创建。在处理OP_SET_ICON的massege前,会先通过getViewIndex获得图标View的位置索引viewIndex,(因为有些图标有可能为空)再更新StatusBarIconList,最后调用Callbacks,也就是StatusBarService的addIcon()或者updateIcon();
以addIcon()为例,StatusBarService的addIcon()会创建一个新的StatusBarIconView,将第步中所创建的StatusBarIcon实例设置进去,然后把这个view添加到LinearLayout的viewIndex位置。
这样一个电池相关图标就在状态栏上添加或者更新了。删除操作类似。
4.2 通知处理
在应用Activity中实现通知栏图标变化的程序中。是用NotificationManager对象mNotificationManager来发送通知。通知为Notification
mNotification& 对象,填充mNotification&
的图标和消息内容以及一个when,然后构造了一个Intent对象intent,包含了本Activity对象的引用,以及本Activity的类名,一个PendingIntent
pi对象,包含上述Intent对象以及本Activity对象的引用,是用于消息列表中显示本Activity项。点击时重新激活Activity。然后调用nm.setLatestEventInfo设置状态栏下拉列表项内容。最后调用nm.notify(1,n)方法来发送通知,接着改变状态栏的工作就由NotificationManager和StatusBarManagerService交互了。
下面来看看NotificationManager 是如何和StatusBarManagerService 交互的。
nm.notify(1,n)方法做了最重要的事,就是所谓的发送通知&
该方法的代码如下:
public void notify(int id, Notification notification)&
&&&&&&&&notify(null, id, notification);
实际上是调用了下面这个函数:
public void notify(String tag, int id, Notification notification)
&&&&&&&&int[] idOut = new int[1];
&&&&&&&&INotificationManager service = getService();
&&&&&&&&String pkg = mContext.getPackageName();
&&&&&&&&if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
&&&&&&&&try {
&&&&&&&&&&&&service.enqueueNotificationWithTag(pkg, tag, id, notification, idOut);
&&&&&&&&&&&&if (id != idOut[0]) {
&&&&&&&&&&&&&&&&Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
&&&&&&&&&&&&}
&&&&&&&&} catch (RemoteException e) {
该函数中主要做了2件事:获取一个服务,用该服务将通知事件“入队”插入通知队列,所以应该在某个地方有人在不停的读取通知队列。
getService的代码,这里的INotificationManager.Stub.asInterface(b)这个形式在好多地方出现,一定要详细理解该类代码,在Binder机制中。
static public INotificationManager getService()
&&&&&&&&if (sService != null) {
&&&&&&&&&&&&return sS
&&&&&&&&IBinder b = ServiceManager.getService("notification");
&&&&&&&&sService = INotificationManager.Stub.asInterface(b);
&&&&&&&&return sS
在StatusBarManagerService中添加了该消息:
NotificationManagerService的enqueueNotificationInternal函数中:
r.statusBarKey =&
mStatusBar.addNotification(n);&&
其中n是由notification对象构造的statusBarNotification对象&mStatusBar是一个StutusBarManagerService的引用。
在addNotification()中执行了:
synchronized (mNotifications) {
&&&&&&&&&&&&IBinder key = new Binder();
&&&&&&&&&&&&mNotifications.put(key, notification);
&&&&&&&&&&&&if (mBar != null) {
&&&&&&&&&&&&&&&&try {
&&&&&&&&&&&&&&&&&&&&mBar.addNotification(key, notification);
&&&&&&&&&&&&&&&&} catch (RemoteException ex) {
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&
这里先执行了mNotification.put将该通知加入一个hashMap结构体中
然后执行了mBar.addNotification(key,notification)&
调用了CommandQueue中的addNotification方法,该方法利用Handler调用了mCallbacks.addNotification方法,其实就是StatusBarService中的。
这个mBar是由方法:
public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList,
&&&&&&&&&&&&List&IBinder& notificationKeys, List&StatusBarNotification& notifications) {
&&&&&&&&enforceStatusBarService();
&&&&&&&&Slog.i(TAG, "registerStatusBar bar=" + bar);
&&&&&&&&mBar =
&&&&&&&&synchronized (mIcons) {
&&&&&&&&&&&&iconList.copyFrom(mIcons);
&&&&&&&&synchronized (mNotifications) {
&&&&&&&&&&&&for (Map.Entry&IBinder,StatusBarNotification& e: mNotifications.entrySet()) {
&&&&&&&&&&&&&&&&notificationKeys.add(e.getKey());
&&&&&&&&&&&&&&&&notifications.add(e.getValue());
&&&&&&&&&&&&}
在StatusBarService启动的时候注册的mCommandQueue对象的引用&
mCommandQueue = new CommandQueue(this, iconList);
由该对象的实例化以及其构造函数
public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
&&&&&&&&mCallbacks =
&&&&&&&&mList =
可以看出,注册的mCommandQueue中的callbacks接口,是由StatusBarService实现的
public interface Callbacks {
&&&&&&&&public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon);
&&&&&&&&public void updateIcon(String slot, int index, int viewIndex,
&&&&&&&&&&&&&&&&StatusBarIcon old, StatusBarIcon icon);
&&&&&&&&public void removeIcon(String slot, int index, int viewIndex);
&&&&&&&&public void addNotification(IBinder key, StatusBarNotification notification);
&&&&&&&&public void updateNotification(IBinder key, StatusBarNotification notification);
&&&&&&&&public void removeNotification(IBinder key);
&&&&&&&&public void disable(int state);
&&&&&&&&public void animateExpand();
&&&&&&&&public void animateCollapse();
接口声明如上:
其中,StatusBarService对addNotification的实现如下:
public void addNotification(IBinder key, StatusBarNotification notification) {
boolean shouldTick =
if (notification.notification.fullScreenIntent != null) {
shouldTick =
Slog.d(TAG, "Notification has fullScreenI sending fullScreenIntent");
notification.notification.fullScreenIntent.send();
} catch (PendingIntent.CanceledException e) {
StatusBarIconView iconView = addNotificationViews(key, notification);
if (iconView == null)
if (shouldTick) {
tick(notification);
// Recalculate the position of the sliding windows and the titles.
setAreThereNotifications();
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
所以到头来enqueueNotificationInternal方法中mBar.addNotification(key,
notification);其实是调用了StatusBarService实现的addNotification方法,即上面的代码。
上面的代码中这句StatusBarIconView iconView = addNotificationViews(key,
notification);& 以及tick(notification)&
可能是将图标以及信息显示在StatusBarView上的主要语句。接着进入这两个方法。
addNotificationViews():
StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) {
&&&&&&&&NotificationD
&&&&&&&&ViewG
&&&&&&&&final boolean isOngoing = notification.isOngoing();
&&&&&&&&if (isOngoing) {
&&&&&&&&&&&&list = mO
&&&&&&&&&&&&parent = mOngoingI
&&&&&&&&} else {
&&&&&&&&&&&&list = mL
&&&&&&&&&&&&parent = mLatestI
&&&&&&&&// Construct the expanded view.
&&&&&&&&final View[] views = makeNotificationView(notification, parent);
&&&&&&&&if (views == null) {
&&&&&&&&&&&&handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
&&&&&&&&&&&&&&&&&&&&+ notification);
&&&&&&&&&&&&
&&&&&&&&final View row = views[0];
&&&&&&&&final View content = views[1];
&&&&&&&&final View expanded = views[2];
&&&&&&&&// Construct the icon.
&&&&&&&&final StatusBarIconView&iconView&= new StatusBarIconView(this,
&&&&&&&&&&&&&&&&notification.pkg + "/0x" + Integer.toHexString(notification.id));
&&&&&&&&final StatusBarIcon ic = new StatusBarIcon(notification.pkg, notification.notification.icon,
&&&&&&&&&&&&&&&&&&&&notification.notification.iconLevel, notification.notification.number);
&&&&&&&&if (!iconView.set(ic)) {
&&&&&&&&&&&&handleNotificationError(key, notification, "Coulding create icon: " + ic);
&&&&&&&&&&&&
&&&&&&&&// Add the expanded view.
&&&&&&&&final int viewIndex = list.add(key, notification, row, content, expanded, iconView);
&&&&&&&&parent.addView(row, viewIndex);
&&&&&&&&// Add the icon.
&&&&&&&&final int iconIndex = chooseIconIndex(isOngoing, viewIndex);
&&&&&&&&mNotificationIcons.addView(iconView, iconIndex);
&&&&&&&&return iconV
final StatusBarIconView iconView = new StatusBarIconView(this,
&&&&&&&&&&&&&&&&notification.pkg + "/0x" + Integer.toHexString(notification.id));
其中这一句利用传来的notification构造了图标view
mNotificationIcons.addView(iconView, iconIndex);&
其中mNotificationIcons是一个IconMerger对象,IconMerger是继承LinearLayout的类。
这一句将图标显示在StatusBar上。
如上就是当应用发送完notification后
StatusbarService
是如何将发送的信息显示到
4.3 图标更新
4.3.1通过广播接收器的方式
StatusBarPolicy调用
registerReceiver注册了感兴趣的
当感兴趣的intent
发生时,对图标进行更新。例如,设置一个闹钟后,闹钟模块会发出一个叫做
Intent.ACTION_ALARM_CHANGED
的广播,然后
StatusBarPolicy接收到此广播,继而更新状态栏上的闹钟图标。
// Alarm clock StatusBarPolicy构造方法中初始化闹钟图标
mService.setIcon("alarm_clock",R.drawable.stat_notify_alarm, 0);
mService.setIconVisibility("alarm_clock", false);
// StatusBarPolicy构造方法中注册闹钟改变广播
filter.addAction(Intent.ACTION_ALARM_CHANGED);
//改变闹钟图标
private final void updateAlarm(Intent intent) {
boolean alarmSet = intent.getBooleanExtra(“alarmSet”, false);
mService.setIconVisibility(“alarm_clock”, alarmSet);
StatusBarPolicy只是一个策略管理,实际的功能是StatusBarService来实现的。
StatusBarService
初始化时初始化了一个用于显示
statusbar 的StatusBarView。
StatusBarView
里面定义了
icon名字,的显示顺序,对应的png
StatusBarService调用
makeStatusBarView
方法时实现
statusbar的初始化
4.3.2通过远程代理方式
StatusBarManager有一个更新图标的方法:
public void updateIcon(IBinder key, String slot, int iconId, int iconLevel),不过
StatusBarManager
并未把方法公开在
sdk 中,但是应该有方法可以访问的。
&&& public void updateIcon(IBinder key, String slot, int iconId, int iconLevel) {
&&&&&&& try {
&&&&&&&&&&& mService.updateIcon(key, slot, mContext.getPackageName(), iconId, iconLevel);
&&&&&&& } catch (RemoteException ex) {
&&&&&&&&&&&&&&&&&&&&&& throw new RuntimeException(ex);
mService 是StatusBarManager的一个成员变量,
StatusBarManager
被构建的时候被赋值,他是
IStatusBar
的一个代理对象
&&&StatusBarManager(Context context) {
&&&&&&& mContext =
&&&&&&& mService = IStatusBar.Stub.asInterface(
&&&&&&&&&&&&&&& ServiceManager.getService(Context.STATUS_BAR_SERVICE));
4.4 拖动刷新
4.4.1 StatusbarView从被点击到拖动
从点击StatusBar会出现新的View,它的流程如下:
StatusBarView 就是StatusBar 所代表的View ,那么查看它的代码,看它处理点击的方法。
它属性变量保存了StatusBarService的引用mService,它的点击处理函数onTouchEvent()和onInterceptTouchEvent()都会调用到StatusBarService类中的interceptTouchEvent()方法。
当我们点击StatusBar 时,会先走到onInterceptTouchEvent() 这个函数,而且这个函数只会在第一次走到,然后会走到onTouchEvent() 方法,这个方法每收到一个TouchEvent()
就会走到,因此会走到多次。
函数onInterceptTouchEvent() 的处理:
1 、调用到StatusBarService 中的interceptTouchEvent() ,在这里又会走到event.getAction()
== MotionEvent.ACTION_DOWN 分支,在分支中,由于mExpanded == false 且y & hitSize会继续调用prepareTracking(y) 。
2 、函数prepareTracking() 处理:这里由于mExpanded == false所以会向H 中发送MSG_ANIMATE_REVEAL
消息,进入StatusBarService 自己的消息循环。执行doRevealAnimation() 函数。
3 、函数doRevealAnimation() 处理:这个实现的功能很简单,就是在TrackingView( 就是点击时StatusBar
下出现的View) 还没有完全显示出来的时候,通过动画的方式,一点一点的将TrackingView 显示出来。
当我们手指离开时调用顺序如下:
1 、StatusBarView :onTouchEvent() ,此时Action != MotionEvent.ACTION_DOWN
走到 StatusBarService :interceptTouchEvent() ;
2 、interceptTouchEvent() 中会走到分支else if (mTracking) ;
3 、由于ACTION_UP所以会调用performFling() ,在这里会向Handler 发送
MSG_ANIMATE消息,然后进入函数doAnimation() 。
4 、在doAnimation() 由于mAnimY & mStatusBarView.getHeight() 分支成立,会继续调用updateExpandedViewPos(0)
和performCollapse();
5 、在performCollapse() 中,通过mTrackingView.setVisibility(View.GONE)实现了让mTrackingView
的隐藏,其实这个函数还实现了其他的View 的隐藏,比如我们点击后进行拖动所出现的其他View 。
4.5 远程接口
4.5.1 Statusbar远程接口简介
StatusBarManagerService通过使用
IStatusBar
aidl调用 CommandQueue&在
CommandQueue 中定义Callbacks&
StatusBarService实现了
CommandQueue
Callbacks的回调
public interface Callbacks {
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon);
public void updateIcon(String slot, int index, int viewIndex,
StatusBarIcon old, StatusBarIcon icon);
public void removeIcon(String slot, int index, int viewIndex);
public void addNotification(IBinder key, StatusBarNotification notification);
public void updateNotification(IBinder key, StatusBarNotification notification);
public void removeNotification(IBinder key);
public void disable(int state);
public void animateExpand();
public void animateExpandToggles(boolean needForceStatusBar);
public void animateCollapse();
public void showSIMIndicator(String businessType);
public void hideSIMIndicator();
由上述源码我们可以得出在StatusbarService.java中都有增加
删除状态栏图标、增加/
notification
Statusbar、
指示信息的隐藏和显示、还有Statusbar拖动动画的实现。
4.5.2 StatusBarManager的使用
所讲,通过远程代理方式更新状态栏图标,因为
StatusBarManager
SDK中并未公开如下就讲述对StatusBarManager的使用方法。
在StatusbarService.java中的的
方法,就实现并扩展了了StatusbarManager的
所实现的功能(如statusbar的禁止拖动,不显示通知图标,不显示ticker
Java代码 &
&SPAN&style="FONT-SIZE:&x-small"&&&&&&&&public&void&disable(int&state)&{
&&&&&&&&&&final&int&old&=&mD &&&&&&&&&&final&int&diff&=&state&^& &&&&&&&&&&mDisabled&=& &&&&&&&&&&if&((diff&&&StatusBarManager.DISABLE_EXPAND)&!=&0)&{ &&&&&&&&&&&&&&if&((state&&&StatusBarManager.DISABLE_EXPAND)&!=&0)&{ &&&&&&&&&&&&&&&&&&if&(SPEW)&Slog.d(TAG,&"DISABLE_EXPAND:&yes"); &&&&&&&&&&&&&&&&&&animateCollapse(); &&&&&&&&&&&&&&} &&&&&&&&&&} &&&&&&&&&&if&((diff&&&StatusBarManager.DISABLE_NOTIFICATION_ICONS)&!=&0)&{ &&&&&&&&&&&&&&if&((state&&&StatusBarManager.DISABLE_NOTIFICATION_ICONS)&!=&0)&{
&&&&&&&&&&&&&&&&&&if&(SPEW)&Slog.d(TAG,&"DISABLE_NOTIFICATION_ICONS:&yes"); &&&&&&&&&&&&&&&&&&if&(mTicking)&{ &&&&&&&&&&&&&&&&&&&&&&mTicker.halt(); &&&&&&&&&&&&&&&&&&}&else&{ &&&&&&&&&&&&&&&&&&&&&&setNotificationIconVisibility(false,&com.android.internal.R.anim.fade_out); &&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&}&else&{ &&&&&&&&&&&&&&&&&&if&(SPEW)&Slog.d(TAG,&"DISABLE_NOTIFICATION_ICONS:&no"); &&&&&&&&&&&&&&&&&&if&(!mExpandedVisible)&{ &&&&&&&&&&&&&&&&&&&&&&setNotificationIconVisibility(true,&com.android.internal.R.anim.fade_in); &&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&} &&&&&&&&&&}&else&if&((diff&&&StatusBarManager.DISABLE_NOTIFICATION_TICKER)&!=&0)&{
&&&&&&&&&&&&&&if&(mTicking&&&&(state&&&StatusBarManager.DISABLE_NOTIFICATION_TICKER)&!=&0)&{
&&&&&&&&&&&&&&&&&&if&(SPEW)&Slog.d(TAG,&"DISABLE_NOTIFICATION_TICKER:&yes"); &&&&&&&&&&&&&&&&&&mTicker.halt(); &&&&&&&&&&&&&&} &&&&&&&&&&} &&&&&&&} &&下面在将一种简单的对StatusBarManager的引用方法: &&Object&service&=&getSystemService&("statusbar"); &&&&&&try&{ &&Class&&?&&statusBarManager&=&Class.forName &&("android.app.StatusBarManager"); &&Method&expand&=&statusBarManager.getMethod&("disable",int.class);
&&expand.invoke&(service,<span style="color:#c000001); &&}&catch&(Exception&e)&{ &&e.printStackTrace(); &&}&/SPAN&&&
[java] &span&style="font-size:10"&&span&style="font-size:10"&&&&&&&&public&void&disable(int&state)&{&&&&&&&&&&final&int&old&=&mD&&&&&&&&&&final&int&diff&=&state&^&&&&&&&&&&&mDisabled&=&&&&&&&&&&&if&((diff&&&StatusBarManager.DISABLE_EXPAND)&!=&0)&{&&&&&&&&&&&&&&if&((state&&&StatusBarManager.DISABLE_EXPAND)&!=&0)&{&&&&&&&&&&&&&&&&&&if&(SPEW)&Slog.d(TAG,&"DISABLE_EXPAND:&yes");&&&&&&&&&&&&&&&&&&animateCollapse();&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&&&&&if&((diff&&&StatusBarManager.DISABLE_NOTIFICATION_ICONS)&!=&0)&{&&&&&&&&&&&&&&if&((state&&&StatusBarManager.DISABLE_NOTIFICATION_ICONS)&!=&0)&{&&&&&&&&&&&&&&&&&&if&(SPEW)&Slog.d(TAG,&"DISABLE_NOTIFICATION_ICONS:&yes");&&&&&&&&&&&&&&&&&&if&(mTicking)&{&&&&&&&&&&&&&&&&&&&&&&mTicker.halt();&&&&&&&&&&&&&&&&&&}&else&{&&&&&&&&&&&&&&&&&&&&&&setNotificationIconVisibility(false,&com.android.internal.R.anim.fade_out);&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&}&else&{&&&&&&&&&&&&&&&&&&if&(SPEW)&Slog.d(TAG,&"DISABLE_NOTIFICATION_ICONS:&no");&&&&&&&&&&&&&&&&&&if&(!mExpandedVisible)&{&&&&&&&&&&&&&&&&&&&&&&setNotificationIconVisibility(true,&com.android.internal.R.anim.fade_in);&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&}&&&&&&&&&&}&else&if&((diff&&&StatusBarManager.DISABLE_NOTIFICATION_TICKER)&!=&0)&{&&&&&&&&&&&&&&if&(mTicking&&&&(state&&&StatusBarManager.DISABLE_NOTIFICATION_TICKER)&!=&0)&{&&&&&&&&&&&&&&&&&&if&(SPEW)&Slog.d(TAG,&"DISABLE_NOTIFICATION_TICKER:&yes");&&&&&&&&&&&&&&&&&&mTicker.halt();&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&&}&&下面在将一种简单的对StatusBarManager的引用方法:&&Object&service&=&getSystemService&("statusbar");&&&&&&try&{&&Class&&?&&statusBarManager&=&Class.forName&&("android.app.StatusBarManager");&&Method&expand&=&statusBarManager.getMethod&("disable",int.class);&&expand.invoke&(service,0x);&&}&catch&(Exception&e)&{&&e.printStackTrace();&&}&/span&&/span&&&
&uses-permission android:name="android.permission.STATUS_BAR"/&
&uses-permission android:name="android.permission.DISABLE_STATUS_BAR"/&
这个方法也是禁用statusbar 的一种方法。
五、重要文件的介绍
StatusBarManagerService.java
StatusBarManagerService 是服务端
StatusBarService 的管理者
顾名思义,StatusBarManagerService是
StatusBarService的管理者,是StatusBarService与外界通信的桥梁,如4.2所讲。
StatusBarManagerService.java
中,有 addNotification,
removeNotification,updateNotification
等方法用于管理传递给他的通知对象。这个类是一些管理方法,实际执行相关动作的是在IStatusBar.java里面,这个是
framework/base/core/java/com /android/internal/statusbar/IStatusBar.aidl自动生成的用于
StatusBarService.java
StatusBarservice 是Statusbar
StatusBarService这个服务是Statusbar模块的中心点,所有关于图标的加载、更新、删除等处理,与应用的交互,对通知信息的处理,动画的完成等都是建立在StatusBarService这个基础之上的。
StatusBarPolicy.java
StatusBarPolicy 负责状态栏显示的策略管理
Android中状态栏上有很多图标,这些图标什么时候显示什么时候不显示,这些都是StatusBarPolicy
来管理的。
StatusBarPolicy的构造函数里初始化了好几个图标,如闹钟icon,信号栏icon等。默认时有很多图标是不显示的,需要显示时再进行更新。StatusBarPolicy调用registerReceiver
注册了感兴趣的intent,当感兴趣的intent发生时,对图标进行更新。
StatusBarPolicy只是一个策略管理,实际的功能是StatusBarService来实现的。StatusBarService初始化时初始化了一个用于显示statusbar的StatusBarView。StatusBarView里面定义了icon名字,的显示顺序,对应的png图等,在StatusBarService调用makeStatusBarView方法时实现statusbar的初始化。
CommandQueue.java
CommandQueue 是StatusBarservice
和StatusBarManagerService
交互的枢纽
IStatusBar.java里面对应的方法是用CommandQueue
的接口callback
的形式调用的,
callback的实现在对应的服务提供类也就是StatusBarService.java中提供的。
最终执行状态栏更新通知等事件都是在实现的CommandQueue.Callbacks里面执行。
本文档主要讲述了SystemUI
Statusbar模块的主要功能和实先步骤,文档中介绍了Statusbar的功能,使用方法,模块框架,以及模块一些实现的主要流程等。
希望大家在阅读文档的过程中,如果发现文档的缺点和错误,请及时反馈,我将以最快的速度加以改进。
发表评论:
TA的最新馆藏

我要回帖

更多关于 mac 终端退出root权限 的文章

 

随机推荐