Android 工作中的相机意图

Camera Intent in Android for Work

我正在触发相机 Intent 以使用相机应用程序拍照。它在我的应用程序的默认版本中按预期工作。

我已经为我的应用程序的 "Android for Work" 版本实现了相同的代码,但最终出现了奇怪的行为。通常,根据 "Android for Work" 视频,如果 Intent 在不同的配置文件中,则无法处理。例如,如果我的工作配置文件中没有安装相机应用程序,相机意图在解析后应该为空,这是预期的。

但在我的情况下,Camera Intent 由安装在我的默认用户配置文件中的相机应用程序处理(Work Profile 没有相机应用程序)。拍照时,它会返回 onActivityResult 并带有 resultCode Activity.RESULT_CANCELED

所以,我的问题是,如何区分用户的 Real Cancel Event 和这种情况?两者的结果相同,Activity.RESULT_CANCELED

下面的代码显示了我如何触发相机 Intent。

/* Create Camera Intent */
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

/* Check if the Camera Intent is Available */
if (cameraIntent.resolveActivity(getActivity().getPackageManager()) == null) {

    /* Notify User in Error Case */
    UIUtils.notifyUser(getActivity(), getString(R.string.error), getString(R.string.no_camera_application_found));

} else {

    /* Create a new File with Random Photo Name */
    takenPhoto = new File(FileUtils.getExternalPhotoCacheDirectory(), generatePhotoName());
    takenPhoto.createNewFile();

    /* Create Uri to send to within the Intent */
    Uri outputFileUri = Uri.fromFile(takenPhoto);

    /* Set Photo destination File Uri */
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

    /* Start Activity for Result */
    startActivityForResult(cameraIntent, ACTION_TAKE_PHOTO);
 }

编辑: 这是我管理面板的一些屏幕截图。

根据 setCameraDisabled() method for DevicePolicyManager:

Called by an application that is administering the device to disable all cameras on the device, for this user. After setting this, no applications running as this user will be able to access any cameras on the device.

因此,只有工作配置文件中的应用程序 运行 将无法访问相机 - 如其所示,这不会影响默认用户配置文件。

管理员应用程序需要调用 addCrossProfileIntentFilter() with the FLAG_PARENT_CAN_ACCESS_MANAGED 来禁用来自工作配置文件应用程序的意图,如果父(默认用户)应用程序不希望从工作发送任何意图个人资料到用户个人资料。

现在,如果您希望使用 ACTION_IMAGE_CAPTURE 的应用在工作资料上运行,您可以按照以下说明操作:

Android 上的每个用户都有一个完全沙盒存储 space,包括 public 个存储目录。这意味着默认用户配置文件相机应用无法读取工作配置文件应用可访问的任何文件目录。

相反,您需要提供一个他们可以写入的 URI,例如 FileProvider as explained in the file sharing training.

返回的 URI
/* Create a new File with Random Photo Name */
takenPhoto = new File(getActivity().getCacheDir(), generatePhotoName());
takenPhoto.createNewFile();

/* Create Uri to send to within the Intent */
Uri outputFileUri = FileProvider.getUriForFile(getActivity(),
    "your.authority.read.the.docs", takenPhoto);

/* Set Photo destination File Uri */
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

请务必注意,此处的文件将保存到您的应用程序的缓存目录 - 而不是 public 存储位置。

您还需要包含基于 Uri 的权限:

cameraIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
cameraIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
cameraIntent.setClipData(ClipData.newRawUri(null, outputFileUri));

通常,只有 setData(uri) 中包含的 Uri 被授予权限,但剪辑数据中也包含的任何 Uri 也将被授予权限,从而允许相机应用程序能够读取和写入您的 MediaStore.EXTRA_OUTPUT 乌里