web-dev-qa-db-ja.com

USB_DEVICE_ATTACHEDインテントが起動しない

Android.hardware.usb.action.USB_DEVICE_ATTACHED」を機能させることができた人はいますか?

わかりましたので、新しいUSBホストモード機能を使用して、USBデバイスが接続されていることを検出しようとしています。私の目的のために、デバイスが接続されたときはいつでも通知を受けたいです。私はそれが起こるのを見ることができませんでした。動作することがわかっているブロードキャストレシーバーを使用しています(ホームボタンが押されているなど、他のことを聞いている場合。何を試しても、発動する意図がないようです。..物事を簡単にするために、プロジェクトを忘れて、Google独自のサンプルコードを使用して、少なくともそれが機能するかどうかを確認することにしました。ミサイルランチャーが1つもありませんが、少なくともUSB_Device_Attachedを取得できると考えました他のデバイスで機能するようにコードを調整しました。最初にデバイスフィルターのxmlを調整してみました。デバイス(キーボード)を追加しました。

<usb-device vendor-id="1050" product-id="0010" />

Lsusbコマンドからベンダーと製品を入手しました。デバイスが接続されると、logcatはデバイスが見つかったことを示します

D/EventHub(  144): No input device configuration file found for device 'Yubico Yubico Yubikey II'.
I/EventHub(  144): New device: id=43, fd=219, path='/dev/input/event8', name='Yubico Yubico Yubikey II', classes=0x80000003, configuration='', keyLayout='/system/usr/keylayout/Generic.kl', keyCharacterMap='/system/usr/keychars/Generic.kcm', builtinKeyboard=false
I/InputReader(  144): Device added: id=43, name='Yubico Yubico Yubikey II', sources=0x00000101
I/ActivityManager(  144): Config changed: { scale=1.0 imsi=0/0 loc=en_US touch=3 keys=2/1/1 nav=1/2 orien=L layout=0x10000014 uiMode=0x11 seq=47}
D/MissileLauncherActivity(16191): intent: Android.intent.action.MAIN
I/EventHub(  144): Removed device: path=/dev/input/event8 name=Yubico Yubico Yubikey II id=43 fd=219 classes=0x80000003
I/InputReader(  144): Device removed: id=43, name='Yubico Yubico Yubikey II', sources=0x00000101
I/ActivityManager(  144): Config changed: { scale=1.0 imsi=0/0 loc=en_US touch=3 keys=1/1/2 nav=1/2 orien=L layout=0x10000014 uiMode=0x11 seq=48}
D/dalvikvm(  144): GC_EXPLICIT freed 78K, 26% free 14717K/19719K, paused 3ms+3ms
D/MissileLauncherActivity(16191): intent: Android.intent.action.MAIN

Xoomはキーボードを検出し、デバイスから使用できます(ブラウザーで文字を入力するために使用できます)。そして、インテントの種類の発火(しかし、それはAndroid.intent.action.MAINを発火するだけです)私はDEVICE_ATTACHEDインテントを取得しません。ログエントリはサンプルコードから取得されます。

Log.d(TAG, "intent: " + intent.getAction().toString());

レジューム機能で。 USBへの参照をさらに掘り下げて削除した後、キーボードを取り付けたり取り外したりすると、作成したすべてのアプリがレジュームを呼び出すことがわかりました(そのため、インテント:Android.intent.action.MAINログエントリ)。現在私が理解できる唯一のことは、それがAndroidソースのバグであることです。ところで、OS 3.1でwifi xoomを使用しています。

26
D-T

私も同じ問題を抱えていました。最後に、デバイスフィルターのxmlに次の行を追加する必要があることがわかりました。

<usb-device vendor-id-"xxxxx" product-id="yyyyy">

xxxxxとyyyyyは10進数でなければなりません。 16進コードではありません。その後、すべてが宣伝どおりに機能します。遅いのはわかっていますが、お役に立てば幸いです。

21
Srikanth K.

だから私は自分の問題の解決策を見つけ、それが他の誰かを助けることができることを願って多くのことを学びました。

したがって、最初にHIDデバイスは意図を開始しません。また、mUsbManager.getDeviceList()リストにも表示されません。しかし、他のことは行います。 USBメモリスティックを試してみましたが、デバイスがデバイスリストに表示されていることがわかります。また、返されたデバイスにクラス、サブクラス、またはプロトコルがないこともわかりました。デバッグの結果、親インターフェースには適切なクラス/サブクラス/プロトコルが含まれていることがわかりました。また、デバイスフィルターが必要な場合。私は目的のために働くためにclass=0008 (USB STORAGE)になりました。他のクラスも同様に機能すると思います。

では、意図を理解することにしましょう。インテントをランチャーアクティビティにアタッチする必要があることがわかりました。それをサービスまたは受信機に接続しようとする私の試みは、実を結びません。デバイス(USBメモリスティック)を接続すると通知ポップアップが表示され、アプリをそのデバイスのデフォルトとして設定するように求められます。完璧になりました。デバイスを接続するたびにアプリが実行されます。一意のデバイスごとにプロンプ​​トが表示されることに注意してください。しかし、一度だけ。デフォルトのプログラムと同じように登録されているようです。

まあ、それは私が見つけたものの要約についてだと思います。キーボード/マウスが接続されたときに通知を受け取ることができません。ああ、もう1つ。 tiamatカーネルには何の問題もありません。今すぐ実行して問題はありません。

13
D-T

最近、同様の問題の解決策を見つけました。

誰かがすでに述べたように、_HID devices_はインテントを開始しないでください。これはあなたの問題だと思います。

ただし、関連する問題として、USBデバイスが接続されているときにプログラムが実行されるように設定されている場合、アプリケーションが実行されていても、_USB_DEVICE_ATTACHED_アクションをキャプチャできません。代わりに、システムはそのインテントを確認し、「ああ、つまり、このアプリケーションが実行したい(マニフェストで宣言されているとおりに)ことを意味し、_USB_DEVICE_ATTACHED_アクションではなくAndroid.intent.action.MAINアクションを送信します。そして、それはonResume()を呼び出します。アプリが実行されている場合でも、私が知る限り、USBデバイスのときにアプリが実行されることをマニフェストが宣言している場合、_USB_DEVICE_ATTACHED_インテントをキャプチャできませんUSBが接続されているかどうかを確認するには、onResume()にコードを挿入する必要があります。プログラムが実行されている場合でも、USBデバイスが接続されると、onResumeが再度呼び出されます。

私のソリューションの詳細をここに示します: Android 3.1 USB-Host-BroadcastReceiverがUSB_DEVICE_ATTACHEDを受信しません

7

別の回避策は使用することです

new FileObserver("/dev/input") {
  @Override public void onEvent(int event, String path) {
     //gets called on input device insert / remove
  }
};

一部のUSBデバイス(キーボード、マウス)で動作します

2
Thomas Rynne

私も同じ問題を抱えていました。私の最終的な解決策は、昔ながらのポーリング手法を使用することでした。これは問題を私の満足に解決するかなり最小限のクラスです。

package com.YourCompancy.YourProduct;

import Android.app.*;
import Android.content.*;

import Android.hardware.usb.*;
import Java.util.*;
import Android.util.*;
import Android.os.*;

public class UsbDeviceWatcher extends BroadcastReceiver
{   
    public void onReceive(Context context, Intent intent)
    {
        if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED))
        {
            UsbDevice d = (UsbDevice)
                intent.getExtras().get(UsbManager.EXTRA_DEVICE);

            DeviceConnect(d, false);
        }
    }

    public void DeviceConnect(UsbDevice device, boolean Attached)
    {
            if (Attached)
            {
                            // Some suggestions ...
                            //    play sound effect
                            //    notify consumer software
                            //    determine if interested in device
                            //    etc
                            Log.i("usb", "device attached");

            } else
            {
                Log.i("usb", "device detached");
            }

    }

    public UsbManager manager;
    public Handler handler;

    public UsbDeviceWatcher(Context context, Handler handle)
    {

        this.handler = handle;

        manager = (UsbManager) 
            context.getSystemService(Context.USB_SERVICE);

        IntentFilter dev = new IntentFilter();

        dev.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);

        context.registerReceiver(this, dev);    

        final UsbDeviceWatcher _this = this;

        Thread thread = new Thread(new Runnable()
        {
            public void run()
            {
                LinkedList<UsbDevice> seen = new LinkedList<UsbDevice>();
                LinkedList<UsbDevice> attached = new LinkedList<UsbDevice>();

                            //there is a need for multithread support here
                                //   so the thread can watch for an exit condition
                while (true)
                {

                    HashMap<String, UsbDevice>
                        D = manager.getDeviceList();

                    for (UsbDevice d : D.values())
                    {
                        if (!seen.contains(d))
                        {
                            if (!attached.contains(d))
                            {
                                final UsbDevice dev = d;

                                handler.post(new Runnable(){
                                    public void run()
                                    {
                                        DeviceConnect(dev, true);
                                    }
                                });
                            }

                            seen.add(d);
                        }
                    }

                    for (UsbDevice d : seen)
                    {
                        if (!D.values().contains(d)) seen.remove(d);
                    }

                    try
                    {
                        Thread.sleep(500);  
                    } catch (InterruptedException exception)
                    {
                        return; 
                    }
                }

            }
        });

        thread.start();
    }
}
2
RofaMagius

