Android录制Gif

有时候我们需要录制Android手机的屏幕,比如写了一个Demo应用,需要发布到博客和微博上。 对于Android4.4以上的手机,系统自带了一个命令screenrecord,我们可以很方便的使用。 录制命令 adb shell screenrecord /sdcard/test.mp4 视频保存目录可以自己指定,如上面的/sdcard/test.mp4, 命令执行后会一直录制180s,按下ctrl+c可以提前结束录制 设定视频分辨率 对于高分辨率的手机,录制的视频很大,我们分享又不需要这么大的 我们可以设置录制的视频分辨率 adb shell screenrecord --size 848x480 /sdcard/test.mp4 设定视频比特率 默认比特率是4M/s,为了分享方便,我们可以调低比特率为2M adb shell screenrecord --bit-rate 2000000 /sdcard/test.mp4 获取视频文件 使用adb pull 即可把手机SD卡中视频获取到本地 adb pull /sdcard/test.mp4 . 转GIF文件 在Windows下有个不错的软件Free Video to GIF Converter可以把mp4转换成GIF。 转换时还可以删除不需要的帧,这点真得很不错。 Mac上可以使用gifrocket进行转换。 原文链接

May 1, 2018 · FXIO

Android-opencv-cmake

Android-opencv-cmake Android opencv image process samples ,build with cmake 环境要求 Android studio 2.3.3 Cmake ndk14 opencv2.4.13 or opencv3.3 配置 在local.properties 文件中配置opencv sdk 路径 opencv.dir = ${opencv_sdk_dir} ndk.dir=/Users/king/Library/Android/ndk14 sdk.dir=/Users/king/Library/Android/sdk opencv.dir=/Users/king/Libs/OpenCV2413 在build.gradle中配置cmake参数 externalNativeBuild { cmake { cppFlags "-std=c++11 -frtti -fexceptions" arguments "-DOpenCV_DIR=" + getOpenCVDir().toString()+"/sdk/native/jni", "-DANDROID_ARM_NEON=TRUE" } } ndk { abiFilters "armeabi-v7a" //, "arm64-v8a","armeabi", } ... def getOpenCVDir() { Properties properties = new Properties() properties.load(new File(rootDir.absolutePath + "/local.properties").newDataInputStream()) def externalModuleDir = properties.getProperty('opencv.dir', null) if (externalModuleDir == null) { throw new GradleException( "OpenCV location not found. Define location with opencv.dir in the local.properties file!") } return externalModuleDir } 项目地址 源码

March 15, 2017 · FXIO

Android OpenCV CMake 调优

AIDL是什么 ? AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definition language的缩写,AIDL的作用是让你可以在自己的APP里绑定一个其他APP的service,这样你的APP可以和其他APP交互 为什么要有aidl ? 用于两个App之间交换数据的场景 为什么不能直接通讯? 在 Android 上,一个进程通常无法访问另一个进程的内存, 而AIDL只是Android中众多进程间通讯方式中的一种方式 使用方法 服务端AidlApp1 使用Android Studio在Service服务端创建aidl文件: IUserAidlInterface, 然后build一下 package com.joshkryo.aidl; interface IUserAidlInterface { String getUserInfo(int uid); } 创建Service实现类 public class UserAidlService extends Service { private static final String TAG = "UserAidlService"; @Nullable @Override public IBinder onBind(Intent intent) { Log.d(TAG, "onBind: " + intent); return mBinder; } private final IUserAidlInterface.Stub mBinder = new IUserAidlInterface.Stub() { @Override public String getUserInfo(int uid) throws RemoteException { return "{\"id\":" + uid + " ,name\":\"Tom\",\"age\":18}"; } }; } 注册Service <service android:name="com.joshkryo.aidlapp1.service.UserAidlService" android:enabled="true"> <intent-filter> <action android:name="com.joshkryo.aidlapp1.service.UserAidlService"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </service> 客户端AidlApp2 复制AidlApp1的aidl文件到AidlApp2, build一下 bindService class BindService { private void bindAidlService() { Intent intent = new Intent("com.joshkryo.aidlapp1.service.UserAidlService");// service配置的action intent.setPackage("com.joshkryo.aidlapp1");//service服务端包名 bindService(intent, mAidlConn, Context.BIND_AUTO_CREATE); } private ServiceConnection mAidlConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.d(TAG, "onServiceConnected"); userAidlInterface = IUserAidlInterface.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { Log.e(TAG, "onServiceDisconnected: "); userAidlInterface = null; } }; } 使用aidl interface调用AidlApp1里的service class Test { public void getAidlUserInfo(View v) { try { if (userAidlInterface == null) { Log.e(TAG, "onClick: null userAidlInterface instance"); return; } Toast.makeText(MainActivity.this, userAidlInterface.getUserInfo(1), Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { e.printStackTrace(); } } } 可能的错误 Service Intent must be explicit java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.joshkryo.aidlapp1 } at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2854) 原因: Android5.0之后service的intent一定要显性声明 onServiceConnected不调用 可能原因: service 没有在manifest里面注册 服务端, 客户端的 intent action 不一致

March 15, 2017 · FXIO