• スポンサードリンク

UVC機器へアクセスするtargetSdkVersion=28のアプリをAndroid9端末で動かす時ぃ〜

Android Camera USB

うぉ〜😨😨😨めっちゃ悩んでもうたやん、さきちゃんの今日の午後を返せぇ〜(●`ε´●)

昔々あるところに、新しいアプリを作るにあたり折角の機会なのでtargetSdkVersionを28にしてやれと思った人がいました。ドコニー?ココニー。今まではtargetSdkVersionといえば27であったにもかかわらずです。これが全ての困難の始まりでした(。・_・。)

いつも作り慣れたUVC機器アクセスのアプリです。Android Studioで新規プロジェクトを作成し依存するライブラリを追加し…テスト実行(^o^)/
いつもどおりであればサクサクと数時間と掛からずにUVC機器へアクセスできるようになるはずでした。

おかしいです、USB機器アクセスのパーミッションを取得できません。いえ、正確にはアプリにはパーミッション付与されているようなのですが、いざアプリがUVC機器へアクセスしようとするとパーミッションが付与されていないのです。

作成中のアプリをインストールしたAndroid端末へUVC機器を接続すると、「USBデバイス用アプリ選択」のSnackバー/ダイアログが表示されます。
いつもと同じです。

ここで該アプリを選択して「1回のみ」または「常時」ボタンを押すとAndroid側からUSB機器アクセスのパーミッションが付与されてアプリが起動するはずです。
Android側からUSB機器アクセスのパーミッションを付与されたときにはACTION_USB_DEVICE_ATTACHEDアクションとともにIntent#getFlagの値のビット24ビット25がONになったIntentが飛んできます。
ここまでもいつもと同じです。

しかし、いざUVC機器へアクセスしようとするとパーミッションが付与されていません。仕方がないのでアプリ側からUsbManager#requestPermissionを呼び出してパーミッション要求するのですが(これはヘルパークラス内で自動的におこなっています)、パーミッション要求ダイアログが表示されることなく直ぐにBroadcastReceiverへIntentが飛んできます。しかもIntent#getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)は何度試してもfalseしか返ってこないのです。つまり、パーミッションが付与されていません(´・ω・`)

このアプリでは、USB機器アクセルのパーマネントパーミッションを保持できるように、AndroidManifest.xmlandroid.hardware.usb.action.USB_DEVICE_ATTACHEDアクションを受け取れるようにintent-filterを設定してあります。
ですので「USBデバイス用アプリ選択」で「常時」選択してから、端末の設定画面からアプリの設定画面を開き「デフォルトで開く」設定を確認すると「一部デフォルトで設定」になっています。これもいつもと同じです。つまりアプリに対してはUSB機器アクセスのパーマネントパーミッションが付与されているとということです。

にも関わらず、アプリ側からアクセスしようとするとパーミッションが付与されていないのです。
困りました、いつもと全く同じヘルパーライブラリ/クラスを使っているにも関わらずです。
この時点では主要部分は既存アプリからコピペしただけであるにも関わらずです。

同じヘルパークラスを使っている既存のアプリを実行すると、パーミッション要求ダイアログが表示された後UVC機器から正常に映像を取得することでできます。もうわけがわかりません💫💫💫

ちくせぅ〜わかんねぇ〜ということでお昼寝することにしましたZzz…

お昼寝すること3時間あまり、すっかり日が暮れてしまいました💦

気を取り直して別のテスト端末で動かすことにしてみます。
お昼寝前はMoto G6 Plus(Android9)でしたが、今度はMoto Z Play(Android 8)で試してみます。


えっ!あれっ!!にゃ~んと、正常に動きます、お昼寝前にはあれほど取得できなかったUSB機器アクセスのパーミッションもUVC機器アクセスも正常に動きます。
もう一度Moto G6 Plusで試してみると…やっぱり動きません(。・_・。)

なんでやねんなぁ〜〜〜〜💫

AndroidManifest.xmlも実装しているコードはほぼ等価、も使っているヘルパーライブラリ/クラスも同じで大きな違いはありません。なんででしょう?💫logCatにもめぼしい情報は出力されていません。

もうだめじゃぁ〜飲んだくれるしかないんじゃぁ〜と思ったその時✨

閃いたのです✨✨✨
気づいてしまったのです💡💡💡

今回のアプリのtargetSdkVersionが28であることに😵

ジャジャジャッジャーン↓↓↓

ということで、さよならぁ〜(T_T)/~~~

じゃなくて💦

ご存知の通り、Android9からAndroid OS自体にUVC機器アクセスの機能が導入されました。targetSdkVersionが27以下の場合にはその機能は無効なようなのですが(以前試したのですがどうしても使えなかった)、どうやらtargetSdkVersionを28にすると挙動がキョドるようなのです。
試しに同じアプリでコードはそのままにtargetSdkVersion=27とするとMoto G6 Plus(Android9)でも正常に動作します。

いろいろ調べてみると、Android9端末でtargetSdkVersion=28のアプリからUVC機器へアクセスするにはカメラアクセスのパーミッションが必要なようです。

つまりAndroidManifest.xmlに下記の記述をした上で動的パーミッション取得の処理が必要というわけです。

まとめるとAndroid9でUVC機器へアクセスするアプリでは次の実装が必要になります。

  • targetSdkVersionが27以下の場合には、従来どおりUsbManagerを使ったUSB機器アクセスのパーミッション要求が必要
  • targetSdkVersion=28(以降)の場合には、従来どおりのUsbManagerを使ったUSB機器アクセスのパーミッション要求のに、CAMERAアクセスの動的パーミッション要求が必要。ただしAndroid9未満の端末であればCAMERAアクセスのパーミッション処理は不要。

めんどくさい…めんどくさみしかない(。・_・。)2回もパーミッションを要求しないといけないなんて(。・_・。)

Android9以降でのAndroid自体でのUVC機器アクセスの機能(おそらく内蔵カメラと同じようにCamera/Camera 2 APIでアクセスできると思われる)を使ってUVC機器を使うというのであればCAMERAアクセスのパーミッションを必要とするのは納得いきます。
ですが、USB機器の1つとしてUsbManager経由でアクセスパーミッション要求をしているにも関わらず追加でCAMERAパーミッションも必要とするというのは全く納得いかねぇーちくしょぉ〜仕様決めたやつはハゲろぉー毟ってやるぅ(●`ε´●)

ということで今度こそ、さよならぁ〜(^_-)/~~~

«

  • スポンサードリンク

コメントを残す

%d人のブロガーが「いいね」をつけました。