转载至: https://blog.csdn.net/u011056653/article/details/74308254

最近在做小票打印这块,项目需求是蓝牙和WiFi两种都要实现,开始做的时候也是一脸懵,然后网上找了一些代码,看了好多博主的文章,最后自己把这些都综合到一起0.0,结果还好成功了

先看看图吧,蓝牙和WiFi打印出的都是一样的,毕竟都是同一个工具类(打印机型号  爱宝POS-80C 、 资江 ZJ-80)

先来看看WiFi打印(旁边的色块是打印纸自带的,我也很无奈)

首先在你的activity里触发点击事件

right = (TextView) findViewById(R.id.right);//点击WiFi打印
right.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {pos();}
});//调用打印的方法

private void pos() {
        // 开启一个子线程
        new Thread() {
            public void run() {
                try {              //打印机网口IP    打印机端口号     编码方式
                    pos = new Pos(Preference.instance(PayTypeActivity.this).getIPAddress(), Integer.parseInt(Preference.instance(PayTypeActivity.this).getPost_IDs()), "gbk");
                    //初始化打印机
                    pos.initPos();
                    if (!TextUtils.isEmpty(objBean.getHead_img())){
                        pos.printLocation(1);
                        bitmap = pos.compressPic(returnBitMap(objBean.getHead_img()));
                        pos.draw2PxPoint(bitmap);
                    }
                    pos.printLocation(1);
                    pos.bold(true);
                    pos.printTabSpace(2);
                    pos.printWordSpace(1);
                    pos.printTextNewLine(objBean.getShop_name());

pos.printLocation(0);
                    pos.printTextNewLine("----------------------------------------------");
                    pos.bold(false);
                    pos.printTextNewLine("订 单 号:"+objBean.getSn());
                    pos.printTextNewLine("用 户 名:"+objBean.getMember());
                    pos.printTextNewLine("订单日期:"+objBean.getCreate_time());
                    pos.printTextNewLine("支付方式:"+objBean.getPay_way());
                    pos.printTextNewLine("订单折扣:"+objBean.getDiscount());
                    pos.printTextNewLine("订单备注:"+objBean.getRemarks());
                    pos.printLine(2);

pos.printText("货号          尺码    颜色    数量   小计");
                    pos.printLocation(20, 1);
                    pos.printTextNewLine("----------------------------------------------");

for (ParentBean foods : foodsBean) {
                        pos.printTextNewLine(foods.getGoods_name()+"          "+foods.getCode_number()+"     "+foods.getColour()+"      "+foods.getNum()+"      "+foods.getPay_back());
                        pos.printLocation(20, 1);
                    }

pos.printTextNewLine("----------------------------------------------");
                    pos.printLocation(0);
                    pos.printLine(1);
                    pos.printTextNewLine("订单总数:"+objBean.getNums());
                    pos.printTextNewLine("应收金额:"+objBean.getActual_pay());
                    pos.printTextNewLine("优惠金额:"+objBean.getDiscount_pay());
                    pos.printTextNewLine("实收金额:"+objBean.getPay());
                    pos.printLine(2);

//                    //打印二维码  -- 如果提供了二维码的地址则用该方法
//                    pos.qrCode(objBean.getQr_code());

//打印二维码的图片 -- 如果提供了二维码的截图则用该方法
                    if (!TextUtils.isEmpty(objBean.getQr_code())){
                        pos.printLocation(1);
                        Qbitmap = pos.compressPic(returnBitMap(objBean.getQr_code()));//url 转换为bitmap
                        pos.draw2PxPoint(Qbitmap);
                    }
                    //切纸
                    pos.feedAndCut();
                    pos.closeIOAndSocket();
                    pos = null;
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                    showToast(e.toString());
                    Log.d("tag", "错误信息1:" + e.toString());
                } catch (IOException e) {
                    e.printStackTrace();
                    showToast(e.toString());
                    Log.d("tag", "错误信息2:" + e.toString());
                }
            }

}.start();

}

//将图片url转换为bitmap

