Android Camera.open总是抛出异常

时间:2015-12-15 16:07:14

标签: android android-camera

我正在学校项目,我想在其中使用相机闪光灯。一切正常,虽然我没有尝试用相机在另一个活动中拍照。我几乎可以肯定这是错误释放资源的问题。我正在寻找解决方案几个小时,我的代码似乎很好。谢谢提前

这是我的代码:

package smart.tuke.sk.makac;
import ...


public class TrackerActivity extends ActionBarActivity implements ConnectionCallbacks,
    OnConnectionFailedListener, com.google.android.gms.location.LocationListener, SensorEventListener{
private long start;
private int wid;
private Location startLocation;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private Location mLastLocation;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private float totalDistance = 0;
private float distance;
private boolean isTracking;
private long lastPause;
private List<Location> locations;
private boolean firstLocation = false;
private DBHelper helper;
private boolean stopped;
long elapsedTime = 0L;
long startTime = 0L;
private SensorManager mSensorManager;
private Sensor mStepCounterSensor;
private Sensor mStepDetectorSensor;
private boolean cameraIsOn = false;
private boolean asked = false;
android.hardware.Camera cam;
android.hardware.Camera.Parameters p;
private boolean cameraIsOpened;


Handler handler = new Handler();
Runnable runnable = new Runnable() {
    public void run() {
            TextView time = (TextView) findViewById(R.id.time);
            time.setText(formatTime(System.currentTimeMillis() - startTime));
            if((System.currentTimeMillis()/1000) >5000 && !cameraIsOn && !asked) {
                Intent intent = new Intent();
                intent.setAction("smart.tuke.sk.makac.nightDetected");
                sendBroadcast(intent);
                asked = true;
            }
            if(cameraIsOn && cameraIsOpened) {
                p.setFlashMode(android.hardware.Camera.Parameters.FLASH_MODE_TORCH);
                cam.setParameters(p);
                cam.startPreview();

            }
            handler.postDelayed(this, 0);

    }
};

private BroadcastReceiver nightReciever = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        TrackerActivity.this.received();
    }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    isTracking = false;
    setContentView(R.layout.activity_tracker);

    TextView time = (TextView) findViewById(R.id.time);
    time.setText(formatTime(0L));

    TextView distance = (TextView) findViewById(R.id.distance);
    distance.setText("0,00 m");
    locations = new ArrayList<Location>();
    helper = new DBHelper(this);
    buildGoogleApiClient();
    createLocationRequest();
    mGoogleApiClient.connect();
    if (checkPlayServices()) {
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    }
    mSensorManager = (SensorManager)
            getSystemService(Context.SENSOR_SERVICE);
    mStepCounterSensor = mSensorManager
            .getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
    mStepDetectorSensor = mSensorManager
            .getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
}
@Override
protected void onResume() {


    super.onResume();
    mGoogleApiClient.connect();
    mSensorManager.registerListener(this, mStepCounterSensor, SensorManager.SENSOR_DELAY_FASTEST);
    mSensorManager.registerListener(this, mStepDetectorSensor, SensorManager.SENSOR_DELAY_FASTEST);
    IntentFilter filter = new IntentFilter();
    filter.addAction("smart.tuke.sk.makac.nightDetected");
    this.registerReceiver(nightReciever, filter);
    cameraIsOpened = safeCameraOpen();
}
protected void onPause(Bundle savedInstanceState) {
    releaseCameraAndPreview();
    super.onPause();
    if(mGoogleApiClient.isConnected()) {
        stopLocationUpdates();
        mGoogleApiClient.disconnect();
    }
    mSensorManager.unregisterListener(this, mStepCounterSensor);
    this.unregisterReceiver(nightReciever);

}
@Override
public void onDestroy() {
    super.onDestroy();
    releaseCameraAndPreview();
    finish();
}

public void received() {
    PackageManager pm = getPackageManager();
    if(pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
        DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which){
                    case DialogInterface.BUTTON_POSITIVE:
                        cameraIsOn = true;
                        break;

                    case DialogInterface.BUTTON_NEGATIVE:
                        cameraIsOn = false;
                        break;
                }
            }
        };

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(getText(R.string.question)).setPositiveButton(getText(R.string.yes), dialogClickListener)
                .setNegativeButton(getText(R.string.no), dialogClickListener).show();
    }
}


@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_tracker, 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);
}


