Tips

本文主要记录一些小技巧及命令,不定时更新。

Android

adb

查看前端运行应用的包名

1
adb shell dumpsys window | grep mCurrentFocus

image-20220102153144302◎ 查看包名和当前的Activity

结束 app 进程

1
adb shell am force-stop packagename

提取apk

  • 找到包名

    1
    
    adb shell pm list packages
    
  • 找到 apk 路径

    1
    
    adb shell pm path packagename
    
  • 提取 apk

    1
    
    adb pull path
    

图片加入相册

1
2
adb push test.png /sdcard/Pictures
adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///sdcard/Pictures/test.png

scrcpy

-S:立即关闭设备屏幕(投屏正常显示)

-w:当手机插入电源时,保持屏幕常亮,不锁屏

-b:比特率,默认 8M,当使用无线 adb 连接时,降低可提升速度

-m:尺寸,默认为 0(不设置),当使用无线 adb 连接时,调整为较低尺寸可提升速度

以上命令组合后可简写为

scrcpy -Sw -b1M -m800 

Play 保护机制认证

设备制造商会与 Google 合作,以证明已安装 Google 应用的 Android 设备安全无虞,且能够正常运行应用。要获得 Play 保护机制认证,设备必须通过 Android 兼容性测试。如果您无法在 Android 设备上添加 Google 帐号,则表示您的 Android 设备软件可能未通过 Android 兼容性测试,或者设备制造商尚未将结果提交给 Google 以获得批准。在这种情况下,您的设备未经 Play 保护机制认证,可能不安全。

在 Google 注册设备可以解决这一问题

https://www.google.com/android/uncertified/

获取权限

首先在 AndroidManifest.xml 中添加需要的权限,此处以 READ_EXTERNAL_STORAGE 为例。

1
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

然后使用以下代码即可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
    Toast toast = Toast.makeText(this, "有权限", Toast.LENGTH_SHORT);
    toast.show();
} else {
    Toast toast = Toast.makeText(this, "没有权限", Toast.LENGTH_SHORT);
    toast.show();
    ActivityResultLauncher<String> requestPermissionLauncher = registerForActivityResult(
            new ActivityResultContracts.RequestPermission(), isGranted -> {
                if (isGranted) {
                    Toast getPermissionSucceed = Toast.makeText(this, "获取权限成功!", Toast.LENGTH_SHORT);
                    getPermissionSucceed.show();
                } else {
                    Toast getPermissionFailed = Toast.makeText(this, "获取权限失败", Toast.LENGTH_SHORT);
                    getPermissionFailed.show();
                }
            }
    );
    requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE);
}

在 Android 11 以后,有些目录无法通过普通的读写文件进行操作,需要获取 MANAGE_EXTERNAL_STORAGE 权限。

同样,首先在 AndroidManifest.xml 中添加需要的权限。

1
2
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />

然后使用以下代码即可

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@RequiresApi(api = Build.VERSION_CODES.R)
public void getPermission() {
    if (Environment.isExternalStorageManager()) {
        Toast toast = Toast.makeText(this, "有权限", Toast.LENGTH_SHORT);
        toast.show();
    } else {
        Toast toast = Toast.makeText(this, "没有权限", Toast.LENGTH_SHORT);
        toast.show();
        Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
        intent.setData(Uri.parse("package:" + this.getPackageName()));

        ActivityResultLauncher<Intent> setPermissionLauncher = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (Environment.isExternalStorageManager()) {
                        Toast getPermissionSucceed = Toast.makeText(MainActivity.this, "获取权限成功!", Toast.LENGTH_SHORT);
                        getPermissionSucceed.show();
                    } else {
                        Toast getPermissionSucceed = Toast.makeText(MainActivity.this, "获取失败!", Toast.LENGTH_SHORT);
                        getPermissionSucceed.show();
                    }
                }

        );
        setPermissionLauncher.launch(intent);
    }
}

参考链接

1、https://developer.android.com/training/permissions/requesting?hl=zh-cn#java

2、https://developer.android.com/training/data-storage/manage-all-files?hl=zh-cn

