1

I am working on school project and I want to use camera flash in it. Everything worked properly, while I didn't try to take a picture with camera in another activity.I am almost sure it's problem with wrong freeing of resources.I am looking for solution for hours and my code seems to be fine.Thanks in advance.

Here's my code:

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;

}
}

And the stack trace:

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) 
peter21
  • 81
  • 9
  • Use LogCat to examine the Java stack trace associated with your crash: https://stackoverflow.com/questions/23353173/unfortunately-myapp-has-stopped-how-can-i-solve-this We may not be able to help you without seeing the entire stack trace. – CommonsWare Dec 15 '15 at 16:08
  • Thanks for reply. I've already edited my post. – peter21 Dec 15 '15 at 16:21
  • You've got a NullPointerException here at line 449. Check it – MikeKeepsOnShine Dec 15 '15 at 16:40

1 Answers1

0

You should init your variables to null or a proper initial value.

 android.hardware.Camera cam=null;

You are accesing cam in releaseCameraAndPreview() without previous initialization. You should check if it has been previously inited.

private void releaseCameraAndPreview() {
   if(cam!=null)
   {
    cam.stopPreview();
    cam.release();
    cam = null;
   }
}
juanlugm
  • 155
  • 1
  • 11
  • Thanks. This is exactly I did, but anyway Camera throws exception Fail to connect to camera service. Seems like it was not available or in use of another application. – peter21 Dec 15 '15 at 16:58