物理按键一键拍照,一键录像,一键录音
一键拍照,一键录像:
(S版本)
首先在对应的键值逻辑上做逻辑处理
base/services/core/java/com/android/server/policy/PhoneWindowManager.java
case KeyEvent.KEYCODE_CAMERA:{// take photoif (down) {if(getCurrentActivityName().equals("com.freeme.factory.input.KeyboardTest")){break;} else if(!getCurrentActivityName().contains("com.mediatek.camera")) {Intent intent;if (keyguardActive) {//intent = newIntent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE);intent = newIntent(MediaStore.ACTION_IMAGE_CAPTURE_SECURE);intent.putExtra("takePhoto","1");} else {//intent = newIntent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);intent = newIntent(MediaStore.ACTION_IMAGE_CAPTURE);intent.putExtra("takePhoto","1");}
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);startActivityAsUser(intent,UserHandle.CURRENT_OR_SELF);}}break;}case KeyEvent.KEYCODE_F3:{//yantao takevideoif (down) {if(getCurrentActivityName().equals("com.freeme.factory.input.KeyboardTest")){break;} else if (!getCurrentActivityName().contains("com.mediatek.camera")){Intent intent = newIntent(MediaStore.ACTION_VIDEO_CAPTURE);intent.putExtra("takeVideo","1");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);startActivityAsUser(intent,UserHandle.CURRENT_OR_SELF);}}break;}private String getCurrentActivityName() {ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);List<ActivityManager.RunningTaskInfo> taskInfo =am.getRunningTasks(1);ComponentName componentInfo = taskInfo.get(0).topActivity;android.util.Log.i("yantao","currentActivity name=="+componentInfo.getClassName());return componentInfo.getClassName();}
然后在相机应用里改
vendor/mediatek/proprietary/packages/apps/Camera2/host/src/com/mediatek/camera/CameraActivity.java
private staticfinal int DELAY_MSG_ONE_CLICK_CAMERA_FLAG = 100;
在protected voidonResumeTasks() {最后添加
Intent intent =getIntent();
String takeVideo=intent.getStringExtra("takeVideo");
String takePhoto=intent.getStringExtra("takePhoto");
if(takeVideo != null || takePhoto !=null){
if("1".equals(takeVideo) ||"1".equals(takePhoto))mMainHandler.sendEmptyMessageDelayed(DELAY_MSG_ONE_CLICK_CAMERA_FLAG,500);
}
在privateHandler mMainHandler = new Handler() {
加入case
case DELAY_MSG_ONE_CLICK_CAMERA_FLAG:
mCameraAppUI.triggerShutterButtonClick(-1);
break;
这里的调起的不是相机本身这个应用,是里面单独的activity,所以加flag不让显示在后台Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,这样用户就只能点击按键才能进入。
这样有个bug:锁屏的时候点击一键相机会跳到相机默认界面然后拍照,而视频的那个界面一键按不出来,等解锁之后才显示这个video界面但是没有录制
注意!!!!!这个delay做的延迟如果太短的话,界面ui没起来就不会有功能,比如说下面的老版本如果用0,5秒的话功能会有问题,用1秒就正常
(O版本为例)
O版本需要改动cameraactivity里面的逻辑,因为没有triggerShutterButtonClick,这个方法了,需要用到photo和video分别的click方法
还是在src/com/android/camera/CameraActivity.java
private staticfinal int DELAY_MSG_ONE_CLICK_PHOTO_FLAG = 100;
private static final intDELAY_MSG_ONE_CLICK_VIDEO_FLAG = 200;Intent intent =getIntent();
String takeVideo=intent.getStringExtra("takeVideo");
String takePhoto=intent.getStringExtra("takePhoto");
android.util.Log.i("yantao","takeVideo=="+takeVideo+"\ntakePhoto=="+takePhoto);
if(takeVideo != null || takePhoto !=null){if("1".equals(takeVideo) && takePhoto == null){android.util.Log.i("yantao","cameraactivitytakeing");mMainHandler.sendEmptyMessageDelayed(DELAY_MSG_ONE_CLICK_VIDEO_FLAG,1000);}if(takeVideo == null &&"1".equals(takePhoto)){android.util.Log.i("yantao","cameraactivitytakeing");mMainHandler.sendEmptyMessageDelayed(DELAY_MSG_ONE_CLICK_PHOTO_FLAG,1000);}}case DELAY_MSG_ONE_CLICK_PHOTO_FLAG:mModuleManager.onPhotoShutterButtonClick();break;case DELAY_MSG_ONE_CLICK_VIDEO_FLAG:mModuleManager.onVideoShutterButtonClick();break;
注意!!!
如果要满足拍完照或者录完像自动退出的需求,修改如下:
大致和上面一样。需要再加一个handler,因为点击ok键保存图片也需要时间等ui,
private HandlermHandler;
在resume里实例
mHandler = newHandler();
最后在caseDELAY_MSG_ONE_CLICK_PHOTO_FLAG:
加入一个
mHandler.postDelayed(newRunnable() {public void run() {mModuleManager.onOkButtonPress();}}, 1000);
一键录像,再按一次按键就停止录像然后保存退出:
Cameraactivity的都一样不需要改,另外需要在对应的快门处理上加一个按键逻辑
比如O版本的在
src/com/mediatek/camera/mode/VideoMode.java
protectedboolean onKeyDown(int keyCode, KeyEvent event) {
加入,这个F4就是我们一键录像的物理按键,
caseKeyEvent.KEYCODE_F4:onBackPressed();mActivity.finish();break;
这个返回操作是由于源码就设计好了,返回就能保存,调用这个方法就行
protectedboolean onBackPressed() {
Log.d(TAG, "[onBackPressed()]CurrentModeState " + getModeState());
if (ModeState.STATE_IDLE ==getModeState()) {
return false;
}
if (ModeState.STATE_RECORDING ==getModeState()) {
stopVideoRecordingAsync(true);
}
return true;
}
保存完之后还是会回到那个×或√的选项,但此时其实已经保存了,所以只需要最后在finish掉
一键录音:
base/services/core/java/com/android/server/policy/PhoneWindowManager.java
按键处理:
case KeyEvent.KEYCODE_F2:{ //yantao recordif(getTopActivityPacakgeName().equals("com.freeme.factory")||getCurrentActivityName().contains("com.android.soundrecorder")) {break;}if (down) {Intent intent = new Intent();intent.setClassName("com.android.soundrecorder","com.android.soundrecorder.SoundRecorder");intent.putExtra("takeRecord","1");SystemProperties.set("persist.sys.record.taking","1");startActivityAsUser(intent,UserHandle.CURRENT_OR_SELF);}else if (event.getAction() ==KeyEvent.ACTION_UP) {}break;}
这里加入属性persist.sys.record.taking,是为了判断每次按键进入的录音机才有录音功能,如果从recent后台进入的话还是之前的activity,不判断的话依然会有功能。
这里用了源码自带的录音机S版本为例:
vendor/mediatek/proprietary/operator/packages/apps/SoundRecorder/OP01/src/com/android/soundrecorder/SoundRecorder.java
private staticfinal int DELAY_MSG_ONE_CLICK_RECORD_FLAG = 100;
在protected void onResume() {最后添加
Intent intent =getIntent();if(android.os.SystemProperties.get("persist.sys.record.taking","0").equals("1")){String takeRecord=intent.getStringExtra("takeRecord");if(takeRecord != null){if(takeRecord.equals("1")){android.util.Log.i("yantao","takeRecordin");mHandler.sendEmptyMessageDelayed(DELAY_MSG_ONE_CLICK_RECORD_FLAG,100);android.os.SystemProperties.set("persist.sys.record.taking","0");}}}
在handler处理
private HandlermHandler = new Handler() {
添加case
case DELAY_MSG_ONE_CLICK_RECORD_FLAG:onClickRecordButton();break;
注意!!!
不能直接使用点击事件,不然无法成功!!!需要handler做异步处理,
避免直接在UI主线程中处理事务导致影响UI主线程的其他处理工作。那这个录音机为例,如果直接做点击事件的话,那个mService就是空,说明主线程还没准备好,原本是正常的。所以需要用handler做异步处理,这里的延时其实也可以不要直接sendEmptyMessage
sendMessage(Messagemsg)
sendEmptyMessage(int what)
其实这两个方法是一样一样的,一个传Message类型的msg,一个传int类型的what,传what的,最终会转为msg
Handler基本用法:
import android.os.Handler;
mHandler.sendEmptyMessageDelayed(int,100);
private HandlermHandler = new Handler() {
@Override
public void handleMessage(Message msg){
switch(msg.what) {
case int:
break;
default:
break;
}
}
};
想要移除该消息
mHandler.removeMessages(int);
handler.removeMessages(0);是配合
mHandler.postDelayed(new Runnable() {
public void run() {
}
},1000);
整个handler做延时处理,handler.removeMessages(0);就把post操作取消了
MediaStore.ACTION_IMAGE_CAPTURE,MediaStore.ACTION_IMAGE_CAPTURE_SECURE
只是单纯拍照,跳转的界面不能录像,且拍一张就退出了
MediaStore.ACTION_VIDEO_CAPTURE,也是只能录像
MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA和MediaStore.ACTION_IMAGE_CAPTURE_SECURE是直接进入相机
Intent.FLAG_ACTIVITY_NEW_TASK
在Activity上下文之外启动Activity需要给Intent设置FLAG_ACTIVITY_NEW_TASK标志,不然会报异常。
.加了该标志,如果在同一个应用中进行Activity跳转,不会创建新的Task,只有在不同的应用中跳转才会创建新的Task
Intent..FLAG_ACTIVITY_CLEAR_TOP
销毁目标Activity和它之上的所有Activity,重新创建目标Activity
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
如果设置,新的Activity不会在最近启动的Activity的列表中保存。J就是recent里面看不到后台,但实际上还是有的,不过过一会会被清掉
Intent.FLAG_ACTIVITY_SINGLE_TOP
与加载模式singleTop功能相同
栈顶复用(当被启动的Activity处于Task栈顶时,可以复用,直接调用onNewIntent方法)
一般用组合
setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP)
设置了singleTop、singleTask、singleInstance这三种模式的Activity,如果开启一个新的Activity页面,栈顶存在相同的实例就复用,都不会重新创建一个新实例,Activity复用后都会调用onNewIntent(Intent intent)方法。
intent.setFlags是替换原来的flag,addFlags是原有基础上添加flag
物理按键一键拍照,一键录像,一键录音相关推荐
- 案例分享:Qt+Arm+Fpga医疗肾镜(又名内窥镜)(实时影像、冻结、拍照、白平衡、九宫格、录像、背光调整、硬件光源调整、光源手动自动调整、物理按键)
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/111241205 长期持续带来更多项目与技术分 ...
- Esp8266进阶之路17 esp8266自研的快速上电开关五次 (开-关为一次) ,无需按键触发则8266进去一键配网模式。(附带Demo)
本系列博客学习由非官方人员 半颗心脏 潜心所力所写,不做开发板.仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 序号 SDK版本 内容 链接 1 nonos2.0 搭建 ...
- Android一键拍照功能
今天分享的是用系统自带的相机实现一键拍照功能. "` public class MainActivity extends AppCompatActivity { private static ...
- iphone快捷指令一键重启_iPhoneX如何一键重启 iPhoneX一键重启方法介绍【图文】
iPhoneX如何一键重启?相信小伙伴们一定很好奇,下面小编为大家带来了iPhoneX一键重启方法介绍,感兴趣的小伙伴赶紧跟着小编一起来看看吧. iPhone X怎么一键重启?iPhone X重启键在 ...
- ubuntu一键安装LAMP 及一键卸载
ubuntu一键安装LAMP 及一键卸载 一键安装LAMP服务: sudo tasksel install lamp-server 一键卸载LAMP: sudo tasksel remove lamp ...
- php 一键wifi,懒人全自动脚本,一键自动swap2c一键3d加速,一键wifi加速等等.doc
懒人全自动脚本,一键自动swap2c一键3d加速,一键wifi加速等等 前言/注意事项 以下有部分补丁并不是能适合所有的ROM使用,请在下载/使用前看清楚我在帖子中的说明,如果因为用户自身问题造成手机 ...
- chrome浏览器一键切换搜索引擎,一键切换谷歌和百度搜索(不需要重新输入keyword,带关键词切换引擎)
chrome浏览器一键切换搜索引擎,一键切换谷歌和百度搜索(不需要重新输入keyword,带关键词切换引擎) 背景 有么有办法在谷歌和百度之间(或其他引擎或非引擎,如Youtube.B站.Bing等) ...
- 华为虚拟一键部署服务器,服务器一键部署
服务器一键部署 内容精选 换一换 部署提供可视化.一键式部署服务,支持并行部署和流水线无缝集成,实现部署环境标准化和部署过程自动化.本节通过以下五步介绍如何使用部署服务将项目代码部署到云主机上.第一步 ...
- 自定义悬浮球,提供一些快捷操作。比如一键静音,一键锁频,一键截屏,一键回桌面,手电筒等
FloatingBall 项目地址:killer8000/FloatingBall 简介:自定义悬浮球,提供一些快捷操作.比如一键静音,一键锁频,一键截屏,一键回桌面,手电筒等 更多:作者 提 ...
最新文章
- 85.4% mIOU!NVIDIA:使用多尺度注意力进行语义分割,代码已开源!
- 加拿大两院院士裴健:搜索皆智能​,智能皆搜索
- 全球及中国香蕉连接器行业投资商机与前景趋势展望报告2022版
- 简单了解RestTemplate
- 暴雪机器人消防_油库发生大规模爆炸?暴雪机器人、移动水炮、举高喷射车,消防高科技现身现场!...
- go restful 安全_Go语言构建 RESTful Web 服务
- AppStore刷榜那些事儿:猪,也是这么想的
- ROS的学习(三)创建一个工作空间
- 图像有损压缩与无损压缩_有损压缩与无损压缩之间的区别
- 移动oa咋显示无法连接服务器,移动oa办公系统管理维护技巧:让本地连接不再受限的方法...
- matlab方差分析盒型图
- xp系统如何开启445端口?
- Python中request的content,text和string方法的区别
- android 播放wav代码,播放简短的.wav文件 - Android
- 《C系列-实践相关》C语言十
- 网络营销实战课-笔记5
- http://www.prayer-laputa.com/blog/archives/588
- GGGIS地图下载器|手把手教你如何免费下载天地图和谷歌的卫星影像图以及街道地图
- Python实现树结构的两种方式
- 自定义表单mysql_创建自定义表单
热门文章
- 四川传媒学院计算机应用技术分数,2021年四川传媒学院投档线及各省最低录取分数线统计表...
- 鹅厂系列三 : 仿QQ消息拖动小球
- matlab计算复活节概率,复活节算法
- Android 动态切换应用图标方案
- Abz-Ala-Phe-Arg-Phe-Ser-Gln-EDDnp,1926163-28-1,激肽释放酶的多样作用
- 微信小程序+Django实现录音并在服务器上保存在指定文件夹
- 达内java学习day3
- vue2.5重构饿了么APP - 配置问题
- Tsai两步法求手眼标定矩阵
- 基于 NXP iMX8X 测试 GPU FFT 运算