【问题标题】:How to integrate Zxing Barcode Scanner without installing the actual zxing app (cannot resolve symbol: .android.CaptureActivity)?如何在不安装实际 zxing 应用的情况下集成 Zxing Barcode Scanner(无法解析符号:.android.CaptureActivity)?
【发布时间】:2015-03-20 03:50:31
【问题描述】:

我想将 zxing 扫描仪集成到我的应用程序中,而不需要外部应用程序(来自 Play 商店的 zxing 扫描仪)。这是我的代码

Button scan = (Button) findViewById(R.id.scan_button);
scan.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent("com.google.zxing.client.android.SCAN");
        intent.setPackage("com.mypackage.app");
        intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
        startActivityForResult(intent, SCANNER_REQUEST_CODE);
    }
});

@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    if (requestCode == SCANNER_REQUEST_CODE) {
        // Handle scan intent
        if (resultCode == Activity.RESULT_OK) {
            // Handle successful scan
            String contents = intent.getStringExtra("SCAN_RESULT");
            String formatName = intent.getStringExtra("SCAN_RESULT_FORMAT");
            byte[] rawBytes = intent.getByteArrayExtra("SCAN_RESULT_BYTES");
            int intentOrientation = intent.getIntExtra("SCAN_RESULT_ORIENTATION", Integer.MIN_VALUE);
            Integer orientation = (intentOrientation == Integer.MIN_VALUE) ? null : intentOrientation;
            String errorCorrectionLevel = intent.getStringExtra("SCAN_RESULT_ERROR_CORRECTION_LEVEL");

        } else if (resultCode == Activity.RESULT_CANCELED) {
            // Handle cancel
        }
    } else {
        // Handle other intents
    }

}

AndroidManifest.xml

<activity android:name="com.google.zxing.client.android.CaptureActivity"
    android:screenOrientation="landscape"
    android:configChanges="orientation|keyboardHidden"
    android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
    android:windowSoftInputMode="stateAlwaysHidden">
    <intent-filter>
        <action android:name="com.google.zxing.client.android.SCAN"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

我的 Android Studio 说无法解析符号:.android.CaptureActivity,如果我运行它,就会发生错误

java.lang.ClassNotFoundException:找不到类“com.google.zxing.client.android.CaptureActivity”

发生了什么?

