Lineageos 22.1(Android 15)实现负一屏

一、前言

方案是参考的这位大佬的,大家可以去付费订阅支持一波。我大概理一下Android15的修改。
大佬的方案代码

二、Android15适配调整

1.bp调整,加入aidl引入,这样make之后就可以索引代码了

filegroup {name: "launcher-src",srcs: ["src/**/*.java","src/**/*.kt","src/**/*.aidl"],
}

客户端端按照文章来就行,服务端我微调了一下代码,让切换变得更加平顺,具体还的项目中再调整。其实还差手机重复按的时候停止动画之类的东西处理,遇到的时候再说吧。

package com.google.test;import android.animation.Animator;
import android.animation.ValueAnimator;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.LinearInterpolator;
import android.widget.LinearLayout;
import android.widget.TextView;import com.google.android.libraries.launcherclient.ILauncherOverlay;
import com.google.android.libraries.launcherclient.ILauncherOverlayCallback;import androidx.annotation.NonNull;/*** Created by cczheng on 2022/5/25.*/public class ScreenService extends Service {private Context mContext;private WindowManager mWindowManager;private WindowManager.LayoutParams mLayoutParams;private int screenWidth;ILauncherOverlayCallback overlayCallback;private String TAG = "ScreenService";private float progress;@Overridepublic void onCreate() {super.onCreate();mContext = this;mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);mLayoutParams = new WindowManager.LayoutParams();DisplayMetrics outMetrics = new DisplayMetrics();mWindowManager.getDefaultDisplay().getMetrics(outMetrics);screenWidth = outMetrics.widthPixels;Log.d(TAG, "onCreate");}@Overridepublic IBinder onBind(Intent intent) {IBinder iBinder = new ILauncherOverlayImpl().asBinder();Log.i(TAG, "onBind");return iBinder;}public class ILauncherOverlayImpl extends ILauncherOverlay.Stub {private Handler mainThreadHandler;@Overridepublic String getVoiceSearchLanguage() throws RemoteException {return null;}@Overridepublic boolean isVoiceDetectionRunning() throws RemoteException {return false;}@Overridepublic void onPause() throws RemoteException {Log.d(TAG, "onPause");}@Overridepublic void onResume() throws RemoteException {Log.d(TAG, "onResume");}@Overridepublic void requestVoiceDetection(boolean start) throws RemoteException {Log.d(TAG, "requestVoiceDetection");}@Overridepublic void openOverlay(int options) throws RemoteException {Log.i(TAG, "openOverlay");}@Overridepublic void closeOverlay(int options) throws RemoteException {Log.i(TAG, "closeOverlay");}@Overridepublic void startScroll() throws RemoteException {Log.e(TAG, "startScroll");Message.obtain(this.mainThreadHandler, OverlayCallback.START_SCROLL).sendToTarget();}@Overridepublic void onScroll(float progress) throws RemoteException {
//            Log.i(TAG,"onScroll=" + progress);Message.obtain(this.mainThreadHandler, OverlayCallback.UPDATE_SCROLL, progress).sendToTarget();}@Overridepublic void endScroll() throws RemoteException {Log.e(TAG, "endScroll");Message.obtain(this.mainThreadHandler, OverlayCallback.END_SCROLL).sendToTarget();}@Overridepublic void windowAttached(WindowManager.LayoutParams attrs, ILauncherOverlayCallback callbacks,int options) throws RemoteException {Log.i(TAG, "windowAttached.....");
//            doWindowAttached(attrs, callbacks, options);overlayCallback = callbacks;Bundle bundle = new Bundle();bundle.putParcelable("layout_params", attrs);bundle.putInt("client_options", options);OverlayCallback overlayCallback = new OverlayCallback(ScreenService.this);mainThreadHandler = new Handler(Looper.getMainLooper(), overlayCallback);Message.obtain(this.mainThreadHandler, OverlayCallback.WINDOW_ATTACHED,Pair.create(bundle, callbacks)).sendToTarget();}@Overridepublic void windowDetached(boolean isChangingConfigurations) throws RemoteException {Log.d(TAG, "windowDetached");Message.obtain(this.mainThreadHandler, OverlayCallback.WINDOW_DETACHCHED, isChangingConfigurations).sendToTarget();}}private void applyScroll(View view)  {try {overlayCallback.overlayScrollChanged(progress);mLayoutParams.x = (int) (-screenWidth*(1-progress));mWindowManager.updateViewLayout(view, mLayoutParams);} catch (RemoteException e) {throw new RuntimeException(e);}}private void startProgressAnimation(boolean open,View view) {ValueAnimator valueAnimator=(open)? ValueAnimator.ofFloat(progress, 1f):ValueAnimator.ofFloat(progress, 0f);valueAnimator.setDuration(500);valueAnimator.setInterpolator(new LinearInterpolator());valueAnimator.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {}@Overridepublic void onAnimationEnd(Animator animation) {try {overlayCallback.overlayScrollChanged(0);} catch (RemoteException e) {e.printStackTrace();}}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}});valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {progress= (float) valueAnimator.getAnimatedValue();applyScroll(view);}});valueAnimator.start();}class OverlayCallback implements Handler.Callback {public static final int WINDOW_ATTACHED = 100;public static final int START_SCROLL = 101;public static final int UPDATE_SCROLL = 102;public static final int END_SCROLL = 103;public static final int WINDOW_DETACHCHED = 104;private ScreenService screenService;private LinearLayout mOverlayDecorView;public OverlayCallback(ScreenService screenService) {this.screenService = screenService;}@Overridepublic boolean handleMessage(@NonNull Message msg) {try {if (msg.what == WINDOW_ATTACHED) {
//                bundle.putParcelable("layout_params", attrs);
//                bundle.putInt("client_options", options);Pair<Bundle, ILauncherOverlayCallback> pair = (Pair<Bundle, ILauncherOverlayCallback>) msg.obj;WindowManager.LayoutParams layoutParams = pair.first.getParcelable("layout_params");
//                    overlayCallback = pair.second;doWindowAttached(layoutParams, pair.second, 1);} else if (msg.what == START_SCROLL) {} else if (msg.what == UPDATE_SCROLL) {progress = (float) msg.obj;Log.d(TAG, "progress=" + progress);applyScroll(mOverlayDecorView);} else if (msg.what == END_SCROLL) {startProgressAnimation(progress>0.4f,mOverlayDecorView);}} catch (RemoteException e) {e.printStackTrace();}return false;}public void doWindowAttached(WindowManager.LayoutParams lp, ILauncherOverlayCallback cb,int flags) throws RemoteException {mLayoutParams = new WindowManager.LayoutParams();mLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;mLayoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;mLayoutParams.gravity = Gravity.START;// 负一屏的 Window 层级比 Launcher 的大就可以mLayoutParams.type = lp.type + 1;mLayoutParams.token = lp.token;mLayoutParams.flags = WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS |WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS |WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;mLayoutParams.x = -screenWidth;Log.d(TAG, "doWindowAttached." + lp.type + "   " + lp.token + "   " + (-screenWidth));mLayoutParams.format = PixelFormat.TRANSLUCENT;mOverlayDecorView = new LinearLayout(mContext);mOverlayDecorView.setGravity(Gravity.CENTER);mOverlayDecorView.setBackgroundColor(Color.RED);TextView textView = new TextView(mContext);textView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT));textView.setText("XXXXXXXX");textView.setTextSize(25);textView.setTextColor(Color.WHITE);mOverlayDecorView.addView(textView);mWindowManager.addView(mOverlayDecorView, mLayoutParams);mOverlayDecorView.setOnTouchListener(new OverlayOnTouchListener());if (cb != null) {cb.overlayStatusChanged(1);}}}private boolean isDrag;private class OverlayOnTouchListener implements View.OnTouchListener {private int firstX;private int lastX;@Overridepublic boolean onTouch(View view, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:isDrag = false;firstX = (int) event.getRawX();lastX = (int) event.getRawX();break;case MotionEvent.ACTION_MOVE:isDrag = true;int nowX = (int) event.getRawX();int movedX = nowX - lastX;lastX = nowX;
//                    Log.d(TAG,"movedX=" + movedX);if (movedX < 0) {//只能左滑,滑到launcher中mLayoutParams.x = mLayoutParams.x + movedX;progress=1-((float) -mLayoutParams.x )/((float) screenWidth);applyScroll(view);
//                        mWindowManager.updateViewLayout(view, mLayoutParams);
//                        try {
//                            overlayCallback.overlayScrollChanged();
//                        } catch (RemoteException e) {
//                            throw new RuntimeException(e);
//                        }}break;case MotionEvent.ACTION_UP:int stopX = (int) event.getRawX();int movedFX = stopX - firstX;Log.d(TAG,"lastX=" + lastX + "  isDrag=" + isDrag + "  movedFX=" + movedFX);if (isDrag && movedFX < 0) {progress=1-((float) -mLayoutParams.x )/((float) screenWidth);startProgressAnimation(false,view);}break;}return isDrag || view.onTouchEvent(event);}}}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/39437.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

5G NR PRACH 随机接入前导序列

目录 一、前言二、随机接入前导序列的产生三、 N c s N_{cs} Ncs​的规划3.1、 L R A L_{RA} LRA​839 N c s N_{cs} Ncs​规划3.2、 L R A L_{RA} LRA​139 N c s N_{cs} Ncs​规划3.3、 N c s N_{cs} Ncs​确定方法 四、根序列的规划4.1、根序列的选择与确定4.2、循环移位 …

【VUE】day07 路由

【VUE】day07 路由 1. 路由2. 前端路由的工作方式3. 实现简易的前端路由4. 安装和配置路由4.1 安装vue-router包4.2 创建路由模块4.3 导入并挂在路由模块 5. 在路由模块中声明路由的对应关系5.1 router-view 1. 路由 在 Vue.js 中&#xff0c;路由&#xff08;Routing&#xf…

WPS宏开发手册——使用、工程、模块介绍

目录 系列文章前言1、开始1.1、宏编辑器使用步骤1.2、工程1.3、工程 系列文章 使用、工程、模块介绍 JSA语法 第三篇练习练习题&#xff0c;持续更新中… 前言 如果你是开发人员&#xff0c;那么wps宏开发对你来说手拿把切。反之还挺吃力&#xff0c;需要嘻嘻&#xf…

数学概念学习

# 欧式空间 ## 定义 日常生活观察到的几何空间&#xff1a;一维、平面和三维空间。 ## 点与向量 是欧式空间的基本元素。 ## 距离和内积 距离&#xff1a;通过欧几里得距离公式计算 内积&#xff08;点积&#xff09;&#xff1a; 通过两个向量的内积来测量他们的相似性&…

InnoDB 引擎核心知识点

InnoDB 引擎核心知识点 6.1 逻辑存储结构 表空间&#xff08;Tablespace&#xff09;&#xff1a;所有数据逻辑上存储在一个表空间中&#xff0c;物理上可能由多个文件组成。段&#xff08;Segment&#xff09;&#xff1a;分为数据段&#xff08;B树叶子节点&#xff09;、索引…

C++《红黑树》

在之前的篇章当中我们已经了解了基于二叉搜索树的AVL树&#xff0c;那么接下来在本篇当中将继续来学习另一种基于二叉搜索树的树状结构——红黑树&#xff0c;在此和之前学习AVL树类似还是通过先了解红黑树是什么以及红黑树的结构特点&#xff0c;接下来在试着实现红黑树的结构…

java实现coze平台鉴权+工作流调用(踩坑记录)

问题偏多建议大家看完文章后再开始实现 OAuth鉴权 https://www.coze.cn/open/docs/developer_guides/preparation https://www.coze.cn/open/docs/developer_guides/oauth_apps OAuth 授权码鉴权 https://www.coze.cn/open/docs/developer_guides/oauth_code 创建OAuth应…

2025年优化算法:龙卷风优化算法(Tornado optimizer with Coriolis force,TOC)

龙卷风优化算法&#xff08;Tornado optimizer with Coriolis force&#xff09;是发表在中科院二区期刊“ARTIFICIAL INTELLIGENCE REVIEW”&#xff08;IF&#xff1a;11.7&#xff09;的2025年智能优化算法 01.引言 当自然界的狂暴之力&#xff0c;化身数字世界的智慧引擎&…

面试题分享-多线程顺序打印奇偶数

目录 1.题目详情 2.解题思路 2.1.分析题目 2.2.解析思路 3.代码实现 4.运行结果 1.题目详情 昨天刷抖音&#xff0c;遇到一个面试题&#xff0c;描述如下&#xff1a; 请使用两个线程&#xff0c;分别顺序交替打印奇数和偶数&#xff0c;直到10为止。例如有两个线程&#…

QuecPython 网络协议之TCP/UDP协议最祥解析

概述 IP 地址与域名 IP 地址是网络中的主机地址&#xff0c;用于两台网络主机能够互相找到彼此&#xff0c;这也是网络通信能够成功进行的基础。IP 地址一般以点分十进制的字符串来表示&#xff0c;如192.168.1.1。 ​ 我们日常访问的网站&#xff0c;其所在的服务器主机都有…

React - LineChart组件编写(用于查看每日流水图表)

一、简单版本 LineChart.tsx // src/component/LineChart/LineChart.tsx import React, {useEffect,useRef,useImperativeHandle,forwardRef,useMemo,useCallback, } from react; import * as echarts from echarts/core; import type { ComposeOption } from echarts/core; …

医学图像分割数据集肺分割数据labelme格式6299张2类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图像分辨率&#xff1a;1024x1024 图片数量(jpg文件个数)&#xff1a;6299 标注数量(json文件个数)&#xff1a;6299 标注类别数&#xff1a;2 标注类别名称:["leftl…

帕金森病致生活艰难,如何缓解心理负担?

你是否留意到身边有人手部不由自主地颤抖&#xff0c;且肢体变得僵硬&#xff0c;行动也愈发迟缓&#xff1f;这很可能是帕金森病的症状。帕金森病是一种常见的神经系统退行性疾病&#xff0c;多发生于中老年人。​ 静止性震颤往往是帕金森病的首发症状&#xff0c;患者在安静状…

从零构建大语言模型全栈开发指南:第二部分:模型架构设计与实现-2.1.1自注意力机制(Scaled Dot-Product Attention)的逐行代码实现

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 2.1.1 自注意力机制(Scaled Dot-Product Attention)的逐行代码实现1. 自注意力机制的核心原理与数学表达1.1 注意力计算的三元组:`Q, K, V`2. 逐行代码实现与解析2.1 输入嵌入与权重矩阵初始化2.2 完…

机械臂【逆运动学】

回顾正运动学fk&#xff1a; IK&#xff1a; 几何法 代数法 六轴 456轴交再同一点 有解析解 下列公式为正运动学部分结论 a和d是长度 &#xff0c;theta和alfa是角度 **疑问&#xff1a;alfa00&#xff1f; Z轴互相平行 ** 已知末端要在空间XYZ处如下 绿色项&#x…

IDEA批量替换项目下所有文件中的特定内容

文章目录 1. 问题引入2. 批量替换项目下所有文件中的特定内容2.1 右键项目的根目录&#xff0c;点击在文件中替换2.2 输入要替换的内容 3. 解决替换一整行文本后出现空行的问题4. 增加筛选条件提高匹配的精确度 更多 IDEA 的使用技巧可以查看 IDEA 专栏&#xff1a; IDEA 1. 问…

Ubuntu22.04美化MacOS主题

安装Tweaks 参考Ubuntu 22.04 桌面美化成Mac风格这篇更好点 sudo apt install gnome-tweaks gnome-shell-extensions -y安装macos主题 git clone https://github.com/vinceliuice/WhiteSur-gtk-theme.git # 进到文件目录 ./install.sh -t all -N glassy sudo ./tweaks.sh -g…

基于Python的机器学习入门指南

在当今数字化时代&#xff0c;机器学习&#xff08;Machine Learning&#xff09;已经成为科技领域中最热门的话题之一。它不仅改变了我们对数据的理解和处理方式&#xff0c;还在许多行业中得到了广泛应用&#xff0c;如金融、医疗、交通等。Python作为一门强大的编程语言&…

Python前缀和(例题:异或和,求和)

前缀和 前缀和&#xff1a;对于一个长度为n的列表a&#xff0c;前缀和为&#xff1a; sum[i]a[0]a[1]...a[i] 前缀和的性质&#xff1a; 第一条性质用于处理出前缀和&#xff1a; Sum[i]Sum[i-1]a[i] 第二条性质可以在O(l)的时间内求出区间和&#xff1a; a[l]....a[r] S…

统计矩的高阶推广:经验还是理论推导?

矩的发展既是经验总结的结果&#xff0c;也是数学理论推导的产物。研究者们在分析数据、描述物理现象的过程中&#xff0c;发现了低阶矩与日常物理概念&#xff08;如质心、惯性&#xff09;之间的紧密联系&#xff0c;而高阶矩的应用往往出现在更复杂的数学体系中&#xff0c;…