如何从后台服务/线程传递数据并获取通知?

时间:2015-02-22 10:11:05

标签: android bluetooth

Console.class:

public class Console extends Activity  implements Handler.Callback{
    /**
     *  @version 1.1 (28.01.2013)
     *  http://english.cxem.net/arduino/arduino5.php
     *  @author Koltykov A.V. (�������� �.�.)
     * 
     */

    // Store the current connected Device Address;

      private static final String TAG = "bluetooth2";

      Button btnOn, btnOff;
      TextView txtArduino;
      Handler h;

      final static int RECIEVE_MESSAGE = 1;     // Status  for Handler
      private BluetoothAdapter btAdapter = null;
      private BluetoothSocket btSocket = null;
      private StringBuilder sb = new StringBuilder();



      // SPP UUID service
      private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

      // MAC-address of Bluetooth module (you must edit this line)
    //  private static String address = "20:13:03:05:08:07";
      String mCurrentDeviceAddress = null;
        // Name of the connected device
        ConnectedThread mConnectedThread;
        SharedPreferences settings;
        // private String bufferMessege;

        // Local Bluetooth adapter
        BluetoothAdapter mBluetoothAdapter = null;
      /** Called when the activity is first created. */

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

        setContentView(R.layout.activity_console);



        settings = getSharedPreferences(DeviceList.PREFS_NAME, 0);

        mCurrentDeviceAddress = settings.getString(
            DeviceList.PREFS_DEVICE_ADDR, null);




        btnOn = (Button) findViewById(R.id.btnOn);                  // button LED ON
        btnOff = (Button) findViewById(R.id.btnOff);                // button LED OFF
        txtArduino = (TextView) findViewById(R.id.txtArduino);      // for display the received data from the Arduino

