物理按键一键拍照,一键录像,一键录音

一键拍照,一键录像:

(S版本)

首先在对应的键值逻辑上做逻辑处理

base/services/core/java/com/android/server/policy/PhoneWindowManager.java

case KeyEvent.KEYCODE_CAMERA:{// take photo
       if (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 takevideo
           if (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 record
            if(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里面看不到后台,但实际上还是有的,不过过一会会被清掉

  1. Intent.FLAG_ACTIVITY_SINGLE_TOP

  1. 与加载模式singleTop功能相同

  1. 栈顶复用(当被启动的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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Win11一键局域网是指Windows 11操作系统中的一个功能,它可以通过简单的操作将多台电脑连接在同一个局域网内,方便进行共享文件、打印、游戏等操作。 使用Win11一键局域网非常简单,用户只需要在电脑上打开网络设置,找到并点击“一键局域网”按钮即可。系统会自动搜索局域网中的其他电脑,并建立起连接。连接成功后,用户可以在资源管理器中看到局域网中的其他电脑和共享文件夹。 通过Win11一键局域网,用户可以方便地共享文件。例如,可以将文件夹设置为共享,其他连接在同一局域网中的电脑就可以访问和复制这些文件。这样,多台电脑之间的文件传输就变得非常快捷方便。 此外,Win11一键局域网还可以实现共享打印功能。用户可以将一台打印机连接到一台电脑上,并在局域网设置中将该打印机共享。其他电脑只需连接到局域网,即可通过网络打印机打印文件,无需额外的物理连接。 对于喜欢游戏的用户来说,Win11一键局域网也提供了便利。用户可以通过局域网连接,在同一局域网中的电脑之间进行多人游戏。这不仅简化了局域网游戏的连接过程,还能提供更稳定的游戏网络环境,提高游戏体验。 总之,Win11一键局域网功能的使用简单便捷,可以方便地连接多台电脑,实现文件共享、打印共享和局域网游戏等功能。这对于家庭用户、办公人员和游戏爱好者来说都是非常实用和方便的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Youth King

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值