Факел для камеры "0" недоступен из-за существующего пользователя камеры - PullRequest
0 голосов
/ 28 мая 2019

Я хочу создать приложение, в котором есть кнопка для записи видео и еще одна отдельная кнопка для включения режима записи во время записи видео.

Я создал приложение камеры, используя API камеры2 для последних Android, доступ к которому осуществляется с помощью кнопки с изображением. И я установил режим факела доступа к кнопке переключения, но это не работает вообще. Но кнопка переключения может получить доступ к вспышке отдельно.

public class MainActivity extends AppCompatActivity {


    private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            setupCamera(width,height);
            connectCamera();
        }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        createFolder();

        mMediaRecorder = new MediaRecorder();

        mTextureView = (TextureView) findViewById(R.id.textureView);
        mRecordButtonimg = (ImageButton) findViewById(R.id.video_online_button);
                mRecordButtonimg.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                if (misRecording) {
                    misRecording = false;
                    mRecordButtonimg.setImageResource(R.mipmap.ic_launcher);
                    mMediaRecorder.stop();
                    mMediaRecorder.reset();
                    startPreview();
                } else {
                    checkWriteStoragePermission();
                    misRecording = true;
                    mRecordButtonimg.setImageResource(R.mipmap.ic_launcher_round);
                }
            }
        });

        mButtonLights = (ToggleButton) findViewById(R.id.buttonLights);
        mButtonLights.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try{
                    cameraManager.setTorchMode(mCameraId, mButtonLights.isChecked());
                }catch (CameraAccessException e){
                    e.printStackTrace();
                }
            }
            });
    }
}

Я только что добавил режим установки факела в onClickListenser. Должен ли я добавить его в другом месте? Потому что это не делает, чтобы добавить его в предварительный просмотр! И я уже проверяю заднюю камеру в коде (идентификатор равен 0 с фонариком), поэтому я не знаю, почему код не работает.

1 Ответ

0 голосов
/ 28 мая 2019

Используйте код ниже

// write below line in Manifest file
 <uses-feature android:name="android.hardware.camera"
    android:required="true" />

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<permission android:name="android.permission.FLASHLIGHT"
    android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
    android:protectionLevel="normal" />
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />


// write below code in activity xml
 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
<LinearLayout
   android:orientation="horizontal"
   android:layout_width="match_parent"
   android:layout_height="match_parent">
  <FrameLayout
      android:id="@+id/videoview"
      android:layout_width="500px"
      android:layout_height="480px"/>
  <LinearLayout
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="match_parent">
     <Button
         android:id="@+id/mybutton"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:text="REC"
         android:textSize="12dp"/>
     <RadioGroup
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:id="@+id/radio_group"
         android:orientation="vertical">
        <RadioButton
            android:id="@+id/flashoff"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="OFF"
            android:textSize="8dp"
            android:checked="true"/>
        <RadioButton
            android:id="@+id/flashtorch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Torch"
            android:textSize="8dp"/>
     </RadioGroup>
    </LinearLayout>
   </LinearLayout>
  </LinearLayout>


 // Activity source code

 import android.Manifest;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.hardware.Camera;
 import android.media.CamcorderProfile;
 import android.media.MediaRecorder;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.v4.app.ActivityCompat;
 import android.support.v4.content.ContextCompat;
 import android.support.v7.app.AppCompatActivity;
 import android.util.Log;
 import android.view.MotionEvent;
  import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
 import android.widget.Button;
 import android.widget.FrameLayout;
 import android.widget.RadioButton;
 import android.widget.Toast;

import java.io.IOException;

public class MainActivity extends AppCompatActivity {
private Camera myCamera;
private MyCameraSurfaceView myCameraSurfaceView;
private MediaRecorder mediaRecorder;
private Button myButton;
private RadioButton flashOff, flashTorch;
private SurfaceHolder surfaceHolder;
boolean recording;
private int PERMISSION_CODE=1021;
private static final String LOG_TAG=MainActivity.class.getName();
private String[] getDeviceIdPermissions = new String[]{
        Manifest.permission.CAMERA,
        android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
        android.Manifest.permission.READ_EXTERNAL_STORAGE,
        android.Manifest.permission.RECORD_AUDIO};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if(!checkPermission()) {
        askPermission();
    }else{
        init();
    }
}

private boolean checkPermission() {
    if(isPermitted(getDeviceIdPermissions)){
        return true;
    }
    return false;
}

private void askPermission(){
    ActivityCompat.requestPermissions(this,getDeviceIdPermissions,PERMISSION_CODE);
}