        h = new Handler() {
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                case RECIEVE_MESSAGE:                                                   // if receive massage
                    byte[] readBuf = (byte[]) msg.obj;
                    String strIncom = new String(readBuf, 0, msg.arg1);                 // create string from bytes array
                    sb.append(strIncom);                                                // append string
                    int endOfLineIndex = sb.indexOf("\r\n");                            // determine the end-of-line
                    if (endOfLineIndex > 0) {                                           // if end-of-line,
                        String sbprint = sb.substring(0, endOfLineIndex);               // extract string
                        sb.delete(0, sb.length());                                      // and clear
                        txtArduino.setText("Data from Arduino: " + sbprint);            // update TextView
                        btnOff.setEnabled(true);
                        btnOn.setEnabled(true); 
                    }
                    //Log.d(TAG, "...String:"+ sb.toString() +  "Byte:" + msg.arg1 + "...");
                    break;
                }
            };
        };

        btAdapter = BluetoothAdapter.getDefaultAdapter();       // get Bluetooth adapter
        checkBTState();

        btnOn.setOnClickListener(new OnClickListener() {
          public void onClick(View v) {
            btnOn.setEnabled(false);
            mConnectedThread.write("1");    // Send "1" via Bluetooth
            //Toast.makeText(getBaseContext(), "Turn on LED", Toast.LENGTH_SHORT).show();
          }
        });

        btnOff.setOnClickListener(new OnClickListener() {
          public void onClick(View v) {
            btnOff.setEnabled(false);  
            mConnectedThread.write("0");    // Send "0" via Bluetooth
            //Toast.makeText(getBaseContext(), "Turn off LED", Toast.LENGTH_SHORT).show();
          }
        });
      }

      private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
          if(Build.VERSION.SDK_INT >= 10){
              try {
                  final Method  m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class });
                  return (BluetoothSocket) m.invoke(device, MY_UUID);
              } catch (Exception e) {
                  Log.e(TAG, "Could not create Insecure RFComm Connection",e);
              }
          }
          return  device.createRfcommSocketToServiceRecord(MY_UUID);
      }

      @Override
      public void onResume() {
        super.onResume();
       // registerReceiver(receiver, new IntentFilter(aa.NOTIFICATION));
        Log.d(TAG, "...onResume - try connect...");

        // Set up a pointer to the remote node using it's address.
        BluetoothDevice device = btAdapter.getRemoteDevice(mCurrentDeviceAddress);

        // Two things are needed to make a connection:
        //   A MAC address, which we got above.
        //   A Service ID or UUID.  In this case we are using the
        //     UUID for SPP.

        try {
            btSocket = createBluetoothSocket(device);
        } catch (IOException e) {
            errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
        }

        /*try {
          btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
          errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
        }*/

        // Discovery is resource intensive.  Make sure it isn't going on
        // when you attempt to connect and pass your message.
        btAdapter.cancelDiscovery();

        // Establish the connection.  This will block until it connects.
        Log.d(TAG, "...Connecting...");
        try {
          btSocket.connect();
          Log.d(TAG, "....Connection ok...");
        } catch (IOException e) {
          try {
            btSocket.close();
          } catch (IOException e2) {
            errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
          }
        }

        // Create a data stream so we can talk to server.
        Log.d(TAG, "...Create Socket...");

        mConnectedThread = new ConnectedThread(btSocket);
        mConnectedThread.start();
      }
      @Override
      public void onStart() {
           ((MyApplication)getApplication()).setCallBack(this);
        }
      @Override
      public void onPause() {
        super.onPause();
        ((MyApplication)getApplication()).setCallBack(null);

        Log.d(TAG, "...In onPause()...");

        try     {
          btSocket.close();
        } catch (IOException e2) {
          errorExit("Fatal Error", "In onPause() and failed to close socket." + e2.getMessage() + ".");
        }
      }

      private void checkBTState() {
        // Check for Bluetooth support and then check to make sure it is turned on
        // Emulator doesn't support Bluetooth and will return null
        if(btAdapter==null) { 
          errorExit("Fatal Error", "Bluetooth not support");
        } else {
          if (btAdapter.isEnabled()) {
            Log.d(TAG, "...Bluetooth ON...");
          } else {
            //Prompt user to turn on Bluetooth
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, 1);
          }
        }
      }

      private void errorExit(String title, String message){
        Toast.makeText(getBaseContext(), title + " - " + message, Toast.LENGTH_LONG).show();
        finish();
      }

ConnectedThread.class:

       class ConnectedThread extends Thread {
            private final InputStream mmInStream;
            private final OutputStream mmOutStream;

            public ConnectedThread(BluetoothSocket socket) {
                InputStream tmpIn = null;
                OutputStream tmpOut = null;

                // Get the input and output streams, using temp objects because
                // member streams are final
                try {
                    tmpIn = socket.getInputStream();
                    tmpOut = socket.getOutputStream();
                } catch (IOException e) { }

                mmInStream = tmpIn;
                mmOutStream = tmpOut;
            }

            public void run() {
                byte[] buffer = new byte[256];  // buffer store for the stream
                int bytes; // bytes returned from read()

                // Keep listening to the InputStream until an exception occurs
                while (true) {
                    try {
                        // Read from the InputStream
                        bytes = mmInStream.read(buffer);        // Get number of bytes and message in "buffer"
                        h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget();     // Send to message queue Handler
                    } catch (IOException e) {
                        break;
                    }
                }
            }

            /* Call this from the main activity to send data to the remote device */
            public void write(String message) {
                Log.d(TAG, "...Data to send: " + message + "...");
                byte[] msgBuffer = message.getBytes();
                try {
                    mmOutStream.write(msgBuffer);
                } catch (IOException e) {
                    Log.d(TAG, "...Error data send: " + e.getMessage() + "...");     
                  }
            }
        }

    @Override
    public boolean handleMessage(Message arg0) {
        // TODO Auto-generated method stub
        return false;
    }

}

MyApplication.class:

public class MyApplication extends Application  {

    Handler.Callback realCallback = null;
    Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            if (realCallback != null) {
                realCallback.handleMessage(msg);
            }
        };
    };
    public Handler getHandler() {
        return handler;
    }
    public void setCallBack(Handler.Callback callback) {
        this.realCallback = callback;
    }
}