public Bitmap returnBitMap(String url) {
        URL myFileUrl = null;
        Bitmap bitmap = null;
        try {
            myFileUrl = new URL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        try {
            HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            bitmap = BitmapFactory.decodeStream(is);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }
再来看看调用的工具类(蓝牙和WiFi共用一个,只是初始化方式不同)

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class Pos {
    //定义编码方式
    private static String encoding = null;

private Socket sock = null;
    // 通过socket流进行读写
    private OutputStream socketOut = null;
    private OutputStreamWriter writer = null;

/**
     * 初始化Pos实例
     *
     * @param ip 打印机IP
     * @param port 打印机端口号
     * @param encoding 编码
     * @throws IOException
     */
    public Pos(String ip, int port, String encoding) throws IOException {
        sock = new Socket(ip, port);
        socketOut = new DataOutputStream(sock.getOutputStream());
        this.encoding = encoding;
        writer = new OutputStreamWriter(socketOut, encoding);
    }

//蓝牙初始化
    public Pos(OutputStream outputStream, String encoding) throws IOException {
        writer = new OutputStreamWriter(outputStream, encoding);
        socketOut = outputStream;
        initPrinter();
    }

public void print(byte[] bs) throws IOException {
        socketOut.write(bs);
    }

public void printRawBytes(byte[] bytes) throws IOException {
        socketOut.write(bytes);
        socketOut.flush();
    }

/**
     * 初始化打印机
     *
     * @throws IOException
     */
    public void initPrinter() throws IOException {
        socketOut.write(0x1B);
        socketOut.write(0x40);
        socketOut.flush();
    }
    /**
     * 关闭IO流和Socket
     *
     * @throws IOException
     */
    public void closeIOAndSocket() throws IOException {
        writer.close();
        socketOut.close();
        sock.close();
    }

/**
     * 打印二维码
     *
     * @param qrData 二维码的内容
     * @throws IOException
     */
    public void qrCode(String qrData) throws IOException {
        int moduleSize = 8;
        int length = qrData.getBytes(encoding).length;

//打印二维码矩阵
        writer.write(0x1D);// init
        writer.write("(k");// adjust height of barcode
        writer.write(length + 3); // pl
        writer.write(0); // ph
        writer.write(49); // cn
        writer.write(80); // fn
        writer.write(48); //
        writer.write(qrData);

writer.write(0x1D);
        writer.write("(k");
        writer.write(3);
        writer.write(0);
        writer.write(49);
        writer.write(69);
        writer.write(48);

writer.write(0x1D);
        writer.write("(k");
        writer.write(3);
        writer.write(0);
        writer.write(49);
        writer.write(67);
        writer.write(moduleSize);

writer.write(0x1D);
        writer.write("(k");
        writer.write(3); // pl
        writer.write(0); // ph
        writer.write(49); // cn
        writer.write(81); // fn
        writer.write(48); // m

writer.flush();

}

/**
     * 进纸并全部切割
     *
     * @return
     * @throws IOException
     */
    public void feedAndCut() throws IOException {
        writer.write(0x1D);
        writer.write(86);
        writer.write(65);
        //    writer.write(0);
        //切纸前走纸多少
        writer.write(100);
        writer.flush();

//另外一种切纸的方式
        //    byte[] bytes = {29, 86, 0};
        //    socketOut.write(bytes);
    }

/**
     * 打印换行
     *
     * @return length 需要打印的空行数
     * @throws IOException
     */
    public void printLine(int lineNum) throws IOException {
        for (int i = 0; i < lineNum; i++) {
            writer.write("\n");
        }
        writer.flush();
    }

/**
     * 打印换行(只换一行)
     *
     * @throws IOException
     */
    protected void printLine() throws IOException {
        writer.write("\n");
        writer.flush();
    }

/**
     * 打印空白(一个Tab的位置,约4个汉字)
     *
     * @param length 需要打印空白的长度,
     * @throws IOException
     */
    public void printTabSpace(int length) throws IOException {
        for (int i = 0; i < length; i++) {
            writer.write("\t");
        }
        writer.flush();
    }

/**
     * 打印空白(一个汉字的位置)
     *
     * @param length 需要打印空白的长度,
     * @throws IOException
     */
    public void printWordSpace(int length) throws IOException {
        for (int i = 0; i < length; i++) {
            writer.write(" ");
        }
        writer.flush();
    }

/**
     * 打印位置调整
     *
     * @param position 打印位置 0:居左(默认) 1:居中 2:居右
     * @throws IOException
     */
    public void printLocation(int position) throws IOException {
        writer.write(0x1B);
        writer.write(97);
        writer.write(position);
        writer.flush();
    }

/**
     * 绝对打印位置
     *
     * @throws IOException
     */
    public void printLocation(int light, int weight) throws IOException {
        writer.write(0x1B);
        writer.write(0x24);
        writer.write(light);
        writer.write(weight);
        writer.flush();
    }

/**
     * 打印文字
     *
     * @param text
     * @throws IOException
     */
    public void printText(String text) throws IOException {
        String s = text;
        byte[] content = s.getBytes("gbk");
        socketOut.write(content);
        socketOut.flush();
    }

/**
     * 新起一行,打印文字
     *
     * @param text
     * @throws IOException
     */
    public void printTextNewLine(String text) throws IOException {
        //换行
        writer.write("\n");
        writer.flush();

String s = text;
        byte[] content = s.getBytes("gbk");
        socketOut.write(content);
        socketOut.flush();
    }

/**
     * 初始化打印机
     *
     * @throws IOException
     */
    public void initPos() throws IOException {
        writer.write(0x1B);
        writer.write(0x40);
        writer.flush();
    }

/**
     * 加粗
     *
     * @param flag false为不加粗
     * @return
     * @throws IOException
     */
    public void bold(boolean flag) throws IOException {
        if (flag) {
            //常规粗细
            writer.write(0x1B);
            writer.write(69);
            writer.write(0xF);
            writer.flush();
        } else {
            //加粗
            writer.write(0x1B);
            writer.write(69);
            writer.write(0);
            writer.flush();
        }
    }

/**
     * 对图片进行压缩(去除透明度)
     *
     * @param
     */
    public static Bitmap compressPic(Bitmap bitmap) {
        // 获取这个图片的宽和高
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        // 指定调整后的宽度和高度
        int newWidth = 200;
        int newHeight = 200;
        Bitmap targetBmp = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
        Canvas targetCanvas = new Canvas(targetBmp);
        targetCanvas.drawColor(0xffffffff);
        targetCanvas.drawBitmap(bitmap, new Rect(0, 0, width, height), new Rect(0, 0, newWidth, newHeight), null);
        return targetBmp;
    }

/**
     * 灰度图片黑白化,黑色是1,白色是0
     *
     * @param x   横坐标
     * @param y   纵坐标
     * @param bit 位图
     * @return
     */
    public static byte px2Byte(int x, int y, Bitmap bit) {
        if (x < bit.getWidth() && y < bit.getHeight()) {
            byte b;
            int pixel = bit.getPixel(x, y);
            int red = (pixel & 0x00ff0000) >> 16; // 取高两位
            int green = (pixel & 0x0000ff00) >> 8; // 取中两位
            int blue = pixel & 0x000000ff; // 取低两位
            int gray = RGB2Gray(red, green, blue);
            if (gray < 128) {
                b = 1;
            } else {
                b = 0;
            }
            return b;
        }
        return 0;
    }

/**
     * 图片灰度的转化
     */
    private static int RGB2Gray(int r, int g, int b) {
        int gray = (int) (0.29900 * r + 0.58700 * g + 0.11400 * b);  //灰度转化公式
        return gray;
    }

/*************************************************************************
     * 假设一个240*240的图片,分辨率设为24, 共分10行打印
     * 每一行,是一个 240*24 的点阵, 每一列有24个点,存储在3个byte里面。
     * 每个byte存储8个像素点信息。因为只有黑白两色,所以对应为1的位是黑色,对应为0的位是白色
     **************************************************************************/
    /**
     * 把一张Bitmap图片转化为打印机可以打印的字节流
     *
     * @param bmp
     * @return
     */
    public void draw2PxPoint(Bitmap bmp) throws IOException {

//用来存储转换后的 bitmap 数据。为什么要再加1000,这是为了应对当图片高度无法
        //整除24时的情况。比如bitmap 分辨率为 240 * 250,占用 7500 byte,
        //但是实际上要存储11行数据,每一行需要 24 * 240 / 8 =720byte 的空间。再加上一些指令存储的开销,
        //所以多申请 1000byte 的空间是稳妥的,不然运行时会抛出数组访问越界的异常。
        int size = bmp.getWidth() * bmp.getHeight() / 8 + 1000;
        byte[] data = new byte[size];
        int k = 0;
        //设置行距为0的指令
        data[k++] = 0x1B;
        data[k++] = 0x33;
        data[k++] = 0x00;
        // 逐行打印
        for (int j = 0; j < bmp.getHeight() / 24f; j++) {
            //打印图片的指令
            data[k++] = 0x1B;
            data[k++] = 0x2A;
            data[k++] = 33;
            data[k++] = (byte) (bmp.getWidth() % 256); //nL
            data[k++] = (byte) (bmp.getWidth() / 256); //nH
            //对于每一行,逐列打印
            for (int i = 0; i < bmp.getWidth(); i++) {
                //每一列24个像素点,分为3个字节存储
                for (int m = 0; m < 3; m++) {
                    //每个字节表示8个像素点,0表示白色,1表示黑色
                    for (int n = 0; n < 8; n++) {
                        byte b = px2Byte(i, j * 24 + m * 8 + n, bmp);
                        data[k] += data[k] + b;
                    }
                    k++;
                }
            }
            data[k++] = 10;//换行
        }
        socketOut.write(data);
        socketOut.flush();
    }
}

WiFi打印小票到此基本上就可以了
下面开始我们的蓝牙打印
蓝牙打印的话首先就要有权限

//蓝牙权限 
<uses-permission android:name="android.permission.BLUETOOTH" />
 <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
 再来看看蓝牙相关的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <include layout="@layout/top_bar"/>

<TextView
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:background="@color/colorGrayTertiary"
        android:gravity="center_vertical"
        android:paddingLeft="16dp"
        android:text="选择一个已配对的打印设备 (请确保打印机和平板的蓝牙已开通)"
        android:textColor="@color/textColorSecondary"
        android:textSize="14sp" />

<ListView
        android:id="@+id/lv_paired_devices"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@color/colorWhite"
        android:choiceMode="singleChoice"
        android:divider="@android:drawable/divider_horizontal_bright" />

<LinearLayout
        android:layout_marginBottom="15dp"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">
        <Button
            android:background="@drawable/submit_select"
            android:textColor="@color/white"
            android:id="@+id/btn_goto_setting"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:layout_marginLeft="@dimen/common_margin"
            android:layout_marginRight="@dimen/common_margin"
            android:text="还未配对打印机,去设置" />

<Button
            android:background="@drawable/submit_select"
            android:textColor="@color/white"
            android:id="@+id/btn_test_conntect"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:layout_marginLeft="@dimen/common_margin"
            android:layout_marginRight="@dimen/common_margin"

android:text="测试打印机连接" />

<Button
            android:background="@drawable/submit_select"
            android:id="@+id/btn_print"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:layout_marginLeft="@dimen/common_margin"
            android:layout_marginRight="@dimen/common_margin"
            android:text="打印"
            android:textColor="@color/white" />
    </LinearLayout>
</LinearLayout>

接着具体看看代码里面怎么实现的,包括蓝牙的一些检索和设置 
public class PrinterSettingActivity extends BasePrintActivity implements View.OnClickListener{
    private Root root;
    private String result;
    private ObjBean obj;
    private ObjBean objBean;
    private List<ParentBean> foodsBean;
    private List<ListBean> listBeen;
    ListView mLvPairedDevices;
    Button mBtnSetting;
    Button mBtnTest;
    Button mBtnPrint;

DeviceListAdapter mAdapter;
    int mSelectedPosition = -1;

final static int TASK_TYPE_CONNECT = 1;
    final static int TASK_TYPE_PRINT = 2;

private String id;
    private Pos pos;
    private OutputStream mOutputStream = null;
    private Bitmap head_bitmap;
    private Bitmap code_bitmap;
    private LinearLayout back;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_printer_setting);
        id = getIntent().getStringExtra("id");
        setTitle("蓝牙打印");
        initViews();
        print();//获取小票数据
    }

private void print() {
            HttpUtil.ticket(this, id, new HttpUtil.KWiListener() {
                @Override
                public void onResult(int ret, Object msg) {
                    Log.d("tag", "打印小票: " + msg.toString());
                    Gson gson = new Gson();
                    String jsonString = msg.toString();
                    root = gson.fromJson(jsonString, Root.class);
                    result = root.getResult().getResultCode();
                    if (result.equals("0")) {
                        objBean = root.getObj();
                        foodsBean = objBean.getParent();

} else {
                        ToastUtil.show(root.getResult().getResultMessage());
                    }
                }
            });
        }

@Override
    protected void onResume() {
        super.onResume();
        fillAdapter();
    }

private void initViews() {
        back = (LinearLayout) findViewById(R.id.back);
        back.setOnClickListener(this);
        mLvPairedDevices = (ListView) findViewById(R.id.lv_paired_devices);
        mBtnSetting = (Button) findViewById(R.id.btn_goto_setting);
        mBtnTest = (Button) findViewById(R.id.btn_test_conntect);
        mBtnPrint = (Button) findViewById(R.id.btn_print);

mLvPairedDevices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                mSelectedPosition = position;
                mAdapter.notifyDataSetChanged();
            }
        });

