質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

1回答

704閲覧

Android(JAVA)のライブラリ(aar)でUSB接続処理を実装すると権限選択時にアプリが必ず1度クラッシュする。

nrr-mgmg

総合スコア1

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2023/11/02 05:59

編集2023/11/02 06:05

実現したいこと

  • [アプリクラッシュを回避したい。]

USB接続時に必ず1度クラッシュするがクラッシュ後であれば情報を取得することは可能です。
ですが、クラッシュをそもそもしないようにしたいです。
AndroidManifestの設定か、このライブラリを使用する側で何か設定が必要でしょうか?

前提

ライブラリ(USBLib.aar)を作成し、ライブラリ側でUSB接続を行えるようにしています。
アプリはこのaarを呼び出すとUSB情報を取得できます。

実際のアプリはUnityから動作しますが、Androidで作成した動作確認用のテストアプリもあります。
アプリクラッシュはUnityからでもテストアプリからでも発生します。

ライブラリのAndroidManifestにてUSBの権限を設定するような定義にしています。
intent-filterにて対象の製品IDとベンダーIDを定義しており当該情報のみ動作するようにしています。

[クラッシュ具体例]
テストアプリをAndroid端末実機にUSB経由でインストールし、アプリを起動します。(USBデバッグ有効の状態)
起動中にUSB接続を行うとアプリ選択画面が出てくるため、当該アプリを選択するとクラッシュします。
※1回のみを選択
クラッシュ後、USB接続状態でアプリを再度立ち上げてUSB情報取得ボタンを押下すると、USB情報を正常に取得できます。

USB接続時の選択画面にてアプリを選択しない場合、クラッシュしません。
クラッシュしませんがUSB情報取得ボタンを押しても取得できません。

USBを抜いて、再度接続するとまたアプリ選択画面が出るため、アプリを選択するとクラッシュします。
※常時接続を行うと、アプリ選択画面は出ませんが同じようにUSB接続した場合クラッシュして2回目の起動ではクラッシュしない。

発生している問題・エラーメッセージ

AndroidRuntime: java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{パッケージ名}: java.lang.ClassCastException: パッケージ名 cannot be cast to android.app.Activity

該当のソースコード

  • ライブラリ

xml

1<!-- androidmanifest --> 2<?xml version="1.0" encoding="utf-8"?> 3<manifest xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:tools="http://schemas.android.com/tools" 5 package="パッケージ名"> 6 7 <uses-sdk android:minSdkVersion="12" /> 8 9 <uses-feature 10 android:name="android.hardware.usb.host" 11 android:required="false" /> 12 13 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 14 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> /> 15 16 <application 17 android:debuggable="true" 18 tools:ignore="HardcodedDebugMode"> 19 <activity 20 android:name=".USBLib" 21 android:exported="true" 22 tools:ignore="Instantiatable"> 23 <intent-filter> 24 <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> 25 </intent-filter> 26 27 <meta-data 28 android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" 29 android:resource="@xml/device_filter" /> 30 </activity> 31 </application> 32 33</manifest>

xml

1<!-- device_filter--> 2<?xml version="1.0" encoding="utf-8"?> 3 4<resources> 5 <usb-device vendor-id="id" product-id="pid1"/> 6 <usb-device vendor-id="id" product-id="pid2"/> 7 <usb-device vendor-id="id" product-id="pid3"/> 8 </resources> 9

Java

1 2public class USBLib 3{ 4 private Context myContext = null; 5 6 public USBLib() 7 { 8 9 } 10 11 public int setContext(Context context) { 12 myContext = context; 13 return 0; 14 } 15 16 public int setContext() { 17 int result = 0; 18 if (myContext == null){ 19 result = setContext(UnityPlayer.currentActivity.getApplicationContext()); 20 } 21 return result; 22 } 23 24 25 public String GetSts() 26 { 27 28 UsbManager manager = (UsbManager) myContext.getSystemService(Context.USB_SERVICE); 29 HashMap<String, UsbDevice> deviceList = manager.getDeviceList(); 30 Iterator<UsbDevice> deviceIterator = deviceList.values().iterator(); 31 while(deviceIterator.hasNext()) { 32 UsbDevice device = deviceIterator.next(); 33 return device.getDeviceName(); 34 } 35 36 return ""; 37 } 38} 39
  • テストアプリ

Java

