【问题标题】:Android: Bluetooth printingAndroid:蓝牙打印
【发布时间】:2012-04-07 23:46:40
【问题描述】:

我必须为 Android 平板电脑开发一个应用程序,该应用程序需要将文件打印到 蓝牙打印机。通过蓝牙打印是我的应用程序最重要的功能之一。不幸的是,关于这个主题的信息并不多,所以我想请教一下。

据我所知,无法在 Android 上通过蓝牙进行打印(使用本机调用),因为 Android 的 BT Stack 没有实现 BPP(基本打印配置文件)。做了一些研究,我发现了以下替代方案:

SDK/库

  • Sybase-iAnywhere-Blue-SDK-for-Android : 商业 SDK 支持 很多BT配置文件。大公司开发的(好支持我 猜测)。我没有找到很多关于这个的信息。是 有一些关于如何使用这个 SDK 的文档、API 或示例?做 有人知道如何下载演示版吗? (链接似乎是 我上次尝试时坏了)
  • iPrint SDK:商业 SDK。他们网站上有一些例子,但没有其他的。
  • Zebralink:仅适用于 Zebra 打印机(自然)。其他制造商可能也为其打印机提供 API。

Google Play 应用程序

  • PrinterShare:商业(高级密钥)
  • 蓝牙智能打印:免费且轻便。声称可以打印到蓝牙打印机。

理想情况下,我不想被绑定到特定品牌或打印机型号。现在的问题:

  • 您认为最佳选择是什么?
  • 你知道我错过的任何其他选择吗?
  • 我可以使用外部应用轻松地从我的应用打印文件吗?
  • 我的文件应该使用什么格式才能打印出来 蓝牙? (pdf、图片等)
  • 对打印机制造商和型号有何建议?
  • 您是否有过在 Android 上通过蓝牙进行打印的真实体验?
  • 近期是否有计划实施蓝牙 在 Android 上打印?

提前感谢您的帮助;)

【问题讨论】:

  • 我可以担保 PrinterShare 应用程序 - play.google.com/store/apps/… - 它适用于我的 HP Officejet 100 移动打印机设备。不过,我在 Google Play 中找不到 蓝牙智能打印 应用程序。有链接吗?

标签: android bluetooth


【解决方案1】:

Star Micronics 有一个 SDK,用于通过蓝牙(以及以太网和 USB)进行 Android 打印。你可以在这里下载:http://www.starmicronics.com/support/SDKDocumentation.aspx

正如您所提到的,您目前无法进行本地打印,因此您找到的替代解决方案是您今天的选择。

根据我的经验,最好使用 API 而不是外部应用程序。最大的原因是您可以完全控制打印机的行为。如果 API 是智能构建的,这也很容易。使用外部应用程序会受到限制,因为您无法按照自己想要的方式自定义打印输出。

我链接到的 Star SDK 有一个非常棒的示例应用程序,可让您测试和自定义许多打印机功能以查看它们的运行情况。每个函数都记录在源代码中。命令及其参数也可在应用程序本身中作为快速屏幕参考,这很方便。最重要的是,它有据可查。

Star 是一家值得合作的好公司,因为您可以免费获得一台您选择的演示打印机用于您的开发。

如果您选择这种方式,您可以将纯文本连同命令一起发送到打印机。 API 负责将数据转换为打印机可以理解的内容。

【讨论】:

  • Is Star micronics 是一个免许可证的 sdk。
  • STARIOSDK 是否可以帮助打印各种文件。
  • 您知道 SDK 是否可以与其他品牌的蓝牙打印机一起使用吗?
  • StarAndroidSDK 是否不适用于其他公司打印机?因为,我试过了,但它没有显示我的任何蓝牙或网络打印机。
【解决方案2】:

打印到蓝牙打印机的可能性很大程度上取决于您尝试使用的打印机型号。

例如,我使用 CITIZEN CMP-10BT 打印机,它可以通过发送特定的字节序列来控制,这可以使用 Android API 轻松完成。我什至在此基础上构建了一个框架。

