Android destekli cihazınız USB ana makine modundayken USB ana makinesi olarak çalışır, veri yolu ve bağlı USB cihazlarını sıralar. USB ana makine modu, Android 3.1 ve sonraki sürümlerde desteklenir.
API'ye Genel Bakış
Başlamadan önce, hangi sınıflar üzerinde çalışmanız gerektiğini anlamanız önemlidir. İlgili içeriği oluşturmak için kullanılan
Aşağıdaki tabloda android.hardware.usb
paketindeki USB ana makine API'leri açıklanmaktadır.
Sınıf | Açıklama |
---|---|
UsbManager |
Bağlı USB cihazlarını numaralandırmanıza ve bu cihazlarla iletişim kurmanıza olanak tanır. |
UsbDevice |
Bağlı bir USB cihazını temsil eder ve tanımlamaya yönelik yöntemler içerir bilgi, arayüzler ve uç noktalar. |
UsbInterface |
Bir USB cihazı arayüzünü temsil eder ve bu arayüz, olanak tanır. Bir cihazın iletişim kurulacak bir veya daha fazla arayüzü olabilir. |
UsbEndpoint |
Bu arayüz için bir iletişim kanalı olan arayüz uç noktasını temsil eder. arayüz bir veya daha fazla uç noktaya sahip olabilir ve genellikle iki yönlü iletişim kurulmasını sağlar. |
UsbDeviceConnection |
Uç noktalarda veri aktaran cihaz bağlantısını temsil eder. Bu sınıf verileri eşzamanlı veya eşzamansız olarak karşılıklı olarak göndermenize olanak tanır. |
UsbRequest |
UsbDeviceConnection aracılığıyla bir cihazla iletişim kurmak için eşzamansız bir isteği temsil eder. |
UsbConstants |
Linux'un linux/usb/ch9.h'deki tanımlara karşılık gelen USB sabit değerlerini tanımlar kernel'e gidin. |
Çoğu durumda, bu sınıfların tümünü kullanmanız gerekir (UsbRequest
yalnızca eşzamansız iletişim gerçekleştiriyorsanız gereklidir)
iletişim sırasında yürütülür. Genel olarak, istenen UsbDevice
öğesini almak için bir UsbManager
alırsınız.
Cihaz yanınızda olduğunda uygun UsbInterface
ve UsbEndpoint
'nı bulmanız gerekir
bir iletişim arayüzü seçin. Doğru uç noktayı aldıktan sonra, USB cihazıyla iletişim kurmak için bir UsbDeviceConnection
açın.
Android manifesti şartları
Aşağıdaki listede, Google Haritalar'dan ayrılmadan önce uygulamanızın manifest dosyasına eklemeniz gereken bilgileri bulabilirsiniz USB ana makine API'larıyla çalışma:
- Android destekli tüm cihazların USB ana makine API'lerini desteklediği garanti edilmediğinden,
uygulamanızın
<uses-feature>
android.hardware.usb.host
özelliği. - Uygulamanın minimum SDK sürümünü API Düzeyi 12 veya sonraki bir sürüme ayarlayın. USB ana makine API'leri önceki API düzeylerinde mevcuttur.
- Takılı bir USB cihazıyla ilgili olarak uygulamanıza bildirim gönderilmesini istiyorsanız bir
Şu için
<intent-filter>
ve<meta-data>
öğe çifti: Ana etkinliğinizdeandroid.hardware.usb.action.USB_DEVICE_ATTACHED
intent. İlgili içeriği oluşturmak için kullanılan<meta-data>
öğesi, aşağıdakileri bildiren harici bir XML kaynak dosyasına işaret ediyor: algılamak istediğiniz cihazla ilgili tanımlayıcı bilgiler.XML kaynak dosyasında USB için
<usb-device>
öğelerini tanımlayın cihazları seçin. Aşağıdaki listede<usb-device>
Genel olarak, filtre uygulayarak bir filtre oluşturmak için ve bir grup için filtre uygulamak istiyorsanız sınıf, alt sınıf ve protokolü kullanın. depolama cihazları ve dijital kameralar gibi USB cihazlarıyla çalışır. Herhangi bir özellikler. Her USB cihazla eşleşen özellik belirtmemenizi sağlar; bu nedenle bunu yalnızca yapın. uygulamanız gerekiyorsa:vendor-id
product-id
class
subclass
protocol
(cihaz veya arayüz)
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 example 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.host" /> <uses-sdk android:minSdkVersion="12" /> ... <application> <activity ...> ... <intent-filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> </intent-filter> <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" /> </activity> </application> </manifest>
Bu durumda, aşağıdaki kaynak dosya
res/xml/device_filter.xml
ve belirtilen
özelliklerine filtre uygulanması gerekir:
<?xml version="1.0" encoding="utf-8"?> <resources> <usb-device vendor-id="1234" product-id="5678" class="255" subclass="66" protocol="1" /> </resources>
Cihazlarla çalışma
Kullanıcılar USB cihazları Android destekli bir cihaza bağladığında Android sistemi, uygulamanızın bağlı cihazla ilgilenip ilgilenmediğini görebilirsiniz. Öyleyse, hesap erişimini iletişim kurmalarına izin verilmez. Bunun için uygulamanız:
- Kullanıcı aşağıdaki işlemleri gerçekleştirdiğinde bildirim almak için intent filtresi kullanarak bağlı USB cihazları keşfedin bir USB cihazına bağlanarak veya zaten bağlı olan USB cihazlarını numaralandırarak.
- Henüz almadıysanız, kullanıcıdan USB cihazına bağlanma izni isteyin.
- Uygun arayüzde veri okuyup yazarak USB cihazıyla iletişim kurun. uç noktalar.
Bir cihazı keşfedin
Uygulamanız, şu durumlarda bildirim almak için bir intent filtresi kullanarak USB cihazları keşfedebilir: Kullanıcı bir cihazı bağlayarak veya zaten bağlı olan USB cihazlarını numaralandırarak. Bir intent filtresi, uygulamanızın bir anahtar kelimeyi otomatik olarak tercih edebilirsiniz. Tüm bağlı USB cihazlarının listesini almak isterseniz, bu cihazların sıralanması amaçlar için filtre uygulamamış olabilir.
Amaç filtresi kullanın
Uygulamanızın belirli bir USB cihazını bulmasına yardımcı olmak için bir intent filtresi
android.hardware.usb.action.USB_DEVICE_ATTACHED
amacı için filtre uygulayın. Şununla birlikte:
USB özelliklerini belirten bir kaynak dosyası belirtmeniz gerekir
kimlik bilgilerini (ör. ürün ve tedarikçi kimliği) girin. Kullanıcılar, cihazınızla eşleşen bir cihaz bağladığında
filtresini uyguladığınızda sistem, bu kullanıcılara uygulamanızı başlatmak isteyip istemediklerini soran bir iletişim kutusu gösterir.
Kullanıcılar kabul ederse uygulamanızın, şu tarihe kadar cihaza otomatik olarak erişim izni olur:
cihazın bağlantısı kesildi.
Aşağıdaki örnekte intent filtresinin nasıl bildirileceği gösterilmektedir:
<activity ...> ... <intent-filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> </intent-filter> <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" /> </activity>
Aşağıdaki örnekte İlgilendiğiniz USB cihazları:
<?xml version="1.0" encoding="utf-8"?> <resources> <usb-device vendor-id="1234" product-id="5678" /> </resources>
Etkinliğinizde, alan adını temsil eden UsbDevice
ekli cihazı şu şekilde niyetten kaldırın:
Kotlin
val device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)
Java
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
Cihazları numaralandırma
Uygulamanız şu anda bağlı olan tüm USB cihazlarını incelemek istiyorsa
uygulamanız çalışırken veri yolundaki cihazları sıralayabilir. Tüm karma haritalarını almak için getDeviceList()
yöntemini kullanın
bağlı olan USB cihazlarıdır. İsterseniz karma eşleme, USB cihazının adıyla anahtarlanır.
haritadan bir cihaz edinin.
Kotlin
val manager = getSystemService(Context.USB_SERVICE) as UsbManager ... val deviceList = manager.getDeviceList() val device = deviceList.get("deviceName")
Java
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); ... HashMap<String, UsbDevice> deviceList = manager.getDeviceList(); UsbDevice device = deviceList.get("deviceName");
Dilerseniz karma haritasından bir iteratör alıp her cihaz için bir iterasyon yapabilirsiniz. tek tek:
Kotlin
val manager = getSystemService(Context.USB_SERVICE) as UsbManager .. val deviceList: HashMap<String, UsbDevice> = manager.deviceList deviceList.values.forEach { device -> // your code }
Java
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 }
Bir cihazla iletişim kurma izni alma
USB cihazıyla iletişim kurmadan önce, uygulamanızın, yardımcı olur.
Not: Uygulamanız bir intent filtresine dokunun. Bu filtre, bağlı oldukları USB cihazları otomatik olarak alır. izni gerekir. Aksi halde, ve cihaza 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 USB cihazlarını numaralandırır bir. Bir cihazla iletişim kurmayı denemeden önce cihaza erişim iznini kontrol etmeniz gerekir. Eğer Kullanıcı, cihaza erişim izni vermeyi reddettiğinde çalışma zamanı hatası alırsınız.
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ıya bağlanma izni 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 device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE) if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { device?.apply { // call method to set up device communication } } else { Log.d(TAG, "permission denied for device $device") } } } } }
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) { UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { if(device != null){ // call method to set up device communication } } else { Log.d(TAG, "permission denied for device " + device); } } } } };
Yayın alıcıyı kaydetmek için bunu uygulamanızdaki onCreate()
yönteminize ekleyin.
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), PendingIntent.FLAG_IMMUTABLE) 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), PendingIntent.FLAG_IMMUTABLE); IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); registerReceiver(usbReceiver, filter);
Cihaza bağlanmak için kullanıcılardan izin isteyen iletişim kutusunu görüntülemek için requestPermission()
yöntemini çağırın:
Kotlin
lateinit var device: UsbDevice ... usbManager.requestPermission(device, permissionIntent)
Java
UsbDevice device; ... usbManager.requestPermission(device, 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.
olanak tanır.
Bir cihazla iletişim kurma
Bir USB cihazıyla iletişim eşzamanlı veya eşzamansız olabilir. Her iki durumda da,
tüm veri aktarımlarını gerçekleştirecek yeni bir iş parçacığı oluşturmanız gerekir, böylece
Kullanıcı arayüzü iş parçacığı. Bir cihazla iletişimi doğru bir şekilde kurmak için uygun
UsbInterface
ve UsbEndpoint
ve bu uç noktada bir UsbDeviceConnection
ile istek göndermek istediğiniz bir cihaz bulun. Genel olarak, kodunuz:
UsbDevice
nesnesinin özelliklerini (ör. ürün kimliği) kontrol edin aracılığıyla iletişim kurmak isteyip istemediğinizi belirlemek için Tedarikçi Firma kimliğini veya cihaz sınıfını olanak tanır.- Cihazla iletişim kurmak istediğinizden emin olduğunuzda uygun
UsbInterface
ile birlikte iletişim kurmak için kullanmak istediğiniz söz konusu arayüze ait uygunUsbEndpoint
. Arayüzlerde bir olabilir daha fazla uç noktaya sahiptir ve genellikle iki yönlü için bir giriş ve çıkış uç noktasına iyi bir iletişimdir. - Doğru uç noktayı bulduğunuzda bir
UsbDeviceConnection
açın görebilirsiniz. - Uç noktada iletmek istediğiniz verileri
bulkTransfer()
veyacontrolTransfer()
yöntemiyle sağlayın. Şunları yapmalısınız: Ana kullanıcı arayüzü iş parçacığının engellenmesini önlemek için bu adımı başka bir iş parçacığında uygulayın. Daha fazla hakkında daha fazla bilgi için İşlemler ve İleti dizileri.
Aşağıdaki kod snippet'i, eşzamanlı veri aktarımı yapmanın basit bir yoludur. Kodunuz doğru arayüzü ve iletişim noktalarını bulmak için daha fazla mantığa Ayrıca, veri aktarımlarını ana kullanıcı arayüzü iş parçacığından farklı bir iş parçacığında yapmalıdır:
Kotlin
private lateinit var bytes: ByteArray private val TIMEOUT = 0 private val forceClaim = true ... device?.getInterface(0)?.also { intf -> intf.getEndpoint(0)?.also { endpoint -> usbManager.openDevice(device)?.apply { claimInterface(intf, forceClaim) bulkTransfer(endpoint, bytes, bytes.size, TIMEOUT) //do in another thread } } }
Java
private Byte[] bytes; private static int TIMEOUT = 0; private boolean forceClaim = true; ... UsbInterface intf = device.getInterface(0); UsbEndpoint endpoint = intf.getEndpoint(0); UsbDeviceConnection connection = usbManager.openDevice(device); connection.claimInterface(intf, forceClaim); connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT); //do in another thread
Eşzamansız olarak veri göndermek için initialize
için UsbRequest
sınıfını ve eşzamansız bir isteği queue
kullanın, ardından sonucu bekleyin
requestWait()
ile.
Cihazla iletişimi sonlandırma
Bir cihazla iletişimi bitirdiğinizde veya cihaz çıkarıldıysa UsbInterface
ve UsbDeviceConnection
şunları kapatın:
releaseInterface()
ve
close()
. Ayrılan 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_DEVICE_DETACHED == intent.action) { val device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE) device?.apply { // call your method that cleans up and closes communication with the device } } } }
Java
BroadcastReceiver usbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) { UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); if (device != null) { // call your method that cleans up and closes communication with the device } } } };
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.