3、https://woomiao.cn/archives/316.html

MultiDex

我们有时会通过生成并解压一个 apk 文件的形式获得自己编写的 dex,此时可能会发现目录下有多个 dex 文件,这是因为当 minSdkVersion 设为 21 或更高版本时,系统会默认启用 MultiDex,我们可以通过配置关闭该功能,从而获得一个独立的 dex 文件。

修改模块级 build.gradle 文件并关闭 MultiDex 即可。

1
2
3
4
5
6
7
8
9
android {
    defaultConfig {
        ...
        minSdkVersion 21
        targetSdkVersion 31
        multiDexEnabled false
    }
    ...
}

参考链接:https://developer.android.com/studio/build/multidex?hl=zh-cn

网络连接受限

连接 WIFI 后,会提示”网络连接受限“,但是能够正常上网,可执行以下代码,然后重连 WIFI 即可去除警告。

1
2
3
4
adb shell settings delete global captive_portal_https_url
adb shell settings delete global captive_portal_http_url
adb shell settings put global captive_portal_https_url https://connect.rom.miui.com/generate_204
adb shell settings put global captive_portal_http_url http://connect.rom.miui.com/generate_204

或者也可换成:http://google.cn/generate_204、https://google.cn/generate_204

Windows

查看 WIFI 密码

1
2
netsh wlan show profile
netsh wlan show profile "CMCC" key=clear

自动设置 DNS

通过 Windows 设置页面中指定 DNS 后,连接不同网络时仍可能会发生变动,使设置失效。我们可以添加一个计划任务,当连接网络后,自动设置 DNS,从而保证一直使用自己想要的 DNS。

计划任务触发器为“发生事件时”,依次选择以下选项:

  • 日志: Microsoft-Windows-NetworkProfile/Operational
  • 源: NetworkProfile
  • 事件 ID: 10000

可以使用以下命令设置 DNS(需要管理员权限)

1
Set-DnsClientServerAddress WLAN -ServerAddresses ("8.8.8.8")

参考链接:https://superuser.com/questions/262799/how-to-launch-a-command-on-network-connection-disconnection

Linux

搜索文件

1
tree -NCfhl | grep name

在文件中搜索字符串

1
grep -ril blog.svip.dev

解压乱码

1
apt-get install p7zip-full convmv

首先解压,然后转换编码即可

1
2
LANG=C 7z x file.zip
convmv -f GBK -t utf8 --notest -r .

切割大文件

  • 将一个大文件分割为每个最大为 1G 的小文件。
1
split -b 1G android-8.1.0_r1.tar.gz -d split/android-8.1.0_r1.tar.gz.part --verbose
  • 合并
1
cat android-8.1.0_r1.tar.gz.part* > android-8.1.0_r1.tar.gz

Programming

Golang

在代码中使用了 net 包时,如果本地编译环境比较新,将生成的可执行文件部署到服务器上时可能会报错,格式如下

1
2
➜  ~ ./main
./main: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by ./main)

我们只需要在编译前指定环境变量即可

1
export CGO_ENABLED=0

TypeScript

设置字体颜色

使用 console 输入日志时,使用 log、warn、error 有三种不同的颜色,如果想要更多的字体样式,可以进行自定义。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Color {
    private BoldColor = { RESET: "\x1b[39;49;00m", Black: "0;01", Blue: "4;01", Cyan: "6;01", Gray: "7;11", Green: "2;01", Purple: "5;01", Red: "1;01", Yellow: "3;01" };
    private LightColor = { RESET: "\x1b[39;49;00m", Black: "0;11", Blue: "4;11", Cyan: "6;11", Gray: "7;01", Green: "2;11", Purple: "5;11", Red: "1;11", Yellow: "3;11" };
    private colorPrefix = '\x1b[3'
    private colorSuffix = 'm'

    public Black = this.colorPrefix + this.BoldColor.Black + this.colorSuffix;
    public Blue = this.colorPrefix + this.BoldColor.Blue + this.colorSuffix;
    public Cyan = this.colorPrefix + this.BoldColor.Cyan + this.colorSuffix;
    public Gray = this.colorPrefix + this.BoldColor.Gray + this.colorSuffix;
    public Green = this.colorPrefix + this.BoldColor.Green + this.colorSuffix;
    public Purple = this.colorPrefix + this.BoldColor.Purple + this.colorSuffix;
    public Red = this.colorPrefix + this.BoldColor.Red + this.colorSuffix;
    public Yellow = this.colorPrefix + this.BoldColor.Yellow + this.colorSuffix;
    public RESET = this.BoldColor.RESET;

    // console.log(colorPrefix + Color.Red + colorSuffix + "I am Red", Color.RESET);
    // console.log(colorPrefix + LightColor.Red + colorSuffix + "Red Test");
}

