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

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

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

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

Android

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

Android Studio

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

Kotlin

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

Q&A

解決済

2回答

6113閲覧

android studioでkotlinでのCSV出力について

tomo01

総合スコア13

Java

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

Android

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

Android Studio

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

Kotlin

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

0グッド

0クリップ

投稿2019/01/13 05:48

編集2019/01/13 08:22

前提・実現したいこと

android studio で現在、こちらのサイト
https://qiita.com/seaka829/items/613d27035dab7b3a9121 
からibeaconからmajor、minor、RSSIを取得するアプリを作ったのですが、
取得したデータを保存する方法が分からなくて困っています。

作りたいと思っているものが、
時間ごと(1秒ごととか)に、取得したデータと日付を
自動でフォルダに保存するアプリです。

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

CSVファイルは作られたのですが、
最初に検知したデータしか入りません。
for文の位置が悪いのでしょうか?

該当のソースコード

package com.websarva.wings.android.beacon_kotlin import android.annotation.SuppressLint import android.content.Context import android.content.pm.PackageManager import android.os.* import android.support.v7.app.AppCompatActivity import android.support.annotation.RequiresApi import android.support.v4.app.INotificationSideChannel import android.util.Log import android.view.View import android.widget.TextView import android.widget.Toast import kotlinx.android.synthetic.main.activity_main.* import org.altbeacon.beacon.* import java.io.BufferedWriter import java.io.FileWriter import java.io.IOException import java.io.PrintWriter import java.util.* class MainActivity : AppCompatActivity(), BeaconConsumer { // BeaconManager型変数の宣言 private var beaconManager: BeaconManager? = null // uuidの指定 private val uuidString: String = "48534442-4C45-4144-80C0-180000000000" private val uuid = Identifier.parse(uuidString) // ビーコンのフォーマット設定 private val IBEACON_FORMAT: String = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24" private val handler: Handler = Handler() /************************************************** * AppCompatActivity内のメソッドをoverride **************************************************/ // onCreate @RequiresApi(Build.VERSION_CODES.ECLAIR) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // デバイスのBLE対応チェック if (!packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { // 未対応の場合、Toast表示 showToast("このデバイスはBLE未対応です", Toast.LENGTH_LONG) } // API 23以上かのチェック if (Build.VERSION.SDK_INT >= 23) { // パーミッションの要求 checkPermission() } // ビーコンマネージャのインスタンスを生成 beaconManager = BeaconManager.getInstanceForApplication(this) // BeaconManagerの設定 beaconManager!!.beaconParsers.add(BeaconParser().setBeaconLayout(IBEACON_FORMAT)) } // onResume override fun onResume() { super.onResume() // ビーコンサービスの開始 beaconManager!!.bind(this) } // onPause override fun onPause() { super.onPause() // ビーコンサービスの停止 beaconManager!!.unbind(this) } /************************************************** * BeaconConsumer内のメソッドをoverride **************************************************/ // onBeaconServiceConnect override fun onBeaconServiceConnect() { try { // ビーコン情報の監視を開始、第3,4引数はmajor・minor値を指定する時に使用 beaconManager!!.startMonitoringBeaconsInRegion(Region("48534442-4C45-4144-80C0-180000000000", uuid, null, null)) } catch (e: RemoteException) { e.printStackTrace() } // モニタリングの通知受取り処理 beaconManager!!.addMonitorNotifier(object : MonitorNotifier { // 領域内に侵入した時に呼ばれる override fun didEnterRegion(region: Region) { // レンジングの開始 beaconManager!!.startRangingBeaconsInRegion(region) } // 領域外に退出した時に呼ばれる override fun didExitRegion(region: Region) { // レンジングの停止 beaconManager!!.stopRangingBeaconsInRegion(region) } // 領域への侵入/退出のステータスが変化した時に呼ばれる override fun didDetermineStateForRegion(i: Int, region: Region) { // } }) // レンジングの通知受け取り処理 beaconManager!!.addRangeNotifier(object : RangeNotifier { // 範囲内のビーコン情報を受け取る override fun didRangeBeaconsInRegion(beacons: Collection<Beacon>, region: Region) { var maxMajor: Int? var maxMinor: Int? var maxrssi: Int? // 範囲内の複数のビーコン情報を保持させる変数 var getMajorList: ArrayList<Int> = ArrayList() var getMinorList: ArrayList<Int> = ArrayList() var getRssiList: ArrayList<Int> = ArrayList() // 範囲内にビーコンがある時の処理 if (beacons.size > 0) { // 範囲内のビーコンの数だけ繰り返す for (beacon in beacons) { // 複数のビーコン情報をArrayListに分割 getMajorList.add(beacon.id2.toInt()) getMinorList.add(beacon.id3.toInt()) getRssiList.add(beacon.rssi.toInt()) } // RSSIが最も大きいインデックスを取得 var indexRssi: Int = getRssiList.indexOf(getRssiList.max()) // 取得したインデックスのmajor値・minor値を取得 maxMajor = getMajorList[indexRssi] maxMinor = getMinorList[indexRssi] maxrssi = getRssiList[indexRssi] //パスの指定 val fw = FileWriter(Environment.getExternalStorageDirectory().getPath() + "/test.csv") //バッファリングによって文字列を効率的に書き込む val pw = PrintWriter(BufferedWriter(fw)) //内容を指定する pw.print(",") pw.print("MAJOR") pw.print(",") pw.print("MINOR") pw.print(",") pw.print("RSSI") pw.println() for (i in 1..4) { Log.d("Test_Major", maxMajor.toString()) Log.d("Test_Minor", maxMinor.toString()) Log.d("test_rssi", maxrssi.toString()) print(i) pw.print(",") pw.print(maxMajor.toString()) pw.print(",") pw.print(maxMinor.toString()) pw.print(",") pw.print(maxrssi.toString()) pw.println() } //ファイルに書き出す pw.close() handler.post { viewUpdate(maxrssi, maxMajor, maxMinor) } } } }) } /************************************************** * メソッド **************************************************/ // トースト表示のメソッド fun showToast(text: String, length: Int) { // トーストの生成と表示 var toast: Toast = Toast.makeText(this, text, length) toast.show() } @RequiresApi(Build.VERSION_CODES.M) fun checkPermission() { // パーミッション未許可の時 if (checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // パーミッションの許可ダイアログの表示 requestPermissions(arrayOf(android.Manifest.permission.ACCESS_COARSE_LOCATION), 0) } } //一番RRSIが強いmajorとminorの表示と保存 fun viewUpdate(rssi: Int?, major: Int?, minor: Int?) { // Viewの取得 val rssiTextView: TextView = findViewById(R.id.rssi) as TextView val majorTextView: TextView = findViewById(R.id.major) as TextView val minorTextView: TextView = findViewById(R.id.minor) as TextView majorTextView.text = "major:" + major minorTextView.text = "minor:" + minor rssiTextView.text = "RSSI:" + rssi + "dBm" } }

試したこと

for文の位置を変えたりしましたがうまくいきません。
現在のプログラムですと、同じ値が4つ保存される状況です。

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

android studio 3.2.1

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

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

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

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

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

keicha_hrs

2019/01/13 15:58 編集

このプログラムではWRITE_EXTERNAL_STORAGEの許可を得ていませんし、そもそも書き込みできないように見えますが。
tomo01

2019/01/14 00:07

manifestを載せていなくてすみません。 パーミッションでWRITE_EXTERNAL_STORAGEとREAD_EXTERNAL_STORAGEの記述はしました。
keicha_hrs

2019/01/14 02:23

それはAndroidManifest.xmlのuses-permissionタグによる記述の話でしょうか?それも必要ですが、ご提示のコード中にあるcheckSelfPermission()による確認とrequestPermissions()による権限取得も同じ要領で行う必要があります。
tomo01

2019/01/14 02:30

はい、uses-permissionタグのことでした。 MainActivityにも必要なんですね!調べて追記してみます。
keicha_hrs

2019/01/14 02:31

何ならそこも回答に追記します。
tomo01

2019/01/14 02:40

ありがとうございます!
guest

回答2

0

自己解決

FilwWriterの第2引数にtrueを追加することで、追記することができました。

投稿2019/01/22 03:31

tomo01

総合スコア13

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

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

0

追記・修正依頼に書いたコメントは別として、「同じ値が4つ保存される」ということについては、for文の中でmaxMajor、maxMinor、maxrssiが一度も変化していないからでしょう。これでは「同じ値が4つ」になるのは必然です。

kotlin

1 for (i in 1..4) { 2 maxMajor = 書き込みたいInt値 3 maxMinor = 書き込みたいInt値 4 maxrssi = 書き込みたいInt値 5 6 Log.d("Test_Major", maxMajor.toString()) 7 Log.d("Test_Minor", maxMinor.toString()) 8 Log.d("test_rssi", maxrssi.toString()) 9 10 print(i) 11 pw.print(",") 12 pw.print(maxMajor.toString()) 13 pw.print(",") 14 pw.print(maxMinor.toString()) 15 pw.print(",") 16 pw.print(maxrssi.toString()) 17 pw.println() 18 }

のようにして、ループを回る度に新たに書き込みたい値を得る記述が必要ではありませんか。


(01/14 12:00追記)
現状のコードにあるACCESS_COARSE_LOCATION権限の確認・取得に加えて、端末の内部ストレージへの書き込み権限を確認・取得するには、

kotlin

1 // パーミッション未許可の時 2 if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || 3 checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 4 5 // パーミッションの許可ダイアログの表示 6 requestPermissions( 7 arrayOf( 8 android.Manifest.permission.WRITE_EXTERNAL_STORAGE, 9 android.Manifest.permission.ACCESS_COARSE_LOCATION 10 ), 0 11 ) 12 }

のように記述してください。これで、今まで取得していた位置情報と合わせて両方の権限の確認と取得ができます。

それから余談なのですが、書き込み記述について。恐らく書き込みたい値はgetMajorList[]、getMinorList[]、getRssiList[]から得られる値なのだろうと思います(違ったらすみません)。それならば

kotlin

1 for (i in 0..3) { 2 val major = getMajorList[i].toString() 3 val minor = getMinorList[i].toString() 4 val rssi = getRssiList[i].toString() 5 6 Log.d("Test_Major", major) 7 Log.d("Test_Minor", minor) 8 Log.d("test_rssi", rssi) 9 10 pw.println("${i + 1},$major,$minor,$rssi") 11 }

(01/14 21:40 コード訂正)

のように簡潔に書けるはずです。Kotlinには、文字列の中に"${式}"と記述する(変数名のみならば{}は不要)と、式がInt型などであったとしても適切な文字列に変換される機能があります。

投稿2019/01/13 16:09

編集2019/01/14 12:42
keicha_hrs

総合スコア6766

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

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

tomo01

2019/01/14 07:00

ありがとうございます。 はい、書き込みたい値はその3つです。 実際にmainactivityのpermission の記述と、for文の書き換えをしましたが、まだ、書き込みがうまくいっていないようです。一番初めに取得したデータのみ記述して、終わってしまっています。 ``` // レンジングの通知受け取り処理 beaconManager!!.addRangeNotifier(object : RangeNotifier { // 範囲内のビーコン情報を受け取る override fun didRangeBeaconsInRegion(beacons: Collection<Beacon>, region: Region) { //パスの指定 var maxMajor: Int? var maxMinor: Int? var maxrssi: Int? // 範囲内の複数のビーコン情報を保持させる変数 var getMajorList: ArrayList<Int> = ArrayList() var getMinorList: ArrayList<Int> = ArrayList() var getRssiList: ArrayList<Int> = ArrayList() // 範囲内にビーコンがある時の処理 if (beacons.size > 0) { // 範囲内のビーコンの数だけ繰り返す for (beacon in beacons) { // 複数のビーコン情報をArrayListに分割 getMajorList.add(beacon.id2.toInt()) getMinorList.add(beacon.id3.toInt()) getRssiList.add(beacon.rssi.toInt()) } // RSSIが最も大きいインデックスを取得 var indexRssi: Int = getRssiList.indexOf(getRssiList.max()) // 取得したインデックスのmajor値・minor値を取得 maxMajor = getMajorList[indexRssi] maxMinor = getMinorList[indexRssi] maxrssi = getRssiList[indexRssi] val fw = FileWriter(Environment.getExternalStorageDirectory().getPath() + "/test.csv") //バッファリングによって文字列を効率的に書き込む val pw = PrintWriter(BufferedWriter(fw)) //内容を指定する pw.print(",") pw.print("MAJOR") pw.print(",") pw.print("MINOR") pw.print(",") pw.print("RSSI") pw.println() for (i in 0..indexRssi) { val maxMajor = getMajorList[i].toString() val maxMinor = getMinorList[i].toString() val maxrssi = getRssiList[i].toString() Log.d("Test_Major", maxMajor) Log.d("Test_Minor", maxMinor) Log.d("test_rssi", maxrssi) pw.println("${i + 1},$maxMajor,$maxMinor,$maxrssi") } pw.close() handler.post { viewUpdate(maxrssi, maxMajor, maxMinor) } } } }) ```
keicha_hrs

2019/01/14 10:22 編集

> 一番初めに取得したデータのみ記述して、終わってしまっています。 私はindexRssiで得られた回数分回したいのかと思ったのですが、勘違いだったでしょうか?変数の中にmaxと付いているのだから、配列中で一番大きな値を得たかったのかな?配列には必ず4つのデータが入っていて、書き込みのためのループも4回固定で回したかったということでしょうか?
tomo01

2019/01/14 11:41

説明不足ですみません。 仰る通り、indexRssiで得られただけ記録がしたいです。 4つはサンプルとして正しく動いてるか調べるためだけの数でした。
keicha_hrs

2019/01/14 12:45

getMajorList、getMinorList、getRssiListの各リストに入っているデータをそれぞれ頭から4つ書き込む、という前提で例示コードを書き直してみました。こういうことでいいのでしょうかね?ただ、これは各リストに4つ以上データが存在している必要があります。配列範囲外をアクセスをすると、例外が発生してアプリが落ちます。
tomo01

2019/01/21 08:37

日にちがかなり経過してしまい、大変申し訳ないのですが、もう少し助言をお願いします。 あれから自分で考えてやってみましたがうまくいきませんでした。 目標としているCSVファイルの完成予想の表が、     MAJOR MINOR RSSI 1 1 40 -70 2 1 40 -69 3 1 40 -71 4 2 50 -65 5 2 50 -62 . . . . . . . . . . . . のように得られたデータが更新されるごとに書き込んでいくようにしたいです。 あと、 前回の回答で、for文のiの値の範囲をそのまま数字にしてしまうと、 配列範囲外になってしまうということはどういうことなのでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問