簡體   English   中英

嘗試與遠程設備連接時,藍牙聊天應用程序中出現“服務發現失敗”錯誤,該錯誤當時不可用

[英]'service discovery failed' error in bluetooth chat application while trying to connect with a remote device, which is not available at that time

我在android平台上構建一個藍牙聊天應用程序。 一切都很好,但我的應用程序中出現了小毛病。 當我嘗試與配對設備列表中存在但當前無法作為附近設備使用的遠程設備連接時,它會引發“服務發現失敗”異常,並且我的應用程序會自動終止。 為了防止這種自動終止,我還設置了條件,例如發生此類異常,然后再次啟動“接受線程”,但它不起作用。

mainActivity.java源代碼

軟件包simpleweather.bluetooth_test1;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import java.lang.InterruptedException;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.Context;
import android.content.BroadcastReceiver;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TabHost;
import android.widget.TextView;
import java.util.Set;
import android.widget.Toast;
import java.util.ArrayList;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView;
import android.view.View;
import android.widget.ArrayAdapter;
public class MainActivity extends AppCompatActivity {
    private static final int REQUEST_ENABLE_BT = 1;
    BluetoothAdapter bluetoothAdapter;
    private UUID myUUID;
    private String myName;
    Button Refresh;
    ListView NewDevices;
    ArrayList<String> ScanNewList;
    ArrayAdapter<String> ScanNewAdapter;
    server serverconnection=null;
    ArrayList<String> conversation;
    ArrayAdapter<String>  sessionchat;
    ListView MsgList;
    ArrayList<String> pairedDeviceArrayList;
    ListView listViewPairedDevice;
    ArrayAdapter<String> pairedDeviceAdapter;
    client clientconnection=null;
    communication datatransfer=null;
    EditText input;
    FloatingActionButton sent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        NewDevices=(ListView)findViewById(R.id.newDevices);
        ScanNewList=new ArrayList<String>();
        Refresh=(Button)findViewById(R.id.refresh);
        ScanNewAdapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,ScanNewList);
        NewDevices.setAdapter(ScanNewAdapter);
        sent=(FloatingActionButton)findViewById(R.id.send);
        input=(EditText)findViewById(R.id.input);
        MsgList=(ListView)findViewById(R.id.msglist);
        conversation=new ArrayList<String>();
        sessionchat = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, conversation);
        MsgList.setAdapter(sessionchat);
        TabHost tabHost=(TabHost)findViewById(R.id.tabHost);
        tabHost.setup();
        TabHost.TabSpec tabSpec=tabHost.newTabSpec("paireddevices");
        tabSpec.setContent(R.id.pairedDevices);
        tabSpec.setIndicator("Paired Devices");
        tabHost.addTab(tabSpec);
        tabSpec=tabHost.newTabSpec("msgArea");
        tabSpec.setContent(R.id.chatArea);
        tabSpec.setIndicator("Start Chat");
        tabHost.addTab(tabSpec);
        tabSpec=tabHost.newTabSpec("newdiscovered_devices");
        tabSpec.setContent(R.id.newdevices);
        tabSpec.setIndicator("Scan Devices");
        tabHost.addTab(tabSpec);
        listViewPairedDevice=(ListView)findViewById(R.id.listView);
        sent.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                if(datatransfer!=null){
                    byte[] bytesToSend = input.getText().toString().getBytes();
                    datatransfer.write(bytesToSend,input.getText().toString());
                    input.setText("");
                }
            }});
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)){
            Toast.makeText(getBaseContext(),"FEATURE_BLUETOOTH NOT support",Toast.LENGTH_SHORT).show();
            finish();
            return;
        }
        myUUID = UUID.fromString("ec79da00-853f-11e4-b4a9-0800200c9a66");
        myName = myUUID.toString();
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null) {
            Toast.makeText(getBaseContext(),"Bluetooth is not supported on this hardware platform",Toast.LENGTH_SHORT).show();
            finish();
            return;
        }
        if (!bluetoothAdapter.isEnabled()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
        }else{
            server_start();
            client_start();
        }

        Refresh.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (bluetoothAdapter.isDiscovering()) {
                    bluetoothAdapter.cancelDiscovery();
                }
                bluetoothAdapter.startDiscovery();
            }
        });
         // start discovery for new devices
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); // registering broadcast reciever for retrieving information of new devices
        registerReceiver(mReceiver, filter);
        NewDevices.setOnItemClickListener(new OnItemClickListener() { // list of newly scaned devices
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                bluetoothAdapter.cancelDiscovery();
                String info = ((TextView) view).getText().toString();
                String address = info.substring(info.length() - 17);
                BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
                Toast.makeText(MainActivity.this,"Name: " + device.getName() + "\n" + "Address: " + device.getAddress(), Toast.LENGTH_SHORT).show();
                clientconnection = new client(device);
                clientconnection.start();

            }
        });

    }
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
        // check if the request code is same as what is passed  here it is 1
        if(requestCode==1) {
           Log.d("Shashank","Bluetooth turned on ");
            server_start();
            client_start();
        }
    }

    private synchronized void server_start() {
        if(clientconnection!=null)
        {
            clientconnection.cancel();
            clientconnection=null;
        }
        if(datatransfer!=null){
            datatransfer.cancel();
            datatransfer=null;
        }
        if(serverconnection!=null) {
            serverconnection.cancel();
            serverconnection = null;
        }
        serverconnection = new server();
            serverconnection.start();

    }


    @Override
    protected void onDestroy() {

        super.onDestroy();
        if(bluetoothAdapter!=null){
            bluetoothAdapter.cancelDiscovery();
        }
        unregisterReceiver(mReceiver);
        if(serverconnection!=null){
            serverconnection.cancel();
            serverconnection=null;
        }
        if(clientconnection!=null){
            clientconnection.cancel();
            clientconnection=null;
        }

    }
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if(!ScanNewList.contains(device.getName()+"\n"+device.getAddress())) {
                    ScanNewList.add(device.getName() + "\n" + device.getAddress());
                    ScanNewAdapter.notifyDataSetChanged();
                }

            }
        }
    };

    private class server extends Thread {
        private BluetoothServerSocket bluetoothServerSocket = null;
        public server() {
            try {
                bluetoothServerSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(myName, myUUID);
                Toast.makeText(getBaseContext(),"Waiting\n" + "bluetoothServerSocket :\n" + bluetoothServerSocket,Toast.LENGTH_SHORT).show();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                server_start();
            }
        }

        @Override
        public void run() {
            BluetoothSocket bluetoothSocket = null;
            if(bluetoothServerSocket!=null){
                try {
                    bluetoothSocket = bluetoothServerSocket.accept();
                    BluetoothDevice remoteDevice = bluetoothSocket.getRemoteDevice();
                    final String strConnected = "Connected:\n" + remoteDevice.getName() + "\n" +remoteDevice.getAddress();

                    //connected
                    runOnUiThread(new Runnable(){
                        @Override
                        public void run() {
                            Toast.makeText(getBaseContext(),strConnected,Toast.LENGTH_SHORT).show();
                        }});
                    start_communication(bluetoothSocket,remoteDevice.getName());

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    final String eMessage = e.getMessage();
                    runOnUiThread(new Runnable(){
                        @Override
                        public void run() {
                            Toast.makeText(getBaseContext(),"something wrong: \n" + eMessage,Toast.LENGTH_SHORT).show();
                        }});
                    server_start();
                }
            }else{
                runOnUiThread(new Runnable(){
                    @Override
                    public void run() {
                        Toast.makeText(getBaseContext(),"bluetoothServerSocket == null",Toast.LENGTH_SHORT).show();
                    }});
            }
        }

        public void cancel() {
            Toast.makeText(getBaseContext(),"close bluetoothServerSocket", Toast.LENGTH_SHORT).show();
            try {
                bluetoothServerSocket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    private void client_start() {
        Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
        if (pairedDevices.size() > 0) {
            findViewById(R.id.listView).setVisibility(View.VISIBLE);
            pairedDeviceArrayList = new ArrayList<String>();
            pairedDeviceAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, pairedDeviceArrayList);
            for (BluetoothDevice device : pairedDevices) {
                pairedDeviceArrayList.add(device.getName()+"\n"+device.getAddress());

            }
            pairedDeviceAdapter.notifyDataSetChanged();
            listViewPairedDevice.setAdapter(pairedDeviceAdapter);
            listViewPairedDevice.setOnItemClickListener(new OnItemClickListener(){
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    bluetoothAdapter.cancelDiscovery();
                    String info = ((TextView) view).getText().toString();
                    String address = info.substring(info.length() - 17);
                    BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
                    Toast.makeText(MainActivity.this,"Name: " + device.getName() + "\n"+ "Address: " + device.getAddress(),Toast.LENGTH_SHORT).show();
                    clientconnection = new client(device);
                    clientconnection.start();
                }});
        }
    }
    private class client extends Thread {
        private BluetoothSocket bluetoothSocket = null;
        private final BluetoothDevice bluetoothDevice;

        public client(BluetoothDevice device) {
            bluetoothDevice = device;
            try {
                bluetoothSocket = device.createRfcommSocketToServiceRecord(myUUID);
                Toast.makeText(getBaseContext(),"bluetoothSocket: \n" + bluetoothSocket,Toast.LENGTH_SHORT).show();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                //e.printStackTrace();
                server_start();
            }
        }
        @Override
        public void run() {
            boolean success = false;
            try {
                bluetoothSocket.connect();
                success = true;
            } catch (IOException e) {
                e.printStackTrace();
                final String eMessage = e.getMessage();
                runOnUiThread(new Runnable(){
                    @Override
                    public void run() {
                        Toast.makeText(getBaseContext(),"something wrong bluetoothSocket.connect(): \n" + eMessage,Toast.LENGTH_SHORT).show();
                    }});

                try {
                    bluetoothSocket.close();
                }
                catch (IOException e2){
                  e2.printStackTrace();
                    server_start();
                }


            }
            if(success){
                //connect successful
                runOnUiThread(new Runnable(){
                    @Override
                    public void run() {
                        Toast.makeText(getBaseContext(),"connection successfull",Toast.LENGTH_SHORT).show();
                    }});
                start_communication(bluetoothSocket,bluetoothDevice.getName());
            }else{
                //fail
                Toast.makeText(getBaseContext(),"Could not connected with the device!",Toast.LENGTH_SHORT).show();
                server_start();
            }
        }
        public void cancel() {
            Toast.makeText(getBaseContext(), "Closed bluetoothSocket", Toast.LENGTH_SHORT).show();
            try {
                bluetoothSocket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }
    private void start_communication(BluetoothSocket socket,String chater){

        datatransfer = new communication(socket,chater);
        datatransfer.start();
    }
    private class communication extends Thread {
        private final BluetoothSocket connectedBluetoothSocket;
        private final InputStream connectedInputStream;
        private final OutputStream connectedOutputStream;
        String deviceName;
        public communication(BluetoothSocket socket,String chater) {
            connectedBluetoothSocket = socket;
            deviceName=chater;
            InputStream in = null;
            OutputStream out = null;
            try {
                in = socket.getInputStream();
                out = socket.getOutputStream();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            connectedInputStream = in;
            connectedOutputStream = out;
        }

        @Override
        public void run() {
            byte[] buffer = new byte[1024];
            int bytes;
            while (true) {
                try {
                    bytes = connectedInputStream.read(buffer);
                    String strReceived = new String(buffer, 0, bytes);
                    final String msgReceived =strReceived;
                    runOnUiThread(new Runnable(){
                        @Override
                        public void run() {
                            conversation.add(deviceName+" : "+msgReceived);
                            sessionchat.notifyDataSetChanged();
                        }});

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    final String msgConnectionLost = "Connection lost:\n" + e.getMessage();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getBaseContext(), msgConnectionLost, Toast.LENGTH_SHORT).show();
                            server_start();
                        }
                    });
                    break;
                }
            }
        }
        public void write(byte[] buffer,String sendmsg) {
            try {
                connectedOutputStream.write(buffer);
                conversation.add("Me : "+sendmsg);
                sessionchat.notifyDataSetChanged();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                server_start();
            }
        }
        public void cancel() {
            try {
                connectedBluetoothSocket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}

這是活動布局文件

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:context="simpleweather.bluetooth_test1.MainActivity"
        tools:showIn="@layout/activity_main">


        <TabHost
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/tabHost"
            android:layout_alignParentTop="true"
            android:layout_alignRight="@+id/textView2"
            android:layout_alignEnd="@+id/textView2">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <TabWidget
                    android:id="@android:id/tabs"
                    android:layout_width="340dp"
                    android:layout_height="wrap_content"></TabWidget>

                <FrameLayout
                    android:id="@android:id/tabcontent"
                    android:layout_width="392dp"
                    android:layout_height="match_parent">

                    <RelativeLayout
                        android:id="@+id/chatArea"
                        android:layout_width="361dp"
                        android:layout_height="541dp"
                        android:weightSum="1">
                        <ListView
                            android:layout_width="match_parent"
                            android:layout_height="380dp"
                            android:id="@+id/msglist"
                            android:stackFromBottom="true"
                            android:transcriptMode="alwaysScroll"
                            android:layout_weight="0.87"
                            android:layout_above="@+id/send" />
                        <EditText
                            android:layout_width="230dp"
                            android:layout_height="wrap_content"
                            android:id="@+id/input"
                            android:hint="Type Message"
                            android:layout_marginBottom="41dp"
                            android:layout_alignParentBottom="true"
                            android:layout_alignParentLeft="true"
                            android:layout_alignParentStart="true"
                            android:layout_toStartOf="@+id/send"
                            android:layout_toLeftOf="@+id/send"
                            android:layout_marginRight="0dp" />

                        <android.support.design.widget.FloatingActionButton
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:src="@android:drawable/ic_dialog_email"
                            android:id="@+id/send"
                            android:layout_gravity="center_horizontal"

                            android:layout_alignBottom="@+id/input"
                            android:layout_alignParentRight="true"
                            android:layout_alignParentEnd="true"
                            android:layout_marginRight="20dp" />
                    </RelativeLayout>

                    <LinearLayout
                        android:id="@+id/newdevices"
                        android:layout_width="355dp"
                        android:layout_height="516dp"
                        android:orientation="vertical"
                        android:weightSum="1">

                        <Button
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Refresh Scan"
                            android:id="@+id/refresh"
                            android:layout_gravity="center_horizontal"
                            android:layout_marginTop="10dp" />

                        <ListView
                            android:layout_width="match_parent"
                            android:layout_height="379dp"
                            android:id="@+id/newDevices"
                            android:layout_marginTop="30dp"
                            android:layout_weight="0.47" />


                    </LinearLayout>

                    <LinearLayout
                        android:id="@+id/pairedDevices"
                        android:layout_width="374dp"
                        android:layout_height="500dp"
                        android:orientation="vertical"
                        android:weightSum="1">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:textAppearance="?android:attr/textAppearanceMedium"
                            android:text="Tap over the Listed Devices to start Connection"
                            android:id="@+id/textView"
                            android:layout_alignParentTop="true"
                            android:layout_alignParentLeft="true"
                            android:layout_alignParentStart="true"
                            android:layout_marginTop="10dp" />

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:textAppearance="?android:attr/textAppearanceLarge"
                            android:text="Paired Devices"
                            android:id="@+id/textView2"
                            android:layout_below="@+id/textView"
                            android:layout_centerHorizontal="true"
                            android:layout_gravity="center_horizontal" />

                        <ListView
                            android:layout_width="350dp"
                            android:layout_height="450dp"
                            android:id="@+id/listView"
                            android:layout_below="@+id/textView2"
                            android:layout_alignRight="@+id/textView"
                            android:layout_alignEnd="@+id/textView" />
                    </LinearLayout>

                </FrameLayout>
            </LinearLayout>
        </TabHost>
    </RelativeLayout>
</ScrollView>

我有顯示錯誤的屏幕截圖。 屏幕截圖顯示了錯誤

我很困惑為什么這一切發生。 我搜索了類似的問題,但是沒有發現像我的bug這樣的情況。 請幫我 。

我的意思是,如果您的連接由於異常而失敗,那么將執行錯誤路徑。 在錯誤路徑中顯示“ Toast”的代碼與所有其他Toast調用不同。 (即,可能未在UI線程上調用它),因此可能是問題所在。 否則server.start()調用中可能存在問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM