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

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

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

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

Android

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

Android Studio

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

Kotlin

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

Q&A

解決済

1回答

2332閲覧

Kotlinでのhttp通信のテストでのエラー

luke04

総合スコア7

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

Android

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

Android Studio

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

Kotlin

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

0グッド

0クリップ

投稿2019/10/08 10:16

kotlinでandroid開発を勉強している初心者です。
書籍を参考にhttp通信を用いてlivedoorから天気情報を取得して表示させたいのですが、実行してみると繰り返し停止しますというエラーが出て強制終了してしまいます。以下がエラーが出るMainActivity.ktのコードです。実行は実機で、Galaxy S9です。
エラー内容はListItemClickLister内に二つ、WeatherInfoReceiver内に一つで、コメントとして書きました。ご回答よろしくお願いします。

Kotlin

1package com.example.asynksample 2 3import android.os.AsyncTask 4import androidx.appcompat.app.AppCompatActivity 5import android.os.Bundle 6import android.view.View 7import android.widget.AdapterView 8import android.widget.ListView 9import android.widget.SimpleAdapter 10import android.widget.TextView 11import org.json.JSONObject 12import java.io.BufferedReader 13import java.io.InputStream 14import java.io.InputStreamReader 15import java.net.HttpURLConnection 16import java.net.URL 17 18class MainActivity : AppCompatActivity() { 19 20 override fun onCreate(savedInstanceState: Bundle?) { 21 super.onCreate(savedInstanceState) 22 setContentView(R.layout.activity_main) 23 24 //画面部品ListViewを取得 25 val lvCityList = findViewById<ListView>(R.id.lvCityList) 26 //SimpleAdapterで使用するMutableListオブジェクトを用意 27 val cityList: MutableList<MutableMap<String, String>> = mutableListOf() 28 //都市データを格納するMutableMapオブジェクトの用意とcityListへのデータ登録 29 val city = mutableMapOf("name" to "東京","id" to "130010") 30 cityList.add(city) 31 //SimpleAdapterで使用するfrom-to用変数の用意 32 val from = arrayOf("name") 33 val to = intArrayOf(android.R.id.text1) 34 //SimpleAdapterを生成 35 val adapter = SimpleAdapter(applicationContext, cityList, android.R.layout.simple_expandable_list_item_1, from, to) 36 //ListViewにSimpleAdapterを設定 37 lvCityList.adapter = adapter 38 //リストタップのリスナクラス登録 39 lvCityList.onItemClickListener = ListItemClickListener() 40 } 41 42 //リストがタップされたときの処理が記述されたメンバクラス 43 private inner class ListItemClickListener : AdapterView.OnItemClickListener { 44 override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) { 45 //ListViewでタップされた行の都市名と都市IDを取得 46 val item = parent.getItemAtPosition(position) as Map<String,String> //(警告)Unchecked cast: Any! to Map<String, String> 47 val cityName = item["name"] 48 val cityId = item["id"] 49 //取得した都市名をtvCityNameに設定 50 val tvCityName = findViewById<TextView>(R.id.tvCityName) 51 tvCityName.setText(cityName + "の天気:") //エラー: Use of setter method insted of property access syntax 52 //WeatherInfoReceiverインスタンスを生成 53 val receiver = WeatherInfoReceiver() 54 //WeatherInfoReceiverを実行 55 receiver.execute(cityId) 56 } 57 } 58 59 private inner class WeatherInfoReceiver : AsyncTask<String, String, String>() { //(警告)This AsyncTask class should be static or leaks might occur 60 override fun doInBackground(vararg params: String): String { 61 //可変長引数の1個目(インデックス0)を取得。これが都市ID 62 val id = params[0] 63 //都市IDを使って接続URL文字列を作成 64 val urlStr = "http://weather.livedoor.com/forecast/webservise/json/v1?city=${id}" 65 66 //ここに上記URLに接続してJSON文字列を取得する処理を記述 67 //URLオブジェクトを生成 68 val url = URL(urlStr) 69 //URLオブジェクトからHttpURLConnectionオブジェクトを取得 70 val con = url.openConnection() as HttpURLConnection 71 //http接続メソッドを設定 72 con.requestMethod = "GET" 73 //接続 74 con.connect() 75 //HttpURLConnectionオブジェクトからレスポンスデータを取得。天気情報が格納されている 76 val stream = con.inputStream 77 //レスポンスデータであるInputStreamオブジェクトを文字列(JSON文字列)に変換 78 val result = is2String(stream) 79 //HttpURLConnectionオブジェクトを解放 80 con.disconnect() 81 //InputStreamオブジェクトを開放 82 stream.close() 83 84 //JSON文字列を返す 85 return result 86 } 87 88 override fun onPostExecute(result: String) { 89 90 //ここに天気情報JSON文字列を解析する処理を記述 91 //JSON文字列からJSONObjectオブジェクトを生成。これをルートJSONオブジェクトとする 92 val rootJSON = JSONObject(result) 93 //ルートJSON直下の「description」JSONオブジェクトを取得 94 val descriptionJSON = rootJSON.getJSONObject("description") 95 //「description」プロパティ直下の「text」文字列(天気概況文)を取得 96 val desc = descriptionJSON.getString("text") 97 //ルートJSON直下の「forecasts」JSON配列を取得 98 val forecasts = rootJSON.getJSONArray("forecasts") 99 //「forecasts」JSON配列の一つ目(インデックス0)のJSONオブジェクトを取得 100 val forecastNow = forecasts.getJSONObject(0) 101 //「forecasts」一つ目のJSONオブジェクトから「telop」文字列(天気)を取得 102 val telop = forecastNow.getString("telop") 103 104 //天気情報用文字列をTextViewにセット 105 val tvWeatherTelop = findViewById<TextView>(R.id.tvWeatherTelop) 106 val tvWeatherDesc = findViewById<TextView>(R.id.tvWeatherDesc) 107 tvWeatherTelop.text = telop 108 tvWeatherDesc.text = desc 109 } 110 111 private fun is2String(stream: InputStream): String { 112 val sb = StringBuilder() 113 val reader = BufferedReader(InputStreamReader(stream, "UTF-8")) 114 var line = reader.readLine() 115 while(line !=null) { 116 sb.append(line) 117 line = reader.readLine() 118 } 119 reader.close() 120 return sb.toString() 121 } 122 } 123} 124

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2019/10/08 12:32

androidのバージョンとエラーを書いてください
luke04

2019/10/09 06:44

Android9です。 エラーと言うより、ビルドはできるのですが実行してアプリ内のリストをタップするとアプリが強制終了してしまいます。Android studioが出す警告はコード内にコメントで書きました。
guest

回答1

0

ベストアンサー

アプリが落ちたときのLogCatを参照すると、多分

Caused by: java.io.IOException: Cleartext HTTP traffic to weather.livedoor.com not permitted at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:115) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:458) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127) at jp.hrs.keicha.myapplication.MainActivity$WeatherInfoReceiver.doInBackground(MainActivity.kt:73) at jp.hrs.keicha.myapplication.MainActivity$WeatherInfoReceiver.doInBackground(MainActivity.kt:58) at android.os.AsyncTask$2.call(AsyncTask.java:333) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)  at java.lang.Thread.run(Thread.java:764) 

