Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

[Android] Camera App crashes when run

  1. Jul 26, 2012 #1
    I am working on an android application that will need to take and store pictures. I'm familiar with java but not with the Android APIs. I tried to start by just including the functions for taking and saving an image using the information on the android developers page(Camera | Android Developers) however when I attempt to run the program it says it had to close. Install is successful though. My activity, preview class and manifest.xml are below. I do not want to use an intent because I will be displaying images and buttons over the preview and be adding buttons to interact wiht the camera. I would really appreciate it if anyone could point out where the problem is or anything like that.

    Activity:

    Code (Text):


    import android.hardware.*;
    import android.os.*;
    import android.app.*;
    import android.widget.*;
    import android.view.*;
    import android.net.*;
    import java.io.*;
    import android.util.*;
    import java.text.*;
    import java.util.*;
    import android.hardware.Camera.*;
    public class ConverterActivity extends Activity
    {
        private Camera mCamera;
        private CameraPreview mPreview;
    private PictureCallback mPicture = new PictureCallback() {
    private String TAG;
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
    File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
    if (pictureFile == null){
    // Log.d(TAG, "Error creating media file, check storage permissions: " +
    //  e.getMessage());
    return;
    }
    try {
    FileOutputStream fos = new FileOutputStream(pictureFile);
    fos.write(data);
    fos.close();
    } catch (FileNotFoundException e) {
    Log.d(TAG, "File not found: " + e.getMessage());
    } catch (IOException e) {
    Log.d(TAG, "Error accessing file: " + e.getMessage());
    }
    }
    };
     
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
     
    // Add a listener to the Capture button
    Button captureButton = (Button) findViewById(R.id.button_capture);
    captureButton.setOnClickListener(
    new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    // get an image from the camera
    mCamera.takePicture(null, null, mPicture);
    }
    }
    );
            // Create an instance of Camera
            mCamera = Camera.open(this.getBackCamera());
            // 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);
    }
    @Override
        protected void onPause()
        {
            super.onPause();
            releaseCamera();              // release the camera immediately on pause event
        }
        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;
    }
    public int getBackCamera()
    {
    int numCameras = Camera.getNumberOfCameras();
    CameraInfo cInfo = new CameraInfo();
    for (int i = 0; i < numCameras; i++)
    {
    Camera.getCameraInfo(i, cInfo);
    if (cInfo.facing == CameraInfo.CAMERA_FACING_BACK)
    {
    return i;
    }
    }
    return -1;
    }
    }
     


    Camera Preview:

    Code (Text):

    import android.view.*;
    import android.hardware.Camera.*;
    import android.hardware.*;
    import android.content.*;
    import java.io.*;  
     
    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
        private SurfaceHolder mHolder;
        private Camera mCamera;
     
        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());
            }
        }
    }
     


    Manifest.xml

    PHP:
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="[PLAIN]http://schemas.android.com/apk/res/android"[/PLAIN] [Broken]
              package="your.Converter"
              android:versionCode="1"
              android:versionName="1.0" >
         <uses-sdk android:minSdkVersion="10" />
       <uses-permission android:name="android.permissions.CAMERA" />
       <uses-feature android:name="android.hardware.camera" />
       <uses-feature android:name="android.hardware.camera.autofocus" />
         <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
       <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
         <activity
          android:name=".ConverterActivity"
          android:label="@string/app_name"
          android:screenOrientation="landscape">
                    <intent-filter>
             <action android:name="android.intent.action.MAIN" />
             <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
         </activity>
       </application>
       </manifest>
     
    Last edited by a moderator: May 6, 2017
  2. jcsd
  3. Jul 26, 2012 #2

    Ibix

    User Avatar
    Science Advisor

    You haven't posted a stack trace, so I'm going to guess that you're having a problem on start-up. The Eclipse plugin (at least for me) doesn't seem to display a useful stack trace in that case - it's all Android internals. However, if you tell it to resume execution (there's a button in the Eclipse toolbar, from memory) your program finishes crashing, and the useful bit of the stack trace appears in the logcat window. You may need to scroll up a bit.
     
  4. Jul 26, 2012 #3
    Actually I was using AIDE, and ide on the android, it shows logcat but does not have a way of exporting it. I will run app in eclipse when I get home tonight and add stack trace. I was testing on my phone because I did not know how the virtual device in eclipse would deal with the camera.
     
  5. Jul 26, 2012 #4
    Here is logcat errors.
    Code (Text):

    E(  167) Permission Denial: can't use the camera pid=9354, uid=10009  (CameraService)
    E( 9354) FATAL EXCEPTION: main  (AndroidRuntime)
    E( 9354) java.lang.RuntimeException: Unable to start activity ComponentInfo{your.Converter/your.Converter.ConverterActivity}: java.lang.RuntimeException: Fail to connect to camera service  (AndroidRuntime)
    E( 9354) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2049)  (AndroidRuntime)
    E( 9354) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2083)  (AndroidRuntime)
    E( 9354) at android.app.ActivityThread.access$600(ActivityThread.java:134)  (AndroidRuntime)
    E( 9354) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1233)  (AndroidRuntime)
    E( 9354) at android.os.Handler.dispatchMessage(Handler.java:99)  (AndroidRuntime)
    E( 9354) at android.os.Looper.loop(Looper.java:137)  (AndroidRuntime)
    E( 9354) at android.app.ActivityThread.main(ActivityThread.java:4697)  (AndroidRuntime)
    E( 9354) at java.lang.reflect.Method.invokeNative(Native Method)  (AndroidRuntime)
    E( 9354) at java.lang.reflect.Method.invoke(Method.java:511)  (AndroidRuntime)
    E( 9354) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)  (AndroidRuntime)
    E( 9354) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)  (AndroidRuntime)
    E( 9354) at dalvik.system.NativeStart.main(Native Method)  (AndroidRuntime)
    E( 9354) Caused by: java.lang.RuntimeException: Fail to connect to camera service  (AndroidRuntime)
    E( 9354) at android.hardware.Camera.native_setup(Native Method)  (AndroidRuntime)
    E( 9354) at android.hardware.Camera.<init>(Camera.java:317)  (AndroidRuntime)
    E( 9354) at android.hardware.Camera.open(Camera.java:274)  (AndroidRuntime)
    E( 9354) at your.Converter.ConverterActivity.onCreate(ConverterActivity.java)  (AndroidRuntime)
    E( 9354) at android.app.Activity.performCreate(Activity.java:4539)  (AndroidRuntime)
    E( 9354) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)  (AndroidRuntime)
    E( 9354) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2013)  (AndroidRuntime)
    E( 9354) ... 11 more  (AndroidRuntime)
     
     
  6. Jul 26, 2012 #5
    Ok, I found the problem. I said in the manifest,
    <uses-permission android:name="android.permissions.CAMERA" />
    it should say android.permission, not android.permissions.
     
  7. Jul 26, 2012 #6

    Ibix

    User Avatar
    Science Advisor

    Ah. I did wonder if it was permissions, although I was just guessing because the browser on my Android phone isn't rendering the page properly, ironically enough. I always find those strings a risk because they aren't checked or auto-completed by the IDE. I recommend cut-and-paste where possible.

    As a side note, you can deploy to a phone from Eclipse just like the emulator. Turn on USB debugging on the phone, plug in and click run in Eclipse. Works on my phone, anyway.
     
  8. Jul 26, 2012 #7
    Yeah thanks, I had read about that before. Never got around to setting it up though. And I'm away from my desktop a lot, so it's just easier to do it in AIDE and transfer the files to my desktop or dropbox when I work in Eclipse.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook