为macOS打造一个防污染的本地DNS

Cover: 華如桃李 - 豆の素@Pixiv

前言

家里这边DNS劫持是在是有点严重,非常影响开发速度,所以我就使用dnsmasqdnscrypt-proxy搭建了一个防污染防劫持的本地DNS。

效果演示

搭建过程

如果网络有问题,建议先执行以下指令追加hosts

1sudo sh -c 'sync && echo "199.232.4.133 raw.githubusercontent.com">>/etc/hosts'
2sudo sh -c 'sync && echo "199.232.4.133 raw.github.com">>/etc/hosts'

首先要安装Homebrew,这个绝大多数用macOS的人应该都安装了吧,官网https://brew.sh/,安装指令如下。

1/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

然后就是安装dnsmasqdnscrypt-proxy两大组件了。

1brew install dnsmasq
2brew install dnscrypt-proxy

装好之后,编辑配置文件,首先是dnsmasq的配置,文件路径/usr/local/etc/dnsmasq.conf

1#忽略本机DNS解析结果
2no-resolv
3#增加配置文件夹
4conf-dir=/usr/local/etc/dnsmasq.d
5#设置上游服务器为dnscrypt-proxy
6server=127.0.0.1#5300

然后是dnscrypt-proxy的配置,文件路径/usr/local/etc/dnscrypt-proxy.toml

1#本地监听5300端口
2listen_addresses = ['127.0.0.1:5300']
3#防劫持DNS使用NestDNS
4server_names = ['nextdns']
5#设置容错DNS为114DNS
6fallback_resolvers = ['114.114.114.114:53']

配置好了之后,重启两个组件的服务。

1sudo brew services restart dnsmasq
2sudo brew services restart dnscrypt-proxy

之后再把网络设置里的DNS地址修改为127.0.0.1,应用之后就可以享受无污染的DNS了。

执行过上面修改hosts的指令的话建议执行这个清除hosts

1sudo sed -i "" "s/199.232.4.133 raw.githubusercontent.com//g" /etc/hosts
2sudo sed -i "" "s/199.232.4.133 raw.github.com//g" /etc/hosts

国内白名单

虽然DNS没有了污染,但是国内网站DNS全都变慢了,这个肯定不能接受,所以我们接入dnsmasq-china-list项目,来优化本地的DNS。

 1mkdir /usr/local/etc/dnsmasq.d
 2WORKDIR="$(mktemp -d)"
 3curl https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf -o "$WORKDIR/accelerated-domains.china.conf"
 4curl https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/bogus-nxdomain.china.conf -o "$WORKDIR/bogus-nxdomain.china.conf"
 5curl https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/google.china.conf -o "$WORKDIR/google.china.conf"
 6curl https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/apple.china.conf -o "$WORKDIR/apple.china.conf"
 7sudo cp -f "$WORKDIR/accelerated-domains.china.conf" /usr/local/etc/dnsmasq.d/accelerated-domains.china.conf
 8sudo cp -f "$WORKDIR/bogus-nxdomain.china.conf" /usr/local/etc/dnsmasq.d/bogus-nxdomain.china.conf
 9sudo cp -f "$WORKDIR/google.china.conf" /usr/local/etc/dnsmasq.d/google.china.conf
10sudo cp -f "$WORKDIR/apple.china.conf" /usr/local/etc/dnsmasq.d/apple.china.conf
11rm -rf "$WORKDIR"

OK大功告成。

一键安装脚本

项目地址:https://github.com/mouyase/mac_dnscrypt_installer

脚本使用:

1git clone https://github.com/mouyase/mac_dnscrypt_installer
2cd mac_dnscrypt_installer
3./install.sh
「技术」打造一个漂亮的Android标题栏

Cover: 仮想都歌姫 - [email protected]

前言

最近因为正在做新坑Pixiu,本身的计划是照着Pivision做一个UI几乎没区别的复刻版,但是苦于已经好久没有正经开发过安卓App了,很多UI自己根本不会做,一个滑动的题图卡了我一天的时间,不过最后总算是连抄带蒙的做出来了,而且实际上也很简单,所以就写一个日志来记录一下。

效果演示

开发过程

整个效果实现需要三部分的工作,分别解决三个问题

  • StatusBar透明化
  • 带图片可滑动的ToolBar
  • 图片延伸到StatusBar

StatusBar透明化

首先需要在style.xml里添加如下的style,名字随便起。

