Android 實現藍牙打印的功能

第一步:首先需要一個藍牙打印工具類
import android.bluetooth.BluetoothSocket;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;

import com.github.promeg.pinyinhelper.Pinyin;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Calendar;

/**

  • 藍牙打印工具類
    */
    public class PrintUtil {

    private OutputStreamWriter mWriter = null;
    private OutputStream mOutputStream = null;

    public final static int WIDTH_PIXEL = 384;
    public final static int IMAGE_SIZE = 320;
    private static String myTime;

    /**

    • 初始化Pos實例
    • @param encoding 編碼
    • @throws IOException
      */
      public PrintUtil(OutputStream outputStream, String encoding) throws IOException {
      mWriter = new OutputStreamWriter(outputStream, encoding);
      mOutputStream = outputStream;
      initPrinter();
      }

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

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

    /**

    • 初始化打印機
    • @throws IOException
      */
      public void initPrinter() throws IOException {
      mWriter.write(0x1B);
      mWriter.write(0x40);
      mWriter.flush();
      //獲取當前時間
      getTime();
      }

    /**

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

    /**

    • 打印換行(只換一行)
    • @throws IOException
      */
      public void printLine() throws IOException {
      printLine(1);
      }

    /**

    • 打印空白(一個Tab的位置,約4個漢字)
    • @param length 需要打印空白的長度,
    • @throws IOException
      */
      public void printTabSpace(int length) throws IOException {
      for (int i = 0; i < length; i++) {
      mWriter.write("\t");
      }
      mWriter.flush();
      }

    /**

    • 絕對打印位置
    • @return
    • @throws IOException
      */
      public byte[] setLocation(int offset) throws IOException {
      byte[] bs = new byte[4];
      bs[0] = 0x1B;
      bs[1] = 0x24;
      bs[2] = (byte) (offset % 256);
      bs[3] = (byte) (offset / 256);
      return bs;
      }

    public byte[] getGbk(String stText) throws IOException {
    byte[] returnText = stText.getBytes(“GBK”); // 必須放在try內纔可以
    return returnText;
    }

    private int getStringPixLength(String str) {
    int pixLength = 0;
    char c;
    for (int i = 0; i < str.length(); i++) {
    c = str.charAt(i);
    if (Pinyin.isChinese©) {
    pixLength += 24;
    } else {
    pixLength += 12;
    }
    }
    return pixLength;
    }

    public int getOffset(String str) {
    return WIDTH_PIXEL - getStringPixLength(str);
    }

    /**

    • 打印文字
    • @param text
    • @throws IOException
      */
      public void printText(String text) throws IOException {
      mWriter.write(text);
      mWriter.flush();
      }

    /**

    • 對齊0:左對齊,1:居中,2:右對齊
      */
      public void printAlignment(int alignment) throws IOException {
      mWriter.write(0x1b);
      mWriter.write(0x61);
      mWriter.write(alignment);
      }

    public void printLargeText(String text) throws IOException {

     mWriter.write(0x1b);
     mWriter.write(0x21);
     mWriter.write(48);
    
     mWriter.write(text);
    
     mWriter.write(0x1b);
     mWriter.write(0x21);
     mWriter.write(0);
    
     mWriter.flush();
    

    }

    public void printTwoColumn(String title, String content) throws IOException {
    int iNum = 0;
    byte[] byteBuffer = new byte[100];
    byte[] tmp;

     tmp = getGbk(title);
     System.arraycopy(tmp, 0, byteBuffer, iNum, tmp.length);
     iNum += tmp.length;
    
     tmp = setLocation(getOffset(content));
     System.arraycopy(tmp, 0, byteBuffer, iNum, tmp.length);
     iNum += tmp.length;
    
     tmp = getGbk(content);
     System.arraycopy(tmp, 0, byteBuffer, iNum, tmp.length);
    
     print(byteBuffer);
    

    }

    public void printThreeColumn(String left, String middle, String right) throws IOException {
    int iNum = 0;
    byte[] byteBuffer = new byte[200];
    byte[] tmp = new byte[0];

     System.arraycopy(tmp, 0, byteBuffer, iNum, tmp.length);
     iNum += tmp.length;
    
     tmp = getGbk(left);
     System.arraycopy(tmp, 0, byteBuffer, iNum, tmp.length);
     iNum += tmp.length;
    
     int pixLength = getStringPixLength(left) % WIDTH_PIXEL;
     if (pixLength > WIDTH_PIXEL / 2 || pixLength == 0) {
         middle = "\n\t\t" + middle;
     }
    
     tmp = setLocation(192);
     System.arraycopy(tmp, 0, byteBuffer, iNum, tmp.length);
     iNum += tmp.length;
    
     tmp = getGbk(middle);
     System.arraycopy(tmp, 0, byteBuffer, iNum, tmp.length);
     iNum += tmp.length;
    
     tmp = setLocation(getOffset(right));
     System.arraycopy(tmp, 0, byteBuffer, iNum, tmp.length);
     iNum += tmp.length;
    
     tmp = getGbk(right);
     System.arraycopy(tmp, 0, byteBuffer, iNum, tmp.length);
    
     print(byteBuffer);
    

    }

    public void printDashLine() throws IOException {
    printText("--------------------------------");
    }

    public void printBitmap(Bitmap bmp) throws IOException {
    bmp = compressPic(bmp);
    byte[] bmpByteArray = draw2PxPoint(bmp);
    printRawBytes(bmpByteArray);
    }

    /*************************************************************************

    • 假設一個360*360的圖片,分辨率設爲24, 共分15行打印 每一行,是一個 360 * 24 的點陣,y軸有24個點,存儲在3個byte裏面。

    • 即每個byte存儲8個像素點信息。因爲只有黑白兩色,所以對應爲1的位是黑色,對應爲0的位是白色
      **************************************************************************/
      private byte[] draw2PxPoint(Bitmap bmp) {
      //先設置一個足夠大的size,最後在用數組拷貝複製到一個精確大小的byte數組中
      int size = bmp.getWidth() * bmp.getHeight() / 8 + 1000;
      byte[] tmp = new byte[size];
      int k = 0;
      // 設置行距爲0
      tmp[k++] = 0x1B;
      tmp[k++] = 0x33;
      tmp[k++] = 0x00;
      // 居中打印
      tmp[k++] = 0x1B;
      tmp[k++] = 0x61;
      tmp[k++] = 1;
      for (int j = 0; j < bmp.getHeight() / 24f; j++) {
      tmp[k++] = 0x1B;
      tmp[k++] = 0x2A;// 0x1B 2A 表示圖片打印指令
      tmp[k++] = 33; // m=33時,選擇24點密度打印
      tmp[k++] = (byte) (bmp.getWidth() % 256); // nL
      tmp[k++] = (byte) (bmp.getWidth() / 256); // nH
      for (int i = 0; i < bmp.getWidth(); i++) {
      for (int m = 0; m < 3; m++) {
      for (int n = 0; n < 8; n++) {
      byte b = px2Byte(i, j * 24 + m * 8 + n, bmp);
      tmp[k] += tmp[k] + b;
      }
      k++;
      }
      }
      tmp[k++] = 10;// 換行
      }
      // 恢復默認行距
      tmp[k++] = 0x1B;
      tmp[k++] = 0x32;

      byte[] result = new byte[k];
      System.arraycopy(tmp, 0, result, 0, k);
      return result;
      }

    /**

    • 圖片二值化,黑色是1,白色是0
    • @param x 橫座標
    • @param y 縱座標
    • @param bit 位圖
    • @return
      */
      private 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 int RGB2Gray(int r, int g, int b) {
      int gray = (int) (0.29900 * r + 0.58700 * g + 0.11400 * b); // 灰度轉化公式
      return gray;
      }

    /**

    • 對圖片進行壓縮(去除透明度)
    • @param bitmapOrg
      */
      private Bitmap compressPic(Bitmap bitmapOrg) {
      // 獲取這個圖片的寬和高
      int width = bitmapOrg.getWidth();
      int height = bitmapOrg.getHeight();
      // 定義預轉換成的圖片的寬度和高度
      int newWidth = IMAGE_SIZE;
      int newHeight = IMAGE_SIZE;
      Bitmap targetBmp = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
      Canvas targetCanvas = new Canvas(targetBmp);
      targetCanvas.drawColor(0xffffffff);
      targetCanvas.drawBitmap(bitmapOrg, new Rect(0, 0, width, height), new Rect(0, 0, newWidth, newHeight), null);
      return targetBmp;
      }

    public static void printTest(BluetoothSocket bluetoothSocket, Bitmap bitmap) {

     try {
         PrintUtil pUtil = new PrintUtil(bluetoothSocket.getOutputStream(), "GBK");
         // 店鋪名 居中 放大
         pUtil.printAlignment(1);
         pUtil.printLargeText("廣州德勝");
         pUtil.printLine();
         pUtil.printAlignment(0);
         pUtil.printLine();
    
         pUtil.printTwoColumn("時間:", myTime);
         pUtil.printLine();
    
         pUtil.printTwoColumn("訂單號:", System.currentTimeMillis() + "");
         pUtil.printLine();
    
         pUtil.printTwoColumn("付款人:", "VitaminChen");
         pUtil.printLine();
    
         // 分隔線
         pUtil.printDashLine();
         pUtil.printLine();
    
         //打印商品列表
         pUtil.printText("商品");
         pUtil.printTabSpace(2);
         pUtil.printText("數量");
         pUtil.printTabSpace(1);
         pUtil.printText("    單價");
         pUtil.printLine();
    
         pUtil.printThreeColumn("iphone6", "1", "4999.00");
         pUtil.printThreeColumn("測試測試", "1", "4999.00");
    
         pUtil.printDashLine();
         pUtil.printLine();
    
         pUtil.printTwoColumn("訂單金額:", "9998.00");
         pUtil.printLine();
    
         pUtil.printTwoColumn("實收金額:", "10000.00");
         pUtil.printLine();
    
         pUtil.printTwoColumn("找零:", "2.00");
         pUtil.printLine();
    
         pUtil.printDashLine();
         //打印圖片
        // pUtil.printBitmap(bitmap);
    
         pUtil.printLine(4);
    
     } catch (IOException e) {
    
     }
    

    }

    private void getTime() {
    final Calendar c = Calendar.getInstance();
    int year = c.get(Calendar.YEAR);
    int month = c.get(Calendar.MONTH) + 1;
    int day = c.get(Calendar.DATE);
    int hour = c.get(Calendar.HOUR);
    int minute = c.get(Calendar.MINUTE);
    if (month > 9) {
    myTime = year + “-” + month + “-” + day;
    } else {
    if (day > 9) {
    myTime = year + “-” + “0” + month + “-” + day;
    } else {
    myTime = year + “-” + “0” + month + “-” + “0” + day;
    }

     }
    

    }
    }