mBtnSetting.setOnClickListener(this);
        mBtnTest.setOnClickListener(this);
        mBtnPrint.setOnClickListener(this);

mAdapter = new DeviceListAdapter(this);
        mLvPairedDevices.setAdapter(mAdapter);
    }

/**
     * 从所有已配对设备中找出打印设备并显示
     */
    private void fillAdapter() {
        //推荐使用 BluetoothUtil.getPairedPrinterDevices()
        List<BluetoothDevice> printerDevices = BluetoothUtil.getPairedDevices();
        mAdapter.clear();
        mAdapter.addAll(printerDevices);
        refreshButtonText(printerDevices);
    }

private void refreshButtonText(List<BluetoothDevice> printerDevices) {
        if (printerDevices.size() > 0) {
            mBtnSetting.setText("配对更多设备");
        } else {
            mBtnSetting.setText("还未配对打印机,去设置");
        }
    }

@Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_goto_setting:
                startActivity(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
                break;

case R.id.btn_test_conntect:
                connectDevice(TASK_TYPE_CONNECT);
                break;

case R.id.btn_print:
                connectDevice(TASK_TYPE_PRINT);
                break;
            case R.id.back:
                finish();
                break;
            default:
                break;
        }
    }

private void connectDevice(int taskType){
        if(mSelectedPosition >= 0){
            BluetoothDevice device = mAdapter.getItem(mSelectedPosition);
            if(device!= null)
                super.connectDevice(device, taskType);
        }else{
            Toast.makeText(this, "还未选择打印设备", Toast.LENGTH_SHORT).show();
        }
    }

