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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Android Studio

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

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

1回答

544閲覧

ビーコン受信開始をボタンのクリックで実行するには?

yuko0524

総合スコア28

Android Studio

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

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2019/02/12 05:06

編集2019/02/12 05:08

いつもお世話になっております。

以前、似たような質問を上げましたが、質問の仕方が適切ではなかったので閉じた経緯がありました。
今回は自分なりに調べたりトライした上で質問させていただきますのでよろしくお願いします。
(ソース全てを貼り付けたら、文字数オーバーとなってしまいましたので、部分的にソースを割愛しています。)

【目的】付近にあるビーコンをアンドロイド端末で受信して、情報をログに出力する(強度の強い順にMAX3つのビーコン)。

【方法】端末画面にて、ドロップダウンリスト(1~25の番号表示)から1つ選択し、[START]ボタンをクリックすると受信開始し、
[STOP]ボタンクリックで受信を終了する。

【現状】アプリを起動と同時に電波受信開始、アプリ終了で受信終了。
ドロップダウンリストは表示&選択できる状態。ボタンは画面に配置したが、まだ機能はつけていない。

※ソースの下に、実現したいことを記載しています。

Kotlin

1package com.example.*****.myapplication 2import android.Manifest 3//***割愛します****// 4567import org.altbeacon.beacon.* 8 9@Suppress("DEPRECATION") 10class MainActivity : AppCompatActivity() ,BeaconConsumer { 11 12 // BeaconManager型変数の宣言 13 private var beaconManager: BeaconManager? = null 14 15 // uuidの指定 16 private val uuidString = "FDA50693-A4E2-4FB1-AFCF-C6EB07647825" 17 private val uuid = Identifier.parse(uuidString) 18 19 // ビーコンのフォーマット設定 20 private val IBEACON_FORMAT: String = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24" 21 22 // Handlerクラスの変数の宣言(追加) 23 private val handler: Handler = Handler() 24 25 // 選択肢 26 private val spinnerItems = arrayOf("1", "2", "3", "4" , "5" ,"6" , "7" , "8", "9" , "10" , 27 "11" , "12" , "13" , "14", "15", "16", "17", "18", "19", "20", "21", "22","23","24","25") 28 29 /************************************************** 30 * AppCompatActivity内のメソッドをoverride 31 **************************************************/ 32 // onCreate 33 @SuppressLint("HardwareIds") 34 override fun onCreate(savedInstanceState: Bundle?) { 35 super.onCreate(savedInstanceState) 36 setContentView(R.layout.activity_main) 37 38 //-------------------------------------------------------------------------// 39 // ArrayAdapter 40 val adapter = ArrayAdapter(applicationContext, 41 android.R.layout.simple_spinner_item, spinnerItems) 42 43 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) 44 45 // spinner に adapter をセット 46 spinner.adapter = adapter 47 48 // リスナーを登録 49 spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{ 50 // アイテムが選択された時 51 override fun onItemSelected(parent: AdapterView<*>?, 52 view: View?, position: Int, id: Long) { 53 val spinnerParent = parent as Spinner 54 val item = spinnerParent.selectedItem as String 55 // Kotlin Android Extensions 56 textView.text = item 57 val fileName = "logfile" + item + ".txt" 58 Log.d("Rssi_===fileName===", "$fileName") 59 60 } 61 62 // アイテムが選択されなかった時 63 override fun onNothingSelected(parent: AdapterView<*>?) { 64 // 65 } 66 } 67 //-----------------------------------------------------------------------------// 68 // デバイスのBLE対応チェック 69 if (!packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { 70 71 // 未対応の場合、Toast表示 72 showToast("このデバイスはBLE未対応です", Toast.LENGTH_LONG) 73 } 74 75 // API 23以上かのチェック 76 if (Build.VERSION.SDK_INT >= 23) { 77 // パーミッションの要求 78 checkPermission() 79 } 80 // ビーコンマネージャのインスタンスを生成 81 beaconManager = BeaconManager.getInstanceForApplication(applicationContext) 82 83 // BeaconManagerの設定 84 beaconManager!!.beaconParsers.add(BeaconParser().setBeaconLayout(IBEACON_FORMAT)) 85 86 } 87 88 // onResume 89 override fun onResume() { 90 super.onResume() 91 92 // ビーコンサービスの開始 93 beaconManager!!.bind(this) 94 } 95 96 // onPause 97 override fun onPause() { 98 super.onPause() 99 100 // ビーコンサービスの停止 101 beaconManager!!.unbind(this) 102 } 103 104 override fun onBackPressed() { 105 // バックキーの無効化 106 moveTaskToBack (true) 107 } 108 109 110 /************************************************** 111 * BeaconConsumer内のメソッドをoverride 112 **************************************************/ 113 // onBeaconServiceConnect 114 override fun onBeaconServiceConnect() { 115 116 try { 117 // ビーコン情報の監視を開始、第3,4引数はmajor・minor値を指定する時に使用 118 beaconManager!!.startMonitoringBeaconsInRegion(Region("beacon-test", uuid, null, null )) 119 } catch (e: RemoteException) { 120 e.printStackTrace() 121 } 122 123 // モニタリングの通知受取り処理 124 beaconManager!!.addMonitorNotifier(object : MonitorNotifier { 125 126 // 領域内に侵入した時に呼ばれる 127 override fun didEnterRegion(region: Region) { 128 129 // レンジングの開始 130 beaconManager!!.startRangingBeaconsInRegion(region) 131 } 132 133 // 領域外に退出した時に呼ばれる 134 override fun didExitRegion(region: Region) { 135 136 // レンジングの停止 137 beaconManager!!.stopRangingBeaconsInRegion(region) 138 } 139 140 // 領域への侵入/退出のステータスが変化した時に呼ばれる 141 override fun didDetermineStateForRegion(i: Int, region: Region) { 142 // 143 } 144 }) 145 146 // レンジングの通知受け取り処理 147 beaconManager!!.addRangeNotifier { beacons, _ -> 148 149 // 範囲内のビーコン情報を受け取る 150 151 //***ここからしばらく処理のコードがありますが長いので割愛します****// 152 153 // 携帯端末固有ID 154 val deviceId = Settings.Secure.getString(this.getContentResolver(), Settings.System.ANDROID_ID); 155 Log.d("Rssi_0_Maj_Min_Dis_Rs", "$deviceId,$maxName0,$maxMajor0,$maxMinor0,$maxDistance0,$maxRssi0") 156 Log.d("Rssi_1_Maj_Min_Dis_Rs", "$deviceId,$maxName1,$maxMajor1,$maxMinor1,$maxDistance1,$maxRssi1") 157 Log.d("Rssi_2_Maj_Min_Dis_Rs", "$deviceId,$maxName2,$maxMajor2,$maxMinor2,$maxDistance2,$maxRssi2") 158 159 160 // メインスレッドで実装(追加) 161 handler.post { 162 // 空の引数を渡して、Viewの更新 163 //***割愛します****// 164 ) 165 } 166 167 // Viewの更新 168 viewUpdate( 169//***割愛します****// 170 ) 171 } 172 } 173 } 174 175 private fun viewUpdate( 176//***割愛します****// 177 178 ) 179 { 180 181 // Viewの取得 182//***割愛します****// 183 } 184 185 186 /************************************************** 187 * メソッド 188 **************************************************/ 189 // トースト表示のメソッド 190//***割愛します****// 191 192 // パーミッションの許可チェック 193//***割愛します****// 194} 195 196