デバイスの列挙

アプリケーションの実行中に現在接続されているすべてのUSBデバイスの検査に関心がある場合は、バス上のデバイスを列挙できます。接続されているすべてのUSBデバイスのハッシュマップを取得するには、getDeviceList()メソッドを使用します。マップからデバイスを取得する場合、ハッシュマップはUSBデバイスの名前でキー付けされます。

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();

必要に応じて、ハッシュマップからイテレータを取得して、各デバイスを1つずつ処理することもできます。

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while(deviceIterator.hasNext()){
    UsbDevice device = deviceIterator.next()
    //your code
}
2
D-T

より多くの作業、より多くの失敗、しかしいくらかの進歩。

私はSDKドキュメントからもっと知りました。インテントを使用するには、デバイスフィルターが必要なようです。そこで、ベンダー/製品IDの代わりにクラスフィルターを使用することにしました。私はそれがより一般的であり、うまくいけば隠しデバイスをキャッチするだろうと考えています。私はクラスIDとして03hを使用し、さまざまな形式を試し、サブクラスを試しました。デバイスの検出、クラス、サブクラス、およびプロトコルにlsusbを使用しました。これらはまったく役に立たなかったようです。そのため、私はsdkのドキュメントをさらに詳しく調べ、すべてのデバイスを列挙して、OSがクラス/サブクラス/プロトコルの整数をどのように見ているかを確認することにしました。コードをコピーしてクリックリスナーに貼り付け、log.vステートメントを追加しました。 logcatには何も表示されません。

