[Android] Camera App crashes when run

Click For Summary

Discussion Overview

The discussion revolves around an issue with an Android application that crashes when attempting to run a camera feature. Participants are exploring the implementation of camera functionality, including taking and saving pictures, while addressing potential errors in the code provided.

Discussion Character

  • Technical explanation
  • Exploratory
  • Debate/contested

Main Points Raised

  • One participant describes their attempt to implement camera functionality using Java and Android APIs, expressing uncertainty about the cause of the crash.
  • The provided code includes a CameraActivity and a CameraPreview class, with specific methods for taking pictures and managing camera resources.
  • Another participant notes the absence of a stack trace, suggesting that this information could help diagnose the issue.
  • Concerns are raised about the permissions and features declared in the manifest file, particularly regarding camera access and external storage.
  • Some participants propose checking for proper initialization of the camera and ensuring that the SurfaceView is correctly set up before starting the camera preview.

Areas of Agreement / Disagreement

There is no consensus on the specific cause of the crash, and multiple viewpoints regarding potential issues and solutions are present in the discussion.

Contextual Notes

Participants have not provided a stack trace, which may limit the ability to diagnose the problem effectively. There are also unresolved questions regarding the handling of camera permissions and the lifecycle of the camera object.

Yoyo_Guru
Messages
32
Reaction score
0
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:
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:
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] 
          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:
Technology news on Phys.org
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.
 
Ibix said:
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.

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.
 
Ibix said:
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.

Here is logcat errors.
Code:
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)
 
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.
 
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.
 
Ibix said:
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.

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.
 

Similar threads

Replies
3
Views
3K
Replies
11
Views
3K
  • · Replies 1 ·
Replies
1
Views
2K
Replies
4
Views
3K
  • · Replies 1 ·
Replies
1
Views
4K
Replies
1
Views
2K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
1K