从另一个应用发起扫描
意图
| Action | 清单中的过滤器 | 会发生什么 | 结果 |
|---|---|---|---|
com.google.zxing.client.android.SCAN | 是,隐式意图可用。 | 打开扫描器。用户锁定的第一个码会被返回,与 ZXing Barcode Scanner 的做法相同。 | RESULT_OK,附带 SCAN_RESULT 和 SCAN_RESULT_FORMAT |
app.scanner.action.SCAN | 是。 | 打开扫描器。为获取结果而启动时(result launcher 或 startActivityForResult),以同样方式返回码;直接启动时只是在扫描器界面打开应用。 | 为获取结果而启动时,RESULT_OK 附带这两个附加数据 |
app.scanner.action.CARD | 无过滤器:仅接受指定包名 com.verdettoqr.scanner 的显式意图。 | 打开用户自己的联系人名片编辑器,也就是用户用来分享自己信息的码。面向应用自身的小组件和快捷方式;其他应用可以调用,但不会返回任何内容。 | 无 |
android.intent.action.SEND,类型 image/* | 是。 | 解码一张图片:应用为其中的码显示结果面板。 | 无 |
用户可以在“设置”中的“把结果交给其他应用”(“当其他应用请求扫描时,把码返回给该应用”)关闭返回功能,该项默认开启。关闭后,两个扫描 action 都会像普通启动一样打开扫描器,用户离开时你的 launcher 会收到 RESULT_CANCELED。从扫描器返回同样是 RESULT_CANCELED。
目前不读取任何请求附加数据:SCAN_MODE、SCAN_FORMATS、PROMPT_MESSAGE、SAVE_HISTORY 或其他都不读取。扫描器在每次调用时读取它所知的所有码制。被应用检查标记的码仍会返回;用户先看到警告,再自行决定。
结果
SCAN_RESULT(String):码的内容,即码所携带的原始字节,按文本解码(码制允许时为 UTF-8,否则为该码制自身的字符集)。SCAN_RESULT_FORMAT(String):码制名称,大写并以下划线连接,存在 ZXing 名称时沿用之。目前返回:QR_CODE,MICRO_QR_CODE,RMQR_CODE,DATA_MATRIX,AZTEC,PDF417,MAXICODE,HAN_XIN,EAN_13,EAN_8,UPC_A,UPC_E,CODE_128,CODE_39,CODE_93,CODABAR,ITF,DATABAR,DATABAR_EXPANDED,DATABAR_LIMITED,DX_FILM_EDGE,以及应用自有解码器新增的其他码制,拼写方式相同(结果面板上显示的名称转为大写,空格和连字符改为下划线)。
不会传递其他任何东西:没有图片、没有位置、没有历史记录。
Kotlin
private val scan = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val text = result.data?.getStringExtra("SCAN_RESULT")
val format = result.data?.getStringExtra("SCAN_RESULT_FORMAT")
// use text and format
}
}
fun startScan() {
val intent = Intent("app.scanner.action.SCAN")
if (intent.resolveActivity(packageManager) != null) scan.launch(intent)
else startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(GET_VERDETTO)))
}
// the store page, with the developers referrer
private const val GET_VERDETTO =
"https://play.google.com/store/apps/details?id=com.verdettoqr.scanner&referrer=utm_source%3Ddevelopers%26utm_medium%3Ddocs%26utm_campaign%3Ddevelopers"
在 Android 11 及更高版本上,把查询加入你的清单,这样 resolveActivity 才能看到该应用:
<queries>
<intent>
<action android:name="app.scanner.action.SCAN" />
</intent>
</queries>
Java
private final ActivityResultLauncher<Intent> scan = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(), result -> {
if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
String text = result.getData().getStringExtra("SCAN_RESULT");
String format = result.getData().getStringExtra("SCAN_RESULT_FORMAT");
// use text and format
}
});
void startScan() {
Intent intent = new Intent("app.scanner.action.SCAN");
if (intent.resolveActivity(getPackageManager()) != null) scan.launch(intent);
else startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(GET_VERDETTO)));
}
ZXing action
为 ZXing Barcode Scanner 编写的代码可以继续使用:以同样方式发送 com.google.zxing.client.android.SCAN,并读取同样的两个附加数据。如果手机上有多个扫描器响应它,系统会询问用户使用哪一个;把意图发送给包名 com.verdettoqr.scanner 可以跳过这一步。
用户看到的内容
扫描器照常打开,带着它自己的检查。码锁定后,应用把它返回并关闭;屏幕上不会出现任何属于你的内容,用户的任何内容(历史记录、设置、安全列表)也不会被这次调用触及。
在没有安装应用的手机上测试。 带开发者引荐参数的商店页面,也就是示例中回退所打开的地址:在 Google Play 获取。本页面的来源是应用自身的 INTENT.md;两者不一致时,以应用仓库为准,本页面滞后。