1<style name="AppTheme.NoActionBar.TranslucentStatusBar" parent="AppTheme.NoActionBar">
2	<item name="android:windowTranslucentStatus" tools:targetApi="KITKAT">true</item>
3	<item name="android:statusBarColor" tools:targetApi="lollipop">
4		@android:color/transparent
5	</item>
6</style>

首先需要先继承NoActionBar,否则会带上默认的ActionBar,就没办法实现效果。

其次中间有一个tools:targetApi="KITKAT",这个android:windowTranslucentStatus就是设置是否开启透明StatusBar的参数,这个是从Android4.4,也就是Kitkat开始加入的参数,如果不这么写,在value-19里的style.xml写也是可以,不过我比较偷懒,这么写就不用做很多的value文件夹了。

而另一个参数则是Android5.0后加入的,设置StatusBar颜色的参数,这个把他设置成透明的就可以了。

最后则是把目标的Activity设置上这个新的主题。

1<activity
2	android:name=".view.MainActivity"
3	android:theme="@style/AppTheme.NoActionBar.TranslucentStatusBar" />

这样咱们就获得了一个没有标题栏,而且也是透明的,还可以在里面放控件的Activity了。

带图片可滑动的ToolBar

这一步我玩了一上午,但是只是实现一个这样的简单效果并没有多难,只是我坑踩太多。

打开咱们Activity的布局文件,例如这里是activity_main.xml,把根布局换成CoordinatorLayout,然后在里面塞一个AppBarLayout,AppBarLayout里再塞一个CollapsingToolbarLayout,最后在CollapsingToolbarLayout里再分别塞一个ImageView,和一个ToolBar。最后把咱们的主要的布局放在CoordinatorLayout下面,这里放了个LinearLayout

 1<androidx.coordinatorlayout.widget.CoordinatorLayout
 2	android:layout_width="match_parent"
 3	android:layout_height="match_parent">
 4
 5	<com.google.android.material.appbar.AppBarLayout
 6		android:layout_width="match_parent"
 7		android:layout_height="wrap_content">
 8
 9		<com.google.android.material.appbar.CollapsingToolbarLayout
10			android:layout_width="match_parent"
11			android:layout_height="wrap_content"
12			app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
13			app:titleEnabled="false">
14
15			<ImageView
16				android:id="@+id/iv_title/cover"
17				android:layout_width="match_parent"
18				android:layout_height="wrap_content"
19				android:scaleType="centerCrop"
20				app:layout_collapseMode="pin"/>
21
22			<androidx.appcompat.widget.Toolbar
23				android:id="@+id/tb_main"
24				android:layout_width="match_parent"
25				android:layout_height="wrap_content"
26				app:layout_collapseMode="pin"
27				app:title="@string/app_name" />
28
29		</com.google.android.material.appbar.CollapsingToolbarLayout>
30
31	</com.google.android.material.appbar.AppBarLayout>
32
33	<LinearLayout
34		android:layout_width="match_parent"
35		android:layout_height="match_parent"
36		android:orientation="vertical"
37		app:layout_behavior="@string/appbar_scrolling_view_behavior">
38
39	</LinearLayout>
40
41</androidx.coordinatorlayout.widget.CoordinatorLayout>

这里解释一下各个细节,首先是这种滑动变化的布局,必须在CoordinatorLayout里进行,所以说根布局要换成这个,不过如果这个只是页面UI一部分的话,外面也是可以再套其他布局的。

因为要做有多种元素还能滚动的复杂TitleBar,所以要用AppBarLayout包裹ToolBar,这样才能配合CoordinatorLayout实现滚动。

CollapsingToolbarLayout则是相当于一个高级的ToolBar,需要包裹ToolBar才能实现效果。参数中的app:layout_scrollFlags代表了这个控件的可滑动状态。这个参数一共有五种,可以共存,分别是。

参数 功能
scroll 代表这个控件可以被滚动
enterAlways 代表这个控件会被优先滚动,需要和scroll共用
enterAlwaysCollapsed 代表这个控件会被分段滚动,首先先滚动会显示最小高度,到达滚动边界后再完全显示,需要和enterAlways共用
exitUntilCollapsed 代表这个控件会被保留最小高度,不会完全滚动出窗口,需要和scroll共用
snap 代表这个控件滚动时会有边缘吸附效果,需要和scroll共用

因为咱们的控件属于保留最小高度,同时有吸附效果,所以最后需要的是scroll|exitUntilCollapsed|snap

