通过adb实现安卓手机超长截屏

最近一个朋友在诉讼过程中需要将聊天记录作为证据提交,对聊天记录取证可截屏或录像。但是因为聊天记录过长,截屏过程不是很友好。

通过adb可以实现对安卓手机自动截屏、自动滑动,然后再调用合成成一张超长图片。应用范围:1.微信、QQ、淘宝旺旺等聊天软件取证;2.保留亲人或好友的聊天记录打印或珍藏;3.保存超长网页


技术要点:

adb shell /system/bin/screencap -p /sdcard/Download/screenshot.png //控制安卓手机截屏

adb pull /sdcard/Download/screenshot.png d:/screenshot.pn  //将安卓手机上图片拷贝到电脑

adb shell input swpie x0 y0 x1 y1 200   //将屏幕从(x0,y0)滑动到(x1,y1)

使用方式:

  1. 开启手机的开发者模式,不同手机的方式可能不同,以小米为例,打开设置->我的设备->全部参数,然后连点MIUI版本一栏6~7次
  2. 开启手机USB调试模式,仍然以小米为例,打开设置->更多设置->开发者选项->USB调试
  3. 将手机和电脑用数据线连接,会跳出一个授权,点击确定即可
  4. 手机上打开要保存的聊天或网页页面,手动拉到最开始的地方
  5. 在电脑上下载上面的截屏软件,解压。然后双击目录下的start.bat文件,就会开始自动截屏,并且自动向上拉聊天界面。最后会在目录下生成一个数字命名的png图片。

golang通过reflect创建slice及json.Marshal后为null的问题

在gin框架以及json.Marshal在编码一个slice时,有以下两种情况

list1:=new([]User)
list2:=make([]User,0)

res1,_:=json.Marshal(list1)
res2,_:=json.Marshal(list2)

fmt.Println(string(res1),string(res2)) //output: null []

可见,通过new创建的slice会输出null,而make会返回空数组。

同样,在通过反射创建slice时,也有两种方法

方法一:相当于new

func CreateEmptySlice(data interface{}) interface{} {
	return reflect.Zero(reflect.SliceOf(reflect.TypeOf(data))).Interface()
}

方法二:相对于make

func CreateEmptySlice(data interface{}) interface{} {
	return reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(data)),0,10).Interface()
}

编译linux内核的错误:没有规则可制作目标

make[1]: *** 没有规则可制作目标“firmware/radeon/R600_rlc.bin”,由“firmware/radeon/R600_rlc.bin.gen.o” 需求。 停止。
make: *** [Makefile:1053:firmware] 错误 2

CONFIG_FW_LOADER=y
CONFIG_EXTRA_FIRWARE=”radeon/R600_rlc.bin…”
CONFIG_EXTRA_FIRWARE_DIR=”firware”

改成:
CONFIG_EXTRA_FIRWARE_DIR=”/lib/firware”

参考: https://www.linuxquestions.org/questions/linux-newbie-8/r600_cp-failed-to-load-firmware-radeon-r600_rlc-bin-791940/

cgo argument has Go pointer to Go pointer

bytes.Buffer引起 cgo argument has Go pointer to Go pointer错误

先看代码:

函数

func f(data []byte){
    pData:=unsafe.Pointer(&data[0])
    //do something with cgo
    C.f(pData)
}

正确调用

buf:=[]byte("hello")
f(buf) 

错误调用

buf:=bytes.Buffer{}
buf.Write([]byte("hello"))
f(buf.bytes()) //关键在这里

为什么用bytes.Buffer就会报错呢?

因为Go调用C Code时,Go传递给C Code的Go指针所指的Go Memory中不能包含任何指向Go Memory的Pointer。
参考:https://segmentfault.com/a/1190000013590585

这句话的意思比较难懂,通俗将就是指针指向的内存要么是Go的普通变量,要么是C的结构体变量,不能是Go结构体变量。不过不急,可以先来看下bytes.Buffer的源码

...
type Buffer struct {
	buf      []byte 
	off      int   
	lastRead readOp 
	...
}
...
func (b *Buffer) Bytes() []byte { return b.buf[b.off:] } //重点在这里
...

可见,Buffer.Bytes()返回的是结构体里buf这个字段。所以上面调用的最后,data指向的内存都是Buffer结构体的一个field字段,所以违背了上述原则。

解决方案有3个:

  1. 不用bytes.Buffer
  2. 使用copy(dst,src)将值转入新的单个go变量
  3. C.f(pData)调用改成C.f(unsafe.Pointer(&data[0])),为什么这个可以,还需要深入研究下了。

这里推荐第2个或第3个解决方案,因为作为一个封装的库的话,永远也无法保证外面传的变量是什么样的。

golang程序打包成容器镜像 ./app: not found错误

在golang程序打包成容器镜像过程中,出现了一个 ./app: not found错误,app是编译好的执行程序,文件是存在的,基础镜像用的是alpine镜像。想来应该是编译过程的问题,后来加了CGO_ENABLED=0成功解决此问题。

继续阅读golang程序打包成容器镜像 ./app: not found错误

使用fileload解决android sdk ndk avd无法下载问题

在国内,无法下载android studio, android sdk, adnroid ndk, android avd,即使搭梯子,因为网络不稳地,经常出现SSL peer shut down incorrectly之类的错误。

所以我专门写了一个下载器,每次去下载文件的一部分,例如1MB大小,这样网络波动对整体的下载进度影响就不大了。以安卓ndk为例

继续阅读使用fileload解决android sdk ndk avd无法下载问题

golang多线程分块下载器

在使用golang写一个多线程下载器的过程中,发现下载的结果是相同的,首先排除引用传递,确定是值传递,逐步排查,最后确定是http.Request的Header对象是相同的。也就是说,在对象拷贝过程中,对象的部分子元素是共享的。最后写了一个深度拷贝解决这个问题,深度拷贝一般思路是序列号和反序列化,所以gob json等都可以的。

func DeepCopy(dst, src interface{}) error {
	var buf bytes.Buffer
	if err := gob.NewEncoder(&buf).Encode(src); err != nil {
		return err
	}
	return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
}

下载器源码和文档 github

kubernetes dashboard 安装流程

参考:

访问设置相关:https://github.com/kubernetes/dashboard/wiki/Accessing-Dashboard—1.7.X-and-above

用户相关:https://github.com/kubernetes/dashboard/wiki/Creating-sample-user

https无法访问的问题:https://github.com/kubernetes/dashboard/issues/2954

说明

NOTE: Dashboard should not be exposed publicly using kubectl proxy command as it only allows HTTP connection. For domains other than localhost and 127.0.0.1 it will not be possible to sign in. Nothing will happen after clicking Sign in button on login page.

通过 kubectl proxy暴露的控制面板,如果不是从localhost或127.0.0.1访问的话,点击登陆按钮不会有任何反应……

继续阅读kubernetes dashboard 安装流程

Unable to update cni config: No networks found in /etc/cni/net.d

17666 cni.go:171] Unable to update cni config: No networks found in /etc/cni/net.d
17666 kubelet.go:2125] Container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

issue讨论

之前的文章

去掉$KUBELET_NETWORK_ARGS是一个治标不治本的解决办法

可能是原因之一是:国内无法Pull quay.io/coreos/flannel:v0.10.0-amd64这个镜像

具体表现为:/etc/cni/net.d/目录下没有文件或根本没有这个目录

继续阅读Unable to update cni config: No networks found in /etc/cni/net.d