问题仅在于您无法确定最终用户将使用哪种打印机型号,因此某些最终的 SDK 肯定会非常需要。

【讨论】:

  • 感谢您的回答,亚历克斯。出于好奇,您提到的“框架”是开源的。而且,如果是这样,在哪里可以找到它?谢谢。
  • @Josh Pinter:不幸的是,没有。它是商业项目的一部分,所以没有地方可以“找到”它。如果您仍然有兴趣,可以给我写电子邮件(请参阅个人资料中的地址),我可能会提供一些打印所需的代码部分。
  • 谢谢,亚历克斯。找不到您的电子邮件地址,但我想我现在已经找到了我要找的东西。不过,我感谢您提供帮助。
  • @AlexSemeniuk 你能帮我吗?我想使用 CITIZEN CMP-10BT 进行打印,但如果没有 SDK 或一些代码来指导我,我就无法做到。我正在尝试通过 BluetoothSocket 进行连接,但它总是返回 read failed.。你能帮助我吗?我正在为您发送一封电子邮件。
【解决方案3】:

您可以下载此组件: https://components.xamarin.com/view/ocpp-thermal-printer-usb 它在大多数 USB 和蓝牙通用打印机中就像一个魅力。我创建了一个类来发送最常用的 esc 命令。用法:outerInstance.mService.Write(modes.pordefecto());

public class modes
{
    public static byte[] condensado()
    {
        byte[] cmd = new byte[3];
        cmd[0] = 0x1b;
        cmd[1] = 0x21;
        cmd[2] |= 0x01;

        return cmd;
    }

    public static byte[] pordefecto()
    {
        byte[] cmd = new byte[3];
        cmd[0] = 0x1b;
        cmd[1] = 0x21;
        cmd[2] |= 0x00;
        return cmd;
    }

    public static byte[] negrita()
    {
        byte[] cmd = new byte[3];
        cmd[0] = 0x1b;
        cmd[1] = 0x21;
        cmd[2] |= 0x08;
        return cmd;
    }

    public static byte[] lineamenor()
    {
        byte[] cmd = new byte[3];
        cmd[0] = 0x1b;
        cmd[1] = 0x33;
        cmd[2] |= 0x14;
        return cmd;
    }

    public static byte[] cancelalinea()
    {
        byte[] cmd = new byte[2];
        cmd[0] = 0x1b;
        cmd[1] = 0x32;
        return cmd;
    }

    public static byte[] centra()
    {
        byte[] cmd = new byte[3];
        cmd[0] = 0x1b;
        cmd[1] = 0x61;
        cmd[2] |= 0x01;
        return cmd;
    }

    public static byte[] quitacentro()
    {
        byte[] cmd = new byte[3];
        cmd[0] = 0x1b;
        cmd[1] = 0x61;
        cmd[2] |= 0x00;
        return cmd;
    }

    public static byte[] codepage()
    {
        byte[] cmd = new byte[5];
        cmd[0] = 0x1f;
        cmd[1] = 0x1b;
        cmd[2] = 0x1f;
        cmd[3] |= 0xfe;
        cmd[4] |= 0x01;
        return cmd;
    }

    public static byte[] latino()
    {
        byte[] cmd = new byte[5];
        cmd[0] = 0x1f;
        cmd[1] = 0x1b;
        cmd[2] = 0x1f;
        cmd[3] |= 0xff;
        cmd[4] |= 0x12;
        return cmd;
    }
    public static byte[] logo()
    {
        byte[] cmd = new byte[4];
        cmd[0] = 0x1c;
        cmd[1] = 0x70;
        cmd[2] = 0x01;
        cmd[3] |= 0x00;

        return cmd;
    }
}