【実現したいこと】
下記の順番で処理を実行させたい。
1.アプリ起動。
2.ドロップダウンリストにて選択。
3.[START]ボタンクリックで電波受信開始。
4.任意の時間、電波収集
5.[STOP]ボタンクリックで受信終了。

今は、アプリ起動と同時に電波受信が始まります。
実際そのようなコードになっているのだと思いますが、
上記2、3、5の処理をソース中のどこに入れたら良いのかがわかりません。
ボタンのリスナー(まだコードに書いていませんが)を、
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
の下に書いたりしましたが、異常終了してしまいました。
また、//----------------//で挟みましたが、
spinnerのリスナーの場所もそこが正しいのでしょうか。

以上になります。
長々とした質問となり申し訳ございません。
ご教示のほどよろしくお願いいたします。

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

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

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

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

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

jimbe

2019/02/12 16:56

> 今は、アプリ起動と同時に電波受信が始まります。 はい, 実際そのようなコードになっております. Activity のライフサイクルについてお調べになると良いかと思います.
jimbe

2019/02/12 17:36

若干違和感のあるコードと思いまして検索致しました. ↓で提示されているコードを改造されようということでしょうか. https://qiita.com/seaka829/items/613d27035dab7b3a9121 権利云々ということも無いかと思いますが, 元にされたのでしたら, リンクを付けておいて頂けると参考になると思います.
guest