【问题讨论】:

    标签: android zxing


    【解决方案1】:

    虽然已经得到解答,但对于那些想要将 ZXing 作为库而不使用任何自动安装方法(如 ANT)的人来说,我觉得这是一个深入的解决方案。

    ZXing 是一个开源项目,允许(如 ZXing 网站中所述)您将其功能用作项目库,而不是强制在用户设备上安装 3rd 方应用程序,我认为这是大多数项目的首选.

    重要的是要注意,这种方式是创建者可以接受的,并且不会违反他们的任何使用条款,因为我们不会复制他们的代码,而只是将其用作我们项目的库。

    一般流程是这样的:

    1. 正在下载 ZXing 源代码和核心文件。
    2. 将 ZXing 项目导入您想要的任何环境 (Eclipse/Studio)
    3. 将 ZXing 项目定义为库并修复代码以满足这些要求。
    4. 将 ZXing 添加到您自己项目的构建路径中
    5. 根据应用程序的需要添加 ZXing 方法。

    以下是针对使用 Eclipse 的用户的完整详细过程(也可以很容易地在 Studio 中实现):

    下载ZXing源代码和核心文件

    1. 进入 ZXing 的 GitHub 项目页面 (https://github.com/zxing/zxing) 并点击“Download zip”。
    2. 提取文件(我建议使用大多数其他库源所在的位置)

    将 ZXing 项目导入 Eclipse

    1. 打开 Eclipse。
    2. 单击文件>导入,>Android>“现有Android代码到工作区”,从选择窗口导航到您将ZXing zip文件解压到的文件夹,然后选择“Android”文件夹。 Eclipse 现在应该检测到该文件夹​​包含一个名为“captureActivity”的项目,导入该项目。
    3. 您现在应该在工作区中看到捕获活动。根据 您可能需要将 core.jar 文件分配给 ZXing 版本 ZXing 项目,检查您的版本是否是这种情况 打开 captureActivity 项目的 libs 文件夹并检查是否 core.jar 文件是否存在,如果没有则必须自己添加, 否则跳到下一章。

      5.1。要添加 core.jar 文件,右键单击 Eclipse 工作区中的 captureActivity 项目并选择 Build path>configure 构建路径

      5.2。从侧面菜单中选择 Java Build Path 并单击 Libraries 选项卡。

      5.3.单击“添加外部 JAR”并导航到您最初导出 ZXing zip 的位置。

      5.4。进入core文件夹,选择core.jar(名称可能因ZXing版本不同),点击打开

      5.5。您现在应该在构建路径列表中看到 core.jar,单击“Order and Export”选项卡并检查 core.jar

    将 ZXing 定义为库并修复代码

    1. 如果您尚未在构建路径窗口中,请右键单击 captureActivity 项目并选择构建路径>配置构建路径。
    2. 从侧面菜单中选择 Android 并选中 Is Library,单击确定退出窗口
    3. 现在根据你的 ZXing 版本,你可能会看到 Eclipse 标记一些包含错误的 java 文件,如果是这种情况,你必须修复代码以匹配 android java 版本,否则只需移动到下一章

      8.1。在编辑器中打开每个损坏的 java 文件,并用一系列 If Else 语句替换损坏的 Switch 语句,我知道这是一个烦人的部分。

    将 ZXing 添加为您自己项目的库

    1. 如果现在一切正常,则 captureActivity 应该与您工作区中的任何正常项目文件夹一样,没有错误或红色!标志。要将 ZXing 定义为您自己项目中的库,请在工作区中右键单击您的项目并选择 Build path>Configure build path。
    2. 从侧面菜单中选择 Android。单击窗口右下角的添加按钮,然后从窗口中选择 captureActivity。
    3. 就是这样,您的项目现在可以将 ZXing 作为独立库使用,无需任何第三方安装。

    添加应用所需的 ZXing 方法

    这部分并不是真正的指南,只是到目前为止我发现对我自己的需求有用的东西,我主要使用的两种方法是:

    运行扫描仪并获取二维码:

    Intent intent = new Intent(getApplicationContext(),CaptureActivity.class);
    intent.setAction("com.google.zxing.client.android.SCAN");
    intent.putExtra("SAVE_HISTORY", false);
    startActivityForResult(intent, 0);
    

    在onActivityResult()中取回扫描结果:

    if (requestCode == 0) {
    if (resultCode == RESULT_OK) {
    String contents = data.getStringExtra("SCAN_RESULT");
    Log.d(TAG, "contents: " + contents);
    } else if (resultCode == RESULT_CANCELED) {
    // Handle cancel
    Log.d(TAG, "RESULT_CANCELED");
    }
    }
    

    请注意,就像 android capture 活动中的任何其他活动一样,也需要在项目清单中定义,还请注意,您必须授予项目使用相机的权限,如下所示:

    <uses-permission android:name="android.permission.CAMERA" />
    <activity
    android:name="com.google.zxing.client.android.CaptureActivity"
    android:screenOrientation="landscape" >
    </activity>
    

    我希望这将帮助其他人节省几个小时的研究时间。

    作为额外的奖励,我建议阅读: https://biocram.wordpress.com/2013/06/11/integrate-zxing-as-a-library-inside-an-android-project/

    【讨论】:

    • 将 ZXing 定义为库并修复代码 >8.1 不再是 android studio 的难点,将光标指向switch 语句 >按alt+enter,瞧! >Replace 'switch' with 'if',找到了here
    【解决方案2】:

    由于到目前为止我找到的所有答案都是基于 Eclipse 并且到目前为止已经过时了,所以我添加了我的答案,以将 ZXing 添加为 Android Studio (2.1.2) 上的独立库。

    我已经将编译好的项目放到了 Github https://github.com/tarun0/ZXing-Standalone-library 上,只需在你的项目中添加 zxing_standalone 模块就可以了。有关详细信息或为较新版本编译它,请继续阅读。

    这个过程可能看起来很长,但是一旦你经历了它,你会发现它很容易而且很短。

    1. https://github.com/zxing/zxing/下载ZXing库源代码我们只需要android目录。因此,如果您碰巧已经拥有此文件夹,则无需下载大约 126MB 大小的整个分支。
    2. http://repo1.maven.org/maven2/com/google/zxing/core/3.2.1/下载最新的core-x.x.x.jar
    3. 在自己的项目中添加android项目。为此,首先,从Project Explorer 中选择Project(参考图片)

    1. 现在单击您的项目,然后右键单击它并选择New>Module>Import Gradle Project。现在,从下载的源代码中选择android 目录(在步骤1 中)。 (绝对新手参考下面的图片)。或者,更改名称并使用默认设置进行导入。
    2. 在这个导入的项目中,创建一个文件夹libs,并将步骤2中下载的core.jar文件放到这个文件夹中。然后从文件菜单中打开Project Structure 并将这个core.jar 文件添加为依赖项。

    1. 下载CameraConfigurationalUtils.java并将其粘贴到项目中。

    2. 现在对导入的项目的 gradle 文件进行一些修改。 将apply plugin: 'com.android.application' 更改为apply plugin: 'com.android.library' 以告诉系统它是一个库。并删除applicationId ... 语句。

    3. 在导入项目的Manifest.xml文件中,进行如下修改。 在&lt;application... 标记中,删除android:icon...android:logo... 并从意图过滤器中删除此&lt;category android:name="android.intent.category.LAUNCHER"/&gt;,因为它现在是一个库,不应该在启动器上(如果你不删除它,你最终会有两个启动器活动)。

    4. 在您项目的build.gradle 文件中,在dependencies 块中,添加此行compile project (':android') 在此处,将android 替换为您在步骤4 中导入项目时选择的名称。同步和清理该项目。您会在switch 语句中看到一些错误。 点击那些 switch case 并选择 Android Studio 提供的选项 replace with if 选项。

    就是这样。现在您可以在自己的应用程序中使用 ZXing 库。 :)

    要使用添加的库,只需使用上面第一个答案中所述的Intents(仅复制相同的代码):

    扫描时(比如点击按钮),发送 Intent:

    Intent intent = new Intent(getApplicationContext(),CaptureActivity.class);
    intent.setAction("com.google.zxing.client.android.SCAN");
    intent.putExtra("SAVE_HISTORY", false);
    startActivityForResult(intent, 0);
    

    然后,在OnActivityResult

    if (requestCode == 0) {
    if (resultCode == RESULT_OK) {
    String contents = data.getStringExtra("SCAN_RESULT");
    Log.d(TAG, "contents: " + contents);
    } else if (resultCode == RESULT_CANCELED) {
    // Handle cancel
    Log.d(TAG, "RESULT_CANCELED");
    }
    }
    

    我尽量做到描述性强。我希望人们觉得它有用。

    请阅读代码作者之一关于将代码复制到您自己的应用程序中的答案:https://stackoverflow.com/a/9942761

    参考资料: https://stackoverflow.com/a/29818279 https://stackoverflow.com/a/29960361 以及其他一些博客/SO 答案。

    【讨论】:

    • 你的教程对我有用。一步一步很容易理解。
    • 只是感觉注意事项: 1)您需要在Manifest中添加android.permission.CAMERA。 2)从Android 6开始,您需要询问用户权限才能访问相机。
    • @wm1sr 很高兴它对您有所帮助。 'CAMERA' 权限已经在manifest.xml 中列出,是的,它没有更新为 Marshmallow 中引入的运行时权限。所以,是的,开发人员也必须考虑到这一点。
    • 在你的终端上运行svn checkout https://github.com/zxing/zxing/trunk/android,只获取android目录。
    • 非常感谢您的详细解答!
    【解决方案3】:

    我不知道为什么会这样,但最后我使用了另一个库。我使用Zxing-android-minimal 和来自herehere 的教程。现在可以了。

    【讨论】:

      【解决方案4】:

      我真的迟到了,但我想回复这个问题,以便稍后帮助其他人。这并不是说上述方法和解决方案是错误的,它只是一个附加信息,所以对于开发者来说,他/她会选择更好的方法。有千百条路好过有一条路。

      那么,让我们开始进入我们的 gradle 并添加

      compile 'com.journeyapps:zxing-android-embedded:3.2.0@aar'
      compile 'com.google.zxing:core:3.2.1'
      

      像这样调用模块(例如:点击按钮):

      IntentIntegrator integrator = new IntentIntegrator(Home.this);
                  integrator.setDesiredBarcodeFormats(IntentIntegrator.ALL_CODE_TYPES);
                  integrator.setPrompt("Scan Code");
                  integrator.setCameraId(0);
                  integrator.setBeepEnabled(true);
                  integrator.setBarcodeImageEnabled(false);
                  integrator.initiateScan();
      

      得到如下结果:

      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
          IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
          if(intentResult != null) {
              if(intentResult.getContents() == null) {
                  Log.d("MainActivity", "Cancelled");
                  Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
      
              } else {
                  Log.d("MainActivity", "Scanned");
                  Toast.makeText(this, "Scanned: " + intentResult.getContents(), Toast.LENGTH_LONG).show();
              }
          }
      

      }

      有关更多信息,您可以查看链接 https://github.com/pethoalpar/ZxingExample

      【讨论】:

      • 谢谢,这很好,但如果您有不同代码的其他活动结果。是否有类似 startActivityForResult(1002) 等积分器的代码?
      【解决方案5】:

      如果你像我一样找不到罐子,这里有网址:

      http://repo1.maven.org/maven2/com/google/zxing/

      【讨论】:

        【解决方案6】:

        在我的代码中,我得到了这个版本:

        Camera.PreviewCallback myCallBack = new Camera.PreviewCallback() {
           @Override public void onPreviewFrame(byte[] data, Camera camera)
           {
              Camera.Parameters parameters = camera.getParameters();
              int width = parameters.getPreviewSize().width;
              int height = parameters.getPreviewSize().height;
              int format = parameters.getPreviewFormat();
              LuminanceSource source = null;
              if(format == ImageFormat.NV21) //YCbCr_420_SP)
              {
                 source = new PlanarYUVLuminanceSource(imgData, bitmapWidth, bitmapHeight, 0,0, bitmapWidth,bitmapHeight, false);
              } else
              {
                 throw new UnsupportedOperationException("Unsupported image format ");
              }
              BinaryBitmap bBitmap = new BinaryBitmap(new HybridBinarizer(source));
              try
              {
                 Result result = reader.decode(bBitmap);
                 txt.setText(result.getText())
              } catch (NotFoundException e)
              {
                 //txt.setText("");
              }
           }
        };
        

        import android.hardware.Camera;
        import com.google.zxing.BinaryBitmap;
        import com.google.zxing.LuminanceSource;
        import com.google.zxing.MultiFormatReader;
        import com.google.zxing.NotFoundException;
        import com.google.zxing.PlanarYUVLuminanceSource;
        import com.google.zxing.Result;
        import com.google.zxing.common.HybridBinarizer;
        
        Camera mCamera;
        MultiFormatReader reader;
        TextView txt;
        

        我希望这对某人有所帮助。

        安东尼诺

        【讨论】:

          【解决方案7】:

          详细说明 stackex 的答案....创建一个任意名称的活动。

          public class CaptureActivityAnyOrientation extends CaptureActivity {
          }
          

          在清单中定义所需的方向或像下面一样离开以在横向和纵向中工作。

          <activity android:name=".CaptureActivityAnyOrientation"
                android:screenOrientation="fullSensor"
                android:stateNotNeeded="true"
                android:theme="@style/zxing_CaptureTheme"
                android:windowSoftInputMode="stateAlwaysHidden"/>
          

          最后使用setCaptureActivity创建的activity。

          IntentIntegrator.forSupportFragment(fragment)
                              .setCaptureActivity(CaptureActivityAnyOrientation.class)
                              .setOrientationLocked(false)
                              .setBeepEnabled(true)
                              .addExtra("PROMPT_MESSAGE", "Scan QR Code")
                              .initiateScan(IntentIntegrator.QR_CODE_TYPES);
          

          希望这会有所帮助。

          【讨论】:

            【解决方案8】:

            由于这个帖子很旧,但我刚刚遇到了这个问题。因此,我只是为使用 Android Studio 并希望集成核心类的其他人发帖。您需要做的就是添加这个依赖项

            implementation 'com.google.zxing:core:x.x.x'
            

            Android Studio 会自动为您推荐上述的最新版本。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-11-06
              • 1970-01-01
              相关资源
              最近更新 更多