问题
I am new to android app development so please any answers would be great with code examples.
My problem is this, I have to develop a camera app that streams mjpeg to a server.
Now I have successfully created the app for my Motorola Atrix and that works great. My problem is after I signed and exported that app and installed it on an HTC Thunderbolt for additional device testing, I found that it freezes when I try to call for the camera and the app crashes.
Since then I have tried every example/sample code for camera preview on the web and in these forums especially and I constantly get the same results. I get it to work on my Atrix but not on the thunderbolt.
When the app runs on the thunderbolt I get this:
07-01 16:11:12.643: D/AndroidRuntime(1140): Shutting down VM
07-01 16:11:12.643: W/dalvikvm(1140): threadid=1: thread exiting with uncaught exception (group=0x40015560)
07-01 16:11:12.653: E/AndroidRuntime(1140): FATAL EXCEPTION: main
07-01 16:11:12.653: E/AndroidRuntime(1140): java.lang.RuntimeException: Fail to connect to camera service
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.hardware.Camera.native_setup(Native Method)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.hardware.Camera.<init>(Camera.java:258)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.hardware.Camera.open(Camera.java:235)
07-01 16:11:12.653: E/AndroidRuntime(1140): at vcore.java.MainActivity.surfaceCreated(MainActivity.java:95)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.view.SurfaceView.updateWindow(SurfaceView.java:543)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.view.SurfaceView.dispatchDraw(SurfaceView.java:348)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.view.View.draw(View.java:6883)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.widget.FrameLayout.draw(FrameLayout.java:357)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.view.View.draw(View.java:6883)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.widget.FrameLayout.draw(FrameLayout.java:357)
07-01 16:11:12.653: E/AndroidRuntime(1140): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1862)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.view.ViewRoot.draw(ViewRoot.java:1522)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.view.ViewRoot.performTraversals(ViewRoot.java:1258)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.os.Handler.dispatchMessage(Handler.java:99)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.os.Looper.loop(Looper.java:123)
07-01 16:11:12.653: E/AndroidRuntime(1140): at android.app.ActivityThread.main(ActivityThread.java:3683)
07-01 16:11:12.653: E/AndroidRuntime(1140): at java.lang.reflect.Method.invokeNative(Native Method)
07-01 16:11:12.653: E/AndroidRuntime(1140): at java.lang.reflect.Method.invoke(Method.java:507)
07-01 16:11:12.653: E/AndroidRuntime(1140): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
07-01 16:11:12.653: E/AndroidRuntime(1140): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
07-01 16:11:12.653: E/AndroidRuntime(1140): at dalvik.system.NativeStart.main(Native Method)
I emailed HTC themselves and they said they couldn't help me at all so I figured I would try my luck here.
Does anyone know how to properly call the camera (for a camera preview) for an HTC Thunderbolt?
If you could provide code example I would be eternally grateful.
Just some examples of the things I have tried are:
https://stackoverflow.com/a/4798958/1195751
HTC Desire HD not accepts setParameter() with hardware.Camera This also didn't work
Android: Camera Preview Orientation on HTC EVO (Android 2.1 or 2.2) Neither Did this
I have really tried everything to solve this but haven't gotten anything to work so please, any solution to this problem would be extremely helpful.
UPDATE I already have the permissions set in my manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="vcore.java"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"></uses-permission>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.FLASHLIGHT"
android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
android:protectionLevel="normal"/>
<uses-feature android:name="android.hardware.camera.flash" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"></uses-permission>
<uses-permission android:name="android.permission.RECORD_VIDEO"></uses-permission>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true" />
<application
android:icon="@drawable/logo"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".MainActivity"
android:screenOrientation="portrait" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".PushCamera"
android:label="@string/app_name">
<!-- android:screenOrientation="portrait" -->
</activity>
<activity android:name="ImageDisplayActivity"></activity>
</application>
</manifest>
UPDATE 2
public void surfaceCreated(SurfaceHolder holder) {
try {
if (mCamera != null) {
try {
mCamera.stopPreview();
} catch (Exception ignore) {
}
try {
mCamera.release();
} catch (Exception ignore) {
}
mCamera = null;
}
mCamera = Camera.open();
mCamera.setPreviewDisplay(holder);
} catch (Exception ex) {
try {
if (mCamera != null) {
try {
mCamera.stopPreview();
} catch (Exception ignore) {
}
try {
mCamera.release();
} catch (Exception ignore) {
}
mCamera = null;
}
} catch (Exception ignore) {
}
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
try {
if (mCamera != null) {
try {
mCamera.stopPreview();
} catch (Exception ignore) {
}
try {
mCamera.release();
} catch (Exception ignore) {
}
mCamera = null;
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.e(TAG, "surfaceChanged");
try {
Camera.Parameters parameters = mCamera.getParameters();
try {
List<Camera.Size> supportedSizes = null;
//On older devices (<1.6) the following will fail
//the camera will work nevertheless
supportedSizes = parameters.getSupportedPreviewSizes();
//preview form factor
float ff = (float)w/h;
Log.d("Mixare", "Screen res: w:"+ w + " h:" + h + " aspect ratio:" + ff);
//holder for the best form factor and size
float bff = 0;
int bestw = 0;
int besth = 0;
Iterator<Camera.Size> itr = supportedSizes.iterator();
//we look for the best preview size, it has to be the closest to the
//screen form factor, and be less wide than the screen itself
//the latter requirement is because the HTC Hero with update 2.1 will
//report camera preview sizes larger than the screen, and it will fail
//to initialize the camera
//other devices could work with previews larger than the screen though
while(itr.hasNext()) {
Camera.Size element = itr.next();
//current form factor
float cff = (float)element.width/element.height;
//check if the current element is a candidate to replace the best match so far
//current form factor should be closer to the bff
//preview width should be less than screen width
//preview width should be more than current bestw
//this combination will ensure that the highest resolution will win
Log.d("Mixare", "Candidate camera element: w:"+ element.width + " h:" + element.height + " aspect ratio:" + cff);
if ((ff-cff <= ff-bff) && (element.width <= w) && (element.width >= bestw)) {
bff=cff;
bestw = element.width;
besth = element.height;
}
}
Log.d("Mixare", "Chosen camera element: w:"+ bestw + " h:" + besth + " aspect ratio:" + bff);
//Some Samsung phones will end up with bestw and besth = 0 because their minimum preview size is bigger then the screen size.
//In this case, we use the default values: 480x320
if ((bestw == 0) || (besth == 0)){
Log.d("Mixare", "Using default camera parameters!");
bestw = 480;
besth = 320;
}
parameters.setPreviewSize(bestw, besth);
} catch (Exception ex) {
parameters.setPreviewSize(480 , 320);
}
mCamera.setParameters(parameters);
mCamera.startPreview();
} catch (Exception ex) {
ex.printStackTrace();
}
}
回答1:
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (isPreviewRunning) {
camera.stopPreview();
}
try{
Camera.Parameters p = camera.getParameters();
if(p!=null){
List<Size> sizes = p.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, w, h);
p.setPreviewSize(optimalSize.width, optimalSize.height);
camera.setParameters(p);
camera.setPreviewDisplay(holder);;
camera.startPreview();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
isPreviewRunning = true;
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
// TODO Auto-generated method stub
final double ASPECT_TOLERANCE = 0.05;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
Put this code in your surfaceChanged(). getOptimalPreviewSize() is used to set preview parameters according to device resolution. So it will not crash when camera preview is opened. Try this. This works good for me in different devices.
回答2:
You need to give permission to use camera in androidmanifest.xml.
<uses-permission android:name=”android.permission.CAMERA”/>
来源:https://stackoverflow.com/questions/9197331/cannot-get-camera-preview-call-camera-htc-thunderbolt