回答1

0

ベストアンサー

altbeacon の使い方を知らないので失礼しますが, ご質問の内容はビーコンと直接関係無さそうに思います.
まずビーコンに関する処理の実装を別クラスとしておいてダミーを用意し, 画面関係を作られては如何でしょうか.
それによってコード量が減少し動作する状態でのご提示を頂けるようになれば, 回答も得やすくなるものと考えます.


追記・修正依頼と回答が逆になってしまいました. 失礼しました.

一般的にはリスナーの登録などは onCreate 内で行われると思います.
この場合のスピナーやボタンのリスナーの登録も, 同様かと思います.
しかし, ボタンのリスナーを登録したことによる異常終了に関しましては, コードがなければ判断できません.

今は、アプリ起動と同時に電波受信が始まります。

実際そのようなコードになっております.
Activity のライフサイクルについてお調べになると良いかと思います.

投稿2019/02/12 16:23

編集2019/02/12 17:56
jimbe

総合スコア12632

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

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

yuko0524

2019/02/14 03:20 編集

ご指摘いただきありがとうございました。 ライフサイクルもネットや本で読みましたが、 コーディングでどう表現すればよいのかまだ消化しきれていない状態です。 その後やったこととして、 spinnerのリスナーを登録したあと、 (//----------------------------//以下にて、) spinnerと同レベルで[START]ボタンと[STOP]ボタンのリスナーを登録しました。 その各ボタンのリスナーの中に、 //--ビーコンサービスの開始 super.onResume() beaconManager!!.bind(this) や、 //--ビーコンサービスの停止 super.onPause() beaconManager!!.unbind(this) を入れて実行してみました。 そして、 override fun onResume() やoverride fun onPause()が書いてある行は コメントアウトしました。 結果ですが、 スタートボタンで電波受信開始し、ストップで受信停止できました。 ただ、この状態からさらに受信再開するとき、スタートボタンは効きませんでした。 オペレーション的には、アプリを終了させるまではボタン操作で受信と停止を繰り返したいと 考えています。 実現するには、どのようなコーディングをすれば良いのでしょうか。 スキルがまだまだ浅くて申し訳ございません・・・
jimbe

2019/02/14 03:43

ライフサイクルをご存知でしたら「アプリ起動と同時に電波受信が始まる」のはお分かりになるはずです. つまり, アプリ起動時に onCreate 等の後に onResume が呼ばれるため, beaconManager!!.bind(this) が実行されているということになります. ボタンのリスナーは登録でき, 動作し始めておられるようですが, super.onResume(), super.onPause() は入れてはいけないモノです. super.onResume(), super.onPause() は基本的に override した onResume, onPause メソッドで呼ぶもので, その動作如何に関わらずテキトウに呼ぶものではありません. (開始/停止のコメントは bnd/unbind に付けられたもので, super.onXXX は含まれていないはずです.) これらの super なメソッドを何故呼ぶのかについてもお調べになられますようお勧め致します. > スタートボタンは効きませんでした とはどういう状況でしょうか. グレーアウトして押せないのでしょうか. 押せるけれども開始(再開)していないのでしょうか. ボタンのリスナー内で bind が実行されているのはご確認済みでしょうか. スキルがまだまだ…と卑下する必要もお謝りになる必要も御座いません. どの方とも, 量的なものは全世界の全量に比べれば対した違いではありません. ただ, 「名所を見に行きたいと言う方にガイドブックを渡したら『行けませんでした』と言われた」では, 何か起きたのか, どうすれば良いのか分かりません. 方向音痴だったのか, 地図が読めなかったのか, 道が工事等で変わってしまっていたのか, 行きたい名所が載ってなかったのか, ガイドブックが違う地域のものだったのか, もしや外国の方で文字が読めなかったのか…. (極端な事も含めて)色々考えられますので, どうしても次々に色々お聞きしお話することになってしまいます.
yuko0524

2019/02/14 05:46

毎回、ご丁寧にお付き合いいただきまして本当にありがとうございます。 確かに質問の仕方がガサツでした。大変失礼いたしました。 乱暴なソースの書き方をしてるのは、Android開発が初心者であること、 java、Kotlinも初心者であること、にも関わらず短納期で作ってほしいという要求に応えようと あちこちサイトを駆けずり回って質問を投げて、という感じで進めているせいだと思います。 (それはこちらの勝手な都合であります) 本当はオブジェクト指向とは?から勉強しないといけないレベルだと思います。 基礎知識もないのに作ろうとしているので、質問も的確になっていないのだと思います。 申し訳ございません… > スタートボタンは効きませんでした これは、ボタンは押せるのですが(logcatで確認済み)、電波受信が始まらない状態です。 以下のようなコードになります。(onResumeを呼ばないように修正しました) // リスナーをボタンに登録 button.setOnClickListener { Log.d("Rssi_***button : ","START_button***") // ***ビーコンサービスの開始*** beaconManager!!.bind(this) } // リスナーをボタン2に登録 button2.setOnClickListener { Log.d( "Rssi_***button : ","STOP_button***") // ***ビーコンサービスの停止*** beaconManager!!.unbind(this) } 上記のコードですと、起動時して1回目のSTART、STOPは有効なのですが、 続けて2回目からのSTARTボタンを押しても受信開始しません。 ライフサイクル、onResume, onPauseを入れる場所、ビーコンサービスを呼ぶタイミング、 これらの理解がかみ合っていないのだと思います。 ネットでも色々見て回りましたが、いざ自分のソースで実現しようとするといまひとつピンときません。 アプリ起動→(1)STARTボタンで受信開始→(2)STOPボタンで受信停止。 (1)→(2)を好きなだけ繰り返し、任意のタイミングでアプリ終了。 このような流れを実現させたいのですが、どのような順序でコーディングすればよろしいでしょうか。
jimbe

2019/02/14 09:31

start ボタンを押して beaconManager!!.bind(this) で実行され, stop ボタンを押して beaconManager!!.unbind(this) しているのであれば, 2度目の start(bind) で動かないのは beaconManager 内で何か起きている(ガードしている?)と思われます. onBeaconServiceConnect メソッドで行っている中には startXxx というのが多くありますので, もしかすると unbind 時に stopXxx という対応するようなメソッドを呼ばなくてはならない等があるのかもしれません. そのような記述を探していますが, 見つかっておりません. beaconManager からの(1度目と異なる)ログメッセージは logcat に出ていないでしょうか. もしくは 1度目に出ていて2度目に出ていないメッセージはありませんでしょうか.
yuko0524

2019/02/21 07:08 編集

ログも調べましたが、ご指摘の内容は残念ながら見つけられずじまいでした。 結局、STARTボタンで受信開始し、STOPで終了し、アプリも終了、という流れで完結して 続けて受信したいときは、再度アプリ起動→STARTボタンで受信開始し、 受信内容のファイルは前回のものに追加して書き込む、という手段でいくことにしました。 この度は誠にありがとうございました。 初歩的なところのソースの書き方なども勉強になりました。 もっと精進いたします。
jimbe

2019/02/21 07:19

左様でしたか, 私も残念です. もし今後私も beacon を使うようなことがありましたら, また調査してみたいと思います.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問