Android在低电量时候充电图标不动,修改办法:
<itemandroid:maxLevel="0">
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<itemandroid:drawable="@drawable/stat_sys_battery_charge_anim0"android:duration="2000"/>
<itemandroid:drawable="@drawable/stat_sys_battery_charge_anim1"android:duration="1000"/>
<itemandroid:drawable="@drawable/stat_sys_battery_charge_anim2"android:duration="1000"/>
<itemandroid:drawable="@drawable/stat_sys_battery_charge_anim3"android:duration="1000"/>
<itemandroid:drawable="@drawable/stat_sys_battery_charge_anim4"android:duration="1000"/>
<itemandroid:drawable="@drawable/stat_sys_battery_charge_anim5"android:duration="1000"/>
</animation-list>
</item>
下面分析一下:
一、StatusBarPolicy.java中:
privatefinalvoidupdateBattery(Intentintent){
finalintid=intent.getIntExtra("icon-small",0); //获取Icon的id
intlevel=intent.getIntExtra("level",0);
mService.setIcon("battery",id,level); //在这里,是决定显示充电图标的地方,mService:StatusBarManager
……
}
一、StatusBarManager.java中:
publicvoidsetIcon(Stringslot,inticonId,inticonLevel){
try{
mService.setIcon(slot,mContext.getPackageName(),iconId,iconLevel);
}catch(RemoteExceptionex){
//systemprocessisdeadanyway.
thrownewRuntimeException(ex);
}
}
mService:IStatusBarService,其实现函数在CommandQuene.java中,我们进入这个文件:
二、CommandQuene.java:
publicvoidsetIcon(intindex,StatusBarIconicon){
synchronized(mList){
intwhat=MSG_ICON|index;
mHandler.removeMessages(what);
mHandler.obtainMessage(what,OP_SET_ICON,0,icon.clone()).sendToTarget();
}
}
在这里,其实是将需要设置的Icon通过Message发送出去,在处理函数中实现设置:
privatefinalclassHextendsHandler{
publicvoidhandleMessage(Messagemsg){
finalintwhat=msg.what&MSG_MASK;
switch(what){
caseMSG_ICON:{
finalintindex=msg.what&INDEX_MASK;
finalintviewIndex=mList.getViewIndex(index);
switch(msg.arg1){
caseOP_SET_ICON:{
StatusBarIconicon=(StatusBarIcon)msg.obj;
StatusBarIconold=mList.getIcon(index);
if(old==null){
mList.setIcon(index,icon);
mCallbacks.addIcon(mList.getSlot(index),index,viewIndex,icon);
}else{
mList.setIcon(index,icon);
mCallbacks.updateIcon(mList.getSlot(index),index,viewIndex,
old,icon);
}
break;
}
caseOP_REMOVE_ICON:
if(mList.getIcon(index)!=null){
mList.removeIcon(index);
mCallbacks.removeIcon(mList.getSlot(index),index,viewIndex);
}
break;
}
break;
}
……
}
实际处理也就是OP_SET_ICON这个位置:若是Icon存在的,则进行更新:
四、StatusBarService.java:
publicvoidupdateIcon(Stringslot,intindex,intviewIndex,
StatusBarIconold,StatusBarIconicon){
StatusBarIconViewview=(StatusBarIconView)mStatusIcons.getChildAt(viewIndex);
view.set(icon);
}
这段代码说明,从statusIconList对象中获取这个Icon,通过StatusBarIconView进行设置:这里也充分说明了,
StatusBarIcon实际上相当于一个存储,用来存储Icon信息:iconPackage、iconId、iconLevel等等。而StatusBarIconList则是这样的,它根据conifg.xml将StatusBarIcon添加进这个数组里去。在需要时取出。
五、StatusBarIconView.java:
publicbooleanset(StatusBarIconicon){
finalbooleaniconEquals=mIcon!=null
&&streq(mIcon.iconPackage,icon.iconPackage)
&&mIcon.iconId==icon.iconId;
finalbooleanlevelEquals=iconEquals
&&mIcon.iconLevel==icon.iconLevel;
finalbooleanvisibilityEquals=mIcon!=null
&&mIcon.visible==icon.visible;
finalbooleannumberEquals=mIcon!=null
&&mIcon.number==icon.number;
mIcon=icon.clone();
//当icon不同时获取Icon并设置
if(!iconEquals){
Drawabledrawable=getIcon(icon);
if(drawable==null){
Slog.w(StatusBarService.TAG,"Noiconforslot"+mSlot);
returnfalse;
}
setImageDrawable(drawable);
}
if(!levelEquals){
setImageLevel(icon.iconLevel);
}
if(!numberEquals){
if(icon.number>0){
if(mNumberBackground==null){
mNumberBackground=getContext().getResources().getDrawable(
R.drawable.ic_notification_overlay);
}
placeNumber();
}else{
mNumberBackground=null;
mNumberText=null;
}
invalidate();
}
if(!visibilityEquals){
setVisibility(icon.visible?VISIBLE:GONE);
}
returntrue;
}
在这里特别说一下getIcon(),这更能从侧面反映出StatusBarIcon是存储作用,
r=context.getResources();
returnr.getDrawable(icon.iconId);
我们看看getDrawable:实际就是loadDrawable:这其实有解析xml文件的操作:
在publicstaticDrawablegetIcon(Contextcontext,StatusBarIconicon)函数中,
关键代码是:returnr.getDrawable(icon.iconId);
实际上,我们获得一个xml文件的id时,要先将其解析,这时就会调用Drawable.createFromXml(),在这里又会调用loadDrawable(value,id),这个函数才是对XML的解析。
if(file.endsWith(".xml"))是判断要解析的文件是否是xml文件,然后调用下面的函数:
publicstaticDrawablecreateFromXmlInner(Resourcesr,XmlPullParserparser,AttributeSetattrs)
throwsXmlPullParserException,IOException{
Drawabledrawable;
finalStringname=parser.getName();//根据名字来解析文件
if(name.equals("selector")){
drawable=newStateListDrawable();
}elseif(name.equals("level-list")){//为level-list时就创建一个LevelListDrawable实例
drawable=newLevelListDrawable();
}elseif(name.equals("layer-list")){
drawable=newLayerDrawable();
}elseif(name.equals("transition")){
drawable=newTransitionDrawable();
}elseif(name.equals("color")){
drawable=newColorDrawable();
}elseif(name.equals("shape")){
drawable=newGradientDrawable();
}elseif(name.equals("scale")){
drawable=newScaleDrawable();
}elseif(name.equals("clip")){
drawable=newClipDrawable();
}elseif(name.equals("rotate")){
drawable=newRotateDrawable();
}elseif(name.equals("animated-rotate")){
drawable=newAnimatedRotateDrawable();
}elseif(name.equals("animation-list")){
drawable=newAnimationDrawable();
}elseif(name.equals("inset")){
drawable=newInsetDrawable();
}elseif(name.equals("bitmap")){
drawable=newBitmapDrawable();
if(r!=null){
((BitmapDrawable)drawable).setTargetDensity(r.getDisplayMetrics());
}
}elseif(name.equals("nine-patch")){
drawable=newNinePatchDrawable();
if(r!=null){
((NinePatchDrawable)drawable).setTargetDensity(r.getDisplayMetrics());
}
}else{
thrownewXmlPullParserException(parser.getPositionDescription()+
":invaliddrawabletag"+name);
}
drawable.inflate(r,parser,attrs);//这一步十分关键,开始解析
returndrawable;
}
drawable.inflate(r,parser,attrs)创建一个LevelListDrawable后就开始解析xml文件:drawable.inflate(r,parser, attrs);在inflate()中,
TypedArraya=r.obtainAttributes(attrs,
com.android.internal.R.styleable.LevelListDrawableItem);
low=a.getInt(
com.android.internal.R.styleable.LevelListDrawableItem_minLevel,0);
inthigh=a.getInt(
com.android.internal.R.styleable.LevelListDrawableItem_maxLevel,0);
intdrawableRes=a.getResourceId(
com.android.internal.R.styleable.LevelListDrawableItem_drawable,0);
a.recycle();
再往下:可以看到若是LevelDrawable中还包含别的drawable,同样要进行解析。比如电池充电动画就属于这种类型,那么,就要解析AnimationDrawable.
之后,解析出来的LevelListDrawable中的Item添加到DrawableContainer中去,也就是addChild()。
六:AnimationImageView.java:
publicvoidsetImageDrawable(Drawabledrawable){
super.setImageDrawable(drawable); //调用父类方法,将drawable设置进ImageView中
updateAnim();
}
ImageView中的setImageDrawable(drawable)原型如下:
publicvoidsetImageDrawable(Drawabledrawable){
if(mDrawable!=drawable){
mResource=0;
mUri=null;
/*************************************************************************************************************/
/*到此,都只是将包含有动画的Drawable设置进去,那么经过什么样的处理之后才获得其包含的animation-list的?
因为,在updateAnim()中,需要getDrawable(),然后根据这个drawable是否是AnimationDrawable才决定动画与否*/
/*************************************************************************************************************/
updateDrawable(drawable);
requestLayout();
invalidate();
}
}
看看以下函数:
privatevoidupdateDrawable(Drawabled){
if(mDrawable!=null){ //这一段意味着若有变化,之前的Drawable的callback和
mDrawable.setCallback(null); //Message都会除去和它的关联。
unscheduleDrawable(mDrawable);
}
mDrawable=d;
if(d!=null){
d.setCallback(this); //新的drawable设置callback
if(d.isStateful()){ //新的drawable是否是isStateful
d.setState(getDrawableState());//设置state
}
d.setLevel(mLevel); //设置level
mDrawableWidth=d.getIntrinsicWidth();
mDrawableHeight=d.getIntrinsicHeight();
applyColorMod();
configureBounds();
}
}
看看setLevel()作用:
publicfinalbooleansetLevel(intlevel){
if(mLevel!=level){
mLevel=level;
returnonLevelChange(level);
}
returnfalse;
}
需要知道的是:com.android.internal.R.drawable.stat_sys_battery_charge.xml文件对应的是LevelListDrawable,因此,这时onLevelChange()必然是LevelListDrawable.java中重写Drawable的函数,这样我们就看到以下的函数实现:
protectedbooleanonLevelChange(intlevel){
intidx=mLevelListState.indexOfLevel(level);
if(selectDrawable(idx)){
returntrue;
}
returnsuper.onLevelChange(level);
}
来看看OnlevelChanged()中的语句:
intidx=mLevelListState.indexOfLevel(level);
实际上就是获得LevelListDrawable中的Item对应Id,之后才选择Drawable:
selectDrawable(idx);选中这个drawableItem并将其设置为currentdrawable
也就是正在使用的Drawable设置为由level指定的drawable:
publicbooleanselectDrawable(intidx)
{
if(idx==mCurIndex){
returnfalse;
}
if(idx>=0&&idx<mDrawableContainerState.mNumChildren){
Drawabled=mDrawableContainerState.mDrawables[idx];//刚才在解析时添加进来的
if(mCurrDrawable!=null){
mCurrDrawable.setVisible(false,false);
}
mCurrDrawable=d;
mCurIndex=idx;
if(d!=null){
d.setVisible(isVisible(),true);
d.setAlpha(mAlpha);
d.setDither(mDrawableContainerState.mDither);
d.setColorFilter(mColorFilter);
d.setState(getState());
d.setLevel(getLevel());
d.setBounds(getBounds());
}
}else{
if(mCurrDrawable!=null){
mCurrDrawable.setVisible(false,false);
}
mCurrDrawable=null;
mCurIndex=-1;
}
invalidateSelf();
returntrue;
}
相关推荐
并且在整个快速充电期间内,始终适时地采取了消除蓄电池极化的措施,避免了蓄电池在充电过程中产生大量气体和温升过高的问题充电后期采用的充电方法可使蓄电池恢复至完全充电态,达到额定容量在充电系统的设计中,...
电动车电池故障处理方法 2011年04月01日 电动车电池常见的故障与处理方法 绿灯不亮 不转灯原因有三: 一,充电器参数不匹配,产生漂移; 二,线路问题; 三,是电池因素:失水,电池内部有单格短路,硫化较为严重。
蓄电池充电与放电的工作循环过程、充电电流与电压大小和充电控制方式等等,都是直接影响铅酸蓄电池组循环使用寿命的重要因素,而铅酸蓄电池组的容量与电压决定了充电需要的参数,所以充电器的参数要与蓄电池参数...
出,通过设置最大充电电流防止电流过大,利用电压检测电路对充电电压进行实时检测,能够对不同充电电压需求的设备和电池进行充 电。系统主要由太阳能板、STM32F103C8T6控制电路、单片机电压电路采集和监控电路、TL...
1.6.4 有序充电 1.6.5 储能双层优化调度 1.6.6 储能优化配置 ### 2 神经网络回归预测、时序预测、分类清单 **2.1 bp预测和分类** **2.2 lssvm预测和分类** **2.3 svm预测和分类** **2.4 cnn预测和分类** ###...
MAX8844等双输入充电器处理利用USB和适配器供电的充电器,器件还具有高达28V的输入过压保护。 充电器常见的设计考虑是从多电源供电问题,特别是采用圆形连接器时,可能会连接到不正确的适配器。为避免这种事件的...
这款保护电路既可以防止欠充电和过充电,还可以在充电器十小时不转换变灯的情况下自动断电,防止出现严重的...由此掌握蓄电池容量变化的情况,并判断是否出现了充电器不转换变绿灯的问题,以便决定要不要送维修点处理。
提供了不同充电倍率、不同老化程度下可靠和准确的单体SOC分析方法,数据处理较人工神经网络和卡尔曼滤波等方法有较大优势。通过ΔQ/ΔV曲线进行电池的SOC估算,可为目前基于开路电压的均衡提供更为准确的判断条件...
为了给设备提供足够的电压,锂电池包通常由多个电池串联而成,但是如果电池之间的容量... 电池容量的不匹配包括充电状态(SOC)失配和容量/能量(C/E)失配。在两种情况下,电池包的总容量都只能达到最弱电池的容量。在
1.6.4 有序充电 1.6.5 储能双层优化调度 1.6.6 储能优化配置 ### 2 神经网络回归预测、时序预测、分类清单 **2.1 bp预测和分类** **2.2 lssvm预测和分类** **2.3 svm预测和分类** **2.4 cnn预测和分类** ###...
MATLAB代码:基于混合整数规划的微网储能电池容量规划 ...电池充电/放电策略,以及微网中其他单元的配置结果,而且求解的效果更好,已经对代码进行了深入的加工和处理,出图效果非常好,代码质量非常高
还给出了微dian网购电 售电策略,电池充电 放电策略,以及微dian网中其他单元的配置结果,而且求解的效果更好,已经对代码进行了深入的加工和处理,出图效果非常好,代码质量非常高 这段程序主要是一个微电网的调度...
以下是某会议的精髓,... (1)设计方面,把电芯的设计问题集中暴露,集中处理; (2)生产设备方面,设备的标准化程度也会相应高一些,设备企业产品迭代会更快; (3)持续改进和经验推广,通过标准化,可以把
电池容量的不匹配包括充电状态(SOC)失配和容量/能量(C/E)失配。在两种情况下,电池包的总容量都只能达到最弱电池的容量。在大多数情况下,引起电池失配的原因是工艺控制和检测手段的不完善,而不是锂离子本身的化学...
以下是某会议的精髓,提出... (1)设计方面,把电芯的设计问题集中暴露,集中处理; (2)生产设备方面,设备的标准化程度也会相应高一些,设备企业产品迭代会更快; (3)持续改进和经验推广,通过标准化,可
这里注意1117降压芯片降压后不能和充电电路的5v连在一起,这样电池降压后又给电池充电,形成了回路。1117受不了,我的冒烟了。 还有这里的按键检测电路有问题,原来我以为可以程序设计该引脚为上拉状态,但是参考...
这里注意1117降压芯片降压后不能和充电电路的5v连在一起,这样电池降压后又给电池充电,形成了回路。1117受不了,我的冒烟了。 还有这里的按键检测电路有问题,原来我以为可以程序设计该引脚为上拉状态,但是参考...
1.6.4 有序充电 1.6.5 储能双层优化调度 1.6.6 储能优化配置 ### 2 神经网络回归预测、时序预测、分类清单 **2.1 bp预测和分类** **2.2 lssvm预测和分类** **2.3 svm预测和分类** **2.4 cnn预测和分类** ###...
1 铅酸蓄电池在后备电源运行中的问题以及产生的原因 随着蓄电池的广泛应用,特别是备用电源中的应用,由于VRLA蓄电池的运行要求比较严格,电池在偏离了正确的使用条件下运行会影响电池使用寿命,甚至造成严重的后果...