USB aksesuarına genel bakış

USB aksesuar modu, kullanıcıların bağlanmasına olanak tanır Android destekli cihazlar için özel olarak tasarlanmış USB ana makine donanımı. Aksesuarlar uyumlu olmalıdır Android Aksesuar Geliştirme Kiti dokümanlarında belirtilen Android aksesuar protokolüne uygulayın. Bu yöntem, USB ana makinesi gibi çalışamayan Android destekli cihazların USB ile etkileşimde bulunmasına olanak tanır donanım. Android destekli bir cihaz USB aksesuarı modundayken takılı Android USB aksesuarı ana makine olarak çalışır, USB veri yoluna güç sağlar ve bağlı cihazları numaralandırır. Android 3.1 (API düzeyi 12) USB aksesuar modunu destekler ve özellik, Daha geniş bir cihaz yelpazesi için destek sunan Android 2.3.4 (API düzeyi 10).

Doğru USB aksesuar API'lerini seçin

USB aksesuar API'leri Android 3.1'de platforma eklenmiş olsa da aynı zamanda , Android 2.3.4'te Google API'leri eklenti kitaplığıyla kullanılabilir. Bu API'ler harici bir kitaplık kullanılarak geri bağlandığında, USB bağlantısını desteklemek için içe aktarabileceğiniz aksesuar modundan çıkarılabilir. Desteklemek istediğiniz Android destekli cihazlara bağlı olarak birini diğerine tercih etmelisiniz:

  • com.android.future.usb: Android 2.3.4'te USB aksesuar modunu desteklemek için Google API'ları eklentisi kitaplığı, geri bağlantılı USB aksesuar API'lerini içerir ve bu API'ler tıklayın. Android 3.1, bu ad alanındaki sınıfların içe aktarılmasını ve çağrılmasını da destekler. ve eklenti kitaplığıyla yazılmış uygulamaları desteklemelidir. Bu eklenti kitaplığı ince bir sarmalayıcıdır ve USB ana makine modunu desteklemiyor.android.hardware.usb Eğer USB aksesuar modunu destekleyen en geniş cihaz yelpazesini desteklemek istiyorsanız kitaplığını açıp bu paketi içe aktaracaksınız. Bazı Android 2.3.4 cihazların USB aksesuarı özelliğini desteklemek için gereklidir. Her cihaz üreticisi kendi kararını verir Bu özelliği destekleyip desteklemediğinizi, bu nedenle manifest dosyanızda belirtmeniz gerekir. dosyası olarak kaydedebilirsiniz.
  • android.hardware.usb: Bu ad alanı, USB'yi destekleyen sınıfları içerir. aksesuar modunu kullanabilirsiniz. Bu paket, çerçeve API'lerinin bir parçası olarak dahildir. Android 3.1, eklenti kitaplığının kullanılmadığı USB aksesuar modunu destekler. Bu paketi kullan Yalnızca USB için donanım destekli Android 3.1 veya daha yeni sürüm cihazlarla ilgileniyorsanız aksesuar modunda kullanabilirsiniz.

Google API'leri eklenti kitaplığını yükleme

Google API'leri Android API 10'u yükleyerek eklentiyi yükleyebilirsiniz. paketinden yararlanın. Bkz. Google API'lerini yükleme eklentisine bakın.

API'ye genel bakış

Eklenti kitaplığı çerçeve API'leri için bir sarmalayıcı olduğundan USB aksesuarı özellikleri de buna benzer. Eklenti kitaplığını kullanıyor olsanız bile android.hardware.usb için referans belgeleri kullanabilirsiniz.

Not: Ancak, küçük bir kullanım vardır eklenti kitaplığı ile çerçeve API'leri arasındaki farkı belirler.

Aşağıdaki tabloda, USB aksesuarı API'lerini destekleyen sınıflar açıklanmaktadır:

Sınıf Açıklama
UsbManager Bağlı USB aksesuarlarını numaralandırmanıza ve bunlarla iletişim kurmanıza olanak tanır.
UsbAccessory Bir USB aksesuarını temsil eder ve aksesuarın tanımlamasına ilişkin yöntemler içerir ekleyebilirsiniz.

Eklenti kitaplığı ve platform API'leri arasındaki kullanım farklılıkları

Google API'leri eklenti kitaplığı ile platformun kullanımı arasında iki kullanım farkı vardır API'ler.

Eklenti kitaplığını kullanıyorsanız UsbManager nesnesini aşağıdaki şekilde edinmeniz gerekir:

Kotlin

val manager = UsbManager.getInstance(this)

Java

UsbManager manager = UsbManager.getInstance(this);

Eklenti kitaplığını kullanmıyorsanız UsbManager nesnesini aşağıdaki şekilde edinmeniz gerekir:

Kotlin