第二步 :還有一個檢測藍牙是否連接的工具類

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;

public class BluetoothUtil {

/**
 * 藍牙是否打開
 */
public static boolean isBluetoothOn() {
	BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
	if (mBluetoothAdapter != null)
		// 藍牙已打開
		if (mBluetoothAdapter.isEnabled())
			return true;

	return false;
}

/**
 * 獲取所有已配對的設備
 */
public static List<BluetoothDevice> getPairedDevices() {
	List deviceList = new ArrayList<>();
	Set<BluetoothDevice> pairedDevices = BluetoothAdapter.getDefaultAdapter().getBondedDevices();
	if (pairedDevices.size() > 0) {
		for (BluetoothDevice device : pairedDevices) {
			deviceList.add(device);
		}
	}
	return deviceList;
}

/**
 * 獲取所有已配對的打印類設備
 */
public static List<BluetoothDevice> getPairedPrinterDevices() {
	return getSpecificDevice(BluetoothClass.Device.Major.IMAGING);
}

/**
 * 從已配對設配中,刪選出某一特定類型的設備展示
 * @param deviceClass
 * @return
 */
public static List<BluetoothDevice> getSpecificDevice(int deviceClass){
	List<BluetoothDevice> devices = BluetoothUtil.getPairedDevices();
	List<BluetoothDevice> printerDevices = new ArrayList<>();

	for (BluetoothDevice device : devices) {
		BluetoothClass klass = device.getBluetoothClass();
		// 關於藍牙設備分類參考 http://stackoverflow.com/q/23273355/4242112
		if (klass.getMajorDeviceClass() == deviceClass)
			printerDevices.add(device);
	}

	return printerDevices;
}

/**
 * 彈出系統對話框,請求打開藍牙
 */
public static void openBluetooth(Activity activity) {
	Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
	activity.startActivityForResult(enableBtIntent, 666);
}

public static BluetoothSocket connectDevice(BluetoothDevice device) {
	BluetoothSocket socket = null;
	try {
		socket = device.createRfcommSocketToServiceRecord(
				UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
		socket.connect();
	} catch (IOException e) {
		try {
			socket.close();
		} catch (IOException closeException) {
			return null;
		}
		return null;
	}
	return socket;
}

}

第三步:創建一個基類
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

import com.will.bluetoothprinterdemo.utils.BluetoothUtil;

import java.io.IOException;

public abstract class BasePrintActivity extends AppCompatActivity {

String tag = getClass().getSimpleName();
private BluetoothSocket mSocket;
private BluetoothStateReceiver mBluetoothStateReceiver;
private AsyncTask mConnectTask;
private ProgressDialog mProgressDialog;

/**
 * 藍牙連接成功後回調,該方法在子線程執行,可執行耗時操作
 */
public abstract void onConnected(BluetoothSocket socket, int taskType);


/**
 * 藍牙狀態發生變化時回調
 */
public void onBluetoothStateChanged(Intent intent) {

}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    initReceiver();
}

@Override
protected void onStop() {
    cancelConnectTask();
    closeSocket();
    super.onStop();
}

protected void closeSocket() {
    if (mSocket != null) {
        try {
            mSocket.close();
        } catch (IOException e) {
            mSocket = null;
            e.printStackTrace();
        }
    }
}

protected void cancelConnectTask() {
    if (mConnectTask != null) {
        mConnectTask.cancel(true);
        mConnectTask = null;
    }
}

@Override
protected void onDestroy() {
    unregisterReceiver(mBluetoothStateReceiver);
    super.onDestroy();
}

private void initReceiver() {
    mBluetoothStateReceiver = new BluetoothStateReceiver();
    IntentFilter filter = new IntentFilter();
    filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
    registerReceiver(mBluetoothStateReceiver, filter);
}

/**
 * 檢查藍牙狀態,如果已打開,則查找已綁定設備
 *
 * @return
 */
public boolean checkBluetoothState() {
    if (BluetoothUtil.isBluetoothOn()) {
        return true;
    } else {
        BluetoothUtil.openBluetooth(this);
        return false;
    }
}

public void connectDevice(BluetoothDevice device, int taskType) {
    if (checkBluetoothState() && device != null) {
        mConnectTask = new ConnectBluetoothTask(taskType).execute(device);
    }
}


class ConnectBluetoothTask extends AsyncTask<BluetoothDevice, Integer, BluetoothSocket> {

