2

我有一个连接屏幕,其中有一个搜索按钮,单击它后会发布可发现设备的列表,我单击所需的设备进行配对和连接,建立连接,当我锁定屏幕时,连接是迷路了,如何改进我的代码以使服务仍然有效?这就是我尝试实现它的方式,onCreate()、onStart() 和 onResume() 也在 launchApplication() 内部实现。

 public static void launchActivity(Context context, String deviceAddress){
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    mCurrentDeviceAddress = deviceAddress; //getIntent().getExtras().getString(ConnectionScreen.PREFS_DEVICE_ADDR);
    mChatService = new BluetoothMeterService(context, mHandler);
    connectDevice();
    if (mChatService != null) {
        if (mChatService.getState() == BluetoothMeterService.STATE_NONE) {
            mChatService.start();
        }
    }

}


// Automatically try to connec with the known mac address;
private static class ConnectThread extends Thread {

    private final BluetoothDevice device;

    public ConnectThread(BluetoothDevice d) {
        this.device = d;
    }

    public void run() {

        while (mConnectThread == Thread.currentThread()) {
            if (mChatService.getState() == BluetoothMeterService.STATE_CONNECTED) {
                Log.e(TAG, "STATE_CONNECTED");
                break;
            } else if (mChatService.getState() == BluetoothMeterService.STATE_CONNECTING) {
                try {
                    //Thread.sleep(2000);
                    Log.e(TAG, "STATE_CONNECTING");
                    mChatService.connect(device);
                } catch (Exception e) {
                    // Log.e(TAG, e.getMessage());
                }
            } else
                try {

                    Log.e(TAG, "STATE_DISCONECTED");
                    mChatService.start();
                    Thread.sleep(3000);
                } catch (Exception e) {
                    // Log.e(TAG, e.getMessage());
                    Thread.currentThread().interrupt();
                }
        }
    }
}


// create the bluetooth device object, and try to connect with it
// consistantly and automatically.
private static void connectDevice() {
    if (mCurrentDeviceAddress == null) {
        Toast.makeText(context, "Bluetooth MAC address is not assigned.",
                Toast.LENGTH_SHORT).show();
        //context.finish();
        return;
    }
    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mCurrentDeviceAddress);
    // showDialog(Dialog_Connect);
    mConnectThread = new ConnectThread(device);
    mConnectThread.start();
}




// The Handler that gets information back from the BluetoothMeterService
private static final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        Log.e(TAG, msg.toString());
        switch (msg.what) {
            case MESSAGE_STATE_CHANGE:
                switch (msg.arg1) {
                    case BluetoothMeterService.STATE_CONNECTED:
                        Log.e(TAG, "handler - STATE_CONNECTED");
                        for(CustomizedBluetoothDevice device : mDeviceList){
                            if(device.getAddress() == mCurrentDeviceAddress){
                                device.setStatus(BluetoothMeterService.STATE_CONNECTED);
                            }
                        }
                        updateUI(/*mDeviceList*/);
                        // mTextViewTitle.setText("Device: " + mConnectedDeviceName);
                        // mTextViewStatus.setText(R.string.title_connected_to);
                        break;
                    case BluetoothMeterService.STATE_CONNECTING:
                        Log.e(TAG, "handler - STATE_CONNECTING");
                        for(CustomizedBluetoothDevice device : mDeviceList){
                            if(device.getAddress() == mCurrentDeviceAddress){
                                device.setStatus(BluetoothMeterService.STATE_CONNECTING);
                            }
                        }
                        updateUI(/*mDeviceList*/);
                        // mTextViewStatus.setText(R.string.title_connecting);
                        break;
                    case BluetoothMeterService.STATE_NONE:
                        Log.e(TAG, "handler - STATE_NONE");
                        for(CustomizedBluetoothDevice device : mDeviceList){
                            if(device.getAddress() == mCurrentDeviceAddress){
                                device.setStatus(BluetoothMeterService.STATE_NONE);
                            }
                        }
                        updateUI(/*mDeviceList*/);
                        // mTextViewStatus.setText(R.string.title_not_connected);
                        break;
                    case BluetoothMeterService.STATE_DISCONNECTING:
                        Log.e(TAG, "handler - STATE_DISCONNECTING");
                        for(CustomizedBluetoothDevice device : mDeviceList){
                            if(device.getAddress() == mCurrentDeviceAddress){
                                device.setStatus(BluetoothMeterService.STATE_DISCONNECTING);
                            }
                        }
                        updateUI(/*mDeviceList*/);
                        break;
                }
                break;
            case MESSAGE_WRITE:
                break;
            case MESSAGE_READ:
                byte[] readBuf = (byte[]) msg.obj;
                // construct a string from the valid bytes in the buffer
                String readMessage = new String(readBuf, 0, msg.arg1);
                Log.e(TAG, "handler - MESSAGE_READ " + readMessage);
                // bufferMessege += readMessage;
               /* if (mMessage != null) {
                    mMessage.add(new CustomizedMessage(readMessage, true));
                    updateUI();
                }*/
                // bufferMessege = "";
                break;
            case MESSAGE_DEVICE_NAME:
                Log.e(TAG, "handler - MESSAGE_READ " + MESSAGE_DEVICE_NAME);
                // save the connected device's name
                mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
                break;
            case MESSAGE_TOAST:
                Log.e(TAG, "handler - MESSAGE_READ " + MESSAGE_TOAST);

                break;
        }
    }
};

public void stopActivity(){
    if (mChatService != null)
    {
        mChatService.stop();
        mChatService = null;
    }
}
4

2 回答 2

0

我假设 launchActivity 是从您的活动的生命周期方法之一中调用的。

如果是这样 - 您基本上是在创建一个“附加”到活动的后台逻辑,即 UI 组件。这是一个坏主意。

为什么?

因为当资源不足时, Android 在回收后台活动以及从它们产生的线程方面相当快。

您应该做的是明确通知 Android 该逻辑将被视为后台逻辑,即不连接到屏幕开启的活动可见性。

为此,您应该声明一个服务

在清单中:

<service
  android:name="MyConnectionService"
  android:icon="@drawable/icon"
  android:label="@string/service_name"  >
</service> 

在代码中:

public class MyConnectionService extends Service {

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
       // <------------ place connection logic here
  }

  @Override
  public IBinder onBind(Intent intent) {
       return null;
  }
} 

如果您希望您的逻辑在 UI 线程之外执行(我相信您会这样做),请使用IntentService

public class MyConnectionService extends IntentService {

  @Override
  protected void onHandleIntent(Intent intent) {
       // <--------- run connection logic on a dedicated thread here
  }
}

最后,如果您希望您的服务无论如何都保持在空中(并且大多数应用程序不需要这种行为),请将您的服务声明为前台服务:

Notification notification = new Notification(R.drawable.icon, getText(R.string.msg_text),
        System.currentTimeMillis());
Intent notificationIntent = new Intent(this, MyConnectionService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
        getText(R.string.notification_message), pendingIntent);
startForeground(SERVICE_NOTIFICATION_ID, notification);
于 2014-07-17T12:47:43.547 回答
0

这其实很正常。只要您离开应用程序并且 android 生命周期调用该onDestroy()方法,所有连接都应该离线。因此,您需要一个在后台进一步处理的进程。在这里您可以使用 AndroidService组件。只要您使用资源,这将起作用,一旦完成该过程Service就会关闭。所以这取决于你需要什么。如果你需要一个永远在后台工作的后台服务,你应该startForeground()使用Service.

Service关于这里的更多信息:http: //developer.android.com/guide/components/services.html

于 2014-07-17T12:54:20.330 回答