public void onStartClicked(View view) {
    startTime = System.currentTimeMillis() - elapsedTime;
    runnable.run();

    Button start = (Button) findViewById(R.id.start_button);
    Button reset = (Button) findViewById(R.id.reset_button);
    Button resume = (Button) findViewById(R.id.resume_button);
    Button pause = (Button) findViewById(R.id.pause_button);

    start.setVisibility(View.INVISIBLE);
    reset.setVisibility(View.INVISIBLE);
    resume.setVisibility(View.INVISIBLE);
    pause.setVisibility(View.VISIBLE);
    isTracking = true;
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
            mGoogleApiClient);
}

public void onPauseClicked(View view) {
    isTracking = false;
    elapsedTime = System.currentTimeMillis() - startTime;
    handler.removeCallbacks(runnable);

    Button start = (Button) findViewById(R.id.start_button);
    Button reset = (Button) findViewById(R.id.reset_button);
    Button resume = (Button) findViewById(R.id.resume_button);
    Button pause = (Button) findViewById(R.id.pause_button);

    pause.setVisibility(View.INVISIBLE);
    start.setVisibility(View.INVISIBLE);
    reset.setVisibility(View.VISIBLE);
    resume.setVisibility(View.VISIBLE);

    lastPause = SystemClock.elapsedRealtime();

    TextView distance = (TextView) findViewById(R.id.distance);
    if(checkPlayServices()) {

        Location  newLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    }
}


public void onResumeClicked(View view) {
    Button start = (Button) findViewById(R.id.start_button);
    Button reset = (Button) findViewById(R.id.reset_button);
    Button resume = (Button) findViewById(R.id.resume_button);
    Button pause = (Button) findViewById(R.id.pause_button);

    start.setVisibility(View.INVISIBLE);
    reset.setVisibility(View.INVISIBLE);
    resume.setVisibility(View.INVISIBLE);
    pause.setVisibility(View.VISIBLE);
    startTime = System.currentTimeMillis() - elapsedTime;
    runnable.run();
}

public void onResetClicked(View view) {
    Button start = (Button) findViewById(R.id.start_button);
    Button reset = (Button) findViewById(R.id.reset_button);
    Button resume = (Button) findViewById(R.id.resume_button);
    Button pause = (Button) findViewById(R.id.pause_button);
    TextView time = (TextView) findViewById(R.id.time);
    elapsedTime = 0L;
    time.setText(formatTime(0L));
    this.totalDistance = 0;
    TextView distance = (TextView) findViewById(R.id.distance);
    locations.clear();
    distance.setText("0,00 m");
    start.setVisibility(View.VISIBLE);
    reset.setVisibility(View.INVISIBLE);
    resume.setVisibility(View.INVISIBLE);
    pause.setVisibility(View.INVISIBLE);

    startLocationUpdates();
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

}

public void onStopClicked(View view) {

    Intent intent = new Intent(this, SummaryActivity.class);
    SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
    String date = sdf.format(new Date());
    TextView text = (TextView) findViewById(R.id.time);
    TextView distanceText = (TextView) findViewById(R.id.distance);
    Workout workout  = new Workout(date, text.getText().toString(),distance,0);
    helper.insertWorkout(workout);
    wid = helper.getLastWorkoutId();
    Log.v("WID", String.valueOf(wid));
    int i=1;
    for(Location location : locations) {
        helper.insertLocation(wid,i,location.getLatitude(),location.getLongitude());
        i++;
    }
    intent.putExtra("time", text.getText());
    intent.putExtra("distance", distanceText.getText());
    intent.putParcelableArrayListExtra("locations", (ArrayList<? extends Parcelable>) locations);
    startActivity(intent);
}



public long getStart() {
    return start;
}

public void setStart(long start) {
    this.start = start;
}

/**
 * Creating google api client object
 * */
protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API).build();
}

/**
 * Method to verify google play services on the device
 * */
private boolean checkPlayServices() {
    int resultCode = GooglePlayServicesUtil
            .isGooglePlayServicesAvailable(this);
    if (resultCode != ConnectionResult.SUCCESS) {
        if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
            GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                    PLAY_SERVICES_RESOLUTION_REQUEST).show();
        } else {
            Toast.makeText(getApplicationContext(),
                    "This device is not supported.", Toast.LENGTH_LONG)
                    .show();
            finish();
        }
        return false;
    }
    return true;
}    

@Override
public void onConnected(Bundle bundle) {
    startLocationUpdates();
  }

