手机蓝牙连接热敏打印机 打印票据
话不多说上代码:
项目地址:可直接作为项目依赖
- 引用
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
compile'com.github.guochenhome:BluetoothPrint:1.1.2'
}
- 如果第一步报
Error:Execution failed for task ':app:processXXXDebugManifest'. >
Manifest merger failed with multiple errors, see logs
这个错的话
这说明在合并所有的Manfest文件时冲突了,几率最大的两个原因是
1.build.gradle中设置的compileSdkVersion buildToolsVersion minSdkVersion targetSdkVersion不统一,需要按宿主项目的配置进行统一。
2.几个项目的AndroidManifest文件中设置了多个android:allowBackup android:icon android:label android:theme 属性,这里需要在宿主项目的Manfest文件中添加两句话
manifest 节点下加入
xmlns:tools=”http://schemas.android.com/tools”
application节点下加入
tools:replace=”android:allowBackup,icon,theme,label”
不能写成tools:replace=”android:allowBackup,android:icon,android:theme” 虽然不报错,但是不起作用。
那就直接把项目下载直接导入你的项目 按照上述更改依赖的项目;
使用步骤
- 第一步 初始化你的APPINFO
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
AppInfo.init(getApplicationContext());
}
}
- 第二步
/**
1.实现PrinterInterface 接口
2.实例化 EventBus.getDefault().register(MainActivity.this);
bluetoothController = new BluetoothController(this);
bluetoothController.setPrinterInterface(this);
3. 初始化:bluetoothController.init();
4.
*/
public class MainActivity extends BluetoothActivity implements View.OnClickListener, BluetoothController.PrinterInterface {
TextView tv_bluename;
TextView tv_blueadress;
boolean mBtEnable = true;
int PERMISSION_REQUEST_COARSE_LOCATION = 2;
/**
* bluetooth adapter
*/
BluetoothController bluetoothController;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_bluename = (TextView) findViewById(R.id.tv_bluename);
tv_blueadress = (TextView) findViewById(R.id.tv_blueadress);
findViewById(R.id.button4).setOnClickListener(this);
findViewById(R.id.button5).setOnClickListener(this);
findViewById(R.id.button6).setOnClickListener(this);
findViewById(R.id.button).setOnClickListener(this);
//6.0以上的手机要地理位置权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
EventBus.getDefault().register(MainActivity.this);
bluetoothController = new BluetoothController(this);
bluetoothController.setPrinterInterface(this);
}
@Override
protected void onStart() {
super.onStart();
// BluetoothController.init(this);
bluetoothController.init();
}
@Override
public void btStatusChanged(Intent intent) {
super.btStatusChanged(intent);
bluetoothController.init();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.button4:
startActivity(new Intent(MainActivity.this, SearchBluetoothActivity.class));
break;
case R.id.button5:
if (TextUtils.isEmpty(AppInfo.btAddress)) {
ToastUtil.showToast(MainActivity.this, "请连接蓝牙...");
startActivity(new Intent(MainActivity.this, SearchBluetoothActivity.class));
} else {
if (bluetoothController.getmAdapter().getState() == BluetoothAdapter.STATE_OFF) {//蓝牙被关闭时强制打开
bluetoothController.getmAdapter().enable();
ToastUtil.showToast(MainActivity.this, "蓝牙被关闭请打开...");
} else {
ToastUtil.showToast(MainActivity.this, "打印测试...");
Intent intent = new Intent(getApplicationContext(), BtService.class);
intent.setAction(PrintUtil.ACTION_PRINT_TEST);
startService(intent);
}
}
break;
case R.id.button6:
if (TextUtils.isEmpty(AppInfo.btAddress)) {
ToastUtil.showToast(MainActivity.this, "请连接蓝牙...");
startActivity(new Intent(MainActivity.this, SearchBluetoothActivity.class));
} else {
ToastUtil.showToast(MainActivity.this, "打印测试...");
Intent intent2 = new Intent(getApplicationContext(), BtService.class);
intent2.setAction(PrintUtil.ACTION_PRINT_TEST_TWO);
startService(intent2);
}
case R.id.button:
if (TextUtils.isEmpty(AppInfo.btAddress)) {
ToastUtil.showToast(MainActivity.this, "请连接蓝牙...");
startActivity(new Intent(MainActivity.this, SearchBluetoothActivity.class));
} else {
ToastUtil.showToast(MainActivity.this, "打印图片...");
Intent intent2 = new Intent(getApplicationContext(), BtService.class);
intent2.setAction(PrintUtil.ACTION_PRINT_BITMAP);
startService(intent2);
}
// startActivity(new Intent(MainActivity.this,TextActivity.class));
break;
}
}
/**
* handle printer message
*
* @param event print msg event
*/
public void onEventMainThread(PrintMsgEvent event) {
if (event.type == PrinterMsgType.MESSAGE_TOAST) {
ToastUtil.showToast(MainActivity.this, event.msg);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().register(MainActivity.this);
}
@Override
public void NoBT() {
this.tv_bluename.setText("该设备没有蓝牙模块");
this.mBtEnable = false;
}
@Override
public void BT_NoOpen() {
this.tv_bluename.setText("蓝牙未打开");
}
@Override
public void BT_NoBind() {
this.tv_bluename.setText("尚未绑定蓝牙设备");
}
@Override
public void BT_Bind(String name, String address) {
this.tv_bluename.setText("已绑定蓝牙:" + name);
this.tv_blueadress.setText(address);
}
}
- 第三步 下面是我搜索蓝牙的可视化页面
package com.xmwdkk.boothprint;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import com.ysh.rn.printet.bt.BluetoothActivity;
import com.ysh.rn.printet.bt.BtUtil;
import com.ysh.rn.printet.print.PrintQueue;
import com.ysh.rn.printet.print.PrintUtil;
import com.ysh.rn.printet.util.ToastUtil;
import java.lang.reflect.Method;
/**
* 蓝牙搜索界面
* Created by liuguirong on 2017/8/3.
*/
public class SearchBluetoothActivity extends BluetoothActivity implements AdapterView.OnItemClickListener, View.OnClickListener {
private BluetoothAdapter bluetoothAdapter;
private ListView lv_searchblt;
private TextView tv_title;
private TextView tv_summary;
private SearchBleAdapter searchBleAdapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_searchbooth);
lv_searchblt = (ListView) findViewById(R.id.lv_searchblt);
tv_title = (TextView) findViewById(R.id.tv_title);
tv_summary = (TextView) findViewById(R.id.tv_summary);
//初始化蓝牙适配器
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
searchBleAdapter = new SearchBleAdapter(SearchBluetoothActivity.this, null);
lv_searchblt.setAdapter(searchBleAdapter);
init();
searchDeviceOrOpenBluetooth();
lv_searchblt.setOnItemClickListener(this);
tv_title.setOnClickListener(this);
tv_summary.setOnClickListener(this);
}
private void init() {
if (!BtUtil.isOpen(bluetoothAdapter)) {
tv_title.setText("未连接蓝牙打印机");
tv_summary.setText("系统蓝牙已关闭,点击开启");
} else {
if (!PrintUtil.isBondPrinter(this, bluetoothAdapter)) {
//未绑定蓝牙打印机器
tv_title.setText("未连接蓝牙打印机");
tv_summary.setText("点击后搜索蓝牙打印机");
} else {
//已绑定蓝牙设备
tv_title.setText(getPrinterName() + "已连接");
String blueAddress = PrintUtil.getDefaultBluethoothDeviceAddress(this);
if (TextUtils.isEmpty(blueAddress)) {
blueAddress = "点击后搜索蓝牙打印机";
}
tv_summary.setText(blueAddress);
}
}
}
@Override
public void btStatusChanged(Intent intent) {
if ( bluetoothAdapter.getState()==BluetoothAdapter.STATE_OFF ){//蓝牙被关闭时强制打开
bluetoothAdapter.enable();
}
if ( bluetoothAdapter.getState()==BluetoothAdapter.STATE_ON ){//蓝牙打开时搜索蓝牙
searchDeviceOrOpenBluetooth();
}
}
private String getPrinterName(){
String dName = PrintUtil.getDefaultBluetoothDeviceName(this);
if (TextUtils.isEmpty(dName)) {
dName = "未知设备";
}
return dName;
}
private String getPrinterName(String dName) {
if (TextUtils.isEmpty(dName)) {
dName = "未知设备";
}
return dName;
}
/**
* 开始搜索
* search device
*/
private void searchDeviceOrOpenBluetooth() {
if (BtUtil.isOpen(bluetoothAdapter)) {
BtUtil.searchDevices(bluetoothAdapter);
}
}
/**
* 关闭搜索
* cancel search
*/
@Override
protected void onStop() {
super.onStop();
BtUtil.cancelDiscovery(bluetoothAdapter);
}
@Override
public void btStartDiscovery(Intent intent) {
tv_title.setText("正在搜索蓝牙设备…");
tv_summary.setText("");
}
@Override
public void btFinishDiscovery(Intent intent) {
tv_title.setText("搜索完成");
tv_summary.setText("点击重新搜索");
}
@Override
public void btFoundDevice(Intent intent) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d("1","!");
if (null != bluetoothAdapter && device != null) {
searchBleAdapter.addDevices(device);
String dName = device.getName() == null ? "未知设备" : device.getName();
Log.d("未知设备",dName);
Log.d("1","!");
}
}
@Override
public void btBondStatusChange(Intent intent) {
super.btBondStatusChange(intent);
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
switch (device.getBondState()) {
case BluetoothDevice.BOND_BONDING://正在配对
Log.d("BlueToothTestActivity", "正在配对......");
break;
case BluetoothDevice.BOND_BONDED://配对结束
Log.d("BlueToothTestActivity", "完成配对");
connectBlt(device);
break;
case BluetoothDevice.BOND_NONE://取消配对/未配对
Log.d("BlueToothTestActivity", "取消配对");
default:
break;
}
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
if (null == searchBleAdapter) {
return;
}
final BluetoothDevice bluetoothDevice = searchBleAdapter.getItem(position);
if (null == bluetoothDevice) {
return;
}
new AlertDialog.Builder(this)
.setTitle("绑定" + getPrinterName(bluetoothDevice.getName()) + "?")
.setMessage("点击确认绑定蓝牙设备")
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
BtUtil.cancelDiscovery(bluetoothAdapter);
if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
connectBlt(bluetoothDevice);
} else {
Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
createBondMethod.invoke(bluetoothDevice);
}
PrintQueue.getQueue(getApplicationContext()).disconnect();
String name = bluetoothDevice.getName();
} catch (Exception e) {
e.printStackTrace();
PrintUtil.setDefaultBluetoothDeviceAddress(getApplicationContext(), "");
PrintUtil.setDefaultBluetoothDeviceName(getApplicationContext(), "");
ToastUtil.showToast(SearchBluetoothActivity.this,"蓝牙绑定失败,请重试");
}
}
})
.create()
.show();
}
/***
* 配对成功连接蓝牙
* @param bluetoothDevice
*/
private void connectBlt(BluetoothDevice bluetoothDevice) {
if (null != searchBleAdapter) {
searchBleAdapter.setConnectedDeviceAddress(bluetoothDevice.getAddress());
}
init();
searchBleAdapter.notifyDataSetChanged();
PrintUtil.setDefaultBluetoothDeviceAddress(getApplicationContext(), bluetoothDevice.getAddress());
PrintUtil.setDefaultBluetoothDeviceName(getApplicationContext(), bluetoothDevice.getName());
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.tv_title:
break;
case R.id.tv_summary:
searchDeviceOrOpenBluetooth();
break;
}
}
}
Adapter
package com.xmwdkk.boothprint;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.ysh.rn.printet.base.AppInfo;
import com.ysh.rn.printet.print.PrintUtil;
import java.util.ArrayList;
/**
* Created by yefeng on 6/2/15.
* github:yefengfreedom
*/
public class SearchBleAdapter extends BaseAdapter {
private ArrayList<BluetoothDevice> mDevices;
private LayoutInflater mInflater;
private String mConnectedDeviceAddress;
public SearchBleAdapter(Context mContext, ArrayList<BluetoothDevice> mDevices) {
this.mInflater = LayoutInflater.from(mContext);
this.mDevices = null == mDevices ? new ArrayList<BluetoothDevice>() : mDevices;
mConnectedDeviceAddress = PrintUtil.getDefaultBluethoothDeviceAddress(mContext);
}
public ArrayList<BluetoothDevice> getDevices() {
return mDevices;
}
public void setDevices(ArrayList<BluetoothDevice> mDevices) {
if (null == mDevices) {
mDevices = new ArrayList<BluetoothDevice>();
}
this.mDevices = mDevices;
this.notifyDataSetChanged();
}
@Override
public void notifyDataSetChanged() {
if (null != this.mDevices) {
this.mDevices = sortByBond(this.mDevices);
}
super.notifyDataSetChanged();
}
private ArrayList<BluetoothDevice> sortByBond(ArrayList<BluetoothDevice> mDevices) {
if (null == mDevices) {
return null;
}
if (mDevices.size() < 2) {
return mDevices;
}
ArrayList<BluetoothDevice> bondDevices = new ArrayList<BluetoothDevice>();
ArrayList<BluetoothDevice> unBondDevices = new ArrayList<BluetoothDevice>();
int size = mDevices.size();
for (int i = 0; i < size; i++) {
BluetoothDevice bluetoothDevice = mDevices.get(i);
if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
bondDevices.add(bluetoothDevice);
} else {
unBondDevices.add(bluetoothDevice);
}
}
mDevices.clear();
mDevices.addAll(bondDevices);
mDevices.addAll(unBondDevices);
bondDevices.clear();
bondDevices = null;
unBondDevices.clear();
unBondDevices = null;
return mDevices;
}
public void setConnectedDeviceAddress(String macAddress) {
this.mConnectedDeviceAddress = macAddress;
}
public void addDevices(ArrayList<BluetoothDevice> mDevices) {
if (null == mDevices) {
return;
}
for (BluetoothDevice bluetoothDevice : mDevices) {
addDevices(bluetoothDevice);
}
}
public void addDevices(BluetoothDevice mDevice) {
if (null == mDevice) {
return;
}
if (!this.mDevices.contains(mDevice)) {
this.mDevices.add(mDevice);
this.notifyDataSetChanged();
}
}
@Override
public int getCount() {
return mDevices.size();
}
@Override
public BluetoothDevice getItem(int position) {
return mDevices.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView != null) {
holder = (ViewHolder) convertView.getTag();
} else {
convertView = mInflater.inflate(R.layout.adapter_bt_device, parent, false);
holder = new ViewHolder();
if (null != convertView) {
convertView.setTag(holder);
}
}
holder.name = (TextView) convertView.findViewById(R.id.txt_adapter_bt_name);
holder.address = (TextView) convertView.findViewById(R.id.txt_adapter_bt_address);
holder.bond = (TextView) convertView.findViewById(R.id.btn_adapter_bt_has_bond);
BluetoothDevice bluetoothDevice = mDevices.get(position);
String dName = bluetoothDevice.getName() == null ? "未知设备" : bluetoothDevice.getName();
if (TextUtils.isEmpty(dName)) {
dName = "未知设备";
}
holder.name.setText(dName);
String dAddress = bluetoothDevice.getAddress() == null ? "未知地址" : bluetoothDevice.getAddress();
if (TextUtils.isEmpty(dAddress)) {
dAddress = "未知地址";
}
holder.address.setText(dAddress);
int paddingVertical = 8;
int paddingHorizontal = 16;
if (AppInfo.density != 0) {
paddingVertical = (int) (paddingVertical * AppInfo.density);
paddingHorizontal = (int) (paddingHorizontal * AppInfo.density);
}
if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
if (dAddress.equals(mConnectedDeviceAddress)) {
holder.bond.setText("已连接");
holder.bond.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical);
} else {
holder.bond.setText("已配对");
holder.bond.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical);
}
} else {
holder.bond.setText("未配对");
holder.bond.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical);
}
return convertView;
}
static class ViewHolder {
TextView name;
TextView address;
TextView bond;
}
}