みたいなエラーログが出ていることと思います。ここで、Cleartext HTTP traffic toをキーワードにして検索すると、一例として次のような情報が見つかります。

Android 9(Pie)でHTTP通信を有効にする | Qiita

これを参考にして修正することで解決できないでしょうか。


(コメントに対する追記)

他のところの警告は次のようにすれば回避できるのでは。

kotlin

1 @Suppress("UNCHECKED_CAST") 2 val item = parent.getItemAtPosition(position) as Map<String, String> 3 4 5 //tvCityName.setText(cityName + "の天気:") //エラー: Use of setter method insted of property access syntax 6 tvCityName.text = "${cityName}の天気:" // ${}で変数を文字列中に展開できる 7 8 (中略) 9 10 @SuppressLint("StaticFieldLeak") 11 private inner class WeatherInfoReceiver : AsyncTask<String, String, String>() {

setText()やgetText()のようなsetter/getterが用意されたJavaメソッドは、Kotlinでは上記のようにイコールで代入する記述ができるようになっており、そちらが推奨されています。ご提示のコードでも、

kotlin

1 lvCityList.adapter = adapter

ではその手法を使われていますよね?むしろ、こちらではsetAdapter()を使わずにKotlin的な記述をされているのに、setText()の方はなぜそのままにしてしまったのかなと思います。

他の2つについては、警告を発しないようにアノテーションを付与しておけばいいかと思います。

投稿2019/10/08 15:24

編集2019/10/10 08:42
keicha_hrs

総合スコア6768

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

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

luke04

2019/10/09 08:32

```LogCat 2019-10-09 17:28:49.302 27692-28173/com.example.asynksample E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1 Process: com.example.asynksample, PID: 27692 java.lang.RuntimeException: An error occurred while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:354) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383) at java.util.concurrent.FutureTask.setException(FutureTask.java:252) at java.util.concurrent.FutureTask.run(FutureTask.java:271) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:764) Caused by: java.io.FileNotFoundException: http://weather.livedoor.com/forecast/webservise/json/v1?city=130010 at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:251) at com.example.asynksample.MainActivity$WeatherInfoReceiver.doInBackground(MainActivity.kt:76) at com.example.asynksample.MainActivity$WeatherInfoReceiver.doInBackground(MainActivity.kt:59) at android.os.AsyncTask$2.call(AsyncTask.java:333) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)  at java.lang.Thread.run(Thread.java:764)  ``` logcatにはこのように出ていました。
keicha_hrs

2019/10/09 09:59

実際、エラーとされたURLにブラウザでアクセスするとページが見つからないと表示されますね。アクセスすべきURLに間違いはないのでしょうか。
keicha_hrs

2019/10/09 10:01

× webservise ○ webservice のような気がします。スペルミスではないでしょうか。
luke04

2019/10/09 23:06

ありがとうございます、スペルミスでした。ただ正常に実行はできますがコードに警告は残ります。これらはほっといてもいいものですか?
luke04

2019/10/12 08:34

解決しました、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問