至于app:titleEnabled则是代表是否使用系统自带的标题,这里因为要用ToolBar,所以关了就好。

接下来是ToolBar中的,app:layout_collapseMode,这个参数是开启了滚动后才会生效的效果,这个有三种参数。

参数 功能
none 代表这个控件会被滚出屏幕
pin 代表这个控件不会被滚出屏幕
parallax 代表这个控件滚动时会有滚动差

最后是LinearLayout中的app:layout_behavior,behavior就是在CoordinatorLayout中负责处理各种效果的工具,这里使用了一个系统默认的参数@string/appbar_scrolling_view_behavior,效果为跟随appbar滚动,所以这个控件就相当于咱们整个窗口中的根布局了,其他控件放这里就好。

这样咱们就有了一个具有带图片可滑动的ToolBar,而且StatusBar也是透明的Activity了。

图片延伸到StatusBar

这一步卡的时间最久,因为我改了好多布局的方案,最后图片总是不能好好地显示到StatusBar上,要么是不显示,要么是UI错位,最后发现最简单的办法就是给ToolBar设置一个顶部padding,大小为StatusBar的高度,就可以完美实现了。

 1ToolBar tb_main = findViewById(R.id.tb_main);
 2ViewGroup.LayoutParams toolbarParams = tb_main.getLayoutParams();
 3ViewGroup.MarginLayoutParams toolbarMarginParams;
 4if (toolbarParams instanceof ViewGroup.MarginLayoutParams) {
 5	toolbarMarginParams = (ViewGroup.MarginLayoutParams) toolbarParams;
 6} else {
 7	toolbarMarginParams = new ViewGroup.MarginLayoutParams(toolbarParams);
 8}
 9toolbarMarginParams.setMargins(0, ViewSize.getStatusBarHeight(this), 0, 0);
10tb_main.setLayoutParams(toolbarMarginParams);

里面的ViewSize.getStatusBarHeight(Activity activity)如下。

1public static int getStatusBarHeight(Activity activity) {
2	int statusBarHeight = 0;
3	int resourceId_status = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
4	if (resourceId_status > 0) {
5		statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId_status);
6	}
7	return statusBarHeight;
8}

这样就可以给ToolBar设置上padding了,我们的布局也终于正常了。

结语

于是我终于可以开发其他模块了233。

部署一个Django的项目

准备

首先准备好最新版本的Python

1rm -rf /usr/local/python3
2./configure --prefix=/usr/local/python3/
3make && make install
4rm -rf /usr/local/bin/python3
5ln -s /usr/local/python3/bin/python3 /usr/local/bin/python3
6rm -rf /usr/local/bin/pip3
7ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip3

因为我用的是宝塔环境,宝塔自带了Nginx和Supervisor,所以不用单独安装了

然后把代码上传到opt目录,我的上传到了YojigenAPI目录下

这里我是使用了PyCharm的自带Deployment功能进行代码上传

首先打开PyCharm的菜单栏的Tools –> Deployment –> Configure

在里面添加一个新的服务器,我添加的服务器命名为AliyunHK,输入好服务器的登陆信息

然后到Mappings页面,添加一下文件夹对应的路径配置,我这里是将代码放到了服务器的/opt/YojigenAPI目录下

最后到Excluded Paths页面,添加一个Local Path,忽略掉本地的venv虚拟环境文件夹

最后点击PyCharm的菜单栏的Tools –> Deployment –> Upload to AliyunHK,就可以将代码推送到服务器上了

环境配置

ssh登陆到服务器,来到项目目录下,先创建一个虚拟环境

1virtualenv -p /usr/local/bin/python3 --no-site-packages venv

然后进入到虚拟环境里

1source venv/bin/activate

之后恢复pip的包

1pip install -r requirements.txt

注意这里安装了gunicorn,默认的Django项目是不会安装的

包都装完了,就可以退出虚拟环境了

1deactivate

服务配置

先测试一下服务启动命令,10000是监听端口

1venv/bin/gunicorn YojigenAPI.wsgi -b 0.0.0.0:10000

结果发现报错了,The SECRET_KEY setting must not be empty.,这个错误是项目配置文件找不到了,实际上是因为需要设置一下配置文件的环境变量才行,所以只要运行

1venv/bin/gunicorn YojigenAPI.wsgi -b 0.0.0.0:10000 -e DJANGO_SETTINGS_MODULE="YojigenAPI.settings.prod"

之后再启动,如果没错那就没问题了

