Camera2 API获取vendor.camera.aux.packagelist权限被拒问题咨询
我用下述代码通过外部USB摄像头(网络摄像头)捕获图像,代码在多数设备上运行正常,但在Android 9.0(API Level 28)设备上,尝试获取Camera ID打开摄像头时,Logcat会抛出**Access denied finding property "vendor.camera.aux.packagelist"**错误。已授予相机、外部存储及USB设备权限,请求解释该问题原因。
package com.example.camerastatuscheck; import static android.content.ContentValues.TAG; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import android.Manifest; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbManager; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraManager; import android.os.Bundle; import android.os.PendingIntent; import android.util.Log; import android.widget.Button; import android.widget.TextureView; import android.widget.Toast; import java.util.HashMap; import java.util.Iterator; public class MainActivity extends AppCompatActivity { private static final int REQUEST_CAMERA_PERMISSION = 200; public static final String ACTION_USB_PERMISSION = "com.example.usbtestapp.USB_PERMISSION"; static final int intentFlags = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S ? PendingIntent.FLAG_MUTABLE : 0; static final int MY_CAMERA_PERMISSION_CODE = 100; private Context ContextofMainAcitivity; public IntentFilter USBconnectdisconnect_intentFilter; public Intent GetEXTRA_PERMISSION_GRANTEDIntent; public PendingIntent current_usbpermissionIntent; public UsbDevice current_usbdevice; public UsbManager current_usbManager; private static final String TAG = "usbtestapp"; TextureView new_textureview; Button new_open_camera,nextactivity; UsbDeviceConnection usbConnection; PendingIntent permissionIntent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); camera_start(); } private void camera_start() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); return; } Log.d("camera start", "success"); UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); HashMap<String, UsbDevice> deviceList = manager.getDeviceList(); Iterator<UsbDevice> deviceIterator = deviceList.values().iterator(); while(deviceIterator.hasNext()){ UsbDevice device = deviceIterator.next(); manager.requestPermission(device, permissionIntent); //your code } Log.d("Camrea srtart","camera start"); CameraManager cameraManager = (CameraManager)getSystemService(CAMERA_SERVICE); try { for (String cameraId : cameraManager.getCameraIdList()) { CameraCharacteristics chars = cameraManager.getCameraCharacteristics(cameraId); int deviceLevel = chars.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL); Log.d(TAG, " **** device ["+cameraId+"] level:"+deviceLevel); Toast.makeText(getApplicationContext(), "cameraId", Toast.LENGTH_SHORT).show(); } } catch(CameraAccessException e){ e.printStackTrace(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CAMERA_PERMISSION) { if (grantResults[0] == PackageManager.PERMISSION_DENIED) { Toast.makeText(MainActivity.this, "Sorry!!!, you can't use this app without granting permission", Toast.LENGTH_LONG).show(); finish(); } } } private final BroadcastReceiver usbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (ACTION_USB_PERMISSION.equals(action)) { synchronized (this) { UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { if(device != null){ Toast.makeText(context, "Permission granded", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(context, "Permission denied", Toast.LENGTH_SHORT).show(); } } } } }; public boolean supportsExternalCameras() { return this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL); } }
(注:修复了原代码中fornewpos.this的错误引用,补充了缺失的import类)
2023-01-07 15:31:55.318 23651-23651 libc com.example.cmaera5 E Access denied finding property "vendor.camera.aux.packagelist"
<uses-feature android:name="android.hardware.camera" android:required="true" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.camera2.full" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <uses-feature android:name="android.hardware.usb.host" /> <uses-feature android:name="android.hardware.usb.accessory" /> <uses-feature android:name="android.hardware.usb" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
系统属性权限限制:
vendor.camera.aux.packagelist是厂商自定义的系统属性,用于管控可访问辅助摄像头(如USB外接摄像头)的应用列表。Android 9.0中,普通应用没有读取这类厂商系统属性的权限,该错误是系统层面的权限拦截导致,和你手动申请的应用级权限无关。厂商Camera2 API实现差异:部分Android 9.0设备的厂商在实现Camera2 API时,会尝试读取该属性来判断应用是否有权访问外接USB摄像头,但由于普通应用无读取权限,便抛出该错误日志。
代码潜在问题:原代码中
permissionIntent变量未初始化就调用manager.requestPermission(device, permissionIntent),会导致USB权限请求失效,可能间接影响USB摄像头的识别流程。
忽略日志错误:该错误属于系统层面的权限限制,多数情况下不会影响USB摄像头的正常使用,只要应用能正常获取Camera ID并打开摄像头,可直接忽略这条日志。
初始化USB权限请求的PendingIntent:在
onCreate方法中补充初始化逻辑,确保USB权限请求正常执行:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化USB权限请求的PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), intentFlags); // 注册USB广播接收器 USBconnectdisconnect_intentFilter = new IntentFilter(ACTION_USB_PERMISSION); registerReceiver(usbReceiver, USBconnectdisconnect_intentFilter); camera_start(); }
适配Android 9.0 USB摄像头:部分厂商的Android 9.0设备对外接USB摄像头支持有限,可尝试使用第三方USB摄像头库替代原生Camera2 API,绕过系统属性限制。
清理冗余代码:移除原代码中重复定义的
REQUEST_CAMERA_PERMISSION常量,保证代码逻辑清晰。
内容的提问来源于stack exchange,提问作者Ac. Selvan

