我正在尝试根据Android Developers' Camera page在Android Studio上构建一个相机应用。我目前在我的代码中没有错误,但是当我在模拟器或我的Android手机上运行它时,我看到一个按钮,但是当按下时,没有实时预览显示。请告诉我我的代码有什么问题:
package com.example.turboblaze99.humfess;
import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.FrameLayout;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class VideoRecorder extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_recorder);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_video_recorder, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/** 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
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private static final String TAG = "MyActivity";
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());
}
}
}
public class CameraActivity extends Activity {
private Camera mCamera;
private CameraPreview mPreview;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_recorder);
// 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);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
}
}
public class Humfess extends Activity {
private Camera mCamera;
private SurfaceView mPreview;
private MediaRecorder mMediaRecorder;
private boolean prepareVideoRecorder() throws IOException {
mCamera.open();
mCamera.setPreviewDisplay((SurfaceHolder) mPreview);
mCamera.startPreview();
mCamera = getCameraInstance();
mMediaRecorder = new MediaRecorder();
final String TAG = "MyActivity";
// Step 1: Unlock and set camera to MediaRecorder
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(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
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 (mMediaRecorder != null) {
mMediaRecorder.reset(); // clear recorder configuration
mMediaRecorder.release(); // release the recorder object
mMediaRecorder = null;
mCamera.lock(); // lock camera for later use
}
}
private void releaseCamera(){
if (mCamera != null){
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
}
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
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;
}
}
清单文件:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".VideoRecorder"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".VideoRecorder$CameraActivity"
android:label="@string/app_name"
android:screenOrientation="landscape">
<!-- configure this activity to use landscape orientation -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
xml文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_video_recorder"
tools:context="com.example.turboblaze99.humfess.VideoRecorder">
<TextView
android:text="Hello World!"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<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>
</RelativeLayout>
03-23 11:44:27.060 31086-31086/com.example.turboblaze99.humfess D/dalvikvm: Late-enabling CheckJNI
03-23 11:44:27.380 31086-31086/com.example.turboblaze99.humfess W/dalvikvm: VFY: unable to find class referenced in signature (Landroid/view/SearchEvent;)
03-23 11:44:27.380 31086-31086/com.example.turboblaze99.humfess I/dalvikvm: Could not find method android.view.Window$Callback.onSearchRequested, referenced from method android.support.v7.view.WindowCallbackWrapper.onSearchRequested
03-23 11:44:27.380 31086-31086/com.example.turboblaze99.humfess W/dalvikvm: VFY: unable to resolve interface method 18839: Landroid/view/Window$Callback;.onSearchRequested (Landroid/view/SearchEvent;)Z
03-23 11:44:27.380 31086-31086/com.example.turboblaze99.humfess D/dalvikvm: VFY: replacing opcode 0x72 at 0x0002
03-23 11:44:27.380 31086-31086/com.example.turboblaze99.humfess I/dalvikvm: Could not find method android.view.Window$Callback.onWindowStartingActionMode, referenced from method android.support.v7.view.WindowCallbackWrapper.onWindowStartingActionMode
03-23 11:44:27.380 31086-31086/com.example.turboblaze99.humfess W/dalvikvm: VFY: unable to resolve interface method 18843: Landroid/view/Window$Callback;.onWindowStartingActionMode (Landroid/view/ActionMode$Callback;I)Landroid/view/ActionMode;
03-23 11:44:27.380 31086-31086/com.example.turboblaze99.humfess D/dalvikvm: VFY: replacing opcode 0x72 at 0x0002
03-23 11:44:27.560 31086-31086/com.example.turboblaze99.humfess I/dalvikvm: Could not find method android.content.res.TypedArray.getChangingConfigurations, referenced from method android.support.v7.widget.TintTypedArray.getChangingConfigurations
03-23 11:44:27.560 31086-31086/com.example.turboblaze99.humfess W/dalvikvm: VFY: unable to resolve virtual method 415: Landroid/content/res/TypedArray;.getChangingConfigurations ()I
03-23 11:44:27.560 31086-31086/com.example.turboblaze99.humfess D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
03-23 11:44:27.560 31086-31086/com.example.turboblaze99.humfess I/dalvikvm: Could not find method android.content.res.TypedArray.getType, referenced from method android.support.v7.widget.TintTypedArray.getType
03-23 11:44:27.560 31086-31086/com.example.turboblaze99.humfess W/dalvikvm: VFY: unable to resolve virtual method 437: Landroid/content/res/TypedArray;.getType (I)I
03-23 11:44:27.560 31086-31086/com.example.turboblaze99.humfess D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
03-23 11:44:27.565 31086-31086/com.example.turboblaze99.humfess I/dalvikvm: Could not find method android.widget.LinearLayout$LayoutParams.<init>, referenced from method android.support.design.widget.AppBarLayout$LayoutParams.<init>
03-23 11:44:27.565 31086-31086/com.example.turboblaze99.humfess W/dalvikvm: VFY: unable to resolve direct method 19358: Landroid/widget/LinearLayout$LayoutParams;.<init> (Landroid/widget/LinearLayout$LayoutParams;)V
03-23 11:44:27.565 31086-31086/com.example.turboblaze99.humfess D/dalvikvm: VFY: replacing opcode 0x70 at 0x0000
03-23 11:44:27.565 31086-31086/com.example.turboblaze99.humfess I/dalvikvm: Could not find method android.widget.LinearLayout$LayoutParams.<init>, referenced from method android.support.design.widget.AppBarLayout$LayoutParams.<init>
03-23 11:44:27.565 31086-31086/com.example.turboblaze99.humfess W/dalvikvm: VFY: unable to resolve direct method 19358: Landroid/widget/LinearLayout$LayoutParams;.<init> (Landroid/widget/LinearLayout$LayoutParams;)V
03-23 11:44:27.565 31086-31086/com.example.turboblaze99.humfess D/dalvikvm: VFY: replacing opcode 0x70 at 0x0000
03-23 11:44:27.765 31086-31086/com.example.turboblaze99.humfess D/libEGL: loaded /system/lib/egl/libEGL_mali.so
03-23 11:44:27.775 31086-31086/com.example.turboblaze99.humfess D/libEGL: loaded /system/lib/egl/libGLESv1_CM_mali.so
03-23 11:44:27.775 31086-31086/com.example.turboblaze99.humfess D/libEGL: loaded /system/lib/egl/libGLESv2_mali.so
03-23 11:44:27.925 31086-31086/com.example.turboblaze99.humfess D/OpenGLRenderer: Enabling debug mode 0