然而我又报错了,SQLite 3.8.3 or later is required (found 3.7.17).,这个问题是因为我用的是CentOS,系统自带的sqlite3版本太老,升级一下就可以了

1./configure --prefix=/usr/local
2make & make install

编译好了之后,执行一下这个,把/usr/local/lib添加到系统的链接库中

1echo "/usr/local/lib" >> /etc/ld.so.conf
2/sbin/ldconfig

之后再运行应该就可以正常启动了,然后配置更新一下数据库,以及转存一下静态文件

1venv/bin/python manage.py migrate --settings=YojigenAPI.settings.prod
2venv/bin/python manage.py createsuperuser --settings=YojigenAPI.settings.prod
3venv/bin/python manage.py collectstatic --settings=YojigenAPI.settings.prod

接下来就是配置Supervisor守护进程了,因为我用了宝塔,宝塔里面有现成的Supervisor管理器,这里就直接使用宝塔的管理器了

填写进去启动信息,保存即可

最后就是大家都熟悉的Nginx配置反向代理了,反向代理到对应的域名上就可以了,不过这里有个坑,是关于静态文件的,宝塔默认的配置里包含了css和js的相关配置,要去给他删了才行

 1location /
 2{
 3	proxy_pass http://127.0.0.1:10000;
 4	proxy_set_header Host api.yojigen.tech;
 5	proxy_set_header X-Real-IP $remote_addr;
 6	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 7	proxy_set_header REMOTE-HOST $remote_addr;
 8	add_header X-Cache $upstream_cache_status;
 9}
10
11location /static/ 
12{
13	alias /opt/YojigenAPI/static/;
14}

到此配置全部完成,代码成功上线啦。

家乡,硬座火车,和那些社会底层的人民

因为过年回家,我坐上了这列行驶时长25个小时的绿皮硬座火车。

我的家乡很偏僻,在黑龙江的北部,又是一个小地方,所以从北京通往我的家乡的火车只有这一班。于是票就非常的难买,卧铺票可遇不可求,最后我也只能是买到一张硬座的票。

手里拿着票,穿过了密密麻麻的人群,我坐到了自己的座位上。行李架已经放满了,我就只能把自己的背包放在座位下面。

车上挤满了人,人群从车厢一边的门延伸到另一边,每次列车员来卖货都要从人群中挤出一条通道,还得慢慢的避开过道上的人的脚。

因为昨天晚上收拾东西,没睡好,所以我在车开后没多久就睡着了。

然后我就冻醒了。

醒过来的时候,已经是深夜,我摸了摸暖气,凉的。我想把外衣取下来穿上,但是发现外衣已经和窗户冰在一起了。但是虽然我已经被冻醒,腿已经冻的几乎没有知觉,车厢里的其他乘客似乎并没有像我一样在乎暖气很冷这件事,也许是他们已经习惯了这种冰冷的列车,也许是他们没有“当出头鸟”的决心,也许他们都很累,累到已经感受不到这些。

但是我的身体没有说谎,它正用那种麻痹的感觉告诉我这趟列车真的很冷。

于是我叫来了乘务员,质问他为什么没有开暖气。乘务员表示车厢里没有人说冷,所以他们就关掉了。最后在我的强烈要求下,乘务员打开了暖气。我回到座位,守着暖气继续睡了起来。果然人类还是离不开热源。

再醒过来,就已经是白天了,车厢里充满了清晨的阳光,聊天的声音,和泡面的味道。我也拿出了我的泡面,打了点热水泡了起来。

吃着热乎乎的泡面,耳边就听着车上的人们闲聊。

身后的这些人,他们在聊赵本山和范伟。

「赵本山的徒弟们赚了钱都得被他收走一大半」「他那个徒弟,小损样的那个,现在也根本不出来」「他太贪,别人都没钱拿,范德彪都不跟他干了」

总觉得这些说不上是不是「传言」的传言,和现在的时代挺脱节的。赵本山自从2014年彻底退出春晚之后,几乎已经完全是幕后人的存在了,在《乡村爱情》系列里面出演戏份也不是很多,感觉已经很难听到关于他的一些正面或者负面的消息了。至于范伟,已经不知道拿了几个影帝和最佳角色的奖杯。

吃完了面,身体热乎了起来,于是掏出了NS,准备打几把太鼓达人。

打到一半的时候,对面的小哥对NS投过来了好奇的目光,我看到他欲言又止,可能是想和我交流一下游戏的事情,不过他可能是看到我正在激烈的按键,所以并没有追问一些什么。

