2012-06-20 5 views
3

Итак, я пытался следить за http://developer.android.com/guide/topics/media/camera.html, чтобы создать простое приложение, которое захватывает видео и аудио и сохраняет файл на SD-карте. и преуспели. с помощью про андроид 4 (довольно приличной книги)Следующее руководство по созданию приложения для камеры, получение ошибок. Android-sdk

Вот GitHub репо с кодом: https://github.com/androidAwesome/Android-Camcorder

С помощью Сэма, спасибо еще раз !, У меня есть рабочая копия приложения камеры, которая могут быть настроены. Документация немного дрожащая, и я думаю, что она отсутствует в методе prepareVideoREcorder(). Должен быть mCamera.stopPreview(); перед вызовом mCamera.unlock(). Надеюсь, вам не удастся создать проект андроида, добавить класс для SurfaceView, а затем скопировать все здесь и иметь рабочее приложение для видеокамеры, которое вы можете продолжать настраивать!

манифеста:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.camera123.cr" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk android:minSdkVersion="8" /> 

    <uses-permission android:name="android.permission.CAMERA" /> 
    <uses-feature android:name="android.hardware.camera" /> 
    <uses-permission android:name="android.permission.RECORD_AUDIO" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.RECORD_VIDEO" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:name=".Camera123" 
      android:label="@string/app_name" 

      android:screenOrientation="landscape"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

cameraPreview.java:

package com.camera123.cr; 

import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.hardware.Camera; 
import android.hardware.Camera.PreviewCallback; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 

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("DEBUG", "Error setting camera preview: " + e.getMessage()); 
     } 


    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 

    } 

    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("DEBUG", "Error starting camera preview: " + e.getMessage()); 
     } 
    } 
} 

main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="horizontal" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    > 
    <FrameLayout 
    android:id="@+id/camera_preview" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:layout_weight="1" 
    /> 

    <Button 
    android:id="@+id/button_capture" 
    android:text="Capture" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    /> 
</LinearLayout> 

Camera123.java:

package com.camera123.cr; 

import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

import android.app.Activity; 
import android.app.SearchManager.OnCancelListener; 
import android.hardware.Camera; 
import android.hardware.Camera.PictureCallback; 
import android.hardware.Camera.ShutterCallback; 
import android.media.CamcorderProfile; 
import android.media.MediaRecorder; 
import android.net.Uri; 
import android.os.Bundle; 
import android.os.Environment; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.FrameLayout; 

public class Camera123 extends Activity{ 
    /** Called when the activity is first created. */ 
private Camera mCamera; 
    private CameraPreview mPreview; 
    private MediaRecorder mMediaRecorder; 
    private boolean isRecording = false; 
    private Button captureButton; 

    public static final int MEDIA_TYPE_IMAGE = 1; 
    public static final int MEDIA_TYPE_VIDEO = 2; 



    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     // Create an instance of Camera 
     mCamera = getCameraInstance(); 

     // Create our Preview view and set it as the content of our activity. 
     mPreview = new CameraPreview(this, mCamera); 

