Android 藍牙打印小票與WiFi打印小票兩種打印方式的實現(帶有圖片和二維碼)

轉載至: 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() {
    @Override
    public 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章