aa.class:

public class aa extends Service {


    private BluetoothAdapter mBluetoothAdapter;
    public static final String BT_DEVICE = "btdevice";
    public static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
    public static final int STATE_NONE = 0; // we're doing nothing
    public static final int STATE_LISTEN = 1; // now listening for incoming
                                                // connections
    public static final int STATE_CONNECTING = 2; // now initiating an outgoing
                                                    // connection
    public static final int STATE_CONNECTED = 3; // now connected to a remote
                                                    // device
    private ConnectThread mConnectThread;
    private static ConnectedThread mConnectedThread;
    // public mInHangler mHandler = new mInHangler(this);
    private static Handler mHandler = null;
    public static int mState = STATE_NONE;
    public static String deviceName;
    public Vector<Byte> packdata = new Vector<Byte>(2048);
    public static BluetoothDevice device = null;
    SharedPreferences settings;

    @Override
    public void onCreate() {
        Log.d("PrinterService", "Service started");
        super.onCreate();
    }

    @Override
    public IBinder onBind(Intent intent) {
        mHandler = ((MyApplication) getApplication()).getHandler();
        return mBinder;
    }

    public class LocalBinder extends Binder {
        aa getService() {
            return aa.this;
        }
    }



    private final IBinder mBinder = new LocalBinder();

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("PrinterService", "Onstart Command");
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        settings = getSharedPreferences(DeviceList.PREFS_NAME, 0);

        if (mBluetoothAdapter != null) {

        //    device = (Device) intent.getSerializableExtra(BT_DEVICE);
       //     deviceName = device.getDeviceName();
            String macAddress = settings.getString(
                    DeviceList.PREFS_DEVICE_ADDR, null);
            device =   mBluetoothAdapter.getRemoteDevice(macAddress);
            if (macAddress != null && macAddress.length() > 0) {
                connectToDevice(macAddress);
            } else {
                stopSelf();
                return 0;
            }
        }
        String stopservice = intent.getStringExtra("stopservice");
        if (stopservice != null && stopservice.length() > 0) {
            stop();
        }
        return START_STICKY;
    }

    private synchronized void connectToDevice(String macAddress) {
        BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress);
        if (mState == STATE_CONNECTING) {
            if (mConnectThread != null) {
                mConnectThread.cancel();
                mConnectThread = null;
            }
        }

        // Cancel any thread currently running a connection
        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }
        mConnectThread = new ConnectThread(device);
        mConnectThread.start();
        setState(STATE_CONNECTING);
    }

    private void setState(int state) {
        aa.mState = state;
        if (mHandler != null) {
      //      mHandler.obtainMessage(AbstractActivity.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
        }
    }

    public synchronized void stop() {
        setState(STATE_NONE);
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }

        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }
        if (mBluetoothAdapter != null) {
            mBluetoothAdapter.cancelDiscovery();
        }
        stopSelf();
    }

    @Override
    public boolean stopService(Intent name) {
        setState(STATE_NONE);
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }

        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }
        mBluetoothAdapter.cancelDiscovery();
        return super.stopService(name);
    }

    private void connectionFailed() {
        aa.this.stop();
      //  Message msg = mHandler.obtainMessage(Console.MESSAGE_TOAST);
        Bundle bundle = new Bundle();
        //bundle.putString(Console.TOAST, "zeft");
        //msg.setData(bundle);
        //mHandler.sendMessage(msg);
    }

    private void connectionLost() {
        aa.this.stop();
      //  Message msg = mHandler.obtainMessage(AbstractActivity.MESSAGE_TOAST);
        Bundle bundle = new Bundle();
    //    bundle.putString(AbstractActivity.TOAST, getString(R.string.error_connect_lost));
        //msg.setData(bundle);
     //   mHandler.sendMessage(msg);
    }

    private static Object obj = new Object();

    public static void write(byte[] out) {
        // Create temporary object
        ConnectedThread r;
        // Synchronize a copy of the ConnectedThread
        synchronized (obj) {
            if (mState != STATE_CONNECTED)
                return;
            r = mConnectedThread;
        }
        // Perform the write unsynchronized
        r.write(out);
    }

    private synchronized void connected(BluetoothSocket mmSocket, BluetoothDevice mmDevice) {
        // Cancel the thread that completed the connection
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }

        // Cancel any thread currently running a connection
        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }

        mConnectedThread = new ConnectedThread(mmSocket);
        mConnectedThread.start();

        // Message msg =
        // mHandler.obtainMessage(AbstractActivity.MESSAGE_DEVICE_NAME);
        // Bundle bundle = new Bundle();
        // bundle.putString(AbstractActivity.DEVICE_NAME, "p25");
        // msg.setData(bundle);
        // mHandler.sendMessage(msg);
        setState(STATE_CONNECTED);

    }