val manager = getSystemService(Context.USB_SERVICE) as UsbManager

Java

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

Intent filtresi olan bağlı bir aksesuar için filtre uyguladığınızda UsbAccessory nesnesi, bir uygulamadır. Eklenti kitaplığını kullanıyorsanız UsbAccessory nesnesini aşağıdaki şekilde edinmeniz gerekir:

Kotlin

val accessory = UsbManager.getAccessory(intent)

Java

UsbAccessory accessory = UsbManager.getAccessory(intent);

Eklenti kitaplığını kullanmıyorsanız UsbAccessory nesnesini aşağıdaki şekilde edinmeniz gerekir:

Kotlin

val accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY) as UsbAccessory

Java

UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);

Android manifesti şartları

Aşağıdaki listede, Google Haritalar'dan ayrılmadan önce uygulamanızın manifest dosyasına eklemeniz gereken bilgileri bulabilirsiniz yardımcı oluyor. Manifest ve kaynak dosyası örnekler, bu öğelerin nasıl tanımlanacağını gösterir:

  • Android destekli tüm cihazların USB aksesuar API'lerini desteklediği garanti edilmediğinden, uygulamanızın<uses-feature> android.hardware.usb.accessory özelliği.
  • eklenti kitaplığı oluşturabilirsiniz. belirten <uses-library> öğesini ekleyin Kitaplık için com.android.future.usb.accessory.
  • Eklenti kitaplığını kullanıyorsanız uygulamanın minimum SDK sürümünü API Düzeyi 10 olarak ayarlayın android.hardware.usb paketini kullanıyorsanız bu değer 12'dir.
  • Uygulamanıza bir USB aksesuarının takılmasıyla ilgili bildirim almak istiyorsanız bir Şu için <intent-filter> ve <meta-data> öğe çifti: Ana etkinliğinizde android.hardware.usb.action.USB_ACCESSORY_ATTACHED intent. <meta-data> öğesi, şu özelliklere sahip harici bir XML kaynak dosyasına işaret ediyor: algılamak istediğiniz aksesuarla ilgili tanımlayıcı bilgileri bildirir.

    XML kaynak dosyasında, <usb-accessory> aksesuarları seçin. Her <usb-accessory> şuna sahip olabilir: şu özellikleri kullanın:

    • manufacturer
    • model
    • version

    version için filtreleme önerilmez. Bir aksesuar veya cihaz her zaman bir sürüm dizesi belirtmeyebilir (kasıtlı veya bilinçli olarak). Uygulamanız filtrelenecek bir sürüm özelliği ve aksesuar veya cihaz bildirdiğinde bir sürüm dizesi belirtmez, bu durum bir NullPointerException Android'in önceki sürümleri. Bu sorun Android 12'de düzeltilmiştir.

    Kaynak dosyayı res/xml/ dizinine kaydedin. Kaynak dosya adı (.xml uzantısı olmayan) şu adreste belirttiğinizle aynı olmalıdır: <meta-data> öğesi. XML kaynak dosyasının biçimi şurada da gösterilir: aşağıdaki örneğe bakın.

Manifest ve kaynak dosyası örnekleri

Aşağıdaki örnekte örnek bir manifest ve karşılık gelen kaynak dosyası gösterilmektedir:

<manifest ...>
    <uses-feature android:name="android.hardware.usb.accessory" />
    
    <uses-sdk android:minSdkVersion="<version>" />
    ...
    <application>
      <uses-library android:name="com.android.future.usb.accessory" />
        <activity ...>
            ...
            <intent-filter>
                <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
            </intent-filter>

            <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
                android:resource="@xml/accessory_filter" />
        </activity>
    </application>
</manifest>

Bu durumda, aşağıdaki kaynak dosya res/xml/accessory_filter.xml ve ilgili model, üretici ve sürüm filtrelenmelidir. Aksesuar, şunları gönderir: özellikleri:

<?xml version="1.0" encoding="utf-8"?>

<resources>
    <usb-accessory model="DemoKit" manufacturer="Google" version="1.0"/>
</resources>

Aksesuarlarla çalışma

Kullanıcılar USB aksesuarları Android destekli bir cihaza bağladığında Android sistemi şunları yapabilir: uygulamanızın bağlı aksesuarla ilgilenip ilgilenmediğini belirler. Öyleyse, iletişim kurmamaya dikkat edin. Bunun için uygulamanız:

  1. Aksesuarlar için filtre uygulayan amaç filtresi kullanarak bağlı aksesuarları keşfedin ekli etkinlikleri numaralandırmak ve uygun olanı bulmaktır.
  2. Henüz yapmadıysanız kullanıcıdan aksesuarla iletişim kurma izni isteyin yardımcı olur.
  3. Uygun arayüzde verileri okuyup yazarak aksesuarla iletişim kurun uç noktalar.

