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 @@
         @string/status_bar_data_connection
         @string/status_bar_phone_evdo_signal
         @string/status_bar_phone_signal
+        @string/status_bar_record
         @string/status_bar_battery
         @string/status_bar_alarm_clock
         @string/status_bar_secure
@@ -61,6 +62,7 @@
 
     rotate
     headset
+    record
     data_saver
     managed_profile
     ime
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 @@
 
  

  

  
  
  
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 @@
+ +    android:viewportWidth="20" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+   
+

--- 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

 

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(android)