Android usb otg java

Работа с устройствами USB в Android

В недавней статье на Geektimes в комментариях возник вопрос о поддержке в ОС Android периферии, подключенной к шине USB. Действительно, большинство вендорского ПО, к примеру, для работы с принтерами и МФУ, поддерживает только подключение по сети. Однако это не означает, что в самой ОС Android нет такой возможности — это означает лишь то, что большинство устройств не имеют полноценного USB хоста, и далеко не все имеют поддержку OTG. По сети же могут работать абсолютно все без исключения.

Большинство устройств на Android при наличии порта OTG поддерживают на уровне системы (ядра Linux или стандартных компонентов Android) следующие классы устройств:

Подробнее список устройств, поддерживаемых на уровне ядра Linux, можно получить в sysfs:

$ ls /sys/bus/usb/drivers

Если же модуль в принципе доступен в исходниках ядра Linux, но не включен в Android — не стоит рассчитывать на то, что его получится собрать и расставить на все целевые системы.

Однако, начиная с Android 3.1 (API 12), в системе содержатся средства, достаточные для поддержки на уровне приложения любой USB периферии. Данные средства описаны в разделе USB Host руководства по Android API. Здесь же я хочу привести примеры реальной работы с некоторыми видами устройств.

Права доступа

Как и для прочих действий, Android требует, чтобы приложение получило разрешение на доступ к USB периферии. Существует 2 способа получить такое разрешение:

  • Задекларировать список устройств в AndroidManifest
  • Явно показать пользователю диалог “разрешить”
Читайте также:  Распараллелить цикл на python

Итак, нам необходимо добавить в манифест следующее:

А в res/xml/device_filter.xml вписать следующее:

Отмечу, что хотя общепринято указывать VID:PID в 16-ричной системе счисления, здесь они должны быть указаны в десятичной. В документации заявляется, что возможно указание только класса, без VID и PID, но у меня это не стало работать.

Принтеры

На примере принтера я покажу, как непосредственно использовать API android.hardware.usb. На уровне передачи данных все принтеры поддерживают стандартый класс USB устройств:

int UsbConstants.USB_CLASS_PRINTER = 7; 

Класс предельно простой. В рамках этого класса устройство должно поддерживать:

  • Обязательный bulk out endpoind для отправки данных на принтер
  • Опциональный bulk in endpoind для получения статуса принтера
  • 3 управляющих запроса
int GET_DEVICE_ID = 0; int GET_PORT_STATUS = 1; int SOFT_RESET = 2; 

Код, приведенный ниже, предоставляет функциональность, аналогичную устройству /dev/usb/lp в Linux. Далее нам нужен фильтр, преобразующий исходный документ в пакет данных, понятный конкретной модели принтера. Но это тема иной статьи. Как один из вариантов — можно собрать ghostscript с помощью NDK.

Для работы с устройством нам в первую очередь нужно:

1. Найти устройство. В примере для простоты я ищу первый попавшийся:

UsbDevice findDevice() < for (UsbDevice usbDevice: mUsbManager.getDeviceList().values()) < if (usbDevice.getDeviceClass() == UsbConstants.USB_CLASS_PRINTER) < return usbDevice; >else < UsbInterface usbInterface = findInterface(usbDevice); if (usbInterface != null) return usbDevice; >> return null; > UsbInterface findInterface(UsbDevice usbDevice) < for (int nIf = 0; nIf < usbDevice.getInterfaceCount(); nIf++) < UsbInterface usbInterface = usbDevice.getInterface(nIf); if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_PRINTER) < return usbInterface; >> return null; > UsbDevice mUsbDevice = findDevice(); UsbInterface mUsbInterface = findInterface(mUsbDevice); 
for (int nEp = 0; nEp < mUsbInterface.getEndpointCount(); nEp++) < UsbEndpoint tmpEndpoint = mUsbInterface.getEndpoint(nEp); if (tmpEndpoint.getType() != UsbConstants.USB_ENDPOINT_XFER_BULK) continue; if ((mOutEndpoint == null) && (tmpEndpoint.getDirection() == UsbConstants.USB_DIR_OUT)) < mOutEndpoint = tmpEndpoint; >else if ((mInEndpoint == null) && (tmpEndpoint.getDirection() == UsbConstants.USB_DIR_IN)) < mInEndpoint = tmpEndpoint; >> if (mOutEndpoint == null) throw new IOException("No write endpoint: " + deviceName); 

3. Непосредсвенно открыть устройство:

