web-dev-qa-db-fra.com

Comment déplacer l'activité Bluetooth dans un service

L'application offre aux utilisateurs 2 options de connexion, USB et Bluetooth. L'USB fonctionne bien. J'ai obtenu des exemples de codes pour la connexion Bluetooth, mais ils sont conçus pour fonctionner comme une activité. J'ai essayé de le faire dans un service mais j'ai échoué.

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
startService(new Intent(this, MyService.class));

<service Android:enabled="true" Android:name=".MyService" />
enter code here

J'ai besoin d'établir une communication Bluetooth avec un appareil déjà couplé et son adresse MAC connue. Je peux donc ignorer les phases de découverte et d'appariement. Le périphérique que j'essaie de connecter est toujours détectable et en attente de connexion. Existe-t-il un moyen de le faire à partir d'une classe de service et de maintenir cette connexion via d'autres activités?

J'utilise BluetoothChatService et DeviceListActivity

22
wervdon

J'ai écrit un service Bluetooth qui s'exécute en arrière-plan et peut communiquer avec n'importe quelle activité de l'application à l'aide de Messenger http://developer.Android.com/guide/components/bound-services.html .

public class PrinterService 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 Device device = null;

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

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

public class LocalBinder extends Binder {
    PrinterService getService() {
        return PrinterService.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();
    if (mBluetoothAdapter != null) {
        device = (Device) intent.getSerializableExtra(BT_DEVICE);
        deviceName = device.getDeviceName();
        String macAddress = device.getMacAddress();
        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) {
    PrinterService.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() {
    PrinterService.this.stop();
    Message msg = mHandler.obtainMessage(AbstractActivity.MESSAGE_TOAST);
    Bundle bundle = new Bundle();
    bundle.putString(AbstractActivity.TOAST, getString(R.string.error_connect_failed));
    msg.setData(bundle);
    mHandler.sendMessage(msg);
}

private void connectionLost() {
    PrinterService.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);

}

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 (PrinterService.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() {
        while (true) {
            try {
                if (!encodeData(mmInStream)) {
                    mState = STATE_NONE;
                    connectionLost();
                    break;
                } else {
                }
                // mHandler.obtainMessage(AbstractActivity.MESSAGE_READ,
                // bytes, -1, buffer).sendToTarget();
            } catch (Exception e) {
                e.printStackTrace();
                connectionLost();
                PrinterService.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(AbstractActivity.MESSAGE_WRITE, 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);
    }

};
}

[~ # ~] mise à jour [~ # ~]

vous devez utiliser Handler dans votre classe MyApplication

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;
}
33
Kapil Vats