当前位置: 首页 > news >正文

安卓11 SysteUI添加按钮以及下拉状态栏的色温调节按钮

最近客户想要做一个台灯产品,需要实现 串口调节台灯功能 ,其中包括
亮度调节
色温调节
开关
三个功能
话不多说,贴代码

diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
old mode 100644
new mode 100755
index 17f92ee..71fefa0
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -790,5 +790,8 @@</intent-filter></receiver>+        <service android:name=".junjie.MySerialPortService"
+            android:exported="true"/>
+</application></manifest>
diff --git a/packages/SystemUI/res/drawable/ic_qs_td_button.xml b/packages/SystemUI/res/drawable/ic_qs_td_button.xml
new file mode 100755
index 0000000..8a81bc2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_td_button.xml
@@ -0,0 +1,18 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"^M
+    android:width="108dp"^M
+    android:height="108dp"^M
+    android:viewportWidth="1024"^M
+    android:viewportHeight="1024">^M
+  <path^M
+      android:fillColor="#FFFFFFFF"^M
+      android:pathData="M4.3,603.5a1.7,1.7 0,0 0,0 -3.4,1.7 1.7,0 0,0 0,3.4zM904.9,560.7a19.9,19.9 0,0 1,-14.9 -6.7l-315.2,-356.5a19.9,19.9 0,1 1,29.9 -26.4l315.2,356.5a19.9,19.9 0,0 1,-14.9 33.1zM684.2,882.9a19.9,19.9 0,0 1,-14.3 -33.8l216.2,-222a19.9,19.9 0,0 1,28.5 27.8l-216.2,222a19.9,19.9 0,0 1,-14.3 6z"/>^M
+  <path^M
+      android:fillColor="#FFFFFFFF"^M
+      android:pathData="M545.9,235.2a19.9,19.9 0,0 1,-13.7 -34.4l60.3,-56.7a60.3,60.3 0,0 0,-82.5 -87.8l-60.3,56.7a19.9,19.9 0,0 1,-27.3 -29l60.3,-56.7a100.1,100.1 0,0 1,137.2 145.9l-60.3,56.7a19.9,19.9 0,0 1,-13.7 5.4z"/>^M
+  <path^M
+      android:fillColor="#FFFFFFFF"^M
+      android:pathData="M482.2,478.3h-0.6a19.9,19.9 0,0 1,-13.9 -6.3L174.9,160.4a19.9,19.9 0,0 1,0.9 -28.2,233.7 233.7,0 0,1 320.1,340.6 19.9,19.9 0,0 1,-13.6 5.4zM218.3,148.4l264.1,281.1a193.9,193.9 0,0 0,-264.1 -281.1zM1001.5,1024h-725.1a19.9,19.9 0,0 1,-19.9 -19.9c0,-88.8 72.3,-161.1 161.1,-161.1h442.9c88.8,0 161.1,72.3 161.1,161.1a19.9,19.9 0,0 1,-19.9 19.9zM297.8,984.2h682a121.8,121.8 0,0 0,-119.5 -101.3h-442.9a121.8,121.8 0,0 0,-119.5 101.3zM926.9,666.5a72.3,72.3 0,1 1,72.3 -72.3,72.4 72.4,0 0,1 -72.3,72.3zM926.9,561.8a32.5,32.5 0,1 0,32.5 32.5,32.5 32.5,0 0,0 -32.5,-32.5z"/>^M
+  <path^M
+      android:fillColor="#FFFFFFFF"^M
+      android:pathData="M321.7,428.5a101.1,101.1 0,0 1,-52.5 -187.6,19.9 19.9,0 1,1 20.7,34.1 61.3,61.3 0,1 0,82.6 86.6,19.9 19.9,0 1,1 33,22.3 101.1,101.1 0,0 1,-83.9 44.6z"/>^M
+</vector>^M
diff --git a/packages/SystemUI/res/layout/brightness_mirror.xml b/packages/SystemUI/res/layout/brightness_mirror.xml
old mode 100644
new mode 100755
index e3440b5..288947e
--- a/packages/SystemUI/res/layout/brightness_mirror.xml
+++ b/packages/SystemUI/res/layout/brightness_mirror.xml
@@ -18,7 +18,7 @@xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/brightness_mirror"android:layout_width="@dimen/qs_panel_width"
-    android:layout_height="@dimen/brightness_mirror_height"
+    android:layout_height="@dimen/brightness_mirror_height1"android:layout_gravity="@integer/notification_panel_layout_gravity"android:visibility="invisible"><FrameLayout
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
old mode 100644
new mode 100755
index 12127f5..039f633
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -17,17 +17,69 @@xmlns:systemui="http://schemas.android.com/apk/res-auto"android:layout_height="wrap_content"android:layout_width="match_parent"
-    android:layout_gravity="center_vertical"
+    android:orientation="vertical"style="@style/BrightnessDialogContainer">+<com.android.systemui.settings.ToggleSliderViewandroid:id="@+id/brightness_slider"
-        android:layout_width="0dp"
-        android:layout_height="48dp"
-        android:layout_gravity="center_vertical"
-        android:layout_weight="1"
+        android:layout_width="match_parent"
+        android:layout_height="40dp"android:contentDescription="@string/accessibility_brightness"android:importantForAccessibility="no"
-        systemui:text="@string/status_bar_settings_auto_brightness_label" />
+        systemui:text="@string/status_bar_settings_auto_brightness_label"
+        android:visibility="gone"/>
+    <!--liujunjie add -->
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="40dp"
+        android:orientation="horizontal">
+        <SeekBar
+            android:layout_width="0dp"
+            android:layout_weight="5"
+            android:layout_height="40dp"
+            android:id="@+id/seekbar3" />
+        <TextView
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:text="@string/str1"
+            android:gravity="center"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="40dp"
+        android:orientation="horizontal">
+        <SeekBar
+            android:layout_width="0dp"
+            android:layout_weight="5"
+            android:layout_height="40dp"
+            android:id="@+id/seekbar1" />
+        <TextView
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:text="@string/str2"
+            android:gravity="center"/>
+    </LinearLayout>
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="40dp"
+        android:orientation="horizontal">
+        <SeekBar
+            android:layout_width="0dp"
+            android:layout_weight="5"
+            android:layout_height="40dp"
+            android:id="@+id/seekbar2" />
+        <TextView
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:text="@string/str3"
+            android:gravity="center"/>
+    </LinearLayout>
+    <!--liujunjie add end -->
+</LinearLayout>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index a60b9d0..6a864e08 100755
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -20,6 +20,10 @@<resources xmlns:android="http://schemas.android.com/apk/res/android"xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"><string name="app_label" msgid="4811759950673118541">"系统界面"</string>
+    <string name="str1" msgid="4811759950673118544">"屏幕亮度"</string>
+    <string name="str2" msgid="4811759950673118545">"台灯亮度"</string>
+    <string name="str3" msgid="4811759950673118547">"台灯色温"</string>
+    <string name="quick_settings_dtbutton_unlocked_label" msgid="4811759950673118542">"台灯"</string><string name="status_bar_clear_all_button" msgid="2491321682873657397">"清除"</string><string name="status_bar_no_notifications_title" msgid="7812479124981107507">"无通知"</string><string name="status_bar_ongoing_events_title" msgid="3986169317496615446">"正在进行的"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
old mode 100644
new mode 100755
index fcd47d4..6a32d03
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -106,7 +106,7 @@<!-- The default tiles to display in QuickSettings --><string name="quick_settings_tiles_default" translatable="false">
-        wifi,bt,dnd,flashlight,rotation,battery,cell,airplane,cast,screenrecord
+        wifi,bt,tdbutton,airplane</string><!-- The minimum number of tiles to display in QuickSettings -->
@@ -114,7 +114,7 @@<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" --><string name="quick_settings_tiles_stock" translatable="false">
-        wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse
+        wifi,cell,tdbutton,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse</string><!-- The tiles to display in QuickSettings -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
old mode 100644
new mode 100755
index f002a27..ae0fcca
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -426,6 +426,7 @@<dimen name="notification_panel_width">@dimen/match_parent</dimen><dimen name="brightness_mirror_height">48dp</dimen>
+    <dimen name="brightness_mirror_height1">80dp</dimen><!-- The width of the panel that holds the quick settings. --><dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 7f2fbba..e65bdb2 100755
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -19,6 +19,11 @@<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"><!-- Name of the status bar as seen in the applications info settings page. [CHAR LIMIT=12] --><string name="app_label">System UI</string>
+    <string name="str1" >Screen brightness</string>
+    <string name="str2" >Lamp brightness</string>
+    <string name="str3" >Lamp color temperature</string>
+    <!--台灯-->
+    <string name="quick_settings_dtbutton_unlocked_label">DeskLamp</string><!-- The text for the button in the notification window-shade that clearsall of the currently visible notifications. [CHAR LIMIT=10]-->
diff --git a/packages/SystemUI/src/com/android/systemui/junjie/MySerialPortService.java b/packages/SystemUI/src/com/android/systemui/junjie/MySerialPortService.java
new file mode 100755
index 0000000..0df1efb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/junjie/MySerialPortService.java
@@ -0,0 +1,204 @@
+package com.android.systemui.junjie;
+
+import android.app.Service;
+import android.content.Intent;
+import android.hardware.SerialPort;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class MySerialPortService extends Service {
+
+    public static final String port = "/dev/ttyS9";
+    private SerialPort serialPort;
+    private ParcelFileDescriptor parcelFileDescriptor;
+    private ByteBuffer dates = ByteBuffer.allocate(10);
+    public static final String TAG = "MySerialPortService";
+    private FileOutputStream mFileOutputStream;
+    private final IBinder mBinder = new MyBinder();
+
+    public void setStatusChange(StatusChange statusChange) {
+        this.statusChange = statusChange;
+    }
+
+    private StatusChange statusChange;
+
+    public MySerialPortService() {
+
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.d(TAG, "启动service");
+        thread.start();
+
+    }
+
+    public byte[] getRealData(byte[] src){
+        byte[] res = new byte[src.length+1];
+        byte checkSum = 0x0 & 0xff;
+        for (int i = 0; i < src.length; i++) {
+            byte ui = src[i];
+            checkSum +=(ui&0xff);
+            res[i] = src[i];
+        }
+        checkSum = (byte) (checkSum%0x100);
+        res[src.length] = checkSum;
+        Log.d(TAG, "getRealData: checkSun" +checkSum);
+        return res;
+    }
+
+    /**
+     * 打开灯
+     * */
+    public void setPortOff() {
+        Log.d(TAG, "onReceive: 串口关闭");
+        byte[] setui = new byte[]{0x55,(byte) 0xaa,0x1,0x3,0x1,0x0} ;
+        Log.d(TAG, "setPortOff==" + mFileOutputStream);
+        setCommd(setui);
+
+    }
+    /**
+     * 关闭灯
+     * */
+    public void setPortON() {
+        byte[] setui = new byte[]{0x55,(byte) 0xaa,0x1,0x3,0x1,0x1};
+               Log.d(TAG, "setPortON==" + mFileOutputStream);
+        setCommd(setui);
+    }
+    /**
+     * 配置色温
+     */
+    public void  setColorTemperature(int value){
+        //setPortON();
+        byte[] setui = new byte[]{0x55,(byte) 0xaa,0x1,0x5,0x1, (byte) (value&0xff)};
+        setCommd(setui);
+        Log.d(TAG, "setColorTemperature: "+value);
+
+
+    }
+
+    /**
+     * 配置亮度
+     */
+    public void  setBrightness(int value){
+        //setPortON();
+        byte[] setui = new byte[]{0x55,(byte) 0xaa,0x1,0x4,0x1, (byte) (value&0xff)};
+        setCommd(setui);
+        Log.d(TAG, "setColorTemperature: "+value);
+       // queryState();
+    }
+
+    /**
+     * 查询状态
+     * */
+    public void queryState(){
+        byte[] setui = new byte[]{0x55,(byte) 0xaa,0x1,0x1,0x0} ;
+        setCommd(setui);
+
+
+    }
+
+    private void setCommd(byte[] su){
+        try {
+            if (mFileOutputStream != null) {
+                mFileOutputStream.write(getRealData(su));
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+
+
+
+    private final Thread thread = new Thread(new Runnable() {
+        @Override
+        public void run() {
+            serialPort = new SerialPort(port);
+            try {
+                parcelFileDescriptor = ParcelFileDescriptor.open(new File(port), ParcelFileDescriptor.MODE_READ_WRITE);
+                serialPort.open(parcelFileDescriptor, 9600);
+                mFileOutputStream = new FileOutputStream(parcelFileDescriptor.getFileDescriptor());
+                Log.d(TAG,"main Thread start "+mFileOutputStream);
+                writeThread.start();
+                while (true) {
+                    Log.d(TAG, "run: 读取线程阻塞:");
+                    int read = serialPort.read(dates);
+                    readDate();
+                }
+
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+
+        }
+    });
+
+    private final Thread writeThread = new Thread(new Runnable() {
+        @Override
+        public void run() {
+            Log.d(TAG,"writeThread start "+mFileOutputStream);
+            if (mFileOutputStream != null){
+                //setColorTemperature(10);
+                //queryState();
+            }
+        }
+    });
+
+    private void readDate() {
+        byte[] by = dates.array();
+        /*for (byte b:
+             by) {
+            Log.d(TAG, "readDate: sts:"+b);
+        }*/
+        if (statusChange != null && by[3] == 0x2){
+            Log.d(TAG, "readDate: 读取数据 命令字段:"+by[3]+", 数据长度:"+by[4] +"开关状态:"+by[5]+" ,亮度值:"+by[6]+" ,色温值 :"+by[7]);
+            statusChange.dateSet(by[5]==1,by[6],by[7]);
+        }
+    }
+
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        // TODO: Return the communication channel to the service.
+        return mBinder;
+    }
+    public class MyBinder extends Binder {
+        public MySerialPortService getService() {
+            return MySerialPortService.this;
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        try {
+            mFileOutputStream.close();
+            serialPort.close();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+
+        return super.onStartCommand(intent, START_STICKY, startId);
+    }
+
+    public interface StatusChange{
+        void dateSet(boolean status,int br,int color);
+    }
+
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index a87a13c..3ce1e82 100755
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -46,6 +46,7 @@ import com.android.systemui.Dumpable;import com.android.systemui.R;import com.android.systemui.broadcast.BroadcastDispatcher;import com.android.systemui.dump.DumpManager;
+import com.android.systemui.junjie.MySerialPortService;import com.android.systemui.media.MediaHierarchyManager;import com.android.systemui.media.MediaHost;import com.android.systemui.plugins.qs.DetailAdapter;
@@ -63,6 +64,7 @@ import com.android.systemui.tuner.TunerService;import com.android.systemui.tuner.TunerService.Tunable;import com.android.systemui.util.animation.DisappearParameters;+import java.io.FileDescriptor;import java.io.PrintWriter;import java.util.ArrayList;
@@ -82,6 +84,14 @@ import android.content.IntentFilter;import android.content.BroadcastReceiver;import android.util.Log;+import android.widget.Button;
+import android.widget.SeekBar;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.database.ContentObserver;
+import android.provider.Settings;
+
+/** View that represents the quick settings tile panel (when expanded/pulled down). **/public class QSPanel extends LinearLayout implements Tunable, Callback, BrightnessMirrorListener,Dumpable {
@@ -160,6 +170,205 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightneprivate int mMediaTotalBottomMargin;private int mFooterMarginStartHorizontal;private Consumer<Boolean> mMediaVisibilityChangedListener;
+    // liujunjie add
+
+    private static MySerialPortService mySerialPortService;
+    private SeekBar seekBar1,seekBar2,seekBar3;
+    private static boolean isOn;
+    private int br;
+    private int color;
+    public static StatusChange statusChange2;
+
+    private final  MySerialPortService.StatusChange statusChange = new MySerialPortService.StatusChange() {
+        @Override
+        public void dateSet(boolean status, int br1, int color1) {
+
+            br = br1;
+            color = color1;
+            seekBar1.setProgress(br1);
+            seekBar2.setProgress(color1);
+            if (isOn != status){
+                statusChange2.statusChange(status);
+            }
+            isOn = status;
+            //updateSeekStatus();
+
+
+        }
+    };
+    private void updateSeekStatus(){
+        if (isOn){
+            if (seekBar1.getVisibility() != View.VISIBLE){
+                seekBar1.setVisibility(View.VISIBLE);
+                seekBar2.setVisibility(View.VISIBLE);
+            }
+
+        }else {
+            if (seekBar1.getVisibility() != View.GONE){
+                seekBar1.setVisibility(View.GONE);
+                seekBar2.setVisibility(View.GONE);
+            }
+
+            }
+
+
+    }
+
+    public static void setStatusChange(QSPanel.StatusChange statusChange) {
+        statusChange2 = statusChange;
+    }
+
+    public interface StatusChange {
+        void statusChange(boolean status);
+    }
+
+    class BrightnessObserver extends ContentObserver {
+        private Context mContext;
+
+        public BrightnessObserver(Context context) {
+            super(null);
+            mContext = context;
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            super.onChange(selfChange);
+            if (!isMeTouch){
+
+                int brightness = Settings.System.getInt(
+                        mContext.getContentResolver(),
+                        Settings.System.SCREEN_BRIGHTNESS,
+                        0
+                );
+                handleBrightnessChange(brightness);
+
+            }
+
+
+
+        }
+        private void handleBrightnessChange(int brightness) {
+            int st = Math.round((float) brightness /255 * 100);
+            if (seekBar3 != null){
+                seekBar3.setProgress(st);
+            }
+        }
+    }
+    boolean isMeTouch = false;
+    private void junjieInit() {
+        Intent intent = new Intent(mContext, MySerialPortService.class);
+        mContext.bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
+        seekBar1 = mBrightnessView.findViewById(R.id.seekbar1);
+        seekBar2 = mBrightnessView.findViewById(R.id.seekbar2);
+        seekBar3 = mBrightnessView.findViewById(R.id.seekbar3); // 屏幕亮度
+        seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                if (mySerialPortService != null && fromUser  && progress != 0){
+                    mySerialPortService.setBrightness(progress);
+                }
+
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+
+            }
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+
+            }
+        });
+        seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                if (mySerialPortService != null && fromUser){
+                    mySerialPortService.setColorTemperature(progress);
+                }
+
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+
+            }
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+
+            }
+        });
+
+        seekBar3.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                if (isMeTouch){
+                    int st = Math.round((float) progress /100 * 255);
+                    Settings.System.putInt(getContext().getContentResolver(),Settings.System.SCREEN_BRIGHTNESS,st);
+                }
+
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+                isMeTouch = true;
+
+            }
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+                isMeTouch = false;
+
+            }
+        });
+        initStatus();
+        int sy = Settings.System.getInt(getContext().getContentResolver(),Settings.System.SCREEN_BRIGHTNESS,0);
+        seekBar3.setProgress(sy);
+    }
+
+    private void initStatus() {
+        BrightnessObserver brightnessObserver = new BrightnessObserver(getContext());
+        getContext().getContentResolver().registerContentObserver(
+                Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS),
+                true,
+                brightnessObserver
+        );
+
+    }
+
+    public static void liujunjieClick() {
+        if (mySerialPortService != null){
+            if (isOn){
+                mySerialPortService.setPortOff();
+
+            }else {
+                mySerialPortService.setPortON();
+            }
+            isOn = !isOn;
+        }
+    }
+
+    public static boolean getDTStatus() {
+       return isOn;
+    }
+
+    private final ServiceConnection mConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            MySerialPortService.MyBinder binder = (MySerialPortService.MyBinder) service;
+            mySerialPortService = binder.getService();
+            mySerialPortService.setStatusChange(statusChange);
+            mySerialPortService.queryState();
+
+        }
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            mySerialPortService = null;
+
+        }
+    };
+@@ -234,6 +443,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, BrightneaddView(mHorizontalLinearLayout, lp);initMediaHostState();
+            //junjieInit(); // liujunjie add
+            android.util.Log.d("liujunjie","========== 1111 junjieInit  ========");}addSecurityFooter();if (mRegularTileLayout instanceof PagedTileLayout) {
@@ -261,6 +472,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, BrightneaddView(mBrightnessView);mBrightnessController = new BrightnessController(getContext(),findViewById(R.id.brightness_slider), mBroadcastDispatcher);
+        junjieInit();}protected QSTileLayout createRegularTileLayout() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index f9bd43d..e235fb7 100755
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -41,6 +41,7 @@ import com.android.systemui.qs.tiles.NfcTile;import com.android.systemui.qs.tiles.NightDisplayTile;import com.android.systemui.qs.tiles.RotationLockTile;import com.android.systemui.qs.tiles.ScreenRecordTile;
+import com.android.systemui.qs.tiles.TDButtonTile;import com.android.systemui.qs.tiles.UiModeNightTile;import com.android.systemui.qs.tiles.UserTile;import com.android.systemui.qs.tiles.WifiTile;
@@ -83,6 +84,8 @@ public class QSFactoryImpl implements QSFactory {private final Lazy<QSHost> mQsHostLazy;+    private final Provider<TDButtonTile> mTDButtonTileProvider;
+@Injectpublic QSFactoryImpl(Lazy<QSHost> qsHostLazy,Provider<WifiTile> wifiTileProvider,
@@ -105,7 +108,9 @@ public class QSFactoryImpl implements QSFactory {Provider<GarbageMonitor.MemoryTile> memoryTileProvider,Provider<UiModeNightTile> uiModeNightTileProvider,Provider<ScreenRecordTile> screenRecordTileProvider,
-                       Provider<EyeHealthTile> eyeHealthTileProvider) {
+                       Provider<EyeHealthTile> eyeHealthTileProvider,
+                       Provider<TDButtonTile> tDButtonTileProvider
+            ) {mQsHostLazy = qsHostLazy;mWifiTileProvider = wifiTileProvider;mBluetoothTileProvider = bluetoothTileProvider;
@@ -128,6 +133,7 @@ public class QSFactoryImpl implements QSFactory {mUiModeNightTileProvider = uiModeNightTileProvider;mScreenRecordTileProvider = screenRecordTileProvider;mEyeHealthTileProvider=eyeHealthTileProvider;
+        mTDButtonTileProvider = tDButtonTileProvider;}public QSTile createTile(String tileSpec) {
@@ -180,6 +186,8 @@ public class QSFactoryImpl implements QSFactory {return mUiModeNightTileProvider.get();case "screenrecord":return mScreenRecordTileProvider.get();
+            case "tdbutton":
+                return mTDButtonTileProvider.get();}diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/TDButtonTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/TDButtonTile.java
new file mode 100755
index 0000000..76581e3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/TDButtonTile.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles;
+
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.provider.Settings;
+import android.service.quicksettings.Tile;
+import android.widget.Switch;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.R;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.QSPanel;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+
+import javax.inject.Inject;
+
+/** Quick settings tile: Rotation **/
+public class TDButtonTile extends QSTileImpl<BooleanState> {
+
+    private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_td_button);
+
+    @Inject
+    public TDButtonTile(QSHost host) {
+        super(host);
+        QSPanel.setStatusChange(new QSPanel.StatusChange(){
+            @Override
+            public void statusChange(boolean status){
+
+                refreshState();
+
+            }
+
+        });
+    }
+
+    @Override
+    public BooleanState newTileState() {
+        return new BooleanState();
+    }
+
+
+    @Override
+    protected void handleClick() {
+        final boolean newState = !mState.value;
+        QSPanel.liujunjieClick();
+        refreshState(newState);
+    }
+
+
+    @Override
+    public CharSequence getTileLabel() {
+        return getState().label;
+    }
+
+    @Override
+    protected void handleUpdateState(BooleanState state, Object arg) {
+
+        state.value = QSPanel.getDTStatus();
+        state.label = mContext.getString(R.string.quick_settings_dtbutton_unlocked_label);
+        state.icon = mIcon;
+        //tate.contentDescription = getAccessibilityString(rotationLocked);
+        //state.expandedAccessibilityClassName = Switch.class.getName();
+        state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return 0;
+    }
+
+
+    @Override
+    protected void handleSetListening(boolean listening) {
+
+
+    }
+
+    @Override
+    public Intent getLongClickIntent() {
+        Intent homeIntent = new Intent(Intent.ACTION_MAIN);
+        homeIntent.addCategory(Intent.CATEGORY_HOME);xieuy
+        homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return homeIntent;
+    }
+
+}

协议链接

链接:https://pan.baidu.com/s/1kOmVpb5fEKO9FAkN4JsnhA?pwd=s56b 
提取码:s56b 

相关文章:

安卓11 SysteUI添加按钮以及下拉状态栏的色温调节按钮

最近客户想要做一个台灯产品&#xff0c;需要实现 串口调节台灯功能 &#xff0c;其中包括 亮度调节 色温调节 开关 三个功能 话不多说&#xff0c;贴代码 diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml old mode 100644 new …...

多个线程处理不同的数据,等线程都完成后再进行下一步操作

现在有三个任务,三个任务之间没有关联关系,但是第四个任务要等前三个完成之后才能进行,于是使用多线程完成前三个任务节省时间 示例代码: public void saveDataByOnlineTimeNew(LocalDateTime startTime, LocalDateTime endTime) {Objects.requireNonNull(startTime, "开…...

聆听音乐 1.5.9 | 畅听全网音乐,支持无损音质下载

聆听音乐手机版是面向广大音乐爱好者的移动应用程序&#xff0c;用户可以随时随地通过手机享受丰富的音乐资源。它提供了多种魅力功能&#xff0c;让用户在手机上畅享更舒适的音乐体验&#xff0c;每位用户都能享受精彩纷呈的收听体验。此外&#xff0c;软件还支持无损音质音乐…...

Rust 基础入门指南

Rust 基础入门指南 1. Rust 语言概述 Rust 的历史与设计理念 Rust 是由 Mozilla 研究院的 Graydon Hoare 于2010年开始创建的系统编程语言。其设计目标是创建一种安全、并发、实用的编程语言&#xff0c;特别关注内存安全和并发性。 Rust 的核心设计理念包括&#xff1a; …...

青少年编程与数学 02-006 前端开发框架VUE 03课题、编写APP组件

青少年编程与数学 02-006 前端开发框架VUE 03课题、编写APP组件 一、组件二、VUE中的组件三、APP组件四、应用示例1. App.vue - 根组件2. HelloWorld.vue - 子组件3. main.js - 应用入口文件4. router/index.js - 路由配置文件5. index.html - HTML入口文件6. package.json - 项…...

基于Java的银行排号系统的设计与实现【源码+文档+部署讲解】

目 录 内容提要 1. 引言 2. 系统分析 2.1 系统初步调查 2.2 系统可行性分析 2.2.1 经济可行性 2.2.2 操作可行性 2.2.3 技术可行性 2.3 系统开发环境概述 2.3.1 硬件环境 2.3.2 软件环境 2.4 系统需求分析 2.4.1 业务流程分析 2.4.2 系统体系结构设计 2.4.3 系统逻辑模型 2.5 …...

linux-26 文件管理(四)install

说一个命令&#xff0c;叫install&#xff0c;man install&#xff0c;install是什么意思&#xff1f;安装&#xff0c;install表示安装的意思&#xff0c;那你猜install是用来干什么的&#xff1f;猜一猜干什么的&#xff1f;安装软件&#xff0c;安装第三方软件&#xff0c;错…...

VS2015中使用boost库函数时报错问题解决error C4996 ‘std::_Copy_impl‘

在VS2015中使用boost库函数buffer时遇到问题&#xff0c;其他函数定义均能执行&#xff0c;当加上bg::buffer(参数输入正确);语句后就报如下错误&#xff1a; 错误 C4996 std::_Copy_impl: Function call with parameters that may be unsafe - this call relies…...

pikachu靶场--目录遍历和敏感信息泄露

pikachu靶场—目录遍历和敏感信息泄露 目录遍历 概述 在web功能设计中,很多时候我们会要将需要访问的文件定义成变量&#xff0c;从而让前端的功能便的更加灵活。 当用户发起一个前端的请求时&#xff0c;便会将请求的这个文件的值(比如文件名称)传递到后台&#xff0c;后台再…...

植物大战僵尸杂交版3.0.2版本

更新内容 植物大战僵尸杂交版3.0.2版本的更新内容如下&#xff1a; • 修复BUG&#xff1a; • 游戏内贴图错乱的BUG。 • 无尽模式卡死的BUG。 • 卡牌模仿者的一系列BUG。 • 干扰车可能同时出现多辆的BUG。 • 冒险模式部分关卡无法过关的BUG。 • 新增内容&#xf…...

kafka怎么保证顺序消费?

kafka怎么保证顺序消费&#xff1f; 1. 分区内的顺序保证2. 并发消费3. 实现顺序消费的策略4. 注意事项 kafka创建 topic 的时候没有指定分区数量&#xff0c;那么默认只会有一个分区。如果你想要创建一个具有多个分区的 topic&#xff0c;你可以在创建 topic 的命令中指定 --p…...

Makefile 模板 --- 内核模块

内核模块模板 驱动源码同级目录下 #******************************************************************************* # xxx Co., Ltd. All Right Reserved. # Author : # Version : V1.0.0 2020.10.21 # Description : # Note : gaoyang3513163.co…...

仓库叉车高科技安全辅助设备——AI防碰撞系统N2024G-2

在当今这个高效运作、安全第一的物流时代&#xff0c;仓库作为供应链的中心地带&#xff0c;其安全与效率直接关系到企业的命脉。 随着科技的飞速发展&#xff0c;传统叉车作业模式正逐步向智能化、安全化转型&#xff0c;而在这场技术革新中&#xff0c;AI防碰撞系统N2024G-2…...

计算机视觉CV期末总复习

1.计算机视觉基础 数字图像表示 二值图像 仅包含黑白两种颜色的图像&#xff0c;只使用1个比特为&#xff08;0黑或1白&#xff09;表示 彩色图像&#xff1a;分不同的颜色空间 gray灰度图像 每个像素只有一个采样颜色&#xff0c;取值范围0--255&#xff0c;为8比特位&a…...

【微信小程序获取用户手机号

微信小程序获取用户手机号有2种,一种是前端自己解密,一种是获取后发给后端,后端去解密 重点:要在微信公众平台设置里面绑定微信开放平台账号,不然反解不出来用户手机号上代码: <button style"font-size: 16px;" open-type"getPhoneNumber" getphonenumb…...

WFP Listbox绑定数据后,数据变化的刷新

Listbox绑定数据通过ItemsSource来的&#xff0c;如果绑定的是普通的List<数据>&#xff0c;不会自己刷新。 使用ObservableCollection集合 解决问题的方法: 将数组替换为 ObservableCollection ObservableCollection 是专为绑定设计的集合类型&#xff0c;可以通知 W…...

Android Camera压力测试工具

背景描述&#xff1a; 随着系统的复杂化和业务的积累&#xff0c;日常的功能性测试已不足以满足我们对Android Camera相机系统的测试需求。为了确保Android Camera系统在高负载和多任务情况下的稳定性和性能优化&#xff0c;需要对Android Camera应用进行全面的压测。 对于压…...

【华为OD-E卷 - 最优资源分配 100分(python、java、c++、js、c)】

【华为OD-E卷 - 最优资源分配 100分&#xff08;python、java、c、js、c&#xff09;】 题目 某块业务芯片最小容量单位为1.25G&#xff0c;总容量为M*1.25G&#xff0c;对该芯片资源编号为1&#xff0c;2&#xff0c;…&#xff0c;M。该芯片支持3种不同的配置&#xff0c;分…...

字符串格式时间(HH-MM)添加间隔时间后转为HH-MM输出

转换时间代码如下所示 #include <iostream> #include <iomanip> #include <sstream>//添加时间转换为时间 std::string addMinutesToTime(const std::string& timeStr, int minutesToAdd) {int hours, minutes;char delimiter;//解析输入时间std::istri…...

SQL 基础教程 - SQL ORDER BY 关键字

SQL ORDER BY 关键字 ORDER BY 关键字用于对结果集进行排序。 SQL ORDER BY 关键字 ORDER BY 关键字用于对结果集按照一个列或者多个列进行排序。 ORDER BY 关键字默认按照升序对记录进行排序。如果需要按照降序对记录进行排序&#xff0c;您可以使用 DESC 关键字。 SQL ORD…...

DAMOYOLO-S快速上手:移动端浏览器访问Web服务与触屏操作适配说明

DAMOYOLO-S快速上手&#xff1a;移动端浏览器访问Web服务与触屏操作适配说明 1. 开篇&#xff1a;一个能“看懂”世界的AI助手 想象一下&#xff0c;你正用手机拍一张街景照片&#xff0c;屏幕上立刻就能标出“汽车”、“行人”、“交通灯”&#xff0c;甚至“手提包”。这不…...

不只是安装:深入理解TI毫米波雷达开发套件(MMWCAS-RF-EVM)的软件生态与数据流

不只是安装&#xff1a;深入理解TI毫米波雷达开发套件&#xff08;MMWCAS-RF-EVM&#xff09;的软件生态与数据流 毫米波雷达技术正在重塑自动驾驶、工业检测和智能安防等领域&#xff0c;而TI的MMWCAS-RF-EVM评估板作为行业标杆工具&#xff0c;其真正的价值往往被简化为"…...

用快马平台快速原型你的技能学习器:AI一键生成交互式教程项目

最近在尝试做一个交互式Python技能学习生成器&#xff0c;发现用InsCode(快马)平台可以特别高效地完成原型验证。这个工具的核心思路是让用户输入想学习的技能&#xff0c;系统就能自动生成完整的学习项目&#xff0c;包含理论、示例和练习。下面分享下具体实现过程&#xff1a…...

Qwen3-VL-8B系统资源管理:监控与清理GPU显存和C盘空间

Qwen3-VL-8B系统资源管理&#xff1a;监控与清理GPU显存和C盘空间 长期运行像Qwen3-VL-8B这样的大模型服务&#xff0c;就像养了一头“数字大象”——它能力强大&#xff0c;但胃口也不小&#xff0c;尤其能吃GPU显存和硬盘空间。很多朋友刚开始部署时一切顺利&#xff0c;但跑…...

大麦智能抢票系统:告别手速极限的终极解决方案

大麦智能抢票系统&#xff1a;告别手速极限的终极解决方案 【免费下载链接】ticket-purchase 大麦自动抢票&#xff0c;支持人员、城市、日期场次、价格选择 项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase 还在为抢不到热门演唱会门票而烦恼吗&…...

基于WebRTC的P2P文件传输系统:架构设计与实现原理

基于WebRTC的P2P文件传输系统&#xff1a;架构设计与实现原理 【免费下载链接】filepizza :pizza: Peer-to-peer file transfers in your browser 项目地址: https://gitcode.com/GitHub_Trending/fi/filepizza 在当今数字时代&#xff0c;文件传输已成为日常工作和协作…...

万象视界灵坛快速部署:GitLab CI流水线自动触发镜像构建与K8s滚动更新

万象视界灵坛快速部署&#xff1a;GitLab CI流水线自动触发镜像构建与K8s滚动更新 1. 项目概述 万象视界灵坛&#xff08;Omni-Vision Sanctuary&#xff09;是一款基于OpenAI CLIP技术的高级多模态智能感知平台。该平台通过创新的像素风格界面&#xff0c;将复杂的语义对齐过…...

SDXL 1.0插件开发:Photoshop脚本自动化集成

SDXL 1.0插件开发&#xff1a;Photoshop脚本自动化集成 1. 为什么需要Photoshop与SDXL 1.0的深度协作 设计师每天面对的不是单一工具&#xff0c;而是一整套工作流。当AI生成图像成为创意起点&#xff0c;问题就来了&#xff1a;生成的图片如何快速进入专业设计环节&#xff…...

Winhance中文版:让Windows系统管理不再复杂的全能工具

Winhance中文版&#xff1a;让Windows系统管理不再复杂的全能工具 【免费下载链接】Winhance-zh_CN A Chinese version of Winhance. C# application designed to optimize and customize your Windows experience. 项目地址: https://gitcode.com/gh_mirrors/wi/Winhance-zh…...

AutoDL部署大模型后,除了Chat:手把手教你用本地API接口玩转文档总结、代码生成和智能客服

AutoDL部署大模型后&#xff0c;除了Chat&#xff1a;手把手教你用本地API接口玩转文档总结、代码生成和智能客服 当你已经在AutoDL上成功部署了大语言模型&#xff0c;并验证了基础的聊天功能后&#xff0c;是否思考过如何将这些能力真正融入日常工作流&#xff1f;本文将带你…...