@Override
public void onConnectionSuspended(int i) {
    mGoogleApiClient.connect();
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}
protected void createLocationRequest() {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(1000);
    mLocationRequest.setFastestInterval(500);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
protected void startLocationUpdates() {
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}

@Override
public void onLocationChanged(Location location) {
    TextView distance  = (TextView) findViewById(R.id.distance);
    if(isTracking) {
        if(mLastLocation != null && firstLocation) {

        this.distance = location.distanceTo(mLastLocation);
        this.totalDistance += this.distance;
        distance.setText(String.format("%.2f m",this.totalDistance));
        }
    mLastLocation = location;
    locations.add(location);
    firstLocation = true;
    }
}
public String formatTime(long millis) {

    long second = (millis / 1000) % 60;
    long minute = (millis / (1000 * 60)) % 60;
    long hour = (millis / (1000 * 60 * 60)) % 24;
    millis = (millis % 1000);
    String time;
    if(hour >=1) {
         time = String.format("%02d:%02d:%02d", hour, minute, second);
    }else {
         time = String.format("%02d:%02d:%03d",  minute, second, millis);
    }

    return time;
}

@Override
public void onSensorChanged(SensorEvent event) {

    TextView textView = (TextView) findViewById(R.id.steps);
    Sensor sensor = event.sensor;
    float[] values = event.values;
    int value = -1;

    if (values.length > 0) {
        value = (int) values[0];
    }

    if (sensor.getType() == Sensor.TYPE_STEP_COUNTER) {
        Toast.makeText(getApplicationContext(),
                "ZMENA", Toast.LENGTH_LONG)
                .show();
        textView.setText("Step Counter Detected : " + value);
    }else if (sensor.getType() == Sensor.TYPE_STEP_DETECTOR) {
        // For test only. Only allowed value is 1.0 i.e. for step taken
        textView.setText("Step Detector Detected : " + value);
    }
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

private boolean safeCameraOpen() {
    boolean qOpened = false;

    try {
        releaseCameraAndPreview();
        cam = android.hardware.Camera.open();
        qOpened = (cam != null);
        p = cam.getParameters();
    } catch (Exception e) {
        Log.e(getString(R.string.app_name), "failed to open Camera");
        e.printStackTrace();
    }

    return qOpened;
}

private void releaseCameraAndPreview() {
    cam.stopPreview();
        cam.release();
        cam = null;

}
}

堆栈跟踪:

E/AndroidRuntime: FATAL EXCEPTION: main
     E/AndroidRuntime: Process: smart.tuke.sk.makac, PID: 5178
     E/AndroidRuntime: java.lang.RuntimeException: Unable to resume activity {smart.tuke.sk.makac/smart.tuke.sk.makac.TrackerActivity}: java.lang.NullPointerException
     E/AndroidRuntime:     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2964)
     E/AndroidRuntime:     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2993)
     E/AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2395)
     E/AndroidRuntime:     at android.app.ActivityThread.access$800(ActivityThread.java:151)
     E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)
     E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:110)
     E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:193)
     E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5292)
     E/AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method)
     E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:515)
     E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
     E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
     E/AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method)
     E/AndroidRuntime:  Caused by: java.lang.NullPointerException
     E/AndroidRuntime:     at smart.tuke.sk.makac.TrackerActivity.releaseCameraAndPreview(TrackerActivity.java:449)
     E/AndroidRuntime:     at smart.tuke.sk.makac.TrackerActivity.safeCameraOpen(TrackerActivity.java:441)
     E/AndroidRuntime:     at smart.tuke.sk.makac.TrackerActivity.onResume(TrackerActivity.java:141)
     E/AndroidRuntime:     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1197)
     E/AndroidRuntime:     at android.app.Activity.performResume(Activity.java:5343)
     E/AndroidRuntime:     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2950)
     E/AndroidRuntime:     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2993) 
     E/AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2395) 
     E/AndroidRuntime:     at android.app.ActivityThread.access$800(ActivityThread.java:151) 
     E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321) 
     E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:110) 
     E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:193) 
     E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5292) 
     E/AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method) 
     E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:515) 
     E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824) 
     E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640) 
     E/AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method) 

1 个答案:

答案 0 :(得分:0)

您应该将变量初始化为null或正确的初始值。

 android.hardware.Camera cam=null;

您正在访问releaseCameraAndPreview()中的cam,而无需事先初始化。 你应该检查它是否曾经被引入过。

private void releaseCameraAndPreview() {
   if(cam!=null)
   {
    cam.stopPreview();
    cam.release();
    cam = null;
   }
}