我正在学校项目,我想在其中使用相机闪光灯。一切正常,虽然我没有尝试用相机在另一个活动中拍照。我几乎可以肯定这是错误释放资源的问题。我正在寻找解决方案几个小时,我的代码似乎很好。谢谢提前
这是我的代码:
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)
答案 0 :(得分:0)
您应该将变量初始化为null或正确的初始值。
android.hardware.Camera cam=null;
您正在访问releaseCameraAndPreview()中的cam,而无需事先初始化。 你应该检查它是否曾经被引入过。
private void releaseCameraAndPreview() {
if(cam!=null)
{
cam.stopPreview();
cam.release();
cam = null;
}
}