栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

2021SC@SDUSC Zxing开源代码(十六)android-integration 代码分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021SC@SDUSC Zxing开源代码(十六)android-integration 代码分析

文章目录
  • 前言
  • IntentIntegrator 代码分析
    • initiateScan
    • findTargetAppPackage
    • showDownloadDialog()
    • shareText
  • 总结


前言

在前面的博客中,我们已经将 Zxing开源代码中 android包的代码都进行了分析。综合来看,整个 android包实际上就是一个安卓应用“条码扫描器”,其调用 core包中的核心扫码编码算法,来提供相应功能。不过 Zxing除了可以直接使用其提供的应用外,还可以把它集成在自己的 Android项目中,来实现扫码解码等一系列功能。这所依赖的就是 android-integration包中的代码


IntentIntegrator 代码分析

IntentIntegrator是一个实用类,通过 Intent与 android包对应的应用“条码扫描器”集成,可以简单的调用扫码编码功能并接收结果,无需修改或学习项目的源代码

扫码功能集成方法如下:
1、 在自己的项目中,创建 IntentIntegrator对象,调用 initiateScan() 方法
2、如果用户还未下载应用程序“条码扫描器”,initiateScan() 方法会返回一个 alertDialog 对象,来提示用户下载
3、在自己项目的 Activity中,需要有方法 onActivityResult(int, int, Intent)来处理扫描后返回的结果

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
	IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
	if (scanResult != null) {
		// handle scan result
	}
	// else continue with any other code you need in the method
	 ...
}
initiateScan

如果外部程序希望利用 Zxing 实现扫码功能,则首先需要调用这一方法,传入参数为:

参数含义
desiredBarcodeFormats将要扫描的条码格式
cameraId要调用哪一个摄像头(前置/后置)

方法代码如下:

  public final alertDialog initiateScan(Collection desiredBarcodeFormats, int cameraId) {
    // BS_PACKAGE = "com.google.zxing.client.android"
    // 为 Intent 设置action:SCAN
    Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
    intentScan.addCategory(Intent.CATEGORY_DEFAULT);

    // 判断要扫描的何种类型的条码
    if (desiredBarcodeFormats != null) {
      // 设置希望的码制类型
      StringBuilder joinedByComma = new StringBuilder();
      for (String format : desiredBarcodeFormats) {
        if (joinedByComma.length() > 0) {
          joinedByComma.append(',');
        }
        joinedByComma.append(format);
      }
      intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
    }

    // 设置需要的 caremaId
    if (cameraId >= 0) {
      intentScan.putExtra("SCAN_CAMERA_ID", cameraId);
    
    // 在已安装的程序中寻找,是否有“条码扫描器”
    String targetAppPackage = findTargetAppPackage(intentScan);
    // 没找到的话就要显示弹窗,提示安装
    if (targetAppPackage == null) {
      return showDownloadDialog();
    }
    // 为 intent 设定包名
    intentScan.setPackage(targetAppPackage);
    intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intentScan.addFlags(FLAG_NEW_DOC);
    attachMoreExtras(intentScan);
    // 跳转到intentScan中的Activity(这里应是CaptureActivity 的实例对象)进行扫码处理
    startActivityForResult(intentScan, REQUEST_CODE);
    return null;
    }

方法中首先设置了 Intent 需要携带的信息(如扫描码制、cameraId)等,而后通过方法 findTargetAppPackage 找到目标app的包名,最终通过 startActivityForResult 跳转到了相应 app的 Activity中进行具体的扫码操作

findTargetAppPackage

findTargetAppPackage 方法代码实现如下:

  private String findTargetAppPackage(Intent intent) {
    // 获得一个PackageManger(管理所有应用程序包的类)的对象
    PackageManager pm = activity.getPackageManager();
    // 根据 intent 对所有的安装程序进行匹配查询,找到满足条件的app
    List availableApps = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    if (availableApps != null) {
      // 判断满足条件的app是否在事先定义好的目标app列表中
      for (String targetApp : targetApplications) {
        if (contains(availableApps, targetApp)) {
          return targetApp;
        }
      }
    }
    return null;
  }

PackageManager的介绍:通过PackageManager,我们可以获取应用程序信息,这些信息来自AndroidManifest.XML。PackageManager除了负责Android系统中Package的安装、升级、卸载外,还有一项很重要的职责,就是对外提供统一的信息查询功能,其中包括查询系统中匹配某Intent的Activities、BroadCastReceivers或Services等

showDownloadDialog()

若发现在已安装的应用程序中没有目标app, 则调用了 showDownloadDialog() 方法,来显示弹窗提示下载app

  private alertDialog showDownloadDialog() {
    // 创建alertDialog实例对象
    alertDialog.Builder downloadDialog = new alertDialog.Builder(activity);
    // 为弹窗设置标题
    downloadDialog.setTitle(title);
    // 为弹窗设置显示内容
    downloadDialog.setMessage(message);
    // 为点击“Yes”按钮设置监听
    downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialogInterface, int i) {
        String packageName;
        if (targetApplications.contains(BS_PACKAGE)) {
          // 如果目标app列表中存在BS_PACKAGE(也就是Zxing的安卓端应用),那么设置要安装的包名为BS_PACKAGE
          packageName = BS_PACKAGE;
        } else {
          // 否则选择目标app列表的第一个
          packageName = targetApplications.get(0);
        }
        //  跳转到应用商场
        Uri uri = Uri.parse("market://details?id=" + packageName);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        try {
          if (fragment == null) {
            activity.startActivity(intent);
          } else {
            fragment.startActivity(intent);
          }
        } catch (ActivityNotFoundException anfe) {
          // Hmm, market is not installed
          Log.w(TAG, "Google Play is not installed; cannot install " + packageName);
        }
      }
    });
    downloadDialog.setNegativeButton(buttonNo, null);
    downloadDialog.setCancelable(true);
    return downloadDialog.show();
  }
