yanhy的学习记录匣 - 2022年11月 探索知识的宝箱,记录成长的脚步。欢迎来访Yanhy的博客站,在这里,每一页都是对知识无尽好奇的见证,每个故事都是学习旅程中的珍贵篇章,一起激发灵感,分享进步 2022-11-20T23:26:00+08:00 Typecho https://yanhy.top/index.php/feed/atom/2022/11/ <![CDATA[Win11 安装WSA (含Magisk/root/GApps) - Local构建方案]]> https://yanhy.top/index.php/archives/281/ 2022-11-20T23:26:00+08:00 2022-11-20T23:26:00+08:00 yanhy2000 https://yanhy.top

终于想升级到win11了,结果是因为眼馋WSLg这个功能,不过既然都到Win11了,顺手也安装一下WSA吧,既然有特性就算不用也得要装(

本篇学习自:https://www.tjsky.net/tutorial/384

前景

由于很晚才升级win11,以至于想用Magisk+GApps的WSA时,却发现Github的项目页面一个醒目的提醒:This repository has been disabled.

查了一下,原来是因为太多人用Github的Action流导致项目被封禁了,看样子云端编译是没辙了。所幸LSposed团队又出了一个项目 MagiskOnWSALocal ,我们可以使用这个项目进行本地编译,只需要有WSL子系统环境或者虚拟机Linux系统都可以编译运行。正好网上也有大佬做了博客,我就根据自己的经验二次整理了一下。


环境配置

系统环境:

  • Win系统版本:Win11 >=22000.x
  • 主板支持UEFI虚拟化(能安装WSA或者WSL就可以)
  • 微软商店:>=22110.1402.6.0
  • 运行内存:>=8G

编译环境:

  • WSL (Ubuntu20Debian10)及更高版本 或 虚拟机Ubuntu等系统


准备工作

  • 卸载现有的WSA并清除数据(可以尝试保留数据,但可能会出问题)
  • Win-设置-应用程序-可选功能--更多Windows功能-打开Hyper-v虚拟机平台 (其他虚拟机组件不影响)
  • 1.png
  • 2.png
  • 安装虚拟机(可网上自行查找教程,推荐Vmware+Ubuntu21+桌面环境+最小化安装+Vmware Tools)
  • 3.png

构建WSA安装包

不想自己构建可以去下面的“安装”章节下载本篇文章构建好的

0、 (可选) 打开Github,前往作者团队的项目MagiskOnWSALocal(https://github.com/LSPosed/MagiskOnWSALocal) 并Star,支持作者团队

1、打开虚拟机,打开终端,输入指令sudo apt update来更新软件源,稍后我们要安装几个软件包(保持网络畅通)

2、切换到Home目录,然后安装Git工具并克隆项目,如果网络不好可能会很慢,耐心等待

cd ~
sudo apt install git -y
git clone https://github.com/LSPosed/MagiskOnWSALocal.git

4.png

3、等克隆完毕且没有明显报错(报错可能就是网络不好无法继续克隆)后,切换目录到项目内

cd MagiskOnWSALocal

4、开始运行一键脚本,自动安装与配置环境

sudo ./scripts/run.sh

5.png

5、经过大概20分钟的等待,终端内会显示选项,此时开始自定义安装;如果中途有选择错误,强制退出再重新执行脚本即可

接下来的小标题格式为:菜单选项 | 大致意思 | 推荐选择

5-1、Build Arch | 编译架构 | 默认
用键盘方向键选择X64 (个人电脑一般都是Intel或者AMD,大多数为X64架构,可能也有部分Arm设备,可以自行编译试试看)

6.png

5-2、WSA release type | WSA发行类型 | 默认
一般选择retail,零售版,也解释为稳定版;如果想体验预览版,可选择Beta或者Dev通道的版本

8.png

5-3、Magisk version | 面具版本通道 | 默认
顾名思义是面具的更新通道,一般来说稳定就好,和手机上刷root用的面具玩法一样

7.png

5-4、Install GApps | 安装GApps | 是
如果没有一个好的网络环境也可以不安装,可以使用第三方安装器安装软件

9.png

5-5、Which GApps do you want to install? | 安装哪种版本的GApps | OpenGApps
推荐使用OpenGapps,体验过就明白了

10.png

5-6(略过)、Variants of gapps | 选择安装什么体积的GApps | 无
此选择目前略过,因为GApps没跟上WSA安卓版本(12)的更新,目前只有Pico量级的能用,默认跳过

5-7、 Remove Amazon Appstore | 移除亚马逊市场 | 否
憨憨亚马逊市场,app真的少,大部分游戏还都是益智游戏,建议选否,不保留

11.png

5-8、Root solution | Root解决方案 | Magisk
嗯,就一个面具,就选它,或者你不想root可以选none,这样就可以构建个无root但有GApps的WSA了

12.png

5-9、Compress output | 压缩构建包 | 是
如果你是老电脑,建议选否,压缩是一件很吃cpu的事情,虚拟机推荐压缩,方便导出文件,咱这边要分享到社区,所以选择压缩

13.png

5-10、Compress format | 压缩格式 | zip
同上述,压缩很吃cpu,7z更吃,tar.xz会好一些,但是在win下需要压缩软件支持,zip适合大众需求,空格选择,回车即确定

14.png

6、选择完成后,即可开始构建WSA安装包(会下载一些软件包,需要保持好的网络环境)

15.png

7、等待十几分钟,即可构建完毕(包体大概八百多MB)

16.png

17.png


安装WSA构建包

此处为第一次安装WSA,如果之前有WSA请先卸载再安装,如果之前也是MagiskOnWSA,需要更新的话看下文,本篇文章构建包分享:https://www.123pan.com/s/Dpq0Vv-ORuHd提取码:CcO3

1、将上一步中构建完成的包(或是本文分享的构建包)解压到D盘/WSA文件夹中,文件夹可自行创建,但解压后不可删除,解压路径即为运行路径,我给解压到了D:/Users/xxxx
(一开始没改名,改名时检测被占用,一看果然这个文件夹是WSA的本体,悲,只能等下次更新的时候找机会换掉)

21.png

(和我上一次构建的版本一样,就是不知道里面小版本有没有改,本文会放出本次构建的共享链接)
(云盘校验没通过无法秒传,看样子里面小版本可能修改过,也可能只是文件属性变了)
18.png

2、进入文件夹,找到run.bat,运行即可(图中为我上一次构建的安装,稍后会讲到更新MagiskOnWSA,那时候再把我自己的包更新了)

19.png

3、等待安装完毕,会自动打开Magisk软件与Play商店,也可能只弹出一个,但是只要能运行即可代表安装完成。我参考的那篇教程里面说,Magisk默认是没开Zygisk,需要手动安装LSposed_Zygisk,但是在本文编写的时候,Zygisk就已经内置进Magisk内了

20.png


更新MagiskOnWSA

首先,请勿在微软商店内更新WSA,并且记得关掉微软商店的自动更新
更新方法:删除上一次git克隆文件夹,重新拉取代码并重新构建,得到压缩完的构建包后,先关闭WSA(用适用于Androidtm的windows子系统设置),再解压替换文件夹,并再次运行run.bat,用户数据会被保留

(确实会保留,我那小米12的Win11WSA还在(doge))
22.png

卸载MagiskOnWSA

此处摘抄原文教程(链接在顶部)

  • 打开开始菜单
  • 点击适用于Android™ 的 windows子系统设置
  • 切换到系统窗口,找到关闭适用于Android™ 的 windows子系统,点击【关闭】按钮
  • 点击重置为默认值的【重置】按钮
  • 关闭这个字窗口,重新打开开始菜单
  • 找到适用于Android™ 的 windows子系统设置在上边右键,选择【卸载】
  • 如果你要备份应用数据,可以备份
    %LOCALAPPDATA%PackagesMicrosoftCorporationII.WindowsSubsystemForAndroid_8wekyb3d8bbweLocalCacheuserdata.vhdx

安装WSAHelper(https://github.com/LSPosed/WSAHelper/releases/tag/v1.0),重新恢复开始菜单里的APP图标。

]]>
<![CDATA[ESP32-Micropython-蓝牙串口]]> https://yanhy.top/index.php/archives/279/ 2022-11-17T03:10:00+08:00 2022-11-17T03:10:00+08:00 yanhy2000 https://yanhy.top

还是准备玩esp32加小屏幕了,记录一下开发心得,虽然都做到一半多了,但是为了防止忘记或者是因为习惯性记录,还是准备将新学的给记下来,之前WIFI配网都做好了,那就从蓝牙开始吧...
原文参考链接:https://www.bilibili.com/read/cv15007387

环境配置

硬件:ESP32
编程语言:Micropython
编译器:Thonny

Micropython蓝牙

目标:让esp32模块发出蓝牙信号,手机连接并通过软件发送串口数据,模块接收数据并实现点灯效果

基础测试代码:

from machine import Pin
from time import sleep_ms
import ubluetooth   #导入BLE功能模块

ble = ubluetooth.BLE()  #创建BLE设备
ble.active(True)  #打开BLE

#设置BLE广播数据并开始广播
ble.gap_advertise(100, adv_data = b'\x02\x01\x06\x03\x09\x41\x42')

运行后,可以在手机上搜索到一个蓝牙设备名为“AB"

如要修改蓝牙名称,可这样修改:

name = bytes("aabbcc", 'UTF-8')
ble.gap_advertise(100, adv_data = b'\x02\x01\x06\x02\x0A\x08' + bytearray((len(name)+1,0x09))+name)

一个中文占用3字节储存,而广播数据最多只有31字节,除去硬件配置外,命名也要限制一定字数

广播数据格式可参考:https://www.bilibili.com/read/cv15007387

注:由于esp32模块功率很小,发射的蓝牙信号较小,手机经常连接不上,可通过在广播数据格式内修改发射功率调整,对应的数据为x02x0Ax08 ,完整代码为:

name = bytes("aabbcc", 'UTF-8')
print("蓝牙开始广播")
ble.gap_advertise(100, adv_data = b'\x02\x01\x06\x02\x0A\x08' + bytearray((len(name)+1,0x09))+name)


蓝牙可连接后,需要让其处理各种事件,如蓝牙断开、连接以及收发等,可参考以下代码
详情:https://www.bilibili.com/read/cv15039837

from machine import Pin
from time import sleep_ms
import ubluetooth   #导入BLE功能模块

ble = ubluetooth.BLE()  #创建BLE设备
ble.active(True)  #打开BLE(此时设备将处于就绪态)

#设置BLE广播数据并开始广播(开始广播后设备将处于广播态)
ble.gap_advertise(100, adv_data = b'\x02\x01\x06\x03\x09\x41\x42')


#定义一个函数,用作蓝牙事件中断
def ble_irq(event, data): # 蓝牙中断函数
    if event == 1: #蓝牙已连接(此时蓝牙将处于连接态)
      print("BLE 连接成功")

    elif event == 2: #蓝牙断开连接(此时蓝牙将从链接态进入就绪态)
      print("BLE 断开连接")
      ble.gap_advertise(100, adv_data = b'\x02\x01\x06\x03\x09\x41\x42')#再次启动广播

    elif event == 3: # 收到新write消息
      print("BLE 收到新消息")

ble.irq(ble_irq) #注册蓝牙中断函数


有了中断函数后,可以更方便监听到蓝牙状态。接下来就是准备连接手机并交互了

蓝牙服务与特性创建,详情:https://www.bilibili.com/read/cv15049793

通过注册蓝牙服务,可以使用安卓APP nRF Connect或者微信小程序 谷雨蓝牙调试 进行数据传输,其中服务id为9011特性一9012为可读可写,9013为可读与通知,从esp32到手机上的消息就是通过9013 Notify这个权限获取信息的。

完整代码:

from machine import Pin
from time import sleep_ms,sleep
import ubluetooth   #导入BLE功能模块
sleep(1)
ble = ubluetooth.BLE()  #创建BLE设备
ble.active(True)  #打开BLE(此时设备将处于就绪态)


#创建要使用的UUID
SERVER_1_UUID = ubluetooth.UUID(0x9011)
CHAR_A_UUID = ubluetooth.UUID(0x9012)
CHAR_B_UUID = ubluetooth.UUID(0x9013)

#创建特性并设置特性的读写权限
CHAR_A = (CHAR_A_UUID, ubluetooth.FLAG_READ | ubluetooth.FLAG_WRITE | ubluetooth.FLAG_NOTIFY, )
CHAR_B = (CHAR_B_UUID, ubluetooth.FLAG_READ | ubluetooth.FLAG_NOTIFY, )

SERVER_1 = (SERVER_1_UUID, (CHAR_A , CHAR_B, ) , ) #把特性A和特性B放入服务1
SERVICES = (SERVER_1, ) #把服务1放入服务集和中
((char_a, char_b), ) = ble.gatts_register_services(SERVICES) #注册服务到gatts


#设置BLE广播数据并开始广播(开始广播后设备将处于广播态)
name = bytes("aabbcc", 'UTF-8')
print("蓝牙开始广播")
ble.gap_advertise(100, adv_data = b'\x02\x01\x06\x02\x0A\x08' + bytearray((len(name)+1,0x09))+name)

#定义一个函数,用作蓝牙事件中断
def ble_irq(event, data): # 蓝牙中断函数
    if event == 1: #蓝牙已连接(此时蓝牙将处于连接态)
      print("BLE 连接成功")
    
    elif event == 2: #蓝牙断开连接(此时蓝牙将从链接态进入就绪态)
      print("BLE 断开连接")
      ble.gap_advertise(100, adv_data = b'\x02\x01\x06\x02\x0A\x08' + bytearray((len(name)+1,0x09))+name)#再次启动广播

    elif event == 3: # 收到新write消息
      onn_handle, char_handle = data #判断是来自那个特性的消息
      buffer = ble.gatts_read(char_handle) #读取接收到的消息
      print(char_handle, buffer) #打印消息内容
      ble.gatts_notify(0, char_handle, 'Hello') #回复Hello

ble.irq(ble_irq) #注册蓝牙中断函数

这段代码运行后,通过蓝牙调试软件连接模块后,监听9012特性,可对其发送数据,同时在thonny终端内也可以看到发送的数据,并且每发送一条数据,都会收到来自模块的Notify通道的”Hello"回复。

上述为读写数据创建特定的uuid,下面是较为常用的两种实际应用:
注册电池服务

#创建电池服务和特性的UUID
BATTERY_SERVER_UUID = ubluetooth.UUID(0x180F)
BATTERY_CHAR_UUID = ubluetooth.UUID(0x2A19)

#创建特性并设置特性的读写权限
BATTERY_CHAR = (BATTERY_CHAR_UUID, ubluetooth.FLAG_READ , )

BATTERY_SERVER = (BATTERY_SERVER_UUID, (BATTERY_CHAR, ) , ) #把电量特性放入电池服务
SERVICES = (BATTERY_SERVER, ) #把电池服务服务放入服务集和中

((battery_char,), ) = ble.gatts_register_services(SERVICES) #注册服务到gatts

ble.gatts_write(battery_char, b'\x50') #设置电池电量为80%

注册温湿度服务

#创建环境传感器服务和特性的UUID
ENV_SERVER_UUID = ubluetooth.UUID(0x181A) #环境传感器服务
TEM_CHAR_UUID = ubluetooth.UUID(0x2A6E)   #温度特性
HUM_CHAR_UUID = ubluetooth.UUID(0x2A6F)   #湿度特性

#创建特性并设置特性的读写权限
TEM_CHAR = (TEM_CHAR_UUID, ubluetooth.FLAG_READ , )
HUM_CHAR = (HUM_CHAR_UUID, ubluetooth.FLAG_READ , )

ENV_SERVER = (ENV_SERVER_UUID, (TEM_CHAR, HUM_CHAR, ) , ) #把温湿度特性放入环境服务
SERVICES = (ENV_SERVER, ) #把环境服务放入服务集和中

((tem_char, hum_char, ), ) = ble.gatts_register_services(SERVICES) #注册服务到gatts

ble.gatts_write(tem_char, b'\x06\x08') #设置温度为20.54度(0x0806 = 2054)
ble.gatts_write(hum_char, b'\x09\x07') #设置湿度为18.01%(0x0709 = 1801)

对于一些常用的功能,蓝牙组织联盟已经为其定义好了UUID,我们在开发产品的时候直接使用即可。
16BitUUID定义文档下载地址:https://btprodspecificationrefs.blob.core.windows.net/assigned-values/16-bit%20UUID%20Numbers%20Document.pdf

最后把上面代码结合一起,就可以愉快用蓝牙点灯了!

使用方法:执行代码后,使用谷雨蓝牙连接,并监听9012服务中的read,发送任意数据,收到回复“hello”,发送“led_on”,led打开,收到回复“led on!”;发送“led_off”,led关闭,收到回复“led off!”

from machine import Pin
from time import sleep_ms,sleep
import ubluetooth   #导入BLE功能模块
sleep(1)
ble = ubluetooth.BLE()  #创建BLE设备
ble.active(True)  #打开BLE(此时设备将处于就绪态)
led = Pin(2, Pin.OUT) #led引脚

#创建可读可写可通知的UUID
SERVER_1_UUID = ubluetooth.UUID(0x9011)
CHAR_A_UUID = ubluetooth.UUID(0x9012)
CHAR_B_UUID = ubluetooth.UUID(0x9013)

#创建特性并设置特性的读写权限
CHAR_A = (CHAR_A_UUID, ubluetooth.FLAG_READ | ubluetooth.FLAG_WRITE | ubluetooth.FLAG_NOTIFY, )
CHAR_B = (CHAR_B_UUID, ubluetooth.FLAG_READ | ubluetooth.FLAG_NOTIFY, )

SERVER_1 = (SERVER_1_UUID, (CHAR_A , CHAR_B, ) , ) #把特性A和特性B放入服务1
SERVICES = (SERVER_1, ) #把服务1放入服务集和中
((char_a, char_b), ) = ble.gatts_register_services(SERVICES) #注册服务到gatts


#设置BLE广播数据并开始广播(开始广播后设备将处于广播态)
name = bytes("aabbcc", 'UTF-8')
print("蓝牙开始广播")
ble.gap_advertise(100, adv_data = b'\x02\x01\x06\x02\x0A\x10' + bytearray((len(name)+1,0x09))+name)

#定义一个函数,用作蓝牙事件中断
def ble_irq(event, data): # 蓝牙中断函数
    if event == 1: #蓝牙已连接(此时蓝牙将处于连接态)
      print("BLE 连接成功")
    
    elif event == 2: #蓝牙断开连接(此时蓝牙将从链接态进入就绪态)
      print("BLE 断开连接")
      ble.gap_advertise(100, adv_data = b'\x02\x01\x06\x02\x0A\x08' + bytearray((len(name)+1,0x09))+name)#再次启动广播

    elif event == 3: # 收到新write消息
      onn_handle, char_handle = data #判断是来自那个特性的消息
      buffer = ble.gatts_read(char_handle) #读取接收到的消息
      print(char_handle, buffer,str(buffer, 'UTF-8')) #打印消息内容
      if str(buffer, 'UTF-8')=="led_on":
          led.on()
          ble.gatts_notify(0, char_handle, 'led on!')
      elif str(buffer, 'UTF-8')=="led_off":
          led.off()
          ble.gatts_notify(0, char_handle, 'led off!')
      else:
          ble.gatts_notify(0, char_handle, 'Hello')#回复Hello

ble.irq(ble_irq) #注册蓝牙中断函数
]]>