运行蓝牙作为后台服务无法正常工作

时间:2014-03-01 07:33:11

标签: java android bluetooth android-service

*我是android新手任何帮助请帮助我,并提前感谢。 我希望蓝牙始终在应用程序中连接,同时从一个活动切换到另一个活动。所以我正在做背景服务。第一类显示配对设备列表,第二类用于运行蓝牙作为后台服务。没有错误一切都很好但是当我切换活动时蓝牙断开连接并且它没有显示状态已更改。问我如果您需要任何其他信息*

这是我的第一堂课程主屏幕

  public class Homescreen extends Activity {
    public static Homescreen home;
    private Button mBtnSearch;
    private Button mBtnConnect;
    private ListView mLstDevices;

    private BluetoothAdapter mBTAdapter;

    private static final int BT_ENABLE_REQUEST = 10; // This is the code we use for BT Enable
    private static final int SETTINGS = 20;

    private UUID mDeviceUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // Standard SPP UUID
    // (http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createInsecureRfcommSocketToServiceRecord%28java.util.UUID%29)

    private int mBufferSize = 50000; //Default
    public static final String DEVICE_EXTRA = "com.blueserial.SOCKET";
    public static final String DEVICE_UUID = "com.blueserial.uuid";
    private static final String DEVICE_LIST = "com.blueserial.devicelist";
    private static final String DEVICE_LIST_SELECTED = "com.blueserial.devicelistselected";
    public static final String BUFFER_SIZE = "com.blueserial.buffersize";
    private static final String TAG = "BlueTest5-Homescreen";

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

        setContentView(R.layout.activity_homescreen);
        home=this;
        ActivityHelper.initialize(this); //This is to ensure that the rotation persists across activities and not just this one
        Log.d(TAG, "Created");

        mBtnSearch = (Button) findViewById(R.id.btnSearch);
        mBtnConnect = (Button) findViewById(R.id.btnConnect);

        mLstDevices = (ListView) findViewById(R.id.lstDevices);

        /*
         *Check if there is a savedInstanceState. If yes, that means the onCreate was probably triggered by a configuration change
         *like screen rotate etc. If that's the case then populate all the views that are necessary here 
         */
        if (savedInstanceState != null) {
            ArrayList<BluetoothDevice> list = savedInstanceState.getParcelableArrayList(DEVICE_LIST);
            if(list!=null){
                initList(list);
                MyAdapter adapter = (MyAdapter)mLstDevices.getAdapter();
                int selectedIndex = savedInstanceState.getInt(DEVICE_LIST_SELECTED);
                if(selectedIndex != -1){
                    adapter.setSelectedIndex(selectedIndex);
                    mBtnConnect.setEnabled(true);
                }
            } else {
                initList(new ArrayList<BluetoothDevice>());
            }

        } else {
            initList(new ArrayList<BluetoothDevice>());
        }


        mBtnSearch.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                mBTAdapter = BluetoothAdapter.getDefaultAdapter();

                if (mBTAdapter == null) {
                    Toast.makeText(getApplicationContext(), "Bluetooth not found", Toast.LENGTH_SHORT).show();
                } else if (!mBTAdapter.isEnabled()) {
                    Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(enableBT, BT_ENABLE_REQUEST);
                } else {
                    new SearchDevices().execute();
                }
            }
        });

        mBtnConnect.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                Intent intt=new Intent(Homescreen.this,BluetoothService.class);
                //bindService( intt, null, Context.BIND_AUTO_CREATE);
                BluetoothDevice device = ((MyAdapter) (mLstDevices.getAdapter())).getSelectedItem();
                intt.putExtra(DEVICE_EXTRA, device);
                intt.putExtra(DEVICE_UUID, mDeviceUUID.toString());
                intt.putExtra(BUFFER_SIZE, mBufferSize);
                startService(intt);