Button.OnTouchListener flashButtonOnTouchListener
        = new Button.OnTouchListener(){

    @Override
    public boolean onTouch(View arg0, MotionEvent arg1) {
        // TODO Auto-generated method stub

        if(myCamera != null){
            Camera.Parameters parameters = myCamera.getParameters();

            switch (arg1.getAction()){
                case MotionEvent.ACTION_DOWN:
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                    myCamera.setParameters(parameters);
                    break;
                case MotionEvent.ACTION_UP:
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                    myCamera.setParameters(parameters);
                    break;
            };
        }

        return true;
    }};

Button.OnClickListener flashModeButtonOnClickListener
        = new Button.OnClickListener(){

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub

    }
};

Button.OnClickListener myButtonOnClickListener
        = new Button.OnClickListener(){

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        if(recording){
            // stop recording and release camera
            mediaRecorder.stop();  // stop the recording
            releaseMediaRecorder(); // release the MediaRecorder object

            //Exit after saved
            finish();
        }else{

            //Release Camera before MediaRecorder start
            releaseCamera();

            if(!prepareMediaRecorder()){
                Toast.makeText(MainActivity.this,
                        "Fail in prepareMediaRecorder()!\n - Ended -",
                        Toast.LENGTH_LONG).show();
                finish();
            }

            mediaRecorder.start();
            recording = true;
            myButton.setText("STOP");
        }
    }};

private Camera getCameraInstance(){
    // TODO Auto-generated method stub
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
    }
    return c; // returns null if camera is unavailable
}


private void init(){
    myCamera = getCameraInstance();
    if(myCamera == null){
        Log.d(LOG_TAG,"Failed to get camera");
    }

    myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera);
    FrameLayout myCameraPreview = (FrameLayout)findViewById(R.id.videoview);
    myCameraPreview.addView(myCameraSurfaceView);

    myButton = (Button)findViewById(R.id.mybutton);
    myButton.setOnClickListener(myButtonOnClickListener);

    flashOff = (RadioButton)findViewById(R.id.flashoff);
    flashTorch = (RadioButton)findViewById(R.id.flashtorch);
}

private String getFlashModeSetting(){
    if(flashTorch.isChecked()){
        return Camera.Parameters.FLASH_MODE_TORCH;
    }else {
        return Camera.Parameters.FLASH_MODE_OFF;
    }
}

private boolean prepareMediaRecorder(){
    myCamera = getCameraInstance();

    Camera.Parameters parameters = myCamera.getParameters();
    parameters.setFlashMode(getFlashModeSetting());
    myCamera.setDisplayOrientation(90);
    myCamera.setParameters(parameters);

    mediaRecorder = new MediaRecorder();

    myCamera.unlock();
    mediaRecorder.setCamera(myCamera);

    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);

    mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

    mediaRecorder.setOutputFile("/sdcard/myvideo.mp4");
    mediaRecorder.setMaxDuration(60000); // Set max duration 60 sec.
    mediaRecorder.setMaxFileSize(5000000); // Set max file size 5M

    mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder().getSurface());

    try {
        mediaRecorder.prepare();
    } catch (IllegalStateException e) {
        releaseMediaRecorder();
        return false;
    } catch (IOException e) {
        releaseMediaRecorder();
        return false;
    }
    return true;

}

@Override
protected void onPause() {
    super.onPause();
    releaseMediaRecorder();       // if you are using MediaRecorder, release it first
    releaseCamera();              // release the camera immediately on pause event
}

private void releaseMediaRecorder(){
    if (mediaRecorder != null) {
        mediaRecorder.reset();   // clear recorder configuration
        mediaRecorder.release(); // release the recorder object
        mediaRecorder = null;
        myCamera.lock();           // lock camera for later use
    }
}

private void releaseCamera(){
    if (myCamera != null){
        myCamera.release();        // release the camera for other applications
        myCamera = null;
    }
}

public class MyCameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback{

    private SurfaceHolder mHolder;
    private Camera mCamera;

    public MyCameraSurfaceView(Context context, Camera camera) {
        super(context);
        mCamera = camera;
        mCamera.setDisplayOrientation(90);
        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int weight,
                               int height) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
            // preview surface does not exist
            return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
            // ignore: tried to stop a non-existent preview
        }

        // make any resize, rotate or reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub

    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    boolean isPermitted =isPermitted(permissions);
    if(isPermitted){
        if(requestCode==PERMISSION_CODE){
            init();
        }
    }
}

public boolean isPermitted(String[] permissions) {
    boolean havePermission;
    for (String permission : permissions) {
        havePermission = (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED);
        if (!havePermission)
            return false;
    }
    return true;
}
}
...