Bir aksesuar keşfedin

Uygulamanız, şu durumlarda bildirim almak için intent filtresi kullanarak aksesuarları keşfedebilir: Kullanıcı bir aksesuarı bağlayarak veya zaten bağlı olan aksesuarları numaralandırarak. Bir intent filtresi, uygulamanızın bir anahtar kelimeyi otomatik olarak yapabilirsiniz. Tüm bağlı aksesuarların listesini almak isterseniz veya uygulamanız herhangi bir amaç için filtre uygulamadıysa.

Amaç filtresi kullanın

Uygulamanızın belirli bir USB aksesuarını bulmasını sağlamak için intent filtresi kullanarak android.hardware.usb.action.USB_ACCESSORY_ATTACHED niyetini filtreleyin. Birlikte USB bağlantı noktasının özelliklerini belirten bir kaynak dosyası gibi ayrıntıları özelleştirebilirsiniz.

Aşağıdaki örnekte intent filtresinin nasıl bildirileceği gösterilmektedir:

<activity ...>
    ...
    <intent-filter>
        <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
    </intent-filter>

    <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
        android:resource="@xml/accessory_filter" />
</activity>

Aşağıdaki örnekte İlgilendiğiniz USB aksesuarları:

<?xml version="1.0" encoding="utf-8"?>

<resources>
    <usb-accessory manufacturer="Google, Inc." model="DemoKit" version="1.0" />
</resources>

Etkinliğinizde, alan adını temsil eden UsbAccessory ekli aksesuarı şu şekilde amaçlayın (eklenti kitaplığıyla):

Kotlin

val accessory = UsbManager.getAccessory(intent)

Java

UsbAccessory accessory = UsbManager.getAccessory(intent);

veya aşağıdaki gibi (platform API'leriyle):

Kotlin

val accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY) as UsbAccessory

Java

UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);

Aksesuarları numaralandırma

Uygulamanızın, sizi kendisi tanımlayan aksesuarları numaralandırmasını görebilirsiniz.

getAccessoryList() yöntemini kullan için aşağıdaki adımları uygulayın:

Kotlin

val manager = getSystemService(Context.USB_SERVICE) as UsbManager
val accessoryList: Array<out UsbAccessory> = manager.accessoryList

Java

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
UsbAccessory[] accessoryList = manager.getAccessoryList();

Not: Şu adreste yalnızca bir bağlı aksesuar desteklenir: birlikte çalışır.

Bir aksesuarla iletişim kurma izni alma

USB aksesuarıyla iletişim kurmadan önce uygulamanızın, yardımcı olur.

Not: Uygulamanız bir intent filtresine dokunun. izni gerekir. Aksi halde, ve aksesuara bağlanmadan önce bu izni uygulamanızda açıkça belirtin.

Açıkça izin istemeniz bazı durumlarda (ör. Uygulama, zaten bağlı olan ve ardından iletişim kurmak isteyen aksesuarları numaralandırıyor. bir. Bir aksesuarla iletişim kurmaya çalışmadan önce aksesuara erişim iznini kontrol etmeniz gerekir. İzin verilmiyorsa, kullanıcının aksesuarı.

Açıkça izin almak için önce bir yayın alıcı oluşturun. Bu alıcı şunları dinliyor: requestPermission() adlı kişiyi aradığınızda anons edilen niyeti gösterir. requestPermission() çağrısı, kullanıcı, aksesuara bağlanmak için izin istiyor. Aşağıdaki örnek kod, yayın alıcısını oluşturun:

Kotlin

private const val ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION"

private val usbReceiver = object : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        if (ACTION_USB_PERMISSION == intent.action) {
            synchronized(this) {
                val accessory: UsbAccessory? = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY)

                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    accessory?.apply {
                        // call method to set up accessory communication
                    }
                } else {
                    Log.d(TAG, "permission denied for accessory $accessory")
                }
            }
        }
    }
}

Java

private static final String ACTION_USB_PERMISSION =
    "com.android.example.USB_PERMISSION";
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {

    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ACTION_USB_PERMISSION.equals(action)) {
            synchronized (this) {
                UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);

                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    if(accessory != null){
                        // call method to set up accessory communication
                    }
                }
                else {
                    Log.d(TAG, "permission denied for accessory " + accessory);
                }
            }
        }
    }
};

Yayın alıcısını kaydetmek için bunu uygulamanızdaki onCreate() yönteminize yerleştirin. etkinlik:

Kotlin

private const val ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION"
...
val manager = getSystemService(Context.USB_SERVICE) as UsbManager
...
permissionIntent = PendingIntent.getBroadcast(this, 0, Intent(ACTION_USB_PERMISSION), 0)
val filter = IntentFilter(ACTION_USB_PERMISSION)
registerReceiver(usbReceiver, filter)