var c = new Color();
console.log(c.Black + "I am Black");
console.log(c.Blue + "I am Blue");
console.log(c.Cyan + "I am Cyan");
console.log(c.Gray + "I am Gray");
console.log(c.Green + "I am Green");
console.log(c.Purple + "I am Purple");
console.log(c.Red + "I am Red");
console.log(c.Yellow + "I am Yellow", c.RESET);
console.log("I am normal");

image-20220211145453775

参考链接:https://simplernerd.com/js-console-colors/

VSCode

花括号不换行

设置 C/C++ 代码格式化时花括号不换行,在 setting.json 中添加以下内容即可。

1
"C_Cpp.clang_format_style": "{ BasedOnStyle: Chromium, IndentWidth: 4}",

C/C++ 代码自动格式化

安装 Clang-Format 插件。在设置中搜索 format on save 并勾选。

image-20220803104416000

在项目目录下新建 .clang-format 文件,内容如下,这样当文件保存时,会使用该模板对代码进行格式化。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# 语言: None, Cpp, Java, JavaScript, ObjC, Proto, TableGen, TextProto
Language: Cpp
# BasedOnStyle:	LLVM

# 访问说明符(public、private等)的偏移
AccessModifierOffset: -4

# 开括号(开圆括号、开尖括号、开方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行)
AlignAfterOpenBracket: Align

# 连续赋值时,对齐所有等号
AlignConsecutiveAssignments: false

# 连续声明时,对齐所有声明的变量名
AlignConsecutiveDeclarations: false

# 右对齐逃脱换行(使用反斜杠换行)的反斜杠
AlignEscapedNewlines: Right

# 水平对齐二元和三元表达式的操作数
AlignOperands: true

# 对齐连续的尾随的注释
AlignTrailingComments: true

# 不允许函数声明的所有参数在放在下一行
AllowAllParametersOfDeclarationOnNextLine: false

# 不允许短的块放在同一行
AllowShortBlocksOnASingleLine: true

# 允许短的case标签放在同一行
AllowShortCaseLabelsOnASingleLine: true

# 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All
AllowShortFunctionsOnASingleLine: None

# 允许短的if语句保持在同一行
AllowShortIfStatementsOnASingleLine: true

# 允许短的循环保持在同一行
AllowShortLoopsOnASingleLine: true

# 总是在返回类型后换行: None, All, TopLevel(顶级函数,不包括在类中的函数), 
# AllDefinitions(所有的定义,不包括声明), TopLevelDefinitions(所有的顶级函数的定义)
AlwaysBreakAfterReturnType: None

# 总是在多行string字面量前换行
AlwaysBreakBeforeMultilineStrings: false

# 总是在template声明后换行
AlwaysBreakTemplateDeclarations: true

# false表示函数实参要么都在同一行,要么都各自一行
BinPackArguments: true

# false表示所有形参要么都在同一行,要么都各自一行
BinPackParameters: true

# 大括号换行,只有当BreakBeforeBraces设置为Custom时才有效
BraceWrapping:
  # class定义后面
  AfterClass: false
  # 控制语句后面
  AfterControlStatement: false
  # enum定义后面
  AfterEnum: false
  # 函数定义后面
  AfterFunction: false
  # 命名空间定义后面
  AfterNamespace: false
  # struct定义后面
  AfterStruct: false
  # union定义后面
  AfterUnion: false
  # extern之后
  AfterExternBlock: false
  # catch之前
  BeforeCatch: false
  # else之前
  BeforeElse: false
  # 缩进大括号
  IndentBraces: false
  # 分离空函数
  SplitEmptyFunction: false
  # 分离空语句
  SplitEmptyRecord: false
  # 分离空命名空间
  SplitEmptyNamespace: false