【讨论】:

    【解决方案4】:

    为任何类型的打印机使用 Printooth 库,零配置,简单的使用和良好的文档

    https://github.com/mazenrashed/Printooth

    这是一个打印简单行的示例代码:

    var printables = ArrayList<Printable>()
    var printable = Printable.PrintableBuilder()  
        .setImage(image) 
        .setNewLinesAfter(1) // To provide n lines after sentence
        .build()
    printables.add(printable)
    BluetoothPrinter.printer().print(printables)
    

    您可以在此处继续阅读: https://github.com/mazenrashed/Printooth/blob/master/README.md

    【讨论】:

    • 我正在使用这个库,但我得到了第一行特殊字符。在我的印刷品中。我想删除那条线。
    • 当心!这个库没有正确实现 ESC/POS!它会打印乱码,因为它发送了错误的打印命令。
    【解决方案5】:

    任何使用 ZPL 的打印机都可以通过蓝牙接口将指令写入打印机进行打印(已测试并且可以使用)

    我的问题是我不确定如何检测 BT 设备是否是打印机

    write(zplString, btSocket)
    
    fun write(bytes: String, socket: BluetoothSocket) {
            val mmOutStream = socket.outputStream
            /* Send data to BT device */
            try {
                mmOutStream?.write(bytes.toByteArray(Charset.forName("UTF-8")))
            } catch (e : Exception){
                Log.v("BT", "Unable to send message")
                if (socket.isConnected){
                  socket.close()
                }
                attemptConnection()
                try {
                    for (mSocket in sockets) {
                        val fbOutStream = mSocket.outputStream
                        fbOutStream?.write(bytes.toByteArray(Charset.forName("UTF-8")))
                    }
                } catch (e : Exception){
                    /* Fallback write failed */
                    Log.v("BT", "Unable to send message second attempt")
                }
            }
        }
    
    private fun attemptConnection(){
       for (socket in sockets){
           try{
               if (socket.isConnected){
                  socket.close()
               }
            } catch (e: Exception){
             /* Do nothing, we just want to try to close it */
            }
         }
         sockets.clear()
         for (device in btConnectList) {
            var tempSocket: BluetoothSocket? = null
                try {
                    tempSocket = device.createInsecureRfcommSocketToServiceRecord(myUUID)
                } catch (e: Exception) {
                    Log.v("BT", "Could not connect to socket")
                }
                if (tempSocket != null) {
                    try {
                        tempSocket.connect()
                    } catch (e: IOException) {
                        Log.v("BT", "Connection falied attempting fallback")
                        try {
                            val clazz = tempSocket.remoteDevice.javaClass
                            val paramTypes = arrayOf<Class<*>>(Int::class.java)
                            val m = clazz.getMethod("createRfcommSocket", *paramTypes)
                            val fallbackSocket =
                                m.invoke(tempSocket.remoteDevice, 2) as BluetoothSocket
                            fallbackSocket.connect()
                        } catch (e: Exception) {
                            Log.v("BT", "Fallback failed")
                        }
                    }
                    sockets.add(tempSocket)
                } else {
                    /* Try fallback */
                    try {
                        tempSocket = device.bluetoothClass.javaClass.getMethod(
                            "createRfcommSocket", Int::class.java
                        ).invoke(device, 1) as BluetoothSocket
                        tempSocket.connect()
                        sockets.add(tempSocket)
                    } catch (e: Exception) {
                        Log.v("BT", "Fallback failed")
                    }
                }
            }
        }
    

    【讨论】:

      【解决方案6】:

      从 android 4.4 开始,您可以使用 Android 框架库进行打印,如下所述: https://developer.android.com/training/printing

      例如,要打印图像,您可以执行以下操作:

      private fun doPhotoPrint() {
          activity?.also { context ->
              PrintHelper(context).apply {
                  scaleMode = PrintHelper.SCALE_MODE_FIT
              }.also { printHelper ->
                  val bitmap = BitmapFactory.decodeResource(resources, R.drawable.droids)
                  printHelper.printBitmap("droids.jpg - test print", bitmap)
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-22
        相关资源
        最近更新 更多