1

を開始するアクティビティがありますIntentService:

intent = new Intent(MyApplication.getAppContext(), MyService.class);
intent.putExtra("EXTRA_DEVICE_ADDRESS", value);
MyApplication.getAppContext().startService(intent);

サービスは、送信した MAC アドレスで Bluetooth 接続を開始します。

device = mBluetoothAdapter.getRemoteDevice(macAddress);

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

聞きます:

while (true) {
    try {
        if (mmInStream.available() != 0) {
            bytes = mmInStream.read(buffer);    
            String readMessage = new String(buffer, 0, bytes);
            sendMessageToActivity("incoming", readMessage);
        } else {
            SystemClock.sleep(100);
        }

受信したメッセージをアクティビティに送り返します。

public void sendMessageToActivity(String type, String message) {
    intent = new Intent(BROADCAST_ACTION);
    intent.putExtra(type, message);
    sendBroadcast(intent);
}

を使用しBroadcastReceiverて、サービスからメッセージを受信します。

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        updateUI(intent);
    }
};

アクティビティから呼び出します(問題の一部):

private void writeOut(final String message) {
    msg = message;
    byte[] send = msg.getBytes();
    MyService.write(send);
}

これは、サービスの静的write()メソッドです。

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

私の問題:上記のすべては、を除いて意図したとおりに機能しMyService.write(send)ます。UI が動かなくなる。を使用しようとしましたAsyncTaskが、うまくいきませんでした。write()その静的メソッドの使用をやめて、サービスにメッセージを送信し、彼に任せる必要があると思います。アクティビティでを初期化しHandler、 を介してインテントでサービスに送信する必要があると思いますstartService()

サービスに出入りするメッセージを追跡したい。着信メッセージで正常に動作しています。アクティビティからメッセージを適切に受信して実行し、情報をアクティビティに送り返す方法を見つける必要があります。

4

1 に答える 1

3

まず、についてIntentService

すべてのリクエストは 1 つのワーカー スレッドで処理されます。必要なだけ時間がかかる場合がありますが (アプリケーションのメイン ループをブロックすることはありません)、一度に処理されるリクエストは1 つだけです。

したがって、コードを に移動することを検討してくださいService。Bluetooth 接続と についてはわかりませんが、念NetworkOnMainThreadExceptionのため: aServiceはメイン UI スレッドで実行されることに注意してください。このような例外を回避するには、サービス内に次のようなものが必要になりThreadます。AsyncTasks は理想的には短い操作 (せいぜい数秒) に使用する必要があるAsyncTaskため、使用ないでください。また、システムがサービスのライフサイクルを自動的に管理することに注意してください。

ここで問題に戻ります。(サービスからアクティビティにメッセージを送信するために) ブロードキャスト レシーバーを使用する方法は正しいですが、ResultReceiver(API 3+ で利用可能) の使用を検討してください。広いブロードキャストメッセージを送信するよりも、使用するResultReceiver方が良いと思います。を に入れることができResultReceiverますIntent

アクティビティからサービスにメッセージを送信するには、 に移動したと仮定しますService。に何でも入れて、もう一度Intent呼び出して送信できます。startService()でインテントを取得しますonStartCommand()または、この手法を使用してサービスをバインドした場合は、サービスのメソッドをアクティビティ内から直接呼び出すことができます。

SDK — フォルダー内のサービスを操作するサンプル プロジェクトがいくつかあります[Android SDK]/samples/。エミュレーターでは、API Demos という名前のアプリでこれらのプロジェクトをテストできます。

于 2013-03-13T09:33:13.333 に答える