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 は、アクティビティのライフサイクル メソッドの 1 つから呼び出されると想定しています。

もしそうなら、あなたは基本的にアクティビティ、つまり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 に答える