One-key photo taking, one-key recording, one-key recording

One-click photo, one-click video:

(S version)

First, do logical processing on the corresponding key-value logic

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();
                                }

Then change it in the camera app

vendor/mediatek/proprietary/packages/apps/Camera2/host/src/com/mediatek/camera/CameraActivity.java

private staticfinal int DELAY_MSG_ONE_CLICK_CAMERA_FLAG = 100;

Add at the end of 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() {

join case

case DELAY_MSG_ONE_CLICK_CAMERA_FLAG:
mCameraAppUI.triggerShutterButtonClick(-1);
break;

What is called here is not the application of the camera itself, but a separate activity inside, so add the flag to prevent Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS from being displayed in the background, so that the user can only click the button to enter.

There is a bug like this: when the screen is locked, clicking the camera will jump to the default interface of the camera and then take a picture, but the interface of the video cannot be pressed, and the video interface will be displayed after unlocking, but there is no recording

Notice! ! ! ! ! If the delay made by this delay is too short, the interface UI will not be functional. For example, if the old version below is used for 0.5 seconds, the function will have problems, and it will be normal if it is used for 1 second.

(Take O version as an example)

O version needs to change the logic in cameraactivity, because there is no triggerShutterButtonClick, this method needs to use the click method of photo and video respectively

Still in 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;

Notice! ! !

If you want to meet the requirement of automatically exiting after taking a photo or recording a video, modify it as follows:

Roughly the same as above. You need to add another handler, because clicking the ok button to save the picture also takes time to wait for the ui,

private HandlermHandler;

Example in resume

mHandler = newHandler();

Finally in caseDELAY_MSG_ONE_CLICK_PHOTO_FLAG:

join one

                                mHandler.postDelayed(newRunnable() {
                                                        public void run() {
                                                        mModuleManager.onOkButtonPress();
                                                        }
                                                    }, 1000);

One-button recording, press the button again to stop recording and then save and exit:

Cameraactivity does not need to be changed, and a button logic needs to be added to the corresponding shutter processing

For example, the O version is in

src/com/mediatek/camera/mode/VideoMode.java

protectedboolean onKeyDown(int keyCode, KeyEvent event) {

Join, this F4 is our physical button for one-click recording,

                                caseKeyEvent.KEYCODE_F4:
                                                onBackPressed();
                                                mActivity.finish();
                                            break;

This return operation is because the source code is designed, and it can be saved after returning, just call this method

protectedboolean onBackPressed() {

Log.d(TAG, "[onBackPressed()]CurrentModeState " + getModeState());

if (ModeState.STATE_IDLE ==getModeState()) {

return false;

}

if (ModeState.STATE_RECORDING ==getModeState()) {

stopVideoRecordingAsync(true);

}

return true;

}

After saving, it will return to the option of × or √, but it has actually been saved at this time, so you only need to delete it in finish at the end

One-click recording:

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

Key handling:

    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;
            }

The attribute persist.sys.record.taking is added here to judge that the recorder entered by each key has the recording function. If it is entered from the recent background, it will still be the previous activity. If it is not judged, it will still have the function.

Here we use the S version of the recorder that comes with the source code as an example:

vendor/mediatek/proprietary/operator/packages/apps/SoundRecorder/OP01/src/com/android/soundrecorder/SoundRecorder.java

private staticfinal int DELAY_MSG_ONE_CLICK_RECORD_FLAG = 100;

Add at the end of 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");
              }
       }
       }

Processing in handler

private HandlermHandler = new Handler() {

add case

    case DELAY_MSG_ONE_CLICK_RECORD_FLAG:
                 onClickRecordButton();
                 break;

Notice! ! !

The click event cannot be used directly, otherwise it will not succeed! ! ! Handler is required for asynchronous processing,

Avoid directly processing transactions in the UI main thread and causing other processing work that affects the UI main thread. Take this recorder as an example. If you directly do a click event, the mService is empty, indicating that the main thread is not ready yet, which is normal. So you need to use a handler for asynchronous processing. In fact, the delay here can not directly sendEmptyMessage

sendMessage(Messagemsg)

sendEmptyMessage(int what)

In fact, these two methods are the same, one is to pass message type msg, the other is to pass int type what, if you pass what, it will eventually be converted to msg

Handler basic usage:

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;

}

}

};

want to remove this message

mHandler.removeMessages(int);

handler.removeMessages(0); is a match

mHandler.postDelayed(new Runnable() {

public void run() {

}

},1000);

The whole handler does delay processing, handler.removeMessages(0); cancels the post operation

MediaStore.ACTION_IMAGE_CAPTURE,MediaStore.ACTION_IMAGE_CAPTURE_SECURE

Just take a picture, the jumping interface cannot record video, and exit after taking a picture

MediaStore.ACTION_VIDEO_CAPTURE, also can only record

MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA and MediaStore.ACTION_IMAGE_CAPTURE_SECURE are direct access to the camera

Intent.FLAG_ACTIVITY_NEW_TASK

To start an Activity outside of the Activity context, you need to set the FLAG_ACTIVITY_NEW_TASK flag to the Intent, otherwise an exception will be reported.

.Add this flag, if you jump to the Activity in the same application, no new Task will be created, only when you jump in a different application will a new Task be created

Intent..FLAG_ACTIVITY_CLEAR_TOP

Destroy the target Activity and all activities above it, and recreate the target Activity

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

If set, new activities will not be saved in the list of recently started activities. J means that you can’t see the background in recent, but in fact there are still, but it will be cleared after a while

  1. Intent.FLAG_ACTIVITY_SINGLE_TOP

  1. Same function as loading mode singleTop

  1. Stack top reuse (when the started Activity is at the top of the Task stack, it can be reused and directly calls the onNewIntent method)

General use combination

setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP)

The Activity with the three modes of singleTop, singleTask, and singleInstance is set. If a new Activity page is opened, the same instance on the top of the stack will be reused, and a new instance will not be recreated. After the Activity is reused, it will call onNewIntent(Intent intent) method.

intent.setFlags is to replace the original flag, addFlags is to add the flag on the original basis

Guess you like

Origin blog.csdn.net/youthking1314/article/details/129622405