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

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

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

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

Q&A

解決済

1回答

1658閲覧

Kotlinでapi接続の勉強中に出てきたエラーを解決できない。

mokimokio

総合スコア53

Kotlin

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

0グッド

0クリップ

投稿2022/04/06 09:59

現在AndroidStudioでKotlinを使って勉強しているものです。

天気予報のAPIを使ってネットから天気情報を取り込みたいと考えていました。その中で発生したエラーを解決する手立てが見つかりません。

APIのキーはこの場では空文字にしています。

Kotlin

1import android.content.Intent 2import android.os.Bundle 3import android.util.Log 4import android.view.View 5import androidx.appcompat.app.AppCompatActivity 6import android.widget.* 7import androidx.annotation.UiThread 8import androidx.annotation.WorkerThread 9import androidx.core.os.HandlerCompat 10import org.json.JSONObject 11import java.io.BufferedReader 12import java.io.InputStream 13import java.io.InputStreamReader 14import java.net.HttpURLConnection 15import java.net.SocketTimeoutException 16import java.util.concurrent.Executors 17import android.os.Handler 18import android.widget.AdapterView 19import android.widget.ListView 20import android.widget.SimpleAdapter 21import android.widget.TextView 22 23 24class kintaikiroku_page : AppCompatActivity() { 25 26 // クラス内のprivate定数を宣言するためにcompanion objectブロックとする。 27 companion object { 28 /** 29 * ログに記載するタグ用の文字列。 30 */ 31 private const val DEBUG_TAG = "AsyncSample" 32 /** 33 * お天気情報のURL。 34 */ 35 private const val WEATHERINFO_URL = "https://api.openweathermap.org/data/2.5/weather?lang=ja" 36 /** 37 * お天気APIにアクセスすするためのAPI Key。 38 * ※※※※※この値は各自のものに書き換える!!※※※※※ 39 */ 40 private const val APP_ID = "" 41 } 42 43 /** 44 * リストビューに表示させるリストデータ。 45 */ 46 private var _list: MutableList<MutableMap<String, String>> = mutableListOf() 47 48 49 50 51 override fun onCreate(savedInstanceState: Bundle?) { 52 super.onCreate(savedInstanceState) 53 setContentView(R.layout.activity_kintaikiroku_page) 54 55 56 _list = ⭐️createList() 57 58 val lvCityList = findViewById<ListView>(R.id.kintaikiroku_list) 59 val from = arrayOf("name") 60 val to = intArrayOf(android.R.id.text1) 61 val adapter = SimpleAdapter(this@kintaikiroku_page, _list, android.R.layout.simple_list_item_1, from, to) 62 lvCityList.adapter = adapter 63 lvCityList.onItemClickListener = ⭐️ListItemClickListener() 64 65 66 67 68 /** 69 * リストビューに表示させる天気ポイントリストデータを生成するメソッド。 70 * 71 * @return 生成された天気ポイントリストデータ。 72 */ 73 fun createList(): MutableList<MutableMap<String, String>> { 74 var list: MutableList<MutableMap<String, String>> = mutableListOf() 75 76 var city = mutableMapOf("name" to "大阪", "q" to "Osaka") 77 list.add(city) 78 city = mutableMapOf("name" to "神戸", "q" to "Kobe") 79 list.add(city) 80 city = mutableMapOf("name" to "京都", "q" to "Kyoto") 81 list.add(city) 82 city = mutableMapOf("name" to "大津", "q" to "Otsu") 83 list.add(city) 84 city = mutableMapOf("name" to "奈良", "q" to "Nara") 85 list.add(city) 86 city = mutableMapOf("name" to "和歌山", "q" to "Wakayama") 87 list.add(city) 88 city = mutableMapOf("name" to "姫路", "q" to "Himeji") 89 list.add(city) 90 91 return list 92 } 93 94 95 96 /** 97 * お天気情報の取得処理を行うメソッド。 98 * 99 * @param url お天気情報を取得するURL。 100 */ 101 @UiThread 102 fun receiveWeatherInfo(urlFull: String) { 103 val handler = HandlerCompat.createAsync(mainLooper) 104 val backgroundReceiver = WeatherInfoBackgroundReceiver(handler, urlFull) 105 val executeService = Executors.newSingleThreadExecutor() 106 executeService.submit(backgroundReceiver) 107 } 108 109 110 111 112 /** 113 * 非同期でお天気情報APIにアクセスするためのクラス。 114 * 115 * @param handler ハンドラオブジェクト。 116 * @param url お天気情報を取得するURL。 117 */ 118 class WeatherInfoBackgroundReceiver(handler: Handler, url: String): Runnable { 119 /** 120 * ハンドラオブジェクト。 121 */ 122 private val _handler = handler 123 /** 124 * お天気情報を取得するURL。 125 */ 126 private val _url = url 127 128 @WorkerThread 129 override fun run() { 130 // 天気情報サービスから取得したJSON文字列。天気情報が格納されている。 131 var result = "" 132 // URLオブジェクトを生成。 133 val url = URL(_url) 134 // URLオブジェクトからHttpURLConnectionオブジェクトを取得。 135 val con = url.openConnection() as? HttpURLConnection 136 // conがnullじゃないならば… 137 con?.let { 138 try { 139 // 接続に使ってもよい時間を設定。 140 it.connectTimeout = 1000 141 // データ取得に使ってもよい時間。 142 it.readTimeout = 1000 143 // HTTP接続メソッドをGETに設定。 144 it.requestMethod = "GET" 145 // 接続。 146 it.connect() 147 // HttpURLConnectionオブジェクトからレスポンスデータを取得。 148 val stream = it.inputStream 149 // レスポンスデータであるInputStreamオブジェクトを文字列に変換。 150 result = is2String(stream) 151 // InputStreamオブジェクトを解放。 152 stream.close() 153// result = is2String(it.inputStream) 154// it.inputStream.close() 155 } 156 catch(ex: SocketTimeoutException) { 157 Log.w(DEBUG_TAG, "通信タイムアウト", ex) 158 } 159 // HttpURLConnectionオブジェクトを解放。 160 it.disconnect() 161 } 162 val postExecutor = ⭐️WeatherInfoPostExecutor(result) 163 _handler.post(postExecutor) 164 } 165 166 /** 167 * InputStreamオブジェクトを文字列に変換するメソッド。 変換文字コードはUTF-8。 168 * 169 * @param stream 変換対象のInputStreamオブジェクト。 170 * @return 変換された文字列。 171 */ 172 private fun is2String(stream: InputStream): String { 173 val sb = StringBuilder() 174 val reader = BufferedReader(InputStreamReader(stream, "UTF-8")) 175 var line = reader.readLine() 176 while(line != null) { 177 sb.append(line) 178 line = reader.readLine() 179 } 180 reader.close() 181 return sb.toString() 182 } 183 } 184 185 186 187 188 /** 189 * 非同期でお天気情報を取得した後にUIスレッドでその情報を表示するためのクラス。 190 * 191 * @param result Web APIから取得したお天気情報JSON文字列。 192 */ 193 class ⭐️WeatherInfoPostExecutor(result: String): Runnable { 194 /** 195 * 取得したお天気情報JSON文字列。 196 */ 197 private val _result = result 198 199 @UiThread 200 override fun run() { 201 // ルートJSONオブジェクトを生成。 202 val rootJSON = JSONObject(_result) 203 // 都市名文字列を取得。 204 val cityName = rootJSON.getString("name") 205 // 緯度経度情報JSONオブジェクトを取得。 206 val coordJSON = rootJSON.getJSONObject("coord") 207 // 緯度情報文字列を取得。 208 val latitude = coordJSON.getString("lat") 209 // 経度情報文字列を取得。 210 val longitude = coordJSON.getString("lon") 211 // 天気情報JSON配列オブジェクトを取得。 212 val weatherJSONArray = rootJSON.getJSONArray("weather") 213 // 現在の天気情報JSONオブジェクトを取得。 214 val weatherJSON = weatherJSONArray.getJSONObject(0) 215 // 現在の天気情報文字列を取得。 216 val weather = weatherJSON.getString("description") 217 // 画面に表示する「〇〇の天気」文字列を生成。 218 val telop = "${cityName}の天気" 219 // 天気の詳細情報を表示する文字列を生成。 220 val desc = "現在は${weather}です。\n緯度は${latitude}度で経度は${longitude}度です。" 221 // 天気情報を表示するTextViewを取得。 222 val tvWeatherTelop = findViewById<TextView>(R.id.tvWeatherTelop) 223 val tvWeatherDesc = findViewById<TextView>(R.id.tvWeatherDesc) 224 // 天気情報を表示。 225 tvWeatherTelop.text = telop 226 tvWeatherDesc.text = desc 227 } 228 } 229 230 231 232 /** 233 * リストがタップされた時の処理が記述されたリスナクラス。 234 */ 235 class ListItemClickListener: AdapterView.OnItemClickListener { 236 override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) { 237 val item = _list.get(position) 238 val q = item.get("q") 239 q?.let { 240 val urlFull = "$WEATHERINFO_URL&q=$q&appid=$APP_ID" 241 receiveWeatherInfo(urlFull) 242 } 243 } 244 } 245 } 246} 247

エラー箇所は以上の4点です。(下記まとめました)
_list = ⭐️createList()
エラー内容⬇︎
Unresolved reference: createList

⭐️ListItemClickListener()
エラー内容⬇︎
Unresolved reference: ListItemClickListener

⭐️WeatherInfoPostExecutor(result)
エラー内容⬇︎
Unresolved reference: WeatherInfoBackgroundReceiver

class ⭐️WeatherInfoPostExecutor(result: String): Runnable {
エラー内容⬇︎
Unresolved reference: WeatherInfoPostExecutor

どれも同じ内容のエラーが出ているのですがこれを解決するコードを教えてください。わかる方よろしくお願いします><。

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

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

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

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

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

hoshi-takanori

2022/04/06 10:08

onCreate メソッドの中に他の関数やクラスを書いてるのはなぜでしょうか?
mokimokio

2022/04/08 01:03

初歩的なミスでした>< 無事に解決しました!ありがとうございます!
guest

回答1

0

自己解決

質問に書いていただいたコメントにより解決しました!
onCreate メソッドの中に他の関数やクラスを書いてるためこのようなバグが発生していました!

投稿2022/04/08 01:04

mokimokio

総合スコア53

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問