@Override
    public void onConnected(BluetoothSocket socket, int taskType) {
        switch (taskType){
            case TASK_TYPE_PRINT:
                if(socket != null&&socket.isConnected()){
                    pos(socket);
                }

break;
        }
    }

private void pos(final BluetoothSocket socket) {
        // 开启一个子线程
        new Thread() {
            public void run() {
                try {
                    //初始化打印机
                    pos = new Pos(socket.getOutputStream(),"GBK");
                    if (!TextUtils.isEmpty(objBean.getHead_img())){
                        pos.printLocation(1);
                        head_bitmap = pos.compressPic(returnBitMap(objBean.getHead_img()));
                        pos.draw2PxPoint(head_bitmap);
                    }
                    pos.printLocation(1);
                    pos.bold(true);
                    pos.printTabSpace(2);
                    pos.printWordSpace(1);
                    pos.printTextNewLine(objBean.getShop_name());

pos.printLocation(0);
                    pos.printTextNewLine("----------------------------------------------");
                    pos.bold(false);
                    pos.printTextNewLine("订 单 号:"+objBean.getSn());
                    pos.printTextNewLine("用 户 名:"+objBean.getMember());
                    pos.printTextNewLine("订单日期:"+objBean.getCreate_time());
                    pos.printTextNewLine("支付方式:"+objBean.getPay_way());
                    pos.printTextNewLine("订单折扣:"+objBean.getDiscount());
                    pos.printTextNewLine("订单备注:"+objBean.getRemarks());
                    pos.printLine(2);

pos.printText("货号          尺码    颜色    数量   小计");
                    pos.printLocation(20, 1);
                    pos.printTextNewLine("----------------------------------------------");

for (ParentBean foods : foodsBean) {
                        pos.printTextNewLine(foods.getGoods_name()+"          "+foods.getCode_number()+"     "+foods.getColour()+"      "+foods.getNum()+"      "+foods.getPay_back());
                        pos.printLocation(20, 1);

}

pos.printTextNewLine("----------------------------------------------");
                    pos.printLocation(0);
                    pos.printLine(1);
                    pos.printTextNewLine("订单总数:"+objBean.getNums());
                    pos.printTextNewLine("应收金额:"+objBean.getActual_pay());
                    pos.printTextNewLine("优惠金额:"+objBean.getDiscount_pay());
                    pos.printTextNewLine("实收金额:"+objBean.getPay());
                    pos.printLine(2);
                    //打印二维码  -- 如果提供了二维码的地址则用该方法
//                  pos.qrCode(objBean.getQr_code());

//打印二维码的图片 -- 如果提供了二维码的截图则用该方法
                    if (!TextUtils.isEmpty(objBean.getQr_code())){
                        pos.printLocation(1);
                        code_bitmap = pos.compressPic(returnBitMap(objBean.getQr_code()));
                        pos.draw2PxPoint(code_bitmap);
                    }
                    pos.printLine(4);
                    //切纸
                    pos.feedAndCut();
//                  pos.closeIOAndSocket();
                    pos = null;
                } catch (UnknownHostException e) {
                    Log.d("tag", "错误信息1:" + e.toString());
                } catch (IOException e) {
                    Log.d("tag", "错误信息2:" + e.toString());
                }
            }

}.start();

}
    class DeviceListAdapter extends ArrayAdapter<BluetoothDevice> {

public DeviceListAdapter(Context context) {
            super(context, 0);
        }

@Override
        public View getView(int position, View convertView, ViewGroup parent) {

BluetoothDevice device = getItem(position);
            if (convertView == null) {
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_bluetooth_device, parent, false);
            }

TextView tvDeviceName = (TextView) convertView.findViewById(R.id.tv_device_name);
            CheckBox cbDevice = (CheckBox) convertView.findViewById(R.id.cb_device);

tvDeviceName.setText(device.getName());

cbDevice.setChecked(position == mSelectedPosition);

return convertView;
        }
    }
    public Bitmap returnBitMap(String url) {
        URL myFileUrl = null;
        Bitmap bitmap = null;
        try {
            myFileUrl = new URL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        try {
            HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            bitmap = BitmapFactory.decodeStream(is);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }
}

R.layout.item_bluetooth_device的布局如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:paddingLeft="@dimen/common_margin"
    android:paddingRight="@dimen/common_margin">

<TextView
        android:id="@+id/tv_device_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:text="蓝牙打印机"
        android:textColor="@color/textColorPrimary"
        android:textSize="14sp" />

<android.support.v7.widget.AppCompatCheckBox
        android:id="@+id/cb_device"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:textSize="14sp" />

</RelativeLayout>

最后还是打印小票的方法 pos(socket);这个方法和之前WiFi方法基本一致,只是初始化不一样

private void pos(final BluetoothSocket socket) {
        // 开启一个子线程
        new Thread() {
            public void run() {
                try {
                    //初始化打印机
                    pos = new Pos(socket.getOutputStream(),"GBK");
                    if (!TextUtils.isEmpty(objBean.getHead_img())){
                        pos.printLocation(1);
                        head_bitmap = pos.compressPic(returnBitMap(objBean.getHead_img()));
                        pos.draw2PxPoint(head_bitmap);
                    }
                    pos.printLocation(1);
                    pos.bold(true);
                    pos.printTabSpace(2);
                    pos.printWordSpace(1);
                    pos.printTextNewLine(objBean.getShop_name());
 
                    pos.printLocation(0);
                    pos.printTextNewLine("----------------------------------------------");
                    pos.bold(false);
                    pos.printTextNewLine("订 单 号:"+objBean.getSn());
                    pos.printTextNewLine("用 户 名:"+objBean.getMember());
                    pos.printTextNewLine("订单日期:"+objBean.getCreate_time());
                    pos.printTextNewLine("支付方式:"+objBean.getPay_way());
                    pos.printTextNewLine("订单备注:"+objBean.getRemarks());
                    pos.printLine(2);
 
                    pos.printText("货号          尺码    颜色    数量   小计");
                    pos.printLocation(20, 1);
                    pos.printTextNewLine("----------------------------------------------");
 
                    for (ParentBean foods : foodsBean) {
                        pos.printTextNewLine(foods.getGoods_name()+"            "+foods.getCode_number()+"     "+foods.getColour()+"      "+foods.getNum()+"      "+foods.getPay_back());
                        pos.printLocation(20, 1);
 
                    }
 
                    pos.printTextNewLine("----------------------------------------------");
                    pos.printLocation(0);
                    pos.printLine(1);
                    pos.printTextNewLine("总数:"+objBean.getNums());
                    pos.printTextNewLine("合计:"+objBean.getPay());
                    pos.printLine(2);
                    //打印二维码  -- 如果提供了二维码的地址则用该方法
//                  pos.qrCode(objBean.getQr_code());
 
 
                    //打印二维码的图片 -- 如果提供了二维码的截图则用该方法
                    if (!TextUtils.isEmpty(objBean.getQr_code())){
                        pos.printLocation(1);
                        code_bitmap = pos.compressPic(returnBitMap(objBean.getQr_code()));//returnBitmap方法和上面WiFi的一样
                        pos.draw2PxPoint(code_bitmap);
                    }
                    pos.printLine(4);
                    //切纸
                    pos.feedAndCut();
//                  pos.closeIOAndSocket();
                    pos = null;
                } catch (UnknownHostException e) {
                    Log.d("tag", "错误信息1:" + e.toString());
                } catch (IOException e) {
                    Log.d("tag", "错误信息2:" + e.toString());
                }
            }
 
        }.start();
 
    }
 
到此的话基本两种方式都可以了,我用两台打印机试过都没问题

下载地址:https://download.csdn.net/download/u011056653/10567104

Android 蓝牙打印小票与WiFi打印小票两种打印方式的实现(带有图片和二维码)相关推荐

  1. 二维码中加图片(打印带图片的二维码)

    在二维码中,放入图片,遮挡一部分是被允许的. 二维码在少许损伤的情况下还可以读取出来,图片可以放置的位置如图的黄色区域.(具体可以放多大要看二维码生成时的纠错能力) 二维码的纠错级别: 纠错级别越高, ...

  2. android 从图片获取二维码

    之前的博客我记得讲过关于扫描二维码的内容,昨天,组长让我不仅可以扫描获取二维码,还可以通过图片获取里面的二维码.比如别人拍了一张二维码的照片,发送给你,app应该可以获取图片的二维码. 自己在网上查了 ...

  3. Android实现图片和二维码拼在一起

    Android实现图片和二维码拼在一起 依赖implementation 'cn.bingoogolapple:bga-qrcode-zxing:1.3.7' 使用依赖里的方法生成二维码 QRCode ...

  4. 微信小程序实现蓝牙打印(图片、二维码、文字)

    小程序连接蓝牙打印机实现打印功能 这真是一块超级难啃的骨头,我也是参考了很多文章才勉强理解,但是如果你啃动了,那你以后也有了拿得出手的资本了 完整DEMO地址可直接下载下来使用 搜索与连接蓝牙,这个我 ...

  5. 怎么用python编写个apk_【android】如何利用python做Android项目自动化构建,并一键实现构建结果发送到钉钉通知以及通过二维码下载apk或者其他处理等功能...

    今天我们来谈一谈用python做Android项目自动化构建的过程.我们知道在常规的Android开发过程中,开发人员打包的时候需要在Android Studio当中进行,或者通过gradle命令,但 ...

  6. UniAPP Android 蓝牙 ESCPOS打印机 打印图片和二维码

    移动端打印的实现方式参考 上一篇:DCloud UniAPP Android 蓝牙连接ESCPOS打印机 本片来实现 上一篇中 打印图片中 的 img (图片点阵灰度数据) var img=XXXXX ...

  7. android 自定义侧边栏,android界面设计(一)侧边栏的两种实现方式

    dome:https://github.com/linliangliang/sidebar 一.使用slideingMenu结合fragment实现. 二.使用Navigation和DrawerLay ...

  8. 蓝牙连接打印机打印文字图片条形码二维码 用的是Gprinter打印机

    实现了蓝牙打印,正在进一步完善,欢迎留言交流 :) Github链接

  9. AD使用技巧——如何向AD里面导入图片(PCB打印图片、二维码)教程适用各个版本(17版及以前、18及以后、19、20、21版)(内附脚本文件下载)

    如何向AD里面导入图片 很多同学挑选设计了一些个人LOGO以及图片想导入到AD里面,或者想在PCB中印刷上二维码等图案.苦于缺少方法以及资源,本文详细介绍如何向AD里面导入图片,文末有导入图片所需脚本 ...