//              Toast.makeText(Homescreen.this, "Device Connected", Toast.LENGTH_LONG).show();
//              BluetoothDevice device = ((MyAdapter) (mLstDevices.getAdapter())).getSelectedItem();
//              Intent intent = new Intent(getApplicationContext(), MainBluetooth.class);
//              intent.putExtra(DEVICE_EXTRA, device);
//              intent.putExtra(DEVICE_UUID, mDeviceUUID.toString());
//              intent.putExtra(BUFFER_SIZE, mBufferSize);
//              startActivity(intent);
            }
        });
    }

    /**
     * Called when the screen rotates. If this isn't handled, data already generated is no longer available
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        MyAdapter adapter = (MyAdapter) (mLstDevices.getAdapter());
        ArrayList<BluetoothDevice> list = (ArrayList<BluetoothDevice>) adapter.getEntireList();

        if (list != null) {
            outState.putParcelableArrayList(DEVICE_LIST, list);
            int selectedIndex = adapter.selectedIndex;
            outState.putInt(DEVICE_LIST_SELECTED, selectedIndex);
        }
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
        case BT_ENABLE_REQUEST:
            if (resultCode == RESULT_OK) {
                msg("Bluetooth Enabled successfully");
                new SearchDevices().execute();
            } else {
                msg("Bluetooth couldn't be enabled");
            }

            break;
        case SETTINGS: //If the settings have been updated
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
            String uuid = prefs.getString("prefUuid", "Null");
            mDeviceUUID = UUID.fromString(uuid);
            Log.d(TAG, "UUID: " + uuid);
            String bufSize = prefs.getString("prefTextBuffer", "Null");
            mBufferSize = Integer.parseInt(bufSize);

            String orientation = prefs.getString("prefOrientation", "Null");
            Log.d(TAG, "Orientation: " + orientation);
            if (orientation.equals("Landscape")) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            } else if (orientation.equals("Portrait")) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            } else if (orientation.equals("Auto")) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
            }
            break;
        default:
            break;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * Quick way to call the Toast
     * @param str
     */
    private void msg(String str) {
        Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
    }

    /**
     * Initialize the List adapter
     * @param objects
     */
    private void initList(List<BluetoothDevice> objects) {
        final MyAdapter adapter = new MyAdapter(getApplicationContext(), R.layout.list_item, R.id.lstContent, objects);
        mLstDevices.setAdapter(adapter);
        mLstDevices.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                adapter.setSelectedIndex(position);
                mBtnConnect.setEnabled(true);
            }
        });
    }

    /**
     * Searches for paired devices. Doesn't do a scan! Only devices which are paired through Settings->Bluetooth
     * will show up with this. I didn't see any need to re-build the wheel over here
     * @author ryder
     *
     */
    private class SearchDevices extends AsyncTask<Void, Void, List<BluetoothDevice>> {

        @Override
        protected List<BluetoothDevice> doInBackground(Void... params) {
            Set<BluetoothDevice> pairedDevices = mBTAdapter.getBondedDevices();
            List<BluetoothDevice> listDevices = new ArrayList<BluetoothDevice>();
            for (BluetoothDevice device : pairedDevices) {
                listDevices.add(device);
            }
            return listDevices;

        }

        @Override
        protected void onPostExecute(List<BluetoothDevice> listDevices) {
            super.onPostExecute(listDevices);
            if (listDevices.size() > 0) {
                MyAdapter adapter = (MyAdapter) mLstDevices.getAdapter();
                adapter.replaceItems(listDevices);
            } else {
                msg("No paired devices found, please pair your serial BT device and try again");
            }
        }

    }

    /**
     * Custom adapter to show the current devices in the list. This is a bit of an overkill for this 
     * project, but I figured it would be good learning
     * Most of the code is lifted from somewhere but I can't find the link anymore
     * @author ryder
     *
     */
    private class MyAdapter extends ArrayAdapter<BluetoothDevice> {
        private int selectedIndex;
        private Context context;
        private int selectedColor = Color.parseColor("#abcdef");
        private List<BluetoothDevice> myList;

        public MyAdapter(Context ctx, int resource, int textViewResourceId, List<BluetoothDevice> objects) {
            super(ctx, resource, textViewResourceId, objects);
            context = ctx;
            myList = objects;
            selectedIndex = -1;
        }

        public void setSelectedIndex(int position) {
            selectedIndex = position;
            notifyDataSetChanged();
        }

        public BluetoothDevice getSelectedItem() {
            return myList.get(selectedIndex);
        }

        @Override
        public int getCount() {
            return myList.size();
        }

        @Override
        public BluetoothDevice getItem(int position) {
            return myList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        private class ViewHolder {
            TextView tv;
        }

        public void replaceItems(List<BluetoothDevice> list) {
            myList = list;
            notifyDataSetChanged();
        }

        public List<BluetoothDevice> getEntireList() {
            return myList;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View vi = convertView;
            ViewHolder holder;
            if (convertView == null) {
                vi = LayoutInflater.from(context).inflate(R.layout.list_item, null);
                holder = new ViewHolder();

                holder.tv = (TextView) vi.findViewById(R.id.lstContent);

                vi.setTag(holder);
            } else {
                holder = (ViewHolder) vi.getTag();
            }

            if (selectedIndex != -1 && position == selectedIndex) {
                holder.tv.setBackgroundColor(selectedColor);
            } else {
                holder.tv.setBackgroundColor(Color.WHITE);
            }
            BluetoothDevice device = myList.get(position);
            holder.tv.setText(device.getName() + "\n   " + device.getAddress());

            return vi;
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.homescreen, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.action_settings:
            Intent intent = new Intent(Homescreen.this, PreferencesActivity.class);
            startActivityForResult(intent, SETTINGS);
            break;
        }
        return super.onOptionsItemSelected(item);
    }
}