mConnection = mUsbManager.openDevice(mUsbDevice); if (mConnection == null) throw new IOException("Can't open USB connection:" + deviceName); mConnection.claimInterface (mUsbInterface, true); 

4. После этого мы можем читать и писать в устройство:

public int read(final byte[] data) throws IOException < int size = Math.min(data.length, mInEndpoint.getMaxPacketSize()); return mConnection.bulkTransfer(mInEndpoint, data, size, getReadTimeout()); >public int write(final byte[] data, final int length) throws IOException < int offset = 0; while (offset < length) < int size = Math.min(length - offset, mInEndpoint.getMaxPacketSize()); int bytesWritten = mConnection.bulkTransfer(mOutEndpoint, Arrays.copyOfRange(data, offset, offset + size), size, getWriteTimeout()); if (bytesWritten return offset; > 

5. По завершении работы — закрыть устройство:

Преобразователи USB-Serial

В отличие от притеров, преобразователи USB-Serial гораздо менее стандартизированы. Существует несколько распространенных чипов, для которых существенно отличается установка параметров последовательного порта — битрейта, чётности и проч. К счастью, есть библиотека github.com/mik3y/usb-serial-for-android, поддерживающая практически все существующие чипы. Библиотека полностью скрывает USB API, сводя все необходимые действия к минимуму вызовов с минимумом параметров.

1. Найти и открыть устройство:

UsbSerialPort mUsbSerialPort; UsbManager mUsbManager = (UsbManager) DEVICE.getSystemService(Context.USB_SERVICE); String type = “FTDI”; for (UsbDevice usbDevice: mUsbManager.getDeviceList().values())

2. Установить параметры последовательного порта:

mUsbSerialPort.setParameters(baudRate, dataBits, stopBits, parity); 
public int read(final byte[] data) throws IOException < return mUsbSerialPort.read(data, getReadTimeout()); >public int write(final byte[] data, final int length) throws IOException

4. По завершении работы — закрыть порт:

Резюме

Надеюсь, что мне удалось показать, что работа с USB периферией достаточно проста и логична. Безусловно, реализация протоколов некоторых конкретных устройств не блещет простотой — но это проявится в любой системе в одинаковой степени.

Все приведенные примеры я взял из реального проекта, лишь исключил очевидные проверки, оставив только ключевые строки.

Источник

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

License

quantum6/Android-USB-OTG-Camera

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

AndroidUSBCamera is developed based on the saki4510t/UVCCamera, the project of USB Camera (UVC equipment) and the use of video data acquisition are highly packaged, and it can help developers using USB Camera devices easily by a few simple APIs. By using AndroidUSBCamera,you can detect and connect to a USB Camera simply.And you also can use it to realize taking picture,recording mp4,switching resolutions ,getting h.264/aac/yuv(nv21) stream and setting camera’s contrast or brightness,supporting 480P、720P、1080P and higher,etc.supporting overlay and record device’s mic.

Supporting Android 5.0,6.0,7.0,8.0,9.0,10.0

1.Add to your Android Studio project

Step 1. Add the JitPack repository to your build file.Add it in your root build.gradle at the end of repositories:

allprojects < repositories < . maven < url 'http://raw.github.com/saki4510t/libcommon/master/repository/' > maven < url 'https://jitpack.io' > > >

Step 2. Add the dependency

dependencies < implementation 'com.github.jiangdongguo:AndroidUSBCamera:2.3.4' >

(1) In order to using it correctly,the following four steps must be achieved:

mUVCCameraView = (CameraViewInterface) mTextureView; mUVCCameraView.setCallback(mCallback); mCameraHelper = UVCCameraHelper.getInstance(); // set default preview size mCameraHelper.setDefaultPreviewSize(1280,720); // set default frame format,defalut is UVCCameraHelper.Frame_FORMAT_MPEG // if using mpeg can not record mp4,please try yuv // mCameraHelper.setDefaultFrameFormat(UVCCameraHelper.FRAME_FORMAT_YUYV); mCameraHelper.initUSBMonitor(this, mUVCCameraView, mDevConnectListener);

To be attention,mCallback is a object of interface CameraViewInterface.Callback,and it’s used to be listenering surfaceView created or detoryed.mDevConnectListener is a object of interface UVCCameraHelper.OnMyDevConnectListener,and it’s used to be listenering to detect and conntect USB device.Here is the coding order:

private CameraViewInterface.Callback mCallback = new CameraViewInterface.Callback mCallback()< @Override public void onSurfaceCreated(CameraViewInterface view, Surface surface) < // must have if (!isPreview && mCameraHelper.isCameraOpened()) < mCameraHelper.startPreview(mUVCCameraView); isPreview = true; > > @Override public void onSurfaceChanged(CameraViewInterface view, Surface surface, int width, int height) < >@Override public void onSurfaceDestroy(CameraViewInterface view, Surface surface) < // must have if (isPreview && mCameraHelper.isCameraOpened()) < mCameraHelper.stopPreview(); isPreview = false; > > > private UVCCameraHelper.OnMyDevConnectListener listener = new UVCCameraHelper.OnMyDevConnectListener() < @Override public void onAttachDev(UsbDevice device) < // request open permission(must have) if (!isRequest) < isRequest = true; if (mCameraHelper != null) < mCameraHelper.requestPermission(0); > > > @Override public void onDettachDev(UsbDevice device) < // close camera(must have) if (isRequest) < isRequest = false; mCameraHelper.closeCamera(); > > @Override public void onConnectDev(UsbDevice device, boolean isConnected) < >@Override public void onDisConnectDev(UsbDevice device) < >>;
mCameraHelper.capturePicture(picPath, new AbstractUVCCameraHandler.OnCaptureListener() < @Override public void onCaptureResult(String path) < Log.i(TAG,"save path:" + path); > >);

(3) Recording Mp4,supporting close voice and save file automatic.

RecordParams params = new RecordParams(); params.setRecordPath(videoPath); params.setRecordDuration(0); // 0,do not cut save params.setVoiceClose(mSwitchVoice.isChecked()); // is close voice params.setSupportOverlay(true); // overlay only support armeabi-v7a & arm64-v8a mCameraHelper.startPusher(params, new AbstractUVCCameraHandler.OnEncodeResultListener() < @Override public void onEncodeResult(byte[] data, int offset, int length, long timestamp, int type) < // type = 1,h264 video stream if (type == 1) < // FileUtils.putFileStream(data, offset, length); > // type = 0,aac audio stream if(type == 0) < >> @Override public void onRecordResult(String videoPath) < Log.i(TAG,"videoPath pl-s1">videoPath); > >); // of course,if you only want to getting h.264 and aac stream // you can do like this mCameraHelper.startPusher(listener);

(4) setting camera’s brightness and contrast.

mCameraHelper.setModelValue(UVCCameraHelper.MODE_BRIGHTNESS,progress); mCameraHelper.setModelValue(UVCCameraHelper.MODE_CONTRAST,progress); mCameraHelper.getModelValue(UVCCameraHelper.MODE_BRIGHTNESS); mCameraHelper.getModelValue(UVCCameraHelper.MODE_CONTRAST); .

(5) switch resolutions and camera.

mCameraHelper.updateResolution(widht, height);

At last,remember adding permissions:

uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> uses-permission android:name="android.permission.RECORD_AUDIO" />

Please checking your preview format and change YUV to MJPEG or MJPEG to YUV,because some usb devices only supporting YUV

  1. never found the device
  • confirm your phone support otg
  • get a file from your sd card named failed-device.txt in the path of root sd card/UsbCamera/failed-device.txt and tell me
  • if your device is Android 10(Q),please change your versionTarget to 27 and below, because these is a bug in Android Q SDK.
  1. support adding time overlay(attention: overlay only support armeabi-v7a & arm64-v8a);
  2. support recording device mic;
  3. update to androidx and update commonLibVersion from 2.14.2 to 4.1.1;
  4. fix saving files failed.
  1. fix pull version 2.3.2 failed.
  2. fix android 9.0 sometimes can not preview.
  3. fix the exception when pull up the device.
  4. update to all so files to new.

In order to display the functions, I develop a simple released apk,which is based on version 2.3.1,and the build version is 28.0.3.Here is my configs and if you have any questions please issues to me ,I will follow it do my best.

ext < androidXVersion = '1.1.0' // variable that can be referenced to keep support libs consistent commonLibVersion= '4.1.1' versionCompiler = 28 versionTarget = 27 // versionTarget>27 android 10 may previewed failed. // if hope supporting 4.4 // please modify it to 16 minSdkVersion = 21 versionNameString = '1.2.1.20200414' javaSourceCompatibility = JavaVersion.VERSION_1_8 javaTargetCompatibility = JavaVersion.VERSION_1_8 > 

Other Library about Android Camera

OkCamera Android Camera univsersally operation.
AndroidRecordMp4 Using MediaCodec realize record mp4.
AndroidYuvOsd YUV data operation.
Lame4Mp3 pcm to mp3 and pcm to aac.

Copyright 2020 Jiangdongguo Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 

Источник

Оцените статью