最新文章

  1. python 模拟键盘_Python 模拟键盘输入 | 学步园
  2. Controller的要求
  3. C#机房重构-总结(三)
  4. 使用links方式安装eclipse插件
  5. android编译非静态内部类,Android 非静态内部类/匿名类引起的内存泄漏
  6. jQuery异步加载数据并添加事件示例
  7. Android Canvas类介绍和Android Draw Rect 坐标图示
  8. 中国海洋大学计算机考研指导
  9. Java定义People类
  10. python generator类型_python生成器(Generator)
  11. android利用itext5制作pdf,Itext5生成PDF
  12. U盘之家工具包 V1.4
  13. 第二十八篇 -- 学习第五十一天打卡20190819
  14. 免费天气API接口,全国天气免费接口,2018年3月测试稳定OK
  15. 对“数字+企业数字化+数据中台”的灵魂追问
  16. 云计算技术的概念、原理
  17. Vue:获取v-for循环中的数组下标、索引及数据
  18. Qt 内存管理与布局管理器
  19. 渣渣渣变渣渣系列(1)
  20. 【前端】制作个人博客第三天

热门文章

  1. D2-Net: A Trainable CNN for Joint Description and Detection of Local Features精读
  2. Linux如何部署私有IPFS(安装、部署、共享key,添加节点,测试)
  3. 如何撰写数据分析报告?
  4. Java并发编程 - 第十一章 Java并发编程实践
  5. echarts天气预报
  6. 在R语言中如何安装包?
  7. 【Banner—闭组会议总结】
  8. JDK1.8 JVM内存模型
  9. 黑客入侵步骤(超详细版)
  10. Visio卷积神经网络模型(三)-网络卷积层示意图