5

ここのリンクで指定されている USB 接続の作成に取り組んでおり、正常に実装されています。その動作は正常に受け入れられ、頻繁に切断されます。このリンクとこのリンクから、Android OS に USB 接続イベントのブロードキャスト イベントがないというバグがあることを知りました。あまり重要ではない USB 切断イベントを取得するためのレシーバーを実装しました。また、このリンクを参照して、USB との安定した接続を作成します。つまり、USB 接続後に損失なくデータ通信を開始します。アプリケーションに単一のアクティビティまたは単一の画面がある場合、この全体が正常に機能しています。

複数の画面の場合、この接続に問題があります。つまり、接続が安定しておらず、いつでも任意のアクティビティで USB 経由でデータを受信できるアプリケーションに複数の画面があります。だから私は可能であればいくつかのコードで答えを求めている2つの質問があります

  1. AndroidでシリアルUSB経由で接続されたデバイスと複数の画面で安定した接続を確立するにはどうすればよいですか
  2. 複数画面のアプリケーションで頻繁に切断される問題を解決する方法

どんな助けでも素晴らしいでしょう

編集:

USBとの通信を担当し、データを継続的に受信するためのスレッドを開始するサービスを追加しています

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;

import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.hardware.usb.UsbManager;
import android.os.IBinder;
import arya.omnitalk.com.usb.R;
import arya.omnitalk.com.usb.constants.FileReadingWritingConstants;
import arya.omnitalk.com.usb.constants.GeneralConstant;
import arya.omnitalk.com.usb.constants.UsbDataWriterConstants;

import com.hoho.android.usbserial.driver.UsbSerialProber;

public class UsbCommunicationService extends Service{

    public static ArrayList<String> _dataArray = new ArrayList<String>();
    private Thread mCommunicationThread = null;

    private class ReadThread implements Runnable {
        @Override
        public void run() {

            while (mCommunicationThread!= null && !mCommunicationThread.isInterrupted()) {

                // Here I write code to parse data received via USB

                 }          
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();

        UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); // Creating object of usb manager
        UsbDataWriterConstants.driver = UsbSerialProber.acquire(manager); // Acquiring usb channel

        if (UsbDataWriterConstants.driver != null) {
            try {
                UsbDataWriterConstants.driver.open();
            } catch (IOException e1) {
                e1.printStackTrace();
            }

            try {
                ReadThread mReadThread = new ReadThread();
                mCommunicationThread = new Thread(mReadThread);
                mCommunicationThread.start();
            } catch (SecurityException e) {
                DisplayError(R.string.error_security);
                DisplayError(R.string.error_security);
            }
        }

    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);

    }

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

    @Override
    public void onDestroy() {
        if (mCommunicationThread != null)
            mCommunicationThread.interrupt();
        super.onDestroy();
    }


}
4

2 に答える 2

0

あなたのサービスはバインドされたサービスにすぎないため、切断されている可能性があります。最初のアクティビティが開始され、サービスにバインドされてからサービスが開始されます。別のアクティビティに切り替えると、最初のアクティビティが停止するため、バインドが解除されます。この時点で、サービスはバインドされていないため、強制終了されます。バインドされたサービスについては、http: //developer.android.com/guide/components/bound-services.htmlで説明しています。

おそらく必要なのは、USB が接続されている限りサービスを実行し続けることです。それを実現するには、ここで説明されているように、開始された「永続的な」サービスが必要です。 http://developer.android.com/guide/components/services.html 受け取ったアクティビティの onCreate でサービスを開始できます。以下を使用した CONNECTED イベント:

public class HomeActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        // ...
        Intent intent = new Intent(this, UsbCommunicationService.class);
        startService(intent);
        // ...
    }
}

UsbCommunicationService は、このメソッドを介して開始されます (onStart() は非推奨です)。

public class UsbCommunicationService extends Service {
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        // TODO : connect to USB...

        // We want this service to continue running until it is explicitly
        // stopped, so return sticky.       
        return START_STICKY;
    }
}

次に、すべてのアクティビティは、生き残るこのサービスに「バインド」、「バインド解除」、および「再バインド」できます。以下を使用して、DISCONNECT イベントで停止することを忘れないでください。

stopSelf(); // Will actually stop AFTER all clients unbind... 
于 2013-04-08T23:51:30.780 に答える
0

これは、USB アクセサリに登録されているアクティビティのコードです。

    public class UsbAccessoryAttachedWorkaroundActivity extends Activity {

    /**
     * Used only to catch the USB_ACCESSORY_ATTACHED event, has it is not broadcasted to 
     * anything else than the activity with the right accessory_filter (no Service, nor Receiver...)
     * DETACHED event is broadcasted as other events. 
     */

     @Override
     public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             Intent intent = new Intent(this, UsbService.class);
             startService(intent);
             finish(); // <- die ASAP, without displaying anything.
     }
    }

このようにして、アクティビティがまだ生きていないため、すべての CONNECT イベントを取得します => アクセサリが検出されるたびに Android を再起動します... My Service は、誰もバインドされていない場合にのみ HomeActivity を開始します。誰かがバインドされている場合は、UI が既に存在していることを意味するため、USB 接続が回復したことをリスナーに通知するだけです...

于 2013-04-09T09:22:45.010 に答える