android8.1 状态栏添加动态闪烁图标

mac2024-05-09  7

    近日做了一个需求,要求设备录音中的时候,状态栏显示一个动态图标,提醒用户处于录音中状态,录音结束则动态图标停止显示。

    软件版本:android8.1

    硬件平台:展讯

    最开始UI提供了一个三个图层的icon,结果设置进去发现背景图层一直存在,相当丑陋,后来了解到状态栏图标都是一些矢量xml文件,需要svg矢量图转为xml格式(Android studio就可以转,具体可百度),于是将svg格式转化成了矢量xml,结果发现设置进去,依然有背景图层,后来修改了xml中一个参数,关于透明度的,android:fillAlpha 这个值改为0,图标就透明了。

    素材OK了,下边直接粘贴代码改动:

diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index fbd24643a..5baf20615 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -53,6 +53,7 @@          <item><xliff:g id="id">@string/status_bar_data_connection</xliff:g></item>          <item><xliff:g id="id">@string/status_bar_phone_evdo_signal</xliff:g></item>          <item><xliff:g id="id">@string/status_bar_phone_signal</xliff:g></item>+        <item><xliff:g id="id">@string/status_bar_record</xliff:g></item>          <item><xliff:g id="id">@string/status_bar_battery</xliff:g></item>          <item><xliff:g id="id">@string/status_bar_alarm_clock</xliff:g></item>          <item><xliff:g id="id">@string/status_bar_secure</xliff:g></item> @@ -61,6 +62,7 @@        <string translatable="false" name="status_bar_rotate">rotate</string>      <string translatable="false" name="status_bar_headset">headset</string>+    <string translatable="false" name="status_bar_record">record</string>      <string translatable="false" name="status_bar_data_saver">data_saver</string>      <string translatable="false" name="status_bar_managed_profile">managed_profile</string>      <string translatable="false" name="status_bar_ime">ime</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index f9f48adbe..861263dfb 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2583,6 +2583,7 @@      <java-symbol type="string" name="status_bar_rotate" />

   <java-symbol type="string" name="status_bar_headset" />+  <java-symbol type="string" name="status_bar_record" />    <java-symbol type="string" name="status_bar_data_saver" />    <java-symbol type="string" name="status_bar_managed_profile" />    <java-symbol type="string" name="status_bar_ime" /> diff --git a/packages/SystemUI/res/drawable-hdpi/record_icon.xml b/packages/SystemUI/res/drawable-hdpi/record_icon.xml new file mode 100755 index 000000000..213223782 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/record_icon.xml @@ -0,0 +1,4 @@+<vector android:height="24dp" android:viewportHeight="20" +    android:viewportWidth="20" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> +    <path android:fillColor="#FF000000" android:pathData="M10.3,12.5c1.9,0 3.4,-1.5 3.4,-3.3V6.3c0,-1.9 -1.5,-3.3 -3.4,-3.3S6.9,4.5 6.9,6.3v2.8C6.9,11 8.4,12.5 10.3,12.5zM15.6,8.4c0,-0.3 -0.3,-0.6 -0.7,-0.6s-0.6,0.3 -0.6,0.6c0,0.1 0,0.1 0,0.2v0.5c0,2.2 -1.8,4 -4.1,4c-2.2,0 -4.1,-1.8 -4.1,-4V8.5c0,0 0,-0.1 0,-0.1c0,-0.3 -0.3,-0.6 -0.6,-0.6C5.3,7.8 5,8.1 5,8.4v0.9c0,2.7 2,4.8 4.6,5.2v1.2H7.8c-0.4,0 -0.7,0.3 -0.7,0.7c0,0.4 0.3,0.6 0.7,0.6h4.8c0.4,0 0.6,-0.3 0.6,-0.6c0,-0.3 -0.3,-0.7 -0.6,-0.7h-1.8v-1.2c2.7,-0.3 4.7,-2.5 4.7,-5.2V8.4z"/> +</vector>

--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -44,6 +44,7 @@ import android.os.Handler;  import android.os.RemoteException;  import android.os.UserHandle;  import android.os.UserManager;+import android.os.Message;  import android.provider.Settings;  import android.provider.Settings.Global;  import android.service.notification.StatusBarNotification; @@ -112,6 +113,7 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,      private final String mSlotManagedProfile;      private final String mSlotRotate;      private final String mSlotHeadset;+    private final String mSlotRecord;      private final String mSlotDataSaver;      private final String mSlotLocation;   @@ -153,6 +155,13 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,        private BluetoothController mBluetooth;  +    private static final int MSG_RECORDING = 400; +    private static final int MSG_RECORD_HIDE = 600; +    private static final int MSG_STOP_RECORDING = 800; +    private static boolean recordState = false; +    private static boolean recordingNow = false;

