屏幕锁定时服务仍在运行

时间:2014-07-17 12:27:57

标签: android bluetooth screen-lock

我有一个连接屏幕,我有一个搜索按钮,点击它后发布了可发现的设备列表,我点击所需的设备进行配对和连接,建立连接,当我锁定屏幕连接丢失了,我怎样才能改进我的代码以使服务仍然有效?这就是我尝试实现它的方法,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;
    }
}

2 个答案:

答案 0 :(得分:0)

我假设在您的一个活动的生命周期方法中调用了launchActivity。

如果是这样的话 - 你基本上是在创建一个附加的背景逻辑'一个活动,即一个UI组件。 这是一个坏主意。

为什么?

因为Android在回收后台活动以及从中产生的线程时非常快,所以当资源不足时。

你应该做的是明确告知Android这个逻辑被视为背景逻辑,即 没有连接到屏幕上的活动可见性。

为此,您应该声明service

在清单中:

<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);

答案 1 :(得分:0)

这实际上是正常的。到目前为止,您离开应用程序并且android生命周期调用onDestroy()方法,所有连接都应该脱机。因此,您需要一个在后台进一步工作的流程。您可以在此处使用Android Service组件。只要您使用资源,这将有效,只要它完成Service即将关闭的过程。所以这取决于你需要什么。如果您需要在后台永久运行的后台服务,则应使用startForeground()的{​​{1}}方法。

此处有关Service的更多信息:http://developer.android.com/guide/components/services.html