ConnectThread.class:

    private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;

        public ConnectThread(BluetoothDevice device) {
            this.mmDevice = device;
            BluetoothSocket tmp = null;
            try {
                tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(SPP_UUID));
            } catch (IOException e) {
                e.printStackTrace();
            }
            mmSocket = tmp;
        }

        @Override
        public void run() {
            setName("ConnectThread");
            mBluetoothAdapter.cancelDiscovery();
            try {
                mmSocket.connect();
            } catch (IOException e) {
                try {
                    mmSocket.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                connectionFailed();
                return;

            }
            synchronized (aa.this) {
                mConnectThread = null;
            }
            connected(mmSocket, mmDevice);
        }

        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                Log.e("PrinterService", "close() of connect socket failed", e);
            }
        }
    }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        public ConnectedThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                Log.e("Printer Service", "temp sockets not created", e);
            }
            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        @Override
        public void run() {
             byte[] buffer = new byte[256];  // buffer store for the stream
                int bytes ;
            while (true) {
                try {
                     bytes = mmInStream.read(buffer);   
                    mHandler.obtainMessage(Console.RECIEVE_MESSAGE,
                     bytes, -1, buffer).sendToTarget();
                } catch (Exception e) {
                    e.printStackTrace();
                    connectionLost();
                    aa.this.stop();
                    break;
                }

            }
        }

        private byte[] btBuff;


        public void write(byte[] buffer) {
            try {
                mmOutStream.write(buffer);

                // Share the sent message back to the UI Activity
                mHandler.obtainMessage(Console.RECIEVE_MESSAGE, buffer.length, -1, buffer).sendToTarget();
            } catch (IOException e) {
                Log.e("PrinterService", "Exception during write", e);
            }
        }

        public void cancel() {
            try {
                mmSocket.close();

            } catch (IOException e) {
                Log.e("PrinterService", "close() of connect socket failed", e);
            }
        }

    }

    public void trace(String msg) {
        Log.d("AbstractActivity", msg);
        toast(msg);
    }

    public void toast(String msg) {
        Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onDestroy() {
        stop();
        Log.d("Printer Service", "Destroyed");
        super.onDestroy();
    }

    private void sendMsg(int flag) {
        Message msg = new Message();
        msg.what = flag;
        handler.sendMessage(msg);
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {//
            if (!Thread.currentThread().isInterrupted()) {
                switch (msg.what) {
                case 3:

                    break;

                case 4:

                    break;
                case 5:
                    break;

                case -1:
                    break;
                }
            }
            super.handleMessage(msg);
        }

    };


} 

1 个答案:

答案 0 :(得分:0)

关于

  

如何从后台服务/线程传递数据并获取通知   对吗?

我相信Android AsyncTask就是为此而设计的,但您需要正确使用它,因为它经常被误解,尤其是处理应用程序的整个生命周期。

至于为什么你的代码不起作用,正如Ranjith说我们需要更多细节。

要在模拟器中运行蓝牙,请尝试使用VM和USB加密狗:

How to use android emulator for testing bluetooth application?