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

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

    软件版本: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

 

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值