您的位置:首页 > 移动开发 > Android开发

android 修改电池电量图标介绍

2016-09-19 09:47 696 查看
图片修改

首先我们要修改系统图标,就要联想到在framework中的资源,那么我们要修改framework中的资源的话当然必不可少的要去编译framework/base/core下的res。。。。

当然我们首先要找到对应的电量图标,然后要有你想该完之后的图标,那么你可以到网上找,到rom中提取,或则你自己做(当然比较麻烦),那么我们要精确到1%,所以我们应该有101张图片去替换原有图片(原有图片)不能精确到1%,而是5%,所以我们可以找到配置文件,在drawble/stat_sys_battery.xml文件,将原来的注释掉,修改如下:<item android:maxLevel="0" android:drawable="@android:drawable/stat_sys_battery_0" />

    <item android:maxLevel="1" android:drawable="@android:drawable/stat_sys_battery_1"  />

    <item android:maxLevel="2" android:drawable="@android:drawable/stat_sys_battery_2" />

    <item android:maxLevel="3" android:drawable="@android:drawable/stat_sys_battery_3"  />

。。。。。。。

    <item android:maxLevel="100" android:drawable="@android:drawable/stat_sys_battery_100"  />

而且,如果你要更改充电时的图标,也可以相应的找图片替换原有充电时的图片。。。

drawble/stat_sys_battery-charge.xml的代码不用修改,但是图片要相应的替换(你可以在网上下载framework-res.apk,从其中提起出来图片再替换)。。。

当然免不了要在源码环境下编译了,首先我们要编译framework/base/core下的res,用生成的framework-res.apk替换你机器里的framework-res.apk(前提是你的手机要root过)

,其次是要编译frameworks/base/services$下的java生成system/framework/services.jar也替换手机里的services.jar,最后应该是从新编译一下SystemUI.apk再替换就可以了。。

低电分析

我们都知道android电量的一些功能很多在service中,低电量也是如此,在BatteryService.java中我们可以从jni层(当然jni层的电量也是从下层kernel接收而来,这里就不做过多分析,有兴趣的可以去深入了解一下)获得机器的电量mBatteryLevel,我们也知道当手机电量低的时候它会有警告有些还发出声音提醒你,并且太低时会自动关机!

下面简单介绍一下其流程:

在BatteryService.java中,当我们从jni获得当前电量之后,可以在 update()中做一个判断:

final boolean sendBatteryLow = !plugged

                && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN

                && mBatteryLevel <= mLowBatteryWarningLevel

                && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel);

            

如果当前电量小于警告电量(在config.xml中 <integer name="config_lowBatteryWarningLevel">15</integer>)则弹出电量低提示,或者电量为0(当然这个有误差也可能是5%时就自动关机)时自动关机。

在下面会有判断是否低电量:

if (sendBatteryLow) {

                mSentLowBatteryBroadcast = true;

                statusIntent.setAction(Intent.ACTION_BATTERY_LOW);

                mContext.sendBroadcast(statusIntent);

      }

如果低电量的话就发送一个广播出去。

这段代码是电量太低而自动关机:

private final void shutdownIfNoPower() {

      

        if (mBatteryLevel == 0 && !isPowered() && ActivityManagerNative.isSystemReady()) {

            Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);

            intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);

            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            mContext.startActivity(intent);

        }

    }

而在StatusBarPolicy.java中会有接收广播:private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {

        @Override

        public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();

               。。。。。。。。。

里面会有判断当接受到ACTION_BATTERY_LOW时:

else if (action.equals(Intent.ACTION_BATTERY_LOW)) {

                onBatteryLow(intent);

            }

在StatusBarPolicy.java中会有onBatteryLow(intent)方法来处理:

private void onBatteryLow(Intent intent) {

        if (SHOW_LOW_BATTERY_WARNING) {

            if (false) {

                Slog.d(TAG, "mPhoneState=" + mPhoneState

                      + " mLowBatteryDialog=" + mLowBatteryDialog

                      + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);

            }

            if (SHOW_BATTERY_WARNINGS_IN_CALL || mPhoneState == TelephonyManager.CALL_STATE_IDLE) {

                showLowBatteryWarning();

            } else {

                mBatteryShowLowOnEndCall = true;

            }

        }

    }

然后就是弹出低电提醒的Dialog了:

private void showLowBatteryWarning() {

        closeLastBatteryView();

        // Show exact battery level.

        CharSequence levelText = mContext.getString(

                    R.string.battery_low_percent_format, mBatteryLevel);

        if (mBatteryLevelTextView != null) {

            mBatteryLevelTextView.setText(levelText);

        } else {

            View v = View.inflate(mContext, R.layout.battery_low, null);

            mBatteryLevelTextView=(TextView)v.findViewById(R.id.level_percent);

            mBatteryLevelTextView.setText(levelText);

            AlertDialog.Builder b = new AlertDialog.Builder(mContext);

                b.setCancelable(true);

                b.setTitle(R.string.battery_low_title);

                b.setView(v);

                b.setIcon(android.R.drawable.ic_dialog_alert);

                b.setPositiveButton(android.R.string.ok, null);

                final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);

                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK

                        | Intent.FLAG_ACTIVITY_MULTIPLE_TASK

                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

                        | Intent.FLAG_ACTIVITY_NO_HISTORY);

                if (intent.resolveActivity(mContext.getPackageManager()) != null) {

                    b.setNegativeButton(R.string.battery_low_why,

                            new DialogInterface.OnClickListener() {

                        public void onClick(DialogInterface dialog, int which) {

                            mContext.startActivity(intent);

                            if (mLowBatteryDialog != null) {

                                mLowBatteryDialog.dismiss();

                            }

                        }

                    });

                }

            AlertDialog d = b.create();

            d.setOnDismissListener(mLowBatteryListener);

            d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

            d.show();

            mLowBatteryDialog = d;

        }

        //waring voiced

        final ContentResolver cr = mContext.getContentResolver();

        if (Settings.System.getInt(cr,

                Settings.System.POWER_SOUNDS_ENABLED, 1) == 1)

        {

            final String soundPath = Settings.System.getString(cr,

                Settings.System.LOW_BATTERY_SOUND);

            if (soundPath != null) {

                final Uri soundUri = Uri.parse("file://" + soundPath);

                if (soundUri != null) {

                    final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);

                    if (sfx != null) {

                        sfx.setStreamType(AudioManager.STREAM_SYSTEM);

                        sfx.play();

                    }

                }

            }

        }

    } 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: