不期而遇123 2019-08-25 16:22 采纳率: 0%
浏览 713

Android 蓝牙通信问题

安卓开发萌新。在做一个蓝牙通信的APP,现在打开蓝牙可以搜索到周围一开启蓝牙的设备,点击连接后,也会出现配对的窗口,但软件会出现闪退,不知是何问题。以下是源代码,希望各路大佬可以帮我解决一下这个问题,是否是线程未开启呢。是否是因为我已经设置与单片机通信的UUID的问题。

package com.windfire;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import android.app.Activity;
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.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class WindFireDemoActivity extends Activity implements OnClickListener {
    /** Called when the activity is first created. */
    /*建立蓝牙适配器,搜索可连接设备,进行配对,*/
    public static final int RECV_VIEW = 0;
    private BluetoothAdapter mBluetoothAdapter;//蓝牙适配器
    private ArrayAdapter<String> deviceAdapter;//设备显示列表适配器
    private ConnectThread connectthread;
    private List<String> listDevices;
    private ListView text;//显示需要配对设备
    private Button parameterinput;//参数录入
    private Button teststart;//开始测试
    private Button search;//寻找设备按钮
    private Button send;//发送按钮
    private TextView datatest;
    private boolean sendflag = false;
    private final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");//蓝牙串口服务
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTheme(android.R.style.Theme_Black_NoTitleBar);
        setContentView(R.layout.main);

        initview();//实例化
        initBroadcast();//初始化广播

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();//获取本地蓝牙适配器,初始化蓝牙
        //是否支持蓝牙功能
        if(mBluetoothAdapter == null)
        {
            Toast.makeText(WindFireDemoActivity.this, "所持设备不支持蓝牙", Toast.LENGTH_SHORT).show();
        }     
    }

/************************定义广播接收,查找设备,检查配对信息,添加到listDevices中*************************/    
    private BroadcastReceiver mReceiver = new BroadcastReceiver()
    {         
        @Override
        public void onReceive(Context context, Intent intent)
        {             
            String action = intent.getAction();//服务发现远程设备时
            String str = "";
            if(BluetoothDevice.ACTION_FOUND.equals(action))//每扫描到一个设备,系统都会发送此广播
            {
                //从Intent中获取device信息
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);//获取搜索到的设备信息
                str = device.getName()+ ":" + device.getAddress() + "\n";
                //当发现的新设备不存在于设备配对列表中时,将设备的名字和地址添加到ArrayAdapter中
                if(listDevices.indexOf(str) == -1)//防止重复添加
                {
                    listDevices.add(str);//添加搜索到的设备信息
                    deviceAdapter.notifyDataSetChanged();
                }
            }
            else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
            {
                Toast.makeText(WindFireDemoActivity.this, "Discovery finished", Toast.LENGTH_SHORT).show();
            }
        }
    };

/**************************************UI实例化*************************************************/   
    public void initview()
    {
        parameterinput =(Button)findViewById(R.id.input);
        teststart =(Button)findViewById(R.id.start);
        search =(Button)findViewById(R.id.button);
        send =(Button)findViewById(R.id.send);
        text = (ListView)findViewById(R.id.listView1);
        datatest = (TextView)findViewById(R.id.datatest); 

        parameterinput.setOnClickListener(this);
        teststart.setOnClickListener(this);
        search.setOnClickListener(this);
        send.setOnClickListener(this);

        listDevices = new ArrayList<String>();
        deviceAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, listDevices);//列表显示listDevices的设备名称及mac
        text.setAdapter(deviceAdapter);
        text.setOnItemClickListener( new OnItemClickListener(){
            @Override
            public void onItemClick(AdapterView<?> adapterview, View view, int position,long id) 
            {
                // TODO Auto-generated method stub
                    //绑定所选择的蓝牙MAC地址设备
                    String str = deviceAdapter.getItem(position);
                    if(null == str)
                    {
                        Toast.makeText(getApplicationContext(), "未选中设备", Toast.LENGTH_SHORT).show();
                    }
                    String mac = str.substring(str.indexOf(":")+1).trim();
                    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mac);//以mac去创建一个device
                    connectthread = new ConnectThread(device);
                    connectthread.start();
                    Toast.makeText(getApplicationContext(), "连接到所选设备", Toast.LENGTH_SHORT).show();
            }
        });
    }
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch(v.getId())
        {
        case R.id.input:
            Intent intent1 = new Intent(WindFireDemoActivity.this,parametershow.class);
            startActivity(intent1);
            break;
        case R.id.start:
            Intent intent2 = new Intent(WindFireDemoActivity.this,datashow.class);
            startActivity(intent2);
            break;
        case R.id.button:
            if(!mBluetoothAdapter.isEnabled())
            {
                Intent enabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivity(enabler);//开启蓝牙
                if (mBluetoothAdapter.isEnabled())//设置可见
                {  
                    if (mBluetoothAdapter.getScanMode()!=BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE)
                    {  
                        Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);  
                        discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 200); 
                        startActivity(discoverableIntent);  
                    }  
                }
            }
            if (mBluetoothAdapter.isDiscovering()) 
            {
                mBluetoothAdapter.cancelDiscovery();
                Toast.makeText(getApplicationContext(), "Exit Discovery", Toast.LENGTH_SHORT).show();
            }
            else//搜索未开始
            {
                mBluetoothAdapter.startDiscovery();//开始搜索
                Toast.makeText(getApplicationContext(), "Start Discovery", Toast.LENGTH_SHORT).show();
            }
            break;
        case R.id.send:
            if(connectthread != null)//连接建立完成,准备发送指令开始通信
            {
                try
                {
                    sendflag = true;
                    String str = "0x33";
                    connectthread.write(getHexBytes(str));
                    datatest.setText("send success");
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
            else
            {
                Toast.makeText(WindFireDemoActivity.this, "未连接蓝牙设备", Toast.LENGTH_SHORT).show();
            }
            break;

        }
    }
/**************************************Broadcast初始化*************************************************/ 
    public void initBroadcast(){
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        registerReceiver(mReceiver,filter);
    }
/**************************************连接线程*************************************************/
    public class ConnectThread extends Thread 
    {
        private BluetoothSocket btSocket;
        private InputStream in;
        private OutputStream out;
        //private BluetoothDevice btDev;

        public ConnectThread (BluetoothDevice device)
        {
            try
            {
                btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
            }
            catch(IOException e)
            {
                e.printStackTrace();
            } 
        }
        public void run()
        {
            //发现服务会减慢连接建立速度,因此关闭掉
            if(mBluetoothAdapter.isDiscovering())
            {
                mBluetoothAdapter.cancelDiscovery();
            }//退出搜索
            try
            {
                //请求连接,该操作会阻塞线程
                btSocket.connect();
                Toast.makeText(WindFireDemoActivity.this, "连接建立", Toast.LENGTH_SHORT).show();
                in = btSocket.getInputStream();
                out = btSocket.getOutputStream();
                if(sendflag)
                {
                    new Thread(new Runnable(){
                        @Override
                        public void run(){
                            byte[] buffer = new byte[1024];
                            int bytes;
                            try{
                                while((bytes = in.read(buffer)) != -1)
                                {
                                    String str = new String(buffer,"UTF-8");
                                    str = str.substring(0, bytes);
                                    if(str.endsWith(" "))
                                    {
                                        datatest.append(str);
                                        continue;
                                    }
                                    Bundle bundle = new Bundle();
                                    Message message = new Message();
                                    bundle.putString("recv", datatest.toString());
                                    message.what = RECV_VIEW;
                                    message.setData(bundle);
                                    handler.sendMessage(message);
                                }
                            }
                            catch(IOException e)
                            {
                                e.printStackTrace();
                            }
                        }
                    }).start();
                }
            }
            catch(IOException e){
                try{
                    btSocket.close();
                }
                catch(IOException e1){
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
        }
        public void write(byte[] bytes)
        {
            try
            {
                out.write(bytes);
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }
        }
        public void cancel()
        {
            try
            {
                btSocket.close();
            } 
            catch (IOException e)
            {

            }
        }
    }
/******************************************Handler处理message*************************************/
      private Handler handler = new Handler()
      {
        @Override
        public void handleMessage(Message msg)
        {
            Bundle bundle = null;
            switch(msg.what)
            {
            case RECV_VIEW:
                bundle = msg.getData();
                String recv = bundle.getString("recv");
                datatest.append(recv+"\n");
                break;
            default:
                Toast.makeText(getApplicationContext(), "接受信息失败", Toast.LENGTH_SHORT).show();
            /*case NOTICE_VIEW:
                bundle = msg.getData();
                String notice = bundle.getString("notice");
                datatest.append(notice);*/
                break;
            }   
        }
      };

      public byte[] getHexBytes(String message) 
      {
          int len = message.length() / 2;
          char[] chars = message.toCharArray();
          String[] hexStr = new String[len];
          byte[] bytes = new byte[len];
          for (int i = 0, j = 0; j < len; i += 2, j++) 
          {
              hexStr[j] = "" + chars[i] + chars[i + 1];
              bytes[j] = (byte) Integer.parseInt(hexStr[j], 16);
          }
          return bytes;
      }

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


}

希望尽快解答

  • 写回答

1条回答

  • Zhangzhiqiang01 2019-08-27 18:13
    关注

    闪退看log报错信息。
    建议使用三方库进行操作

    评论

报告相同问题?

悬赏问题

  • ¥15 Matlab问题解答有两个问题
  • ¥50 Oracle Kubernetes服务器集群主节点无法访问,工作节点可以访问
  • ¥15 LCD12864中文显示
  • ¥15 在使用CH341SER.EXE时不小心把所有驱动文件删除了怎么解决
  • ¥15 gsoap生成onvif框架
  • ¥15 有关sql server business intellige安装,包括SSDT、SSMS。
  • ¥15 stm32的can接口不能收发数据
  • ¥15 目标检测算法移植到arm开发板
  • ¥15 利用JD51设计温度报警系统
  • ¥15 快手联盟怎么快速的跑出建立模型