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

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

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

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

Android

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

Q&A

解決済

1回答

5599閲覧

androidStudioで天気予報のアプリを作りたい

shinmo

総合スコア9

Java

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

Android

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

0グッド

0クリップ

投稿2020/11/26 22:48

編集2020/12/13 10:38

#androidStudioで天気予報のアプリを作りたいのですが、jsonで取得したデータが出力出来ません。
####[参照]天気予報のアプリ

###【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 <TextView 10 android:id="@+id/messageTextView" 11 android:text="Hello World!!" 12 android:textSize="32sp" 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content" 15 app:layout_constraintTop_toTopOf="parent" 16 app:layout_constraintLeft_toLeftOf="parent" 17 android:layout_marginLeft="101dp" 18 android:layout_marginTop="81dp" /> 19 20 <Button 21 android:id="@+id/mybottun" 22 android:onClick="changeTextView" 23 android:text="ラベルを変更" 24 android:layout_width="wrap_content" 25 android:layout_height="wrap_content" 26 app:layout_constraintTop_toTopOf="parent" 27 app:layout_constraintLeft_toLeftOf="parent" 28 android:layout_marginLeft="138dp" 29 android:layout_marginTop="160dp" /> 30 31</androidx.constraintlayout.widget.ConstraintLayout>

###【AndroidManifest.xml】

xml

1?xml version="1.0" encoding="utf-8"?> 2<manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.ddd"> 4 <!-- ネット接続を許可する --> 5 <uses-permission android:name="android.permission.INTERNET" /> 6 <application 7 android:allowBackup="true" 8 android:icon="@mipmap/ic_launcher" 9 android:label="@string/app_name" 10 android:roundIcon="@mipmap/ic_launcher_round" 11 android:supportsRtl="true" 12 android:theme="@style/AppTheme"> 13 14 <activity android:name=".MainActivity"> 15 <intent-filter> 16 17 <action android:name="android.intent.action.MAIN" /> 18 19 <category android:name="android.intent.category.LAUNCHER" /> 20 21 </intent-filter> 22 </activity> 23 </application> 24 25</manifest>

###【MainActivity.java】

java