1 2 3public class MainActivity extends AppCompatActivity implements View.OnClickListener 4{ 5 6 USBLib reader = new USBLib(); 7 @Override 8 protected void onCreate(Bundle savedInstanceState) { 9 super.onCreate(savedInstanceState); 10 setContentView(R.layout.activity_main); 11 12 findViewById(R.id.button).setOnClickListener(this); 13 } 14 @Override 15 public void onClick(View v) { 16 17 Context context = this.getApplicationContext(); 18 String dump = ""; 19 try { 20 21 reader.setContext(context); 22 dump = reader.GetSts(); 23 } 24 catch (Exception ex) 25 { 26 dump = ex.toString(); 27 } 28 } 29}

試したこと

ボタン押下時ではないため、関係ないと思いつつも
USB取得処理を無効化しても変わらなかった。

USB選択時であるのでおそらくAndroidManifestの問題?

AndroidManifestの
<activityをServiceにしてみると、アプリ選択ができなかった。

Unityからの呼び出しでも同じ

補足情報(FW/ツールのバージョンなど)

Android Gradle Plugin Version 4.0.2
Gradle Version 6.1.1

gradle(抜粋)

1 compileSdkVersion 34 2 defaultConfig { 3 minSdkVersion 26 4 targetSdkVersion 34 5 versionCode 1 6 versionName "1.0" 7 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 8 consumerProguardFiles "consumer-rules.pro" 9 } 10 11 compileOptions { 12 sourceCompatibility JavaVersion.VERSION_1_8 13 targetCompatibility JavaVersion.VERSION_1_8 14 } 15 16 configurations.implementation { 17 exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8' 18 exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk7' 19}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

java

1public class USBLib 2{
<activity android:name=".USBLib"

USBLib クラスは Activity じゃないですね。


USBLib を AAR 化し、テスト用のアプリから使用するまでをやってみました。
使っているのは "Android Studio Flamingo | 2022.2.1 Patch 1" です。
どこか一箇所でも「これやってない」みたいな所が見つかると良いのですが…。

new project で "Phone and Tablet" の "Empty Views Activity" を選んで [Next] 、Name="q_kuopgz3a19cr8a" 、 package="com.teratail.q_kuopgz3a19cr8a" としました。(名前はこちらの都合でこのようにしているだけです。)

一通りプロジェクトの生成が終わったら、メニューから [New Module] を実行します。
New Module 選択

表示されたダイアログで "Android Library" を選択し、名前等を入力し [Finish]。
"Create New Module" Dialog

"app" と同じ高さにモジュールの名前のフォルダ ("usblib") が出来ますので、 app と usblib のそれぞれにコードを置いていきます。(AndroidManifest.xml は触りません。)
イメージ説明

app 側 (テストアプリ)
MainActivity.java

java

1package com.teratail.q_kuopgz3a19cr8a; 2 3import androidx.appcompat.app.AppCompatActivity; 4 5import android.os.Bundle; 6import android.widget.TextView; 7 8import com.teratail.usblib.USBLib; 9 10public class MainActivity extends AppCompatActivity { 11 @Override 12 protected void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 setContentView(R.layout.activity_main); 15 16 USBLib reader = new USBLib(); 17 reader.setContext(this); 18 19 TextView textView = findViewById(R.id.textView); 20 21 findViewById(R.id.button).setOnClickListener(v -> { 22 String dump; 23 try { 24 dump = reader.GetSts(); 25 } catch (Exception e) { 26 dump = e.getLocalizedMessage(); 27 } 28 textView.setText(dump); 29 }); 30 } 31}

res/layout/activity_main.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 tools:context=".MainActivity"> 8 9 <Button 10 android:id="@+id/button" 11 android:layout_width="wrap_content" 12 android:layout_height="wrap_content" 13 android:text="check" 14 app:layout_constraintBottom_toTopOf="@id/textView" 15 app:layout_constraintEnd_toEndOf="parent" 16 app:layout_constraintStart_toStartOf="parent" 17 app:layout_constraintTop_toTopOf="parent" /> 18 19 <TextView 20 android:id="@+id/textView" 21 android:layout_width="wrap_content" 22 android:layout_height="wrap_content" 23 android:textSize="30dp" 24 app:layout_constraintBottom_toBottomOf="parent" 25 app:layout_constraintEnd_toEndOf="parent" 26 app:layout_constraintStart_toStartOf="parent" 27 app:layout_constraintTop_toBottomOf="@id/button" /> 28 29</androidx.constraintlayout.widget.ConstraintLayout>

usblib 側 (ライブラリ)
USBLib.java

java

1package com.teratail.usblib; 2 3import android.content.Context; 4import android.hardware.usb.*; 5 6public class USBLib { 7 private Context myContext; 8 9 public int setContext(Context context) { 10 myContext = context; 11 return 0; 12 } 13 14 /* UnityPlayer クラスが無くてエラーになるためコメント化 15 public int setContext() { 16 int result = 0; 17 if (myContext == null) { 18 result = setContext(UnityPlayer.currentActivity.getApplicationContext()); 19 } 20 return result; 21 } 22 */ 23 24 public String GetSts() { 25 UsbManager manager = (UsbManager) myContext.getSystemService(Context.USB_SERVICE); 26 for (UsbDevice device : manager.getDeviceList().values()) { 27 return device.getDeviceName(); 28 } 29 return "nothing"; 30 } 31}

MainActiviry.java で USBLib のエラーが出るので、 "Gradle Scripts" の "build.gradle (Module :app)" 内の dependencies に以下を追加します。

implementation project(path: ':usblib')

これで、テストアプリを実行してボタンを押すと USB の最初の情報 ( もしくは "nothing") が表示されるはずです。( XperiaXZ3 Android10 で確認 )

Project で usblib を選択してメニューから [Make Module(~)] を実行すれば AAR ファイルが生成されました。
Make Module
イメージ説明
"-debug" と付いているのは build が debug だからです。 release にするには普通のアプリと同様に認証情報を入れないといけないかもしれません。

app 側 (テストアプリ) の AndroidManifest.xml の activity タグ (name=".MainActivity") 内に質問本文と同様に

xml

1 <intent-filter> 2 <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> 3 </intent-filter> 4 <meta-data 5 android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" 6 android:resource="@xml/device_filter" />

を入れ res/xml/device_filter.xml に手持ちの機器の情報を定義しましたら、選択確認後にテストアプリが起動できました。

投稿2023/11/02 06:57

編集2023/11/06 14:19
jimbe

総合スコア13318

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nrr-mgmg

2023/11/02 06:59

はい、Activityじゃないです。 USBLibをActivityにすると、別画面?が立ち上がるような動きになってうまく動作しないです。 設定か何かで複製されないようにしたりできますか?
nrr-mgmg

2023/11/02 07:47

後ライブラリなので画面ではないのでAcitivityは継承不要かなと ただAcitivityの機能を使いたいのでxmlは定義できるのかなと思うのですが違うのでしょうか? ※WindowsFormでFormの機能を利用したいときなどのような 違う場合はどうすれば回避できますでしょうか?
jimbe

2023/11/02 08:14

普通のアプリを作る環境を流用してモジュールを作っているのでしょうか。 モジュールの AndroidManifest には("アプリケーション"では無いのですから) Application タグは入らないはずです。 モジュールが特定のアクティビティの機能に依存するのであれば、それはモジュールでは無くアプリの一部として実装しなければならないのでは無いでしょうか。
nrr-mgmg

2023/11/06 01:29

最終的にはUnityで実装したいのですがUnity側(C#script?)で実装しないといけないということでしょうか? USBアクセスのタグを使う際の使用例がApplication~Activityのタグでしたのでそのようにしています。 Android歴がほとんどないのでよくわかっていないです。
jimbe

2023/11/06 04:22

私は逆に Unity は全く分かりません。 恐らく使用例として参考にされたものは、画面を含めた一つのアプリとして成っているものだと思います。その一部を AAR にして利用しようとするのならそのままではダメでしょう。 これを機に Android の AAR の作り方からお調べになっては如何でしょうか。
nrr-mgmg

2023/11/06 07:32

調べてもわからなかったのでここで質問している次第になります。
nrr-mgmg

2023/11/06 08:54

本件の問題とかけ離れている問答になっていると考えます。 aar事態は作成できています。
nrr-mgmg

2023/11/06 09:07

誤解しているように見えるので補足いたします。 調べても分からなかったに関してかかる箇所は 本題の話であってAARの作り方ではありません。
nrr-mgmg

2023/11/14 01:24

アプリ側に実装を義務付けすることでライブラリ側に記載がなくてもアクセスすることが出来ました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問