# 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行)
BreakBeforeBinaryOperators: NonAssignment

# 在大括号前换行: Attach(始终将大括号附加到周围的上下文), Linux(除函数、命名空间和类定义,与Attach类似), 
#   Mozilla(除枚举、函数、记录定义,与Attach类似), Stroustrup(除函数定义、catch、else,与Attach类似), 
#   Allman(总是在大括号前换行), GNU(总是在大括号前换行,并对于控制语句的大括号增加额外的缩进), WebKit(在函数前换行), Custom
#   注:这里认为语句块也属于函数
BreakBeforeBraces: Custom

# 在三元运算符前换行
BreakBeforeTernaryOperators: false

# 在构造函数的初始化列表的冒号后换行
BreakConstructorInitializers: AfterColon

#BreakInheritanceList: AfterColon

BreakStringLiterals: false

# 每行字符的限制,0表示没有限制
ColumnLimit: 0

CompactNamespaces: true

# 构造函数的初始化列表要么都在同一行,要么都各自一行
ConstructorInitializerAllOnOneLineOrOnePerLine: false

# 构造函数的初始化列表的缩进宽度
ConstructorInitializerIndentWidth: 4

# 延续的行的缩进宽度
ContinuationIndentWidth: 4

# 去除C++11的列表初始化的大括号{后和}前的空格
Cpp11BracedListStyle: true

# 继承最常用的指针和引用的对齐方式
DerivePointerAlignment: false

# 固定命名空间注释
FixNamespaceComments: true

# 缩进case标签
IndentCaseLabels: false

IndentPPDirectives: None

# 缩进宽度
IndentWidth: 4

# 函数返回类型换行时,缩进函数声明或函数定义的函数名
IndentWrappedFunctionNames: false

# 保留在块开始处的空行
KeepEmptyLinesAtTheStartOfBlocks: false

# 连续空行的最大数量
MaxEmptyLinesToKeep: 1

# 命名空间的缩进: None, Inner(缩进嵌套的命名空间中的内容), All
NamespaceIndentation: None

# 指针和引用的对齐: Left, Right, Middle
PointerAlignment: Right

# 允许重新排版注释
ReflowComments: true

# 允许排序#include
SortIncludes: false

# 允许排序 using 声明
SortUsingDeclarations: false

# 在C风格类型转换后添加空格
SpaceAfterCStyleCast: false

# 在Template 关键字后面添加空格
SpaceAfterTemplateKeyword: true

# 在赋值运算符之前添加空格
SpaceBeforeAssignmentOperators: true

# SpaceBeforeCpp11BracedList: true

# SpaceBeforeCtorInitializerColon: true

# SpaceBeforeInheritanceColon: true

# 开圆括号之前添加一个空格: Never, ControlStatements, Always
SpaceBeforeParens: ControlStatements

# SpaceBeforeRangeBasedForLoopColon: true

# 在空的圆括号中添加空格
SpaceInEmptyParentheses: false

# 在尾随的评论前添加的空格数(只适用于//)
SpacesBeforeTrailingComments: 1

# 在尖括号的<后和>前添加空格
SpacesInAngles: false

# 在C风格类型转换的括号中添加空格
SpacesInCStyleCastParentheses: false

# 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格
SpacesInContainerLiterals: true

# 在圆括号的(后和)前添加空格
SpacesInParentheses: false

# 在方括号的[后和]前添加空格,lamda表达式和未指明大小的数组的声明不受影响
SpacesInSquareBrackets: false

# 标准: Cpp03, Cpp11, Auto
Standard: Cpp11

# tab宽度
TabWidth: 4

# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always
UseTab: Never
updatedupdated2022-08-032022-08-03