Android for Work中的相机意图

3
我正在使用相机 Intent 拍摄照片,这在我的默认版本应用中按预期工作。
我为“Android for Work”版本的应用程序实现了相同的代码,但出现了奇怪的行为。通常情况下,根据“Android for Work”视频,在不同配置文件中不能处理 Intent。例如,如果在“Work Profile”中未安装相机应用程序,则在解析 Camera Intent 后,Camera Intent 应该为 null,这是预期的。
但在我的情况下,Camera Intent 被安装在默认用户配置文件中的相机应用程序处理(“Work Profile”没有相机应用程序)。当拍摄照片时,它将以 Activity.RESULT_CANCELED 的 resultCode 返回到 onActivityResult 中。
所以,我的问题是,如何区分用户的 “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);
 }

编辑:这是我的管理面板截图。 跨配置文件限制 工作配置文件中允许的应用程序


在触发意图之前,您可以处理任何应用程序是否能够处理该意图 - sadegh saati
@ sadeghsaati 首先,我在 if 语句中使用 resolveActivity 进行操作。但是出乎意料的是,它并没有返回 null。 - osayilgan
1个回答

1
根据DevicePolicyManagersetCameraDisabled()方法:
由管理设备的应用程序调用,以禁用设备上的所有摄像头,对于此用户而言。设置后,没有以此用户身份运行的应用程序将能够访问设备上的任何摄像头。
因此,只有在工作配置文件上运行的应用程序无法访问相机 - 正如所述,这不会影响默认用户配置文件。
管理员应用程序需要使用addCrossProfileIntentFilter()调用,并使用FLAG_PARENT_CAN_ACCESS_MANAGED来禁用工作配置文件应用程序的意图能够在父(默认用户)应用程序上解析,如果不希望从工作配置文件发送任何意图到用户配置文件,则可以这样做。
现在,如果您希望您的应用程序使用ACTION_IMAGE_CAPTURE在工作配置文件上运行,可以按照以下说明进行操作:
Android上的每个用户都拥有完全隔离的存储空间,包括公共存储目录。这意味着默认用户配置文件相机应用程序无法读取对工作配置文件应用程序可访问的任何文件目录。
相反,您需要提供一个URI,以便它们可以写入,例如由FileProvider返回的URI,如file sharing training中所述。
/* 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);

需要注意的是,此处保存的文件将被保存到您应用程序的缓存目录中,而不是公共存储位置。

您还需要包含基于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 Uri。

谢谢您的回答。您说得没错,工作用户和默认用户的存储是分开的,但是对于“Android For Work”,它们同时运行。这仍然不允许它们写入彼此的存储空间。这不是我的问题。因为,如果工作配置文件的相机应用程序未安装(受管理员限制),那么我不希望用户能够访问默认相机应用程序。如果被限制,则用户不应该能够使用它。但是当我启动意图时,工作配置文件仍然可以访问默认配置文件中的应用程序,这是不符合预期的。 - osayilgan
因此,当默认相机应用程序受限时,用户要么不应该访问它,要么如果无法阻止,则返回给活动的resulCode应与Activity.RESULT_CANCELED不同,以便我可以告诉用户为什么他们不能拍照。 - osayilgan
如果我从管理员面板启用相机选项(这将安装相机应用程序到工作配置文件),那么它会按预期工作。 - osayilgan
但是他们可以访问默认的相机应用程序,如果您使用我提供的代码,您可以从那里拍照并将它们提供给您的工作配置文件应用程序。 - ianhanniballake
但这不违背了分离配置文件和提供“相同应用程序但在不同的工作空间”这一理念吗?如果管理员限制了相机应用程序,那么用户就不应该通过我的应用程序访问它。我有什么遗漏的吗? - osayilgan
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接