这是我的第二类蓝牙服务类

    public class BluetoothService extends Service {
        public static BluetoothService service;

        private boolean mConnectSuccessful = true;
        private static boolean isRunning = false;
        private static final String TAG = "BlueTest5-MainActivity";
        private int mMaxChars = 50000;//Default
        //private UUID mDeviceUUID=UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
        private UUID mDeviceUUID;

        private BluetoothSocket mBTSocket;
        private boolean mIsBluetoothConnected = false;

        //private BluetoothDevice mDevice=Homescreen.home.device;
        private BluetoothDevice mDevice;

        @Override
        public void onStart(Intent intent, int startId) {
            // TODO Auto-generated method stub
//          Intent intt = getIntent();
//          Bundle b = intt.getExtras();
//          mDevice = b.getParcelable(Homescreen.DEVICE_EXTRA);
//          mDeviceUUID = UUID.fromString(b.getString(Homescreen.DEVICE_UUID));
//          mMaxChars = b.getInt(Homescreen.BUFFER_SIZE);
//          super.onStart(intent, startId);
        }

        @Override
        public void onCreate() {
            service=this;
              IntentFilter filter1 = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
                IntentFilter filter2 = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
                IntentFilter filter3 = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
                this.registerReceiver(mReceiver, filter1);
                this.registerReceiver(mReceiver, filter2);
                this.registerReceiver(mReceiver, filter3);

            // TODO Auto-generated method stub
//          Intent intent = getIntent();
//          Bundle b = intent.getExtras();
//          mDevice = b.getParcelable(Homescreen.DEVICE_EXTRA);
//          mDeviceUUID = UUID.fromString(b.getString(Homescreen.DEVICE_UUID));
//          mMaxChars = b.getInt(Homescreen.BUFFER_SIZE);


            super.onCreate();
        }

         @Override
            public IBinder onBind(Intent arg0) {
                // TODO Auto-generated method stub
                return null;
            }

       @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub

            Bundle b = intent.getExtras();
            mDevice = b.getParcelable(Homescreen.DEVICE_EXTRA);
            mDeviceUUID = UUID.fromString(b.getString(Homescreen.DEVICE_UUID));
            mMaxChars = b.getInt(Homescreen.BUFFER_SIZE);
            Log.i("mDeviceUUID", ""+mDeviceUUID);
            Log.d("mDevice",""+mDevice );
           new ConnectBT().execute();
           return START_STICKY;
           //return super.onStartCommand(intent, flags, startId);
    }


       public boolean isRunning() {
            return isRunning;
        }

       @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
           // Unregister broadcast listeners
            this.unregisterReceiver(mReceiver);
        super.onDestroy();
    }
        class ConnectBT extends AsyncTask<Void, Void, Void> {

            //ProgressDialog progressDialog;
            @Override
            protected void onPreExecute() {
                // http://stackoverflow.com/a/11130220/1287554
            // progressDialog = ProgressDialog.show(BluetoothService.this, "Hold on", "Connecting");
                Log.d("check check check", "check1");
            }

            @Override
            protected Void doInBackground(Void... devices) {
                Log.d("check check check", "check2");
                try {
                    Log.e("check check check", "check3");
                    if (mBTSocket == null || !mIsBluetoothConnected) {
                        Log.e("UUID", ""+mDeviceUUID);
                        Log.e("mDevice", ""+mDevice);
                        mBTSocket = mDevice.createInsecureRfcommSocketToServiceRecord(mDeviceUUID);
                        Log.d("check check check", "check4");
                        BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
                        mBTSocket.connect();
                        Log.d("check check check", "check5");
                    //  Toast.makeText(BluetoothService.this, "background service start", Toast.LENGTH_LONG).show();
                    }
                } catch (IOException e) {
                    // Unable to connect to device
                    e.printStackTrace();
                    mConnectSuccessful = false;
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                super.onPostExecute(result);

                if (!mConnectSuccessful) {
                    Toast.makeText(BluetoothService.this, "Could not connect to device. Is it a Serial device? Also check if the UUID is correct in the settings", Toast.LENGTH_LONG).show();
                    Log.e("Device Status in service", "Disconnected");



                } else {
                    Toast.makeText(BluetoothService.this, "Connected to device", Toast.LENGTH_SHORT).show();
                    Log.e("Device Status in service", "Device Connected");
                    mIsBluetoothConnected = true;
                     // Kick off input reader
                }
                //progressDialog.dismiss();

            }

        }


          //The BroadcastReceiver that listens for bluetooth broadcasts
        private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
                //Do something if connected
                Toast.makeText(getApplicationContext(), "BT Connected", Toast.LENGTH_SHORT).show();
                Log.e("Bluetooth device connected","BT Connected");
            }
            else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
                //Do something if disconnected
                Toast.makeText(getApplicationContext(), "BT Disconnected", Toast.LENGTH_SHORT).show();
                Log.e("Bluetooth device disconnected","BT Disconnected");
            }
            //else if...
        }
    };


    }

1 个答案:

答案 0 :(得分:0)

Android的AsyncTask类将为您提供帮助。在AsyncTask的doInBackground()方法中执行蓝牙发现任务。您可以在onPostExecute()方法中的任务之后向消息a Toast。 Here是示例代码段,用于演示AsyncTask的使用