又过了许久,无聊的我和对面小哥聊起了工作和经济,聊着聊着,身后一个大哥可能是听到我说人民币汇率波动,突然就非常自信的说:「人民币不可能贬值,贬值都是人家老美贬值,人民币只会涨」。或许民族自信确实非常的强,大家都不相信自己的国家会在经济上落后,虽然人民币贬值也并不代表经济就是衰落的。

火车就这样开了25个小时,载着想要回到家乡的我,载着这些和我一样,想要回到家乡的人民,开进了终点火车站。

车停了,我拎着行礼下了火车,回到了生活了二十年的家乡,我大口的吸着PM2.5只有个位数的新鲜空气,是熟悉的家乡的味道,虽然冷,但是似乎有点甜。北京的空气真的太差,虽然这么多年已经习惯了,但是还是想念家乡的味道。

家乡还是老样子,总会给人一种时间凝固了的感觉,虽然这些年新盖起来不少的楼房,但是总觉得和记忆中的样子没有差太多。而且也不知道为什么,记忆中的家乡总是没有滤镜的,就像是相册中的老照片,虽然感觉颜色暗淡,但是印象依旧深刻。

我的家距离火车站很近,出站只要步行十分钟就走能进家门。我还没登上楼,母亲就已经把门打开等待着我的归来。又是一年没见,母亲一定非常想念我吧。

“儿子,回来了?”

“嗯”

喷一喷垃圾小米的BL解锁体验

前言

因为10月末预购活动,本人于11月1日购入小米9SE一台,并且于11月2日下午2点左右收到机器,因为是Android开发者,同时也是Xposed,Magisk插件开发者,Root权限和BL解锁是一定要做的。所以新机器到手第一件事就是下载解锁工具,进行解锁。

然后出现了以下提示。


怒气值1阶段

看到解锁失败,本人也是第一时间就咨询客服。

我:为什么我不能解锁BL,上面提示账号权限不足或者账号受限是什么意思

客服:因为您是新买的手机呢,为了保证您的安全,新手机要插卡绑定正常使用7天,也就是168个小时才可以解锁呢

我:请问我的账号是不是被你们做了什么限制,为什么上面没有提示我等待168小时而是账号权限不足?

客服:这边帮您查询过了呢,您的账号没有被限制的

我:那我等待7天后再解锁就没问题了对吗?

客服:是的,您需要正常使用168小时就可以了呢

好,7天对吧,那我这7天就轻度使用吧,反正7天后解锁数据全清,自己就不在手机里留太多需要备份的东西了,等就行了。


怒气值2阶段

然后7天就过去了,然后再解锁,嗯,完全一样的提示。

其实中间的几天我也一直有查相关的东西,虽然小米社区和MIUI官方论坛现在都关了,不过其他的手机社区也是可以找到一些蛛丝马迹的,据说是因为老账号可以不等待直接解锁,有很多人租借老账号解锁新机器,所以小米封禁了所有2019年10月前的老账号的权限,但是客服跟我说换账号要再等30天才可以解锁,所以我不敢换,也没测试过,最重要的是,我为什么要在我自己的手机上绑定其他人的账号30天?

所以说咋办,继续骚扰客服吧。

我:为什么我的手机不能解锁BL,上次咨询你们,你们跟我说让我等168小时就可以解锁了,为什么还不行

客服:请您提供一下您的手机型号和您绑定的时间

我:小米9SE,绑定时间11月2日下午3点

客服:这边帮您查询到您确实还没有达到规定的解锁时间呢,请您耐心等待

我:等多久,这个等的时间哪里能看吗?

客服:咱们新手机解锁BL要绑定使用360小时后才可以解锁呢

我:上次我问你们客服,你们跟我说让我等168小时,现在七天过去我还是解不了,你跟我说让我等到360小时,那我15天过去了,我还是解不了,然后再来问你们,你们是不是会让我再等到30天啊?就往后拖拖到我不用这手机就完事了呗?

客服:您好咱们小米手机第一次解锁是要15天才可以解锁的呢,如果是上锁过第二次再解锁的话就是要等30天的呢

我:那第三次锁上了呢?等一年?

客服:之后都是30天的呢

我:那这里显示账号权限不足或者账号受限是什么意思,没有哪里提示我时间不足?

客服:这个意思就是您还没有达到规定的时间所以不能解锁的意思呢

行,我服力,合着就往后推呗?但是这次不知道是客服感觉到了我的不满还是咋样,没过多久他们有个客服经理就给我打电话了,反正说的就还是上面那一套,告诉我等360个小时,然后我就问他,如果360小时之后我还是解不了怎么办,他说不会的,只要等360小时就可以了。

好,等吧。


怒气值3阶段

好,大家看看发帖时间应该就明白我现在的状况了。

提示依旧,失败依旧。

好的,客服麻烦滚出来。

我:为什么我手机还是不能解锁BL,你们让我等7天等15天我都等了,现在还是提示权限不足,怎么解释

客服:这边建议您去售后刷机呢

我:?

我:新手机买过来15天都没能好好用现在你让我送售后了?送售后能刷我自己改过的系统吗?

客服:可以刷MIUI最新版的呢。

之后就是疯狂对线然后客服把异常抛给了他们的客服经理,应我的要求同时报了加急,毕竟现在我在家,还有空处理解锁后数据晴空带来的问题,如果明天去上班再清数据的话,就会很痛苦。


怒气值4阶段

过了十分钟电话接起来。

客服:*先生您好,这边接到您反馈解锁失败。这边建议您到咱们MIUI论坛看一下解锁教程呢

我:你知道你们MIUI论坛已经关了么?现在所有的帖子都无法查看。解锁工具对应链接全部删帖

客服:……您稍等一下……

客服:这个确实解锁这一块最近规则有了变更,可能您的账号确实没有权限解锁了呢

我:意思就是你们小米以后不能解锁BL了是吗

客服:这个这边还不能确定,可以明天帮您查一下您为什么不能解锁然后告知您原因,然后给您一个答复

emmmm,所以说最后折腾15天我终于可以调查清楚我为什么不能解锁了……?

我日我的目的不是知道我为什么不能解锁而是我要解锁我手上这台手机啊!你就算给我什么理由我都无所谓你能不能让我把锁解掉?

等明天电话了,不知道最后会给我个什么结果。

我傻了。

第二日后续

刚刚小米的人给我打电话,问我之前有没有解锁过其他手机,我说我之前解锁我我以前用的小米 4C。然后问是不是我自己手机号的,我说是。然后他就跟我说账号「有可能」是收到了限制,说帮我提交一个申请,申请通过就可以直接解锁了。然后要了我的小米 ID 和手机的 IMEI,据说两天内反馈给我。

真实新号遍地走老号不如狗,我一个从买小米 1S 起就在官网注册账号,一直到小米 4c 小米第一次做 BL 锁机制,我就申请了解锁权限,结果现在到了 9SE 反倒把我忠实老用户的账户限制了。令人唏嘘……

第二日晚上后续

刚刚又给我打电话了。

客服:先生您好,这边查询您的账号确实没有解锁 BL 权限。

我:我在官网申请过解锁权限了,上面已经显示我有权限,而且我还是开发者账号和内测组账号,为什么我的账号没有解锁 BL 权限。

客服:这边帮您查询了确实是没有的。您可以去寻找一个有解锁权限的账号进行解锁操作。

我:意思就是说我在你们这买个手机,然后我还得去登陆个别人的账号,登上一个月,所有小米服务都不能用,还得在别人账号里同步数据?

客服:先生这边建议您这样的。

我:那凭什么别人的账号可以,我的账号就不行,你们不是说帮我去申请权限了吗?怎么这时候就告诉我不可以了?

客服:先生这边没办法帮您开启账号权限的。

服。

于是我跟这位客服先生说,你现在给我的这个答复我无法接受,不管你是找你们经理还是找你们工程师还是找售后,你去找一个能给我解决问题的人来。于是客服表示那请您保持联络,我再去给你问问。

第三日下午后续

刚刚用脑袋想了想,然后就打开了 Charles 和解锁工具,想看看能不能把他收过来的数据改掉拿到权限。结果点了一下解锁,解开了……

最后我也不知道是因为昨天反馈的问题还是真的时间不够我也不知道……

最新进展

刚刚小米又一个客服给我打电话,依旧是告诉我换账号解锁。然后我就跟他聊了聊,似乎言语中可以得出一个结论,就是他们的上级有刻意让他们回避用户申请 BL 解锁的问题。而且他们也不知道实际上我的解锁权限已经下发了。估计是反馈了上面也没跟他们有什么回复。

如果以后有人遇到类似情况的话,建议还是跟客服沟通一下争取让他上报吧。