+    private final static String IFLYTEK_RECORD_STATE = "IFLYTEK_RECORD_STATE"; +      public PhoneStatusBarPolicy(Context context, StatusBarIconController iconController) {          mContext = context;          mIconController = iconController; @@ -181,6 +190,7 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,                  com.android.internal.R.string.status_bar_managed_profile);          mSlotRotate = context.getString(com.android.internal.R.string.status_bar_rotate);          mSlotHeadset = context.getString(com.android.internal.R.string.status_bar_headset);+        mSlotRecord = context.getString(com.android.internal.R.string.status_bar_record);          mSlotDataSaver = context.getString(com.android.internal.R.string.status_bar_data_saver);          mSlotLocation = context.getString(com.android.internal.R.string.status_bar_location);   @@ -194,6 +204,7 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,          filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);          filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);          filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);+        filter.addAction(IFLYTEK_RECORD_STATE);          mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);            // listen for user / profile change. @@ -272,6 +283,7 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,      }        public void destroy() {+        removeRecordMsg();          mRotationLockController.removeCallback(this);          mBluetooth.removeCallback(this);

         mProvisionedController.removeCallback(this); @@ -735,6 +747,55 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,          }      }  +    private Handler mRecordHandler = new Handler() { +         public void handleMessage(android.os.Message msg) { +            switch (msg.what) { +                case MSG_RECORDING: +                    mIconController.setIcon(mSlotRecord, R.drawable.record_icon, null); +                    mIconController.setIconVisibility(mSlotRecord, true); +                    Message msgDisplay = Message.obtain(); +                    msgDisplay.what = MSG_RECORD_HIDE; +                    mRecordHandler.sendMessageDelayed(msgDisplay, 800); +                    break; +                case MSG_RECORD_HIDE: +                    mIconController.setIconVisibility(mSlotRecord, false); +                    Message msgHide = Message.obtain(); +                    msgHide.what = MSG_RECORDING; +                    mRecordHandler.sendMessageDelayed(msgHide, 800); +                    break;+                case MSG_STOP_RECORDING: +                    mRecordHandler.removeMessages(MSG_RECORDING); +                    mRecordHandler.removeMessages(MSG_RECORD_HIDE); +                    break; +            } +        }; +    };

+ +    private void removeRecordMsg() { +        mRecordHandler.removeMessages(MSG_RECORDING); +        mRecordHandler.removeMessages(MSG_RECORD_HIDE); +    } + +    private void updateIflytekRecordState(Intent intent) { +        recordState = intent.getIntExtra("state", 0) != 0; +        if (recordState) { +            if (!recordingNow) {+                recordingNow = true; +                mIconController.setIcon(mSlotRecord, R.drawable.record_icon, null); +                mIconController.setIconVisibility(mSlotRecord, true); +                Message msgStart = Message.obtain(); +                msgStart.what = MSG_RECORDING; +                mRecordHandler.sendMessage(msgStart); +            } +        } else { +            recordingNow = false; +            mIconController.setIconVisibility(mSlotRecord, false); +            Message msgStop = Message.obtain(); +            msgStop.what = MSG_STOP_RECORDING; +            mRecordHandler.sendMessage(msgStop); +        } +    } +      private void updateHeadsetPlug(Intent intent) {          boolean connected = intent.getIntExtra("state", 0) != 0;

         boolean hasMic = intent.getIntExtra("microphone", 0) != 0; @@ -782,6 +843,8 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,                  updateManagedProfile();              } else if (action.equals(AudioManager.ACTION_HEADSET_PLUG)) {                  updateHeadsetPlug(intent);+            } else if (action.equals(IFLYTEK_RECORD_STATE)) { +                updateIflytekRecordState(intent);              }          }      };

 

        大概的实现逻辑做个说明,进入录音中后,相关app会发送自定义广播,附带录音状态字段,收到广播后,调整图标的显示和隐藏,其中闪烁的效果是用了延迟的msg,用handler实现的。

        自己可以通过adb命令模拟广播事件,进行简单测试。

比如发送模拟录音开始的广播  adb shell am broadcast -a IFLYTEK_RECORD_STATE --ei state 1

停止录音广播  adb shell am broadcast -a IFLYTEK_RECORD_STATE --ei state 0

 

 

欢迎留言讨论~~~~如果有更简便的闪烁图标方法的话!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

最新回复(0)