android usb摄像头例子
时间: 2023-06-30 11:05:55 浏览: 111
以下是一个简单的 Android 应用程序,它使用 USB 摄像头并在屏幕上显示预览:
1. 在 AndroidManifest.xml 文件中添加以下权限:
```xml
<uses-feature android:name="android.hardware.usb.host" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
```
2. 创建一个 MainActivity 类来控制应用程序的主要行为:
```java
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final int REQUEST_CAMERA_PERMISSION = 1;
private static final int REQUEST_USB_PERMISSION = 2;
private TextureView mTextureView;
private CameraManager mCameraManager;
private CameraDevice mCameraDevice;
private String mCameraId;
private Size mPreviewSize;
private ImageReader mImageReader;
private HandlerThread mBackgroundThread;
private Handler mBackgroundHandler;
private ImageReader.OnImageAvailableListener mOnImageAvailableListener =
new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage();
// 处理图像数据
image.close();
}
};
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
mCameraDevice = camera;
startPreview();
}
@Override
public void onDisconnected(CameraDevice camera) {
camera.close();
mCameraDevice = null;
}
@Override
public void onError(CameraDevice camera, int error) {
camera.close();
mCameraDevice = null;
finish();
}
};
private CameraCaptureSession.StateCallback mCaptureSessionCallback =
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
try {
CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.addTarget(mTextureView.getSurface());
builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
session.setRepeatingRequest(builder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
Toast.makeText(MainActivity.this, "Failed to configure the camera preview.", Toast.LENGTH_SHORT).show();
}
};
private CameraManager.AvailabilityCallback mAvailabilityCallback = new CameraManager.AvailabilityCallback() {
@Override
public void onCameraAvailable(String cameraId) {
if (TextUtils.equals(mCameraId, cameraId)) {
openCamera();
}
}
@Override
public void onCameraUnavailable(String cameraId) {
if (TextUtils.equals(mCameraId, cameraId)) {
closeCamera();
}
}
};
private BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
requestUsbPermission(device);
}
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null && device.equals(mCameraDevice.getCameraDevice())) {
closeCamera();
}
}
}
};
private UsbManager mUsbManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextureView = findViewById(R.id.texture_view);
mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
startBackgroundThread();
if (mTextureView.isAvailable()) {
openCamera();
} else {
mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
openCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
});
}
registerReceiver(mUsbReceiver, new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED));
registerReceiver(mUsbReceiver, new IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED));
}
@Override
protected void onPause() {
super.onPause();
closeCamera();
stopBackgroundThread();
unregisterReceiver(mUsbReceiver);
}
private void startBackgroundThread() {
mBackgroundThread = new HandlerThread(TAG);
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
private void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void openCamera() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
return;
}
try {
String[] cameraIds = mCameraManager.getCameraIdList();
for (String cameraId : cameraIds) {
CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(cameraId);
if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_BACK) {
mCameraId = cameraId;
break;
}
}
if (mCameraId == null) {
Toast.makeText(this, "No back-facing camera available.", Toast.LENGTH_SHORT).show();
finish();
return;
}
mPreviewSize = chooseOptimalSize();
mImageReader = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.YUV_420_888, 2);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
if (mUsbManager.hasPermission(mCameraDevice.getCameraDevice())) {
mCameraManager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
} else {
requestUsbPermission(mCameraDevice.getUsbDevice());
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void closeCamera() {
if (mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
if (mImageReader != null) {
mImageReader.close();
mImageReader = null;
}
}
private void startPreview() {
try {
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, mImageReader.getSurface()),
mCaptureSessionCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private Size chooseOptimalSize() {
Size[] choices = null;
try {
StreamConfigurationMap map = mCameraManager.getCameraCharacteristics(mCameraId)
.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
choices = map.getOutputSizes(ImageFormat.YUV_420_888);
} catch (CameraAccessException e) {
e.printStackTrace();
}
if (choices == null) {
return new Size(640, 480);
}
int preferredWidth = 640;
int preferredHeight = 480;
int preferredAspectRatio = preferredWidth * 1000 / preferredHeight;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
for (Size size : choices) {
int width = size.getWidth();
int height = size.getHeight();
int aspectRatio = width * 1000 / height;
if (Math.abs(aspectRatio - preferredAspectRatio) > 200) {
continue;
}
double diff = Math.abs(Math.log((double) (preferredWidth * preferredHeight) / (width * height)));
if (diff < minDiff) {
optimalSize = size;
minDiff = diff;
}
}
if (optimalSize == null) {
optimalSize = choices[0];
}
return optimalSize;
}
private void requestUsbPermission(UsbDevice device) {
PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent("com.example.USB_PERMISSION"), 0);
mUsbManager.requestPermission(device, permissionIntent);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CAMERA_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openCamera();
} else {
Toast.makeText(this, "Camera permission denied.", Toast.LENGTH_SHORT).show();
finish();
}
}
}
}
```
3. 在布局文件中添加 TextureView:
```xml
<TextureView
android:id="@+id/texture_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
```
4. 运行应用程序,并插入 USB 摄像头。应用程序将自动请求 USB 权限并打开摄像头。
阅读全文