Android Framework Components

https://www.youtube.com/playlist?list=PLIUuxxIJtMjWR77V4_QbKZY0gZb1kzoJ8

android가 어떻게 구성되어 있는지 좀더 깊이 설명하는 강좌

android official docs : https://developer.android.com/guide/topics/connectivity/usb/host

In general, you obtain a UsbManager to retrieve the desired UsbDevice. When you have the device, you need to find the appropriate UsbInterface and the UsbEndpoint of that interface to communicate on. Once you obtain the correct endpoint, open a UsbDeviceConnection to communicate with the USB device.

usb지원은 API Level 12 or higher

android manifest

  • Because not all Android-powered devices are guaranteed to support the USB host APIs, include a <uses-feature> element that declares that your application uses the android.hardware.usb.host feature.(이것은 기본적으로 항상 넣어야 하는 내용이다)
  • 이미 연결되어 있는 usb기기를 사용하는 경우(wasent 개발에 사용했음) If you want your application to be notified of an attached USB device, specify an    <intent-filter>     and    <meta-data>    element pair for the android.hardware.usb.action.USB_DEVICE_ATTACHED    intent in your main activity. The    <meta-data>    element points to an external XML resource file that declares identifying information about the device that you want to detect.In the XML resource file, declare    <usb-device>    elements for the USB devices that you want to filter. The following list describes the attributes of    <usb-device>. In general, use vendor and product ID if you want to filter for a specific device and use class, subclass, and protocol if you want to filter for a group of USB devices, such as mass storage devices or digital cameras. You can specify none or all of these attributes. Specifying no attributes matches every USB device, so only do this if your application requires it:vendor-idproduct-idclasssubclassprotocol (device or interface)Save the resource file in the res/xml/ directory. The resource file name (without the .xml extension) must be the same as the one you specified in the <meta-data> element. The format for the XML resource file is in the example below.

AndroidManifest.xml의 예시

<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>

res/xml/device_filter.xml 의 예시

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

<resources>
   <usb-device vendor-id="1234" product-id="5678" class="255" subclass="66" protocol="1" />
</resources>

.

.

.

android에서 usb를 사용하는 과정을 아래와 같다.

  1. Discover connected USB devices by using an intent filter to be notified when the user connects a USB device or by enumerating USB devices that are already connected.
  2. Ask the user for permission to connect to the USB device, if not already obtained.
  3. Communicate with the USB device by reading and writing data on the appropriate interface endpoints.

1번과정 discover하는 방법은 두가지가 있다.

– Use an intent filter

– Enumerate devices

.

.

Use an intent filter를 이용 discover

<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>
<?xml version="1.0" encoding="utf-8"?>

<resources>
   <usb-device vendor-id="1234" product-id="5678" />
</resources>
val device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)

.

.

Enumerate devices를 이용 discover 

val manager = getSystemService(Context.USB_SERVICE) as UsbManager

val deviceList = manager.getDeviceList()
val device = deviceList.get(“deviceName”)

val manager = getSystemService(Context.USB_SERVICE) as UsbManager
..
val deviceList: HashMap<String, UsbDevice> = manager.deviceList
deviceList.values.forEach { device ->
   //your code
}

.

.

.

.

obtaining permission

Note: If your application uses an intent filter(위에서 첫번째방법을 사용하는 경우) to discover USB devices as they’re connected, it automatically receives permission if the user allows your application to handle the intent. If not, you must request permission explicitly in your application before connecting to the device.

https://stackoverflow.com/questions/14111353/android-bluetooth-printing/53922171#53922171

https://developer.android.com/training/printing

https://stackoverflow.com/questions/43462836/android-print-to-any-bluetooth-printer

https://www.androidcode.ninja/android-bluetooth-tutorial/

https://stackoverflow.com/questions/14796422/how-to-send-data-to-bluetooth-printer-via-android-app

constructor

https://stackoverflow.com/a/48612819/3151712

class TextViewLight : TextView {

constructor(context: Context) : super(context){
    val typeface = ResourcesCompat.getFont(context, R.font.ccbackbeat_light_5);
    setTypeface(typeface)
}

constructor(context: Context, attrs : AttributeSet) : super(context,attrs){
    val typeface = ResourcesCompat.getFont(context, R.font.ccbackbeat_light_5);
    setTypeface(typeface)
}

constructor(context: Context,  attrs: AttributeSet , defStyleAttr : Int) : super(context, attrs, defStyleAttr){
    val typeface = ResourcesCompat.getFont(context, R.font.ccbackbeat_light_5);
    setTypeface(typeface)
}

}

.

.

.

constructor

https://stackoverflow.com/a/56542516/3151712

There are several ways to override your constructors,

When you need default behavior

class MyWebView(context: Context): WebView(context) {
    // code
}

When you need multiple version

class MyWebView(context: Context, attr: AttributeSet? = null): WebView(context, attr) {
    // code
}

When you need to use params inside

class MyWebView(private val context: Context): WebView(context) {
    // you can access context here
}

When you want cleaner code for better readability

class MyWebView: WebView {

    constructor(context: Context): super(context) {
        mContext = context
        setup()
    }

    constructor(context: Context, attr: AttributeSet? = null): super(context, attr) {
        mContext = context
        setup()
    }
}

.

.

.

constructor

https://stackoverflow.com/a/29168553/3151712

Kotlin supports multiple constructors since M11 which was released 19.03.2015. The syntax is as follows:

class MyView : View {
    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
        // ...
    }
 
    constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0) {}
}

More info here and here.

Edit: you can also use @JvmOverloads annotation so that Kotlin auto-generates the required constructors for you:

class MyView @JvmOverloads constructor(
    context: Context, 
    attrs: AttributeSet? = null, 
    defStyle: Int = 0
) : View(context, attrs, defStyle)

Beware, though, as this approach may sometimes lead to the unexpected results, depending on how the class you inherit from defines its constructors. Good explanation of what might happen is given in that article.

.

.

.