2
votes

La torche de la caméra "0" n'est pas disponible en raison d'un utilisateur de caméra existant

Je souhaite créer une application dotée d'un bouton pour enregistrer la vidéo et d'un autre bouton à bascule séparé pour activer le flah pendant l'enregistrement de la vidéo.

J'ai créé l'application appareil photo à l'aide de l'API camera2 pour les androïdes récents, accessible par un bouton d'image. Et j'ai défini l'accès en mode torche à un bouton à bascule, mais cela ne fonctionne pas du tout. Mais le bouton à bascule est capable d'accéder au flash séparément.

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

Je viens d'ajouter le mode de torche réglé au onClickListenser. Dois-je l'ajouter ailleurs? Beacuse il n'en fait pas pour l'ajouter à l'aperçu! Et je vérifie déjà la caméra arrière dans le code (l'ID est 0 avec une lampe de poche), donc je ne sais pas pourquoi le code ne fonctionne pas.


0 commentaires

3 Réponses :


1
votes

Utilisez le code ci-dessous

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


1 commentaires

hé j'utilise camera2API et non l'ancienne version, alors pourriez-vous me donner une idée pour régler mon flash sur la minuterie lors de l'enregistrement de la vidéo.



1
votes

Peut-être que cela vous aide. Je crée une application qui applique des shaders OpenGL EL à un aperçu de la caméra. Et ma tâche était presque la même: allumer / éteindre la lampe de poche par un bouton tout en traitant un aperçu de la caméra. J'ai réussi à le faire assez facilement: j'arrête de répéter des demandes, j'allume / éteins une lampe de poche dans un constructeur et je recommence à répéter des demandes. Quelque chose comme ceci:

cameraSession.stopRepeating()
requestBuilder.set(CaptureRequest.FLASH_MODE, if(turnFlashOn) CaptureRequest.FLASH_MODE_TORCH else null)
cameraSession.setRepeatingRequest(requestBuilder!!.build(), null, null)


1 commentaires

Qu'est-ce que cameraSession et requestBuilder ici?



0
votes

Comprendre comment allumer et éteindre la torche pendant la prévisualisation de la caméra. Sur le bouton cliquez pour allumer / éteindre la lumière, utilisez ce code:

//at some other function where camera is initialised and start preview
//...
Camera camera = Camera.open();
camera.startPreview();
//...
boolean lightOn = false;
//...

buttonLight.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
                Camera.Parameters p = camera.getParameters();

                if (!lightOn) {
                    lightOn = true;
                    p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                    camera.setParameters(p);
                } else {
                    lightOn = false;
                    p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                    camera.setParameters(p);
                }
        }
    });

Bon codage! : D


3 commentaires

@Psijic pouvez-vous expliquer ce que vous entendez par caméra déjà ouverte? Si basé sur mon code ci-dessus .. les 3ème et 4ème lignes sont les codes pour ouvrir la caméra. La caméra déjà ouverte est maintenue par cette variable «caméra» de type Caméra.


caméra déjà ouverte signifie qu'aucune variable de caméra n'est enregistrée car la caméra a été ouverte par un tiers.


@Psijic dans ce cas, vous pouvez voir ce post sur la façon de rechercher la caméra déjà ouverte stackoverflow.com/questions/21559699/... selon ce que je sais, il n'y a aucun moyen d'obtenir l'identifiant de la caméra sans le stocker en premier lieu ... mais l'un des la réponse dans le post montre comment faire une boucle pour obtenir les informations de la caméra qui contiennent l'identifiant de la caméra que vous voulez que ce soit à l'avant ou à l'arrière, etc.