Java

UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
private static final String ACTION_USB_PERMISSION =
    "com.android.example.USB_PERMISSION";
...
permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(usbReceiver, filter);

Kullanıcıların aksesuara bağlanması için izin isteyen iletişim kutusunu görüntülemek için requestPermission() yöntem:

Kotlin

lateinit var accessory: UsbAccessory
...
usbManager.requestPermission(accessory, permissionIntent)

Java

UsbAccessory accessory;
...
usbManager.requestPermission(accessory, permissionIntent);

Kullanıcılar iletişim kutusuna yanıt verdiğinde yayın alıcınız EXTRA_PERMISSION_GRANTED ekstra (bir boole değeri) temsil eder. aksesuarı.

Aksesuarla iletişim kurma

Şu işlemleri yapmak için UsbManager cihazını kullanarak aksesuarla iletişim kurabilirsiniz: veri okumak ve yazmak için giriş ve çıkış akışlarını ayarlayabileceğiniz bir dosya tanımlayıcısı edinin açıklayıcıdır. Akışlar, aksesuarın giriş ve çıkış toplu uç noktalarını temsil eder. Bu dönüşüm işlemini veya aksesuarın arasındaki iletişimi başka bir iş parçacığında kullanıcı arayüzü iş parçacığı. Aşağıdaki örnekte, iletişim kurmak için bir aksesuarın nasıl açılacağı gösterilmektedir:

Kotlin

private lateinit var accessory: UsbAccessory
private var fileDescriptor: ParcelFileDescriptor? = null
private var inputStream: FileInputStream? = null
private var outputStream: FileOutputStream? = null
...

private fun openAccessory() {
    Log.d(TAG, "openAccessory: $mAccessory")
    fileDescriptor = usbManager.openAccessory(accessory)
    fileDescriptor?.fileDescriptor?.also { fd ->
        inputStream = FileInputStream(fd)
        outputStream = FileOutputStream(fd)
        val thread = Thread(null, this, "AccessoryThread")
        thread.start()
    }
}

Java

UsbAccessory accessory;
ParcelFileDescriptor fileDescriptor;
FileInputStream inputStream;
FileOutputStream outputStream;
...

private void openAccessory() {
    Log.d(TAG, "openAccessory: " + accessory);
    fileDescriptor = usbManager.openAccessory(accessory);
    if (fileDescriptor != null) {
        FileDescriptor fd = fileDescriptor.getFileDescriptor();
        inputStream = new FileInputStream(fd);
        outputStream = new FileOutputStream(fd);
        Thread thread = new Thread(null, this, "AccessoryThread");
        thread.start();
    }
}

İleti dizisinin run() yönteminde şu komutu kullanarak aksesuarı okuyabilir ve aksesuara yazabilirsiniz: FileInputStream veya FileOutputStream nesneleri. Okurken FileInputStream nesnesi bulunan bir aksesuardan alınan arabelleğin depolamaya yetecek büyüklükte olması gerekir. Android aksesuar protokolü şunları destekler: tamponları 16.384 bayta kadar kullanabilir, böylece arabelleğin her zaman bu boyutunu seçmeye çalışın.

Not: Daha düşük bir düzeyde, paketler USB için 64 bayttır tam hızlı aksesuarlar ve USB yüksek hızlı aksesuarlar için 512 bayt. Android aksesuarı protokolü, işlemi basitleştirmek için her iki hıza yönelik paketleri tek bir mantıksal pakette birleştirir.

Android'de ileti dizilerini kullanma hakkında daha fazla bilgi için İşlemler ve İleti dizileri.

Bir aksesuarla iletişimi sonlandırma

Bir aksesuarla iletişim kurmayı bitirdiğinizde veya aksesuar çıkarıldıysa close() çağrısı yaparak açtığınız dosya tanımlayıcısı. Müstakil etkinlikleri dinlemek için aşağıdaki gibi bir yayın alıcı oluşturun:

Kotlin

var usbReceiver: BroadcastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {

        if (UsbManager.ACTION_USB_ACCESSORY_DETACHED == intent.action) {
            val accessory: UsbAccessory? = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY)
            accessory?.apply {
                // call your method that cleans up and closes communication with the accessory
            }
        }
    }
}

Java

BroadcastReceiver usbReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
            UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
            if (accessory != null) {
                // call your method that cleans up and closes communication with the accessory
            }
        }
    }
};

Manifest yerine uygulama içinde yayın alıcısını oluşturmak yalnızca çalışma sırasında özel etkinlik yönetimi Bu şekilde, ayrılmış etkinlikler yalnızca o anda çalışan ve tüm uygulamalara yayınlanmayan uygulamaya gönderilir.