1package com.example.ddd; 2 3import androidx.appcompat.app.AppCompatActivity; 4import java.net.MalformedURLException; 5import java.net.URL; 6import android.os.Bundle; 7import android.view.View; 8import android.widget.TextView; 9 10public class MainActivity extends AppCompatActivity { 11 12 @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.activity_main); 16 } 17 18 public void changeTextView(View view) { 19 // 非同期処理(AsyncHttpRequest#doInBackground())を呼び出す 20 try { 21 new AsyncHttpRequest(this).execute(new URL("http://api.openweathermap.org/data/2.5/forecast?id=1850147&units=metric&cnt=1&appid={MY APEKEY}")); 22 } catch (MalformedURLException e) { 23 e.printStackTrace(); 24 } 25 } 26}

###【AsyncHttpRequest.java】

java

1package com.example.ddd; 2 3import android.app.Activity; 4import android.os.AsyncTask; 5import android.widget.TextView; 6import com.example.ddd.R; 7import org.json.JSONException; 8import org.json.JSONObject; 9import java.io.BufferedReader; 10import java.io.IOException; 11import java.io.InputStream; 12import java.io.InputStreamReader; 13import java.net.HttpURLConnection; 14import java.net.URL; 15/** 16 * 非同期処理を行うクラス. 17 */ 18public final class AsyncHttpRequest extends AsyncTask<URL, Void, String> { 19 private int TODAY_FORCAST_INDEX = 0; 20 private Activity mainActivity; 21 22 public AsyncHttpRequest(Activity activity) { 23 // 呼び出し元のアクティビティ 24 this.mainActivity = activity; 25 } 26 27 /** 28 * 非同期処理で天気情報を取得する. 29 * @param urls 接続先のURL 30 * @return 取得した天気情報 31 */ 32 @Override 33 protected String doInBackground(URL... urls) { 34 35 final URL url = urls[0]; 36 HttpURLConnection con = null; 37 38 try { 39 con = (HttpURLConnection) url.openConnection(); 40 con.setRequestMethod("GET"); 41 // リダイレクトを自動で許可しない設定 42 con.setInstanceFollowRedirects(false); 43 con.connect(); 44 45 final int statusCode = con.getResponseCode(); 46 if (statusCode != HttpURLConnection.HTTP_OK) { 47 System.err.println("正常に接続できていません。statusCode:" + statusCode); 48 return null; 49 } 50 51 // レスポンス(JSON文字列)を読み込む準備 52 final InputStream in = con.getInputStream(); 53 String encoding = con.getContentEncoding(); 54 if(null == encoding){ 55 encoding = "UTF-8"; 56 } 57 final InputStreamReader inReader = new InputStreamReader(in, encoding); 58 final BufferedReader bufReader = new BufferedReader(inReader); 59 StringBuilder response = new StringBuilder(); 60 String line = null; 61 // 1行ずつ読み込む 62 while((line = bufReader.readLine()) != null) { 63 response.append(line); 64 } 65 bufReader.close(); 66 inReader.close(); 67 in.close(); 68 69 // 受け取ったJSON文字列をパース 70 JSONObject jsonObject = new JSONObject(response.toString()); 71 JSONObject todayForcasts = jsonObject.getJSONArray("weather").getJSONObject(TODAY_FORCAST_INDEX); 72 73 return "今日の天気は" + todayForcasts.getString("main"); 74 } catch (IOException e) { 75 e.printStackTrace(); 76 return null; 77 } catch (JSONException e) { 78 e.printStackTrace(); 79 return null; 80 } finally { 81 if (con != null) { 82 con.disconnect(); 83 } 84 } 85 } 86 87 /** 88 * 非同期処理が終わった後の処理. 89 * @param result 非同期処理の結果得られる文字列 90 */ 91 @Override 92 protected void onPostExecute(String result) { 93 TextView tv = mainActivity.findViewById(R.id.messageTextView); 94 tv.setText(result); 95 } 96} 97

###【ターミナル】

iMac215-2011:ddd admin$ curl "http://api.openweathermap.org/data/2.5/forecast?id=1850147&units=metric&cnt=1&appid="MyAppID" | jq '.' % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 590 100 590 0 0 2163 0 --:--:-- --:--:-- --:--:-- 2169 { "cod": "200", "message": 0, "cnt": 1, "list": [ { "dt": 1607860800, "main": { "temp": 10.04, "feels_like": 6.37, "temp_min": 10.04, "temp_max": 10.54, "pressure": 1010, "sea_level": 1010, "grnd_level": 1006, "humidity": 78, "temp_kf": -0.5 }, "weather": [ { "id": 802, "main": "Clouds", "description": "scattered clouds", "icon": "03n" } ], "clouds": { "all": 43 }, "wind": { "speed": 4.05, "deg": 97 }, "visibility": 10000, "pop": 0, "sys": { "pod": "n" }, "dt_txt": "2020-12-13 12:00:00" } ], "city": { "id": 1850147, "name": "Tokyo", "coord": { "lat": 35.6895, "lon": 139.6917 }, "country": "JP", "population": 0, "timezone": 32400, "sunrise": 1607809343, "sunset": 1607844516 } } iMac215-2011:ddd admin$

イメージ説明

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

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

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

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

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

dodox86

2020/11/27 00:16

ソースコードはマークダウン記法を用いて読みやすくするようにしてください。インデントも崩れ、読みづらいとそれだけで回答は離れがちになります) https://teratail.com/help/question-tips#questionTips3-5-1 https://teratail.com/questions/238564 あたりを参考にしてソースコードを適切に表示するようにしてください。 更に「AsyncHttpRequest」は自作のクラスだと思いますが、MainActivityとパッケージが違うのではないですか?それぞれのソースファイルが配置されているディレクトリ構造も示しましょう。(質問文中への追記、修正でお願いします)
shinmo

2020/11/29 05:22

ご返事、又ご指摘ありがとうございます。 読みやすいように修正しました。(まだ読みづらかったら教えて下さい) ご指摘どうりAsyncHttpRequest.javaのパッケージを指定したらエラーがなくなりました。ありがとうございました。 申し訳ありませんがディレクトリ構造の示し方がいまいちわからなかったのですが添付したものの事でしょうか?
dodox86

2020/11/29 08:38

「ディレクトリ構造を示してください」と書いたのは、質問当初の「シンボルが見つからない」エラーがパッケージ指定が合っていないのが原因だとも思ったので、パッケージ指定の構造と合っているかどうかを閲覧者、回答者の皆さんが判断できるように、との意図で指摘したものです。そのエラーが解決したのであれば、それで結構です。
dodox86

2020/11/29 23:53

参照されているサイトの記事は2018年6月でまぁ、最近と言えば最近なのですが、「Weather Hacks」のサービスは今はどうもそのままのURLでは使えないようです。ステータスコード302はエラーというよりリダイレクトで、コンテンツの移動を示しています。livedoor内で移動したか、サービス自体が停止しているのでは。Web APIを使うときはいきなりプログラムに組み込むのではなく、curlやwgetなどでまず使い方や結果を確認しましょう。 $ curl http://weather.livedoor.com/forecast/webservice/json/v1?city=270000 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>302 Found</title> </head><body> <h1>Found</h1> <p>The document has moved <a href="http://www.livedoor.com/?city=270000">here</a>.</p> </body></html>
shinmo

2020/12/10 22:04

dodox86さんご指摘ありがとうございます。curlの使い方を確認し結果も出るところまで行ったのですが(別のURLを使いました。)実行すると、エラーは出ず、ボタンを押下するとテキストが消えます。 jsonをパースするのが間違えているのか、取りだす配列が間違えているのかわかりません。 ご教授お願いします。
dodox86

2020/12/13 05:15

[2020/12/13 12:02]の編集履歴を見て: AndroidManifest.xmlの提示の際の記法に間違いがあって、表示がひどく崩れています。 正: ```xml 誤: ``xml それと、一応指摘しておくと、レスポンスで得たJSONのデータは画像で貼ると閲覧した方や回答しようとする方にとって扱いづらいです。検証できません。
shinmo

2020/12/13 10:47

dodox86さんご指摘ありがとうございます! 表示の修正と画像ではなくコードとして入力致しました。 お忙しい中だと思いますが宜しくお願い致します。
guest

回答1

0

ベストアンサー

ご提示のコードではパース処理が足りないです。まず、質問文中に提示されたHTTPレスポンス中のJSON文字列を抜粋すると、およそ以下のようになります。

JSON

1{ 2 "list": [ 3 { 4 "main": { 5 }, 6 "weather": [ 7 { 8 "id": 802, 9 "main": "Clouds", 10 "description": "scattered clouds", 11 "icon": "03n" 12 } 13 ] 14 } 15 ] 16}

ここで、最上位の"list"は配列、その中の"weather"も配列なので、"main"の値を取り出したいのであれば、例えば以下のようなコードになります。

Java

1String content = "{...}" // JSON文字列 2JSONObject jsonContent = new JSONObject(content); 3JSONArray array = jsonContent.getJSONArray("list"); 4JSONObject todayForcasts = array.getJSONObject(0); 5JSONArray items = todayForcasts.getJSONArray("weather"); 6 7// "main": "Clouds" の値をresultに 8String result = items.getJSONObject(0).getString("main"); 9Log.d(TAG, result);

対象のJSON文字列が想定外のものであった場合の例外の捕捉など、エラー系の処理は省いていますので適切に対処してください。

投稿2020/12/13 16:24

dodox86

総合スコア9183

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

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

shinmo

2020/12/14 04:12

dodox86さんご指摘ありがとうございます 1点わからないのですが、『"{...}" // JSON文字列』の"{}"の中にcurlで取得した文字列を全て入れるという認識で合っているでしょうか?
dodox86

2020/12/14 05:49

「curl等を使ってみて」と提言したのは、Web APIを初めて使うような場合はそういったコマンドを使って動作確認した方が理解が早まるはずだからです。ですので、 > curlで取得した文字列を全て入れるという認識で合っているでしょうか? curlコマンドで正しく取得できた場合のJSON文字列と言うのは、ご提示のコードの以下の部分、response.toString() に相当するであろうから、 > // 受け取ったJSON文字列をパース > JSONObject jsonObject = new JSONObject(response.toString()); curlコマンドではなくプログラムで取得する場合はそれを使うことでパースできるでしょう、ということです。
shinmo

2020/12/15 00:10

dodox86さんご指摘ありがとうございました。 無事表示することが出来ました。本当に助かりました! 何度もご返答頂き心より感謝致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問