我在我的Zenfone 2,三星Galaxy S3,Nexus 7(2012)上使用自定义相机(包括后置摄像头和前置摄像头,甚至拍摄照片和录制视频),没有问题。
但是当尝试使用其他设备时,例如:Oppo,Sony Xperia M4,三星Galaxy S6。有一些问题:
Oppo:在我的应用程序中打开相机时发生崩溃,而默认的Oppo相机正常。
Sony xperia M4&三星galaxy S6:无法切换到前置摄像头。甚至,它挂了一段时间。但是,索尼和三星的默认相机都可以。
我的应用程序设置了以下代码以使用相机功能:
<uses-permission android:name = "android.permission.CAMERA" />
<activity
android:windowSoftInputMode = "adjustPan"
android:name = "ui.activity.camera.CustomCamera"
android:configChanges = "orientation|screenSize|keyboardHidden"
android:screenOrientation = "portrait" />
CustomCamera.java - 主要类
public class CustomCamera extends FragmentActivity {
/**
* Single ton section
*/
public static singleton.Camera camera = singleton.Camera.getInstance();
/**
* String section
*/
public static int current_orientation = 0;
/**
* View section
*/
public static Camera mCamera;
public static Camera.CameraInfo mCameraInfo =
new Camera.CameraInfo();
/**
* A safe way to get an instance of the Camera object.
*/
public static Camera getCameraInstance(int camera_id) {
Camera c = null;
try {
c = Camera.open(camera_id); // attempt to get a Camera instance
} catch (Exception e) {
// Camera is not available (in use or does not exist)
e.printStackTrace();
}
return c; // returns null if mCamera is unavailable
}
/** OnCreate method **/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_camera);
// Should initialize new Camera after released
mCamera = null;
initialCamera();
}
@Override
protected void onDestroy() {
super.onDestroy();
// Should release camera before go to the other page
// Because it need release for the other camera apps using camera,
// If it not release, current app will not allow the other app use
releaseCamera();
}
@Override
public void onPause() {
super.onPause();
// Should release camera before go to the other page
// Because it need release for the other camera apps using camera,
// If it not release, current app will not allow the other app use
if (CameraPreviewFragment.IS_RECORDING_VIDEO) {
CustomCamera.mCamera.stopPreview();
// release camera
releaseCamera();
}
}
@Override
protected void onResume() {
super.onResume();
// Re-initialize if camera already released after resume from background
if (mCamera == null) {
// Initialize camera again
initialCamera();
}
}
/**
* Initial methods
*/
private void initialCamera() {
// Back Camera
mCamera = getCameraInstance(0);
// Set Camera Display Orientation
CameraPreviewFragment.setCameraDisplayOrientation(
this, define.Camera.CAMERA_BACK);
// Get orientation listener
new OrientationEventListener(this) {
@Override
public void onOrientationChanged(int orientation) {
getCurrentOrientation(orientation);
}
}.enable();
}
/**
* Basic methods
*/
private int getCurrentOrientation(int orientation) {
orientation = (orientation + 45) / 90 * 90;
this.current_orientation = orientation % 360;
return current_orientation;
}
public static void releaseCamera() {
// Should release camera before go to the other page
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
CameraPreview.java - 相机表面类
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 mCamera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
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
e.printStackTrace();
}
// start preview with new settings
try {
// set preview size and make any resize, rotate or
// reformatting changes here
Camera.Parameters parameters = mCamera.getParameters();
// Set the popular preview size & picture size
// to apply for all android devices : Back camera only
// If for Front camera, it will use default if not suitable
for (Camera.Size size : parameters.getSupportedPictureSizes()) {
if (1600 <= size.width & size.width <= 1920) {
parameters.setPreviewSize(size.width, size.height);
parameters.setPictureSize(size.width, size.height);
break;
}
}
// Set parameters for camera
try {
CustomCamera.mCamera.setParameters(parameters);
} catch (Exception e) {
if (mCamera != null) {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
}
}
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
CameraPreviewFragment.java - 加载自定义相机预览的类
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = getLayoutInflater(savedInstanceState).inflate(
R.layout.fragment_camera_preview, container, false);
/**
* Add Camera Preview into Layout
*/
// Create our Preview view and set it as the content of our activity.
mCameraPreview = new CameraPreview(getActivity(), CustomCamera.mCamera);
mFlCameraPreview.addView(mCameraPreview);
return v;
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.ibtn_switch_back_or_front_camera:
/**
* Should reset camera for camera get new setting
*/
// Switch between Front Camera & Back Camera
current_camera_id = switchCurrentCameraID();
refreshCameraPreview(getActivity(), current_camera_id);
// Should remove view parent before add child
Utils.removeViewParent(mCameraPreview);
/**
* Add Camera Preview into Layout
*/
// Create our Preview view and set it as the content of our activity.
mCameraPreview = new CameraPreview(getActivity(), CustomCamera.mCamera);
mFlCameraPreview.addView(mCameraPreview);
break;
}
}
// for the Preview - from http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)
// note, if orientation is locked to landscape this is only called when setting up the activity, and will always have the same orientation
public static void setCameraDisplayOrientation(Activity activity, int camera_id) {
CustomCamera.mCameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(camera_id, CustomCamera.mCameraInfo);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int result;
if (CustomCamera.mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (CustomCamera.mCameraInfo.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else {
result = (CustomCamera.mCameraInfo.orientation - degrees + 360) % 360;
}
if (CustomCamera.mCamera != null)
CustomCamera.mCamera.setDisplayOrientation(result);
}
activity_custom_camera.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/LinearLayout__Vertical_MatchParent">
<FrameLayout
android:id="@+id/fl_custom_camera"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
</LinearLayout>
fragment_camera_preview.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
style="@style/FrameLayout_"
>
<FrameLayout
android:id="@+id/fl_camera_preview"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>
</FrameLayout>
我想要的是我的应用程序中的自定义相机如何更适合流行的Android设备,如Instagram,Camera 360 ......
另一件事,我没有使用<uses-feature android:name="android.hardware.camera" />
这个会帮我解决什么事情?它会减少支持的Android设备可以从Play商店下载我的应用程序吗?
知道的人,
请帮助我,
谢谢,