これは、usシステムがデバイスを認識していないようです(デバイスが実際に機能している場合でも)。これは、USBデバイスに接続された意図が発火していないことを示しています。今、私は自分のxoom(tiamat)でカスタムカーネルを使用していると言わなければなりません。しばらく前に問題があるのではないかと思ったので、3.1に戻しました。そして今も進歩しています。これは、列挙を試す前の少し前のことなので、今度は、カーネルが問題ではないと確信するまで、再びアラビアンに戻し、在庫を使用し続けます。詳細がわかり次第チェックインします。成功または失敗。もちろん、他の誰かが私よりもこれを理解している場合は、チャイムを送ってください。最後に、ドキュメントでこれを確認したときのotg Hostモード全体が非常に心配です。coeは、列挙。おそらくコピーライターのミスだけですが、このすべての失敗に照らしてまだ心配しています。

1
D-T

私はアプリを_launchMode="singleTop"_に設定しており、そのモードではgetIntent().getAction()は常にアプリを最初に起動したアクションと常に同じように見えます。

したがって、アプリを手動で起動してthenデバイスを接続すると(そのアプリから切り替えた後でも)、_Android.intent.action.MAIN_が返されます。

アプリを終了してからデバイスを接続すると、切り替えてアプリに戻ったり、デバイスを回転させたりした場合でも、常に_Android.hardware.usb.action.USB_DEVICE_ATTACHED_を取得できます。

記載されていないようですが、USBデバイスのプラグを抜くと、奇妙にインテントを受け取ります。ただし、デバイスが取り外されたときは、_USB_DEVICE_ATTACHED_が返されます。

singleTopがなければ、期待どおりに動作しますが、アプリが既に開いていてデバイスを接続すると、別の愚かな余分なアクティビティが発生します。

繰り返しになりますが、AndroidのAPIはバグが多く、複雑すぎて使いづらいです。

1
Timmmm

これは、USB/Media Connectを検出するために行ったものです。

マニフェストファイル

    <receiver
            Android:name=".UsbReceiver"
            Android:enabled="true" >
        <intent-filter>
            <action Android:name="Android.intent.action.MEDIA_MOUNTED"/>
            <action Android:name="Android.intent.action.MEDIA_UNMOUNTED"/>
            <data Android:scheme="file"/>
        </intent-filter>
    </receiver>

アクティビティでもレシーバーでも何もしませんでした。

この行が何かをしているように見えます。

<data Android:scheme="file"/>
1
Prakash

私のテストから、Androidcanは、HIDデバイスが接続されたときにインテントを起動します。(MisileLauncherサンプルアプリケーションは、詳細については、サンプルのソースコードを参照してください。)

ミサイルランチャー(Dream Cheeky USB Missle Launcher)HIDデバイスのサブクラスとプロトコルは0x00に設定されています。詳細については、次を参照してください: http://www.mattcutts.com/blog/playing-with-a-usb-missile-launcher/

注意点は、Androidは特にマウスとキーボードデバイスのインテントをスローしない(おそらくそれ以上)ですが、InterfaceClass = 0x03、InterfaceSubClass = 0x00、InterfaceProtocol = 0x00のHIDデバイスを検出できます。 。私のアプリケーションでは、HIDデバイスは組み込みコントローラーなので、サブクラスとプロトコルの設定は問題になりません。

0
Ryan R

USBキーボードを接続[〜#〜]ウォント[〜#〜]USB_DEVICE_ATTACHED

代わりに、システムが起動しますIntent.ACTION_CONFIGURATION_CHANGED。ただし、構成が変更されたため、システムはアクティビティを再起動します。アクティビティを再起動しても、アクションをキャッチできません。この場合、Android:configChanges = "keyboard | keyboardHidden"をAndroid Manifestに追加して、外部キーボードが接続されると、アクティビティは再開されません。

0
hctang