Android蓝牙打印机应用程序在调试模式下可以正常工作,但在发布模式下不能工作

时间:2019-05-17 10:36:29

标签: android bluetooth

我正在编写一个Android应用程序以在蓝牙热敏打印机上打印文本。 Here is the complete code

该应用在调试模式下可以正常工作,但是当我生成签名的APK并将其安装在设备上时,它根本没有响应。

我尝试了关于stackoverflow的其他建议解决方案,但没有一个起作用。

这是我的主要活动

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.lvrenyang.io.IOCallBack;
import java.lang.ref.WeakReference;

public class MainActivity extends AppCompatActivity {

    private Handler mHandler; // Our main handler that will receive callback notifications
    // #defines for identifying shared types between calling functions
    private final static int REQUEST_ENABLE_BT = 1; // used to identify adding bluetooth names

    private static String TAG = "MAIN_ACTIVITY";
    private Activity activity;
    private Button btnConnect;

    private String name = "MTP-II";
    private String mac_address = "02:15:44:31:49:05";

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

        //Get the activity
        this.activity = this;

        //Button from the XML view
        btnConnect = findViewById(R.id.btnConnect);

        //Start the Init Work Service Async task
        new InitWorkService().execute();

        //Set onClickListener for test print button
        btnConnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    //Check if name and address are set
                    if (name != "null" && mac_address != "null" && mac_address.contains(":")) {

                        if (!WorkService.workThread.isConnected()) {
                            WorkService.workThread.connectBt(mac_address);
                            //Sleep for 3 seconds
                            try {
                                Thread.sleep(3000);
                            } catch (Exception e) {
                            }
                        }
                        //Check if connected
                        if (WorkService.workThread.isConnected()) {
                            //Collect data in background Thread
                            new PrintData().execute();
                        } else {
                            Toast.makeText(activity, Global.toast_notconnect, Toast.LENGTH_SHORT).show();
                        }
                    } else {
                        Toast.makeText(activity, "Please setup printer first!", Toast.LENGTH_LONG).show();
                    }
                }
                catch(Exception e){
                    Log.e(TAG, e.getMessage(), e.fillInStackTrace());}
            }
        });
    }


    /**
     * Background Async Task
     * */
    private class InitWorkService extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
        protected String doInBackground(String... args){
            try{
                WorkService.cb = new IOCallBack() {
                    public void OnOpen() {
                        if (null != mHandler) {
                            Message msg = mHandler.obtainMessage(Global.MSG_IO_ONOPEN);
                            mHandler.sendMessage(msg);
                        }
                    }
                    public void OnClose() {
                        if (null != mHandler) {
                            Message msg = mHandler.obtainMessage(Global.MSG_IO_ONCLOSE);
                            mHandler.sendMessage(msg);
                        }
                    }
                };
            }
            catch(Exception e){
                Log.e(TAG, e.getMessage(), e.fillInStackTrace());
            }
            return null;
        }
        protected void onPostExecute(String file_url){
            try {
                mHandler = new MHandler(MainActivity.this);
                WorkService.addHandler(mHandler);

                if (null == WorkService.workThread) {
                    Intent intent = new Intent(activity, WorkService.class);
                    startService(intent);
                }
            }
            catch (Exception e) {
                Log.e(TAG, e.getMessage(), e.fillInStackTrace());
                Toast.makeText(activity, "Unable to initiate the WorkService!", Toast.LENGTH_LONG).show();
            }
        }
    }

    /**
     * Background Async Task
     * */
    class PrintData extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
        protected String doInBackground(String... args){
            try{
                int nTextAlign=1;
                String text = "Test message!\r\n\r\n\r\n";
                String encoding = "UTF-8";
                byte[] hdrBytes = {0x1c, 0x26, 0x1b, 0x39, 0x01};

                Bundle dataAlign = new Bundle();
                Bundle dataTextOut = new Bundle();
                Bundle dataHdr = new Bundle();

                dataHdr.putByteArray(Global.BYTESPARA1, hdrBytes);
                dataHdr.putInt(Global.INTPARA1, 0);
                dataHdr.putInt(Global.INTPARA2, hdrBytes.length);

                dataAlign.putInt(Global.INTPARA1, nTextAlign);

                dataTextOut.putString(Global.STRPARA1, text);
                dataTextOut.putString(Global.STRPARA2, encoding);

                WorkService.workThread.handleCmd(Global.CMD_POS_WRITE,dataHdr);
                WorkService.workThread.handleCmd(Global.CMD_POS_SALIGN,dataAlign);
                WorkService.workThread.handleCmd(Global.CMD_POS_STEXTOUT,dataTextOut);
            }catch(Exception e){
                Log.e(TAG, e.getMessage(), e.fillInStackTrace());
            }
            return null;
        }
        protected void onPostExecute(String file_url){}
    }


    @Override
    protected void onUserLeaveHint()
    {
        Log.d("onUserLeaveHint","Home button pressed");
        super.onUserLeaveHint();
        //Unregister bluetooth receiver
        try{unregisterReceiver(bluetoothReceiver);}catch(Exception e){}
        //Disconnect bt connection
        try{WorkService.workThread.disconnectBt();}catch(Exception e){}
        // remove the handler
        try{WorkService.delHandler(mHandler);}catch(Exception e){}
        mHandler = null;
    }

    /**
     * Broadcast receiver for bluetooth state changes
     */
    private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            final String action = intent.getAction();
            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED))
            {
                final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,BluetoothAdapter.ERROR);
                switch (state)
                {
                    case BluetoothAdapter.STATE_OFF:
//                        closeConnection();//Close on going connection and disable button
                        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
                        break;
                    case BluetoothAdapter.STATE_ON:
                        break;
                }
            }
        }
    };

    private static class MHandler extends Handler {
        WeakReference<MainActivity> mActivity;
        MHandler(MainActivity activity) {
            mActivity = new WeakReference<>(activity);
        }
        @Override
        public void handleMessage(Message msg) {
            MainActivity theActivity = mActivity.get();
            switch (msg.what) {

                case Global.CMD_POS_STEXTOUTRESULT:
                case Global.CMD_POS_WRITERESULT: {
                    int result = msg.arg1;
                    Toast.makeText(
                            theActivity,
                            (result == 1) ? Global.toast_success
                                    : Global.toast_fail, Toast.LENGTH_SHORT).show();
                    Log.v(TAG, "Result: " + result);
                    break;
                }

            }
        }
    }


}

3 个答案:

答案 0 :(得分:2)

您的应用清单是否声明了要使用蓝牙的权限?

https://developer.android.com/guide/topics/connectivity/bluetooth#Permissions

  

为了在应用程序中使用蓝牙功能,必须声明两个权限。其中第一个是BLUETOOTH。您需要获得此权限才能执行任何蓝牙通信,例如请求连接,接受连接以及传输数据。

     

您必须声明的另一个权限是   ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION。位置许可   是必需的,因为可以使用蓝牙扫描来收集信息   关于用户的位置。此信息可能来自   用户自己的设备以及在位置使用的蓝牙信标   例如商店和公交设施。

答案 1 :(得分:0)

如果仅在您对apk进行签名时发生,则表明您必须更新urguard规则,以排除打印机lib类别或类似内容

答案 2 :(得分:0)

应用程序不响应的原因之一是您在按钮的Click侦听器中的第60行上将主线程停止了3秒钟。 用下面的代码替换 onCreate()方法

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

    //Get the activity
    this.activity = this;

    //Button from the XML view
    btnConnect = findViewById(R.id.btnConnect);

    //Start the Init Work Service Async task
    new InitWorkService().execute();

    final ExecutorService es = Executors.newFixedThreadPool(1);

    //Set onClickListener for test print button
    btnConnect.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            btnConnect.setEnabled(false);
            es.submit(new Runnable() {
                @Override
                public void run() {
                    connect();
                }
            });
        }
    });
}

private void connect() {
    try {
        //Check if name and address are set
        if (name != null && mac_address != null && mac_address.contains(":")) {

            if (!WorkService.workThread.isConnected()) {
                WorkService.workThread.connectBt(mac_address);
                //Sleep for 3 seconds
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {
                }
            }
            //Check if connected
            if (WorkService.workThread.isConnected()) {
                //Collect data in background Thread
                new PrintData().execute();
            } else {
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(activity, Global.toast_notconnect, Toast.LENGTH_SHORT).show();
                    }
                });
            }
        } else {
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(activity, "Please setup printer first!", Toast.LENGTH_LONG).show();
                }
            });
        }
    } catch (Exception e) {
        Log.e(TAG, e.getMessage(), e.fillInStackTrace());
    }
    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            btnConnect.setEnabled(true);
        }
    });
}

现在,连接部分在新线程中执行,只有UI操作进入主线程。

请注意,该代码不是最佳解决方案,因为它没有考虑活动生命周期。如果在线程休眠时重新创建活动,则仍然保留对旧活动的引用。但这应该是您的起点。