shareText

除了可以通过 IntentIntegrator 集成扫码操作,也可以利用 Zxing的编码功能,将给定文本编码为条形码来共享,以便其他用户可以扫描

  public final alertDialog shareText(CharSequence text, CharSequence type) {
    Intent intent = new Intent();
    intent.addCategory(Intent.CATEGORY_DEFAULT);
    // Intent的action为ENCODE
    intent.setAction(BS_PACKAGE + ".ENCODE");
    intent.putExtra("ENCODE_TYPE", type);
    intent.putExtra("ENCODE_DATA", text);
    // 找到目标app 包名
    String targetAppPackage = findTargetAppPackage(intent);
    // 如果没有找到则弹窗提示下载
    if (targetAppPackage == null) {
      return showDownloadDialog();
    }
    intent.setPackage(targetAppPackage);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(FLAG_NEW_DOC);
    attachMoreExtras(intent);
    // 跳转到对应app的Activity中处理
    if (fragment == null) {
      activity.startActivity(intent);
    } else {
      fragment.startActivity(intent);
    }
    return null;
  }

其基本流程与扫码类似,只是 Intent 中 Action 设置不同,这样跳转到“条码扫描器”的 Activity后就可以执行编码功能


总结

到这里,整个 Zxing开源代码中与 Android相关的部分就分析完毕了。从一开始面对近八十个类感觉无从下手,到后面从主线——扫码功能出发,一步步对功能逐个进行分析,最后已经基本完全理清 Zxing项目 Android部分的代码逻辑了。

与此同时,也学习了解了 Android的基本组件、Handler消息传递机制、View体系、Adapter机制等等 Android相关的重要知识。

对比以往自己开发的课设项目,整个 Zxing项目的安卓端应用体量庞大,功能处理逻辑完善,并且考虑了各种各样的情况,包括多种解析格式、长时间无活动自动销毁机制等。这也是我第一次阅读大型项目的源码,其中的开发思想、处理逻辑等都对我今后进行软件工程项目实践有很大启发

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/678572.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号