1

我想在按下耳机按钮时用相机拍照。

但我收到运行时错误消息“无法启动接收器...takePictureFailed”。

米主活动:

public class MainActivity extends AppCompatActivity{

protected static Camera myCamera;
private CameraPreview mPreview;
int iCantCameras;
int iActiveCamera = 0;
Camera.Parameters cpParameters;
AudioManager am;
static Context context;

public static String appName;

private static final String TAG = "MainActivity";

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

    appName = getString(R.string.app_name_long);

    context = getApplicationContext();

    // To register and unregister the receiver of the headset button
    am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
}

@Override
protected void onResume(){
    super.onResume();

    // Check if there's a camera
    if(!checkCameraHardware(this)){
        Toast.makeText(this, R.string.no_camera_message, Toast.LENGTH_SHORT).show();
        return;
    }

    // Start listening for button presses
    am.registerMediaButtonEventReceiver(new ComponentName(this, Receiver.class));

    // Get the number of cameras
    iCantCameras = Camera.getNumberOfCameras();

    // Activate the camera
    if (iCantCameras > 0) {
        activateCamera(iActiveCamera);
    }
}

public static void takeP(){
    // get an image from the camera

    myCamera.takePicture(null, null, mPicture);

    //Toast.makeText(context,"Botón presionado", Toast.LENGTH_SHORT).show();
}

public void takePhoto(View view){
    // get an image from the camera
    myCamera.takePicture(null, null, mPicture);
}

public void showFlashOptions(View view){

}

// Change between cameras
public void switchCamera(View view){
    // Return if there are less than 2 cameras
    if (iCantCameras < 2) {
        return;
    }

    if (iActiveCamera == Camera.CameraInfo.CAMERA_FACING_BACK) {
        iActiveCamera = Camera.CameraInfo.CAMERA_FACING_FRONT;
    } else {
        iActiveCamera = Camera.CameraInfo.CAMERA_FACING_BACK;
    }

    activateCamera(iActiveCamera);
}

// Activate the indicated camera
public void activateCamera(int cameraID){

    // Get an instance of the camera
    releaseCamera();

    myCamera = getCameraInstance(cameraID);
    if(myCamera == null){
        Toast.makeText(this, R.string.no_access_to_camera, Toast.LENGTH_SHORT).show();
        return;
    }

    // Get the camera parameters
    cpParameters = myCamera.getParameters();

    // Set the orientation of the camera
    setCameraDisplayOrientation(this, 0, myCamera);

    // Create our Preview view and set it as the content of our activity.
    mPreview = new CameraPreview(this, myCamera);
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
    preview.removeAllViews(); // This ensures the switch of cameras as this calls the mPreview.surfaceChanged method
    preview.addView(mPreview);

}
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
        // this device has a camera
        return true;
    } else {
        // no camera on this device
        return false;
    }
}

/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(int cameraID){
    Camera c = null;
    try {
        c = Camera.open(cameraID); // 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
}

// Sets the orientation of the camera as the display
public static void setCameraDisplayOrientation(Activity activity,
                                               int cameraId, android.hardware.Camera camera) {
    android.hardware.Camera.CameraInfo info =
            new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    int rotation = activity.getWindowManager().getDefaultDisplay()
            .getRotation();
    int degrees = 0;
    switch (rotation) {
        case Surface.ROTATION_0: degrees = 0; break;
        case Surface.ROTATION_90: degrees = 90; break;
        case Surface.ROTATION_180: degrees = 180; break;
        case Surface.ROTATION_270: degrees = 270; break;
    }

    int result;
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        result = (info.orientation + degrees) % 360;
        result = (360 - result) % 360;  // compensate the mirror
    } else {  // back-facing
        result = (info.orientation - degrees + 360) % 360;
    }
    camera.setDisplayOrientation(result);
}

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

// This saves the picture into the storage
public static Camera.PictureCallback mPicture = new Camera.PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        File pictureFile = getOutputMediaFile();
        if (pictureFile == null) {
            Log.d(TAG, "Error creating media file, check storage permissions");
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }

        // Gets the picture into media library
        MediaScanner client = new MediaScanner(context, pictureFile, null);
    }
};

/** Create a File for saving an image */
private static File getOutputMediaFile(){
    // To be safe, you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this.

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), appName);

    // Create the storage directory if it does not exist
    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            Log.d(appName, "failed to create directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile;
    mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                "IMG_"+ timeStamp + ".jpg");

    return mediaFile;
}

@Override
protected void onStop(){
    super.onStop();
    releaseCamera();
    // Stop listening for button presses
    am.unregisterMediaButtonEventReceiver(new ComponentName(this, Receiver.class));
}

@Override
protected void onDestroy(){
    super.onDestroy();
    releaseCamera();
    // Stop listening for button presses
    am.unregisterMediaButtonEventReceiver(new ComponentName(this, Receiver.class));
}

}

我的预习课:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;

public CameraPreview(Context context, Camera camera) {
    super(context);
    mCamera = camera;

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

public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, now tell the camera where to draw the preview.
    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();
    } catch (IOException e) {
        Log.d("TAG", "Error setting camera preview: " + e.getMessage());
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // empty. Take care of releasing the Camera preview in your activity.
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // 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
    }

    // set preview size and make any resize, rotate or
    // reformatting changes here

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

    } catch (Exception e){
        Log.d("TAG", "Error starting camera preview: " + e.getMessage());
    }
}

}

我的接收器类,我在其中调用 MainActivity 类的 takeP() 方法:

public class Receiver extends BroadcastReceiver {
// Constructor is mandatory
public Receiver ()
{
    super ();
}

@Override
public void onReceive(Context context, Intent intent) {

    if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
        KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
        int key = event.getKeyCode();
        switch (key) {
            case KeyEvent.KEYCODE_BREAK:
            case KeyEvent.KEYCODE_MEDIA_PLAY:
            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
            case KeyEvent.KEYCODE_MEDIA_STOP:
            case KeyEvent.KEYCODE_HEADSETHOOK:
                MainActivity.takeP();
                break;
            default:
                break;
        }

    }
}

}

我的逻辑:

10-30 20:10:43.257 28252-28252/? E/AndroidRuntime: FATAL EXCEPTION: main
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime: Process: com.garanal.photoclick, PID: 28252
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime: java.lang.RuntimeException: Unable to start receiver com.garanal.photoclick.Receiver: java.lang.RuntimeException: takePicture failed
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.app.ActivityThread.handleReceiver(ActivityThread.java:2680)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.app.ActivityThread.access$1700(ActivityThread.java:156)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1428)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:211)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5389)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:  Caused by: java.lang.RuntimeException: takePicture failed
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.hardware.Camera.native_takePicture(Native Method)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.hardware.Camera.takePicture(Camera.java:1475)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.hardware.Camera.takePicture(Camera.java:1420)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at com.garanal.photoclick.MainActivity.takeP(MainActivity.java:82)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at com.garanal.photoclick.Receiver.onReceive(Receiver.java:33)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.app.ActivityThread.handleReceiver(ActivityThread.java:2673)
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.app.ActivityThread.access$1700(ActivityThread.java:156) 
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1428) 
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102) 
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:211) 
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5389) 
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method) 
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372) 
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020) 
10-30 20:10:43.257 28252-28252/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815) 

感谢您给我的任何帮助以及来自哥伦比亚麦德林的问候。

4

0 回答 0