     captureButton = (Button) findViewById(R.id.button_capture); 
     FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); 
     preview.addView(mPreview); 


     captureButton.setOnClickListener(
       new View.OnClickListener() { 
        public void onClick(View v) { 
         if (isRecording) { 
          // stop recording and release camera 
          mMediaRecorder.stop(); // stop the recording 
          releaseMediaRecorder(); // release the MediaRecorder object 
          mCamera.lock();   // take camera access back from MediaRecorder 

          // inform the user that recording has stopped 
          captureButton.setText("Capture"); 
          isRecording = false; 
         } else { 
          // initialize video camera 
          if (prepareVideoRecorder()) { 
           // Camera is available and unlocked, MediaRecorder is prepared, 
           // now you can start recording 
           mMediaRecorder.start(); 

           // inform the user that recording has started 
           captureButton.setText("Stop"); 
           isRecording = true; 
          } else { 
           // prepare didn't work, release the camera 
           releaseMediaRecorder(); 
           // inform user 
          } 
         } 
        } 
       } 
     ); 
    } 






    /** A safe way to get an instance of the Camera object. */ 
    public static Camera getCameraInstance(){ 
     Camera c = null; 
     try { 
     c = Camera.open(); // attempt to get a Camera instance 
     if (c != null){ 
      Camera.Parameters params = c.getParameters(); 
      c.setParameters(params); 
     } 
    } 
    catch (Exception e){ 
     Log.d("DEBUG", "Camera did not open"); 
     // Camera is not available (in use or does not exist) 
    } 
     return c; // returns null if camera is unavailable 
    } 

    private boolean prepareVideoRecorder(){ 


     mMediaRecorder = new MediaRecorder(); 

     // Step 1: Unlock and set camera to MediaRecorder 
     mCamera.stopPreview(); 
     mCamera.unlock(); 
     mMediaRecorder.setCamera(mCamera); 

     // Step 2: Set sources 
     mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); 
     mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 



     // Step 3: Set a CamcorderProfile (requires API Level 8 or higher) 
     mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); 


     // Step 4: Set output file 
     mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()); 

     // Step 5: Set the preview output 
     mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface()); 

     // Step 6: Prepare configured MediaRecorder 
     try { 
      mMediaRecorder.prepare(); 
     } catch (IllegalStateException e) { 
      Log.d("DEBUG", "IllegalStateException preparing MediaRecorder: " + e.getMessage()); 
      releaseMediaRecorder(); 
      return false; 
     } catch (IOException e) { 
      Log.d("DEBUG", "IOException preparing MediaRecorder: " + e.getMessage()); 
      releaseMediaRecorder(); 
      return false; 
     } 
     return true; 
    } 

    /** Create a file Uri for saving an image or video */ 
    private static Uri getOutputMediaFileUri(int type){ 
      return Uri.fromFile(getOutputMediaFile(type)); 
    } 

    private static File getOutputMediaFile(int type){ 
     // 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), "MyCameraApp"); 
     // This location works best if you want the created images to be shared 
     // between applications and persist after your app has been uninstalled. 

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

     // Create a media file name 
     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
     File mediaFile; 
     if (type == MEDIA_TYPE_IMAGE){ 
      mediaFile = new File(mediaStorageDir.getPath() + File.separator + 
      "IMG_"+ timeStamp + ".jpg"); 
     } else if(type == MEDIA_TYPE_VIDEO) { 
      mediaFile = new File(mediaStorageDir.getPath() + File.separator + 
      "VID_"+ timeStamp + ".mp4"); 
     } else { 
      return null; 
     } 

     return mediaFile; 
    } 

    @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 (mMediaRecorder != null) { 
      mMediaRecorder.reset(); // clear recorder configuration 
      mMediaRecorder.release(); // release the recorder object 
      mMediaRecorder = null; 
      mCamera.setPreviewCallback(null); 
      mCamera.lock();   // lock camera for later use 
     } 
    } 

    private void releaseCamera(){ 
     if (mCamera != null){ 
      isRecording = false; 
      mCamera.stopPreview(); 
     mCamera.setPreviewCallback(null); 
      mCamera.release();  // release the camera for other applications 
      mCamera = null; 
     } 
    } 
}  
+1

Пустой указатель Исключение говорит вам строку, где произошла ошибка, пожалуйста, напишите весь LogCat след, если вам нужна помощь. – Sam

ответ

2

Я думаю, что вам нужно изменить:

Button captureButton = (Button) findViewById(R.id.button_capture); 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); 
    preview.addView(mPreview); 

    setContentView(R.layout.main); 
    ... 

к:

Button captureButton; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    captureButton = (Button) findViewById(R.id.button_capture); 
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); 
    preview.addView(mPreview); 

Ваша активность не может найти вид, пока не указать файл XML или макет смотреть в с setContentView().

Добавление

Вы, кажется, есть несколько ошибок при резке & оклейки вам код. Попробуйте изменить это:

super.onCreate(savedInstanceState); 


// Create an instance of Camera 
mCamera = getCameraInstance(); // Setting this too early! 
setContentView(R.layout.main); 

// Create our Preview view and set it as the content of our activity. 
mPreview = new CameraPreview(this, mCamera); 
captureButton = (Button) findViewById(R.id.button_capture); 
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); 
preview.addView(mPreview); 

setContentView(R.layout.main); // Duplicate code that will cause lots of trouble 

к этому:

super.onCreate(savedInstanceState); 
setContentView(R.layout.main); 

// Create an instance of Camera 
mCamera = getCameraInstance(); 

// Create our Preview view and set it as the content of our activity. 
mPreview = new CameraPreview(this, mCamera); 
captureButton = (Button) findViewById(R.id.button_capture); 
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); 
preview.addView(mPreview); 

Если это помогает, пожалуйста, отметьте ответ как правильный. Если у вас больше ошибок, проверьте, как вы вырезаете &, вставляя свой код, и если вы не можете найти его, не стесняйтесь публиковать новый вопрос. Удачи!

+0

Те же ошибки, но спасибо за ответ! – androidAwesome

+0

Да, я заметил, что вы пытаетесь использовать findViewById() неправильно более одного раза ... Я обновил свой ответ. – Sam

+0

Это был билет, однако я все еще испытываю новую ошибку. Ошибка startPreview. его жалоба на эту строку CameraPreview: mCamera.startPreview(); – androidAwesome

0

Я скомпилировал и запустил код на Droid X 2.3.4, где он сработает.
Он устанавливает mCamera = null поскольку getCameraInstance() возвращает null во второй раз, когда он вызывается.
Другие места в коде не проверяют значение null, поэтому вы получаете ошибки.
CameraPreview: mCamera.startPreview(); упомянутый выше. Попробуйте это:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    // Create an instance of Camera 
    if(mCamera==null) 
     mCamera = getCameraInstance();