    int mTaskType;

    public ConnectBluetoothTask(int taskType) {
        this.mTaskType = taskType;
    }

    @Override
    protected void onPreExecute() {
        showProgressDialog("請稍候...");
        super.onPreExecute();
    }

    @Override
    protected BluetoothSocket doInBackground(BluetoothDevice... params) {
        if(mSocket != null){
            try {
                mSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        mSocket = BluetoothUtil.connectDevice(params[0]);;
        onConnected(mSocket, mTaskType);
        return mSocket;
    }

    @Override
    protected void onPostExecute(BluetoothSocket socket) {
        mProgressDialog.dismiss();
        if (socket == null || !socket.isConnected()) {
            toast("連接打印機失敗");
        } else {
            toast("成功!");
        }

        super.onPostExecute(socket);
    }
}


protected void showProgressDialog(String message) {
    if (mProgressDialog == null) {
        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setCanceledOnTouchOutside(false);
        mProgressDialog.setCancelable(false);
    }
    mProgressDialog.setMessage(message);
    if (!mProgressDialog.isShowing()) {
        mProgressDialog.show();
    }
}

protected void toast(String message) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}

/**
 * 監聽藍牙狀態變化的系統廣播
 */
class BluetoothStateReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
        switch (state) {
            case BluetoothAdapter.STATE_TURNING_ON:
                toast("藍牙已開啓");
                break;

            case BluetoothAdapter.STATE_TURNING_OFF:
                toast("藍牙已關閉");
                break;
        }
        onBluetoothStateChanged(intent);
    }
}

}

第四步:主界面代碼

package com.will.bluetoothprinterdemo.ui;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.will.bluetoothprinterdemo.R;
import com.will.bluetoothprinterdemo.utils.BluetoothUtil;
import com.will.bluetoothprinterdemo.utils.PrintUtil;

import java.util.List;

public class PrinterSettingActivity extends BasePrintActivity implements View.OnClickListener{

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;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_printer_setting);
    initViews();
}

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

private void initViews() {
    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;
    }
}

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:
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test_image);
            PrintUtil.printTest(socket, bitmap);
            break;
    }
}


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;
    }
}

}

第五步:主界面佈局
activity_printer_setting.xml

<?xml version="1.0" encoding="utf-8"?>

<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" />

<Button
    android:id="@+id/btn_goto_setting"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="@dimen/common_margin"
    android:layout_marginRight="@dimen/common_margin"
    android:layout_marginTop="@dimen/common_margin"
    android:text="還未配對打印機,去設置" />

<Button
    android:id="@+id/btn_test_conntect"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="@dimen/common_margin"
    android:layout_marginRight="@dimen/common_margin"
    android:layout_marginTop="@dimen/common_margin"
    android:text="測試打印機連接" />

<Button
    android:id="@+id/btn_print"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="@dimen/common_margin"
    android:layout_marginRight="@dimen/common_margin"
    android:layout_marginTop="@dimen/common_margin"
    android:text="打印"
    android:layout_marginBottom="@dimen/common_margin"/>

佈局二:

<?xml version="1.0" encoding="utf-8"?>

<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" />
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章