0

I'm developing android app (my semester work in university) - so I finally stacked - I'm very bad in programming (just started). I know, that this problem was solved here Taking picture from camera without preview and here Background Service to take picture with Camera. But neither of it didn't help me (yeah, I'm so dummy). So, at the moment I have only this Main class:

public class MainActivity extends Activity {

public static SurfaceView surfaceView;
public static SurfaceHolder surfaceHolder;
public static Camera camera;
final String LOG_TAG = "myLogs";

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    Log.d(LOG_TAG, "onCreateMain");
    setContentView(R.layout.main);

    surfaceView = (SurfaceView) findViewById(R.id.surface);
    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            try {
                camera.setPreviewDisplay(holder);
                camera.startPreview();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format,
                                   int width, int height) {
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
        }
    });
}

public void Start(View view){
    startService(new Intent(this, MyService.class));
    Log.d(LOG_TAG, "onStartMain");
    finish();
}

public void Stop(View view){
    stopService(new Intent(this, MyService.class));}
}

And here is Service class:

public class MyService extends Service {

private Camera camera = MainActivity.camera;
private SurfaceView surfaceView = MainActivity.surfaceView;
private SurfaceHolder surfaceHolder = MainActivity.surfaceHolder;
File photoFile;
final String LOG_TAG = "myLogs";

@Override
public void onCreate(){
    super.onCreate();
    Log.d(LOG_TAG, "onCreate");
    File pictures = Environment
            .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    photoFile = new File(pictures, "myphoto.jpg");
}

@Override
public int onStartCommand(Intent intent,int flags, int startId){
    Log.d(LOG_TAG, "onStartCommand");
    camera = Camera.open();
    takePicture();
    return super.onStartCommand(intent, flags, startId);
}

private void takePicture() {
    Log.d(LOG_TAG, "onTakePicture");
    camera.takePicture(null, null, new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            try {
                FileOutputStream fos = new FileOutputStream(photoFile);
                fos.write(data);
                fos.close();
                Log.d(LOG_TAG, "PictureTaken");
            } catch (Exception e) {
                Log.d(LOG_TAG,"Exception");
                e.printStackTrace();
            }
        }
    });
}

@Override
public void onDestroy(){
    Log.d(LOG_TAG, "onDestroy");
    releaseCamera();
    super.onDestroy();
}

private void releaseCamera() {
    if (camera != null)
        camera.release();
    camera = null;
}


@Override
public IBinder onBind(Intent intent) {
    return null;}
}

The program stacks after log

Log.d(LOG_TAG, "onTakePicture");

If I stop service - it's going OK (calls onDestroy()). The problem only that it doesn't take a picture or doesn't save it. There is no log message

Log.d(LOG_TAG, "PictureTaken");

So, can anybody help me to solve that problem?

Community
  • 1
  • 1

1 Answers1

0

I haven't run your code, but I think you should remove the finish() call in MainActivity.Start() since this forces the application to close. The picture is not taken immediately and you have to wait for the callback call onPictureTaken() that you have in the Service class.

Radu Ionescu
  • 3,462
  • 5
  • 24
  • 43
  • Sorry, unrelated to what you have written: Did I get that right that Camera works only through Surface View? If so, is the only way to make SurfaceView to work is by giving access to UI-thread? – Yero Baimuratov Jan 10 '16 at 20:35
  • You need a 'SurfaceView' to render the preview from the camera (mostly for privacy reasons). Since your Service is run in the same context as the MainActivity the calls to the 'Camera' object are sufficient and will handle rendering the preview for you. – Radu Ionescu Jan 11 '16 at 08:23