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

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

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

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Android Studio

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

Q&A

解決済

1回答

1271閲覧

SQLiteのDBから取得したデータをListviewに表示したい

tasojiro

総合スコア16

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Android Studio

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

0グッド

0クリップ

投稿2021/06/09 03:46

前提・実現したいこと

Androidのアプリを開発しており、DB内の一部情報を取得しリスト表示する機能の実装を考えています。

※アプリの開発はAndroid Studioで開発しています。
DBの作成は、「DB Browser for SQLite」で作成しています。

DBは以下の通りです。

idnametag
1施設A娯楽
2施設B飲食店
3施設C娯楽

実現したいことは、

①DBから「tag」を取得してListViewで表示すること
②任意のListを選択すると、選択された「tag」の名前の情報をもって遷移すること

の2点です。

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

プロブラム事態にエラーは発生していないのですが、画面のListViewになにも表示されないという事態が生じています。

public void run()内のリスト表示の処理が原因かなと考えています。

該当のソースコード

以下は、Android Stdioのコードです。

Java

1package com.websarva.wings.android.town_infoapp; 2 3//importは長いので割愛します。 4 5public class MainActivity extends AppCompatActivity { 6 7 private InputMethodManager inputMethodManager; 8 private static final String DEBUG_TAG = "AsyncSample"; 9 private static final String URL = "ローカルURL"; 10 11 @Override 12 protected void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 setContentView(R.layout.activity_main); 15 16 String urlFull = URL; 17 receiveTag(urlFull); 18 19 // タグを格納するListMapを生成。 20 ListView lvtag = findViewById(R.id.lvtag); 21 // クリックリスナーを登録。 22 lvtag.setOnItemClickListener(new ListItemClickListener()); 23 24 } 25 26 private void receiveTag(final String urlFull){ 27 //確実にUIスレッドに処理を戻す 28 Looper mainLooper = Looper.getMainLooper(); 29 //スレッド間通信を行うHandlerオブジェクトを登録 30 Handler handler = HandlerCompat.createAsync(mainLooper); 31 //非同期処理を行うためのインスタンス生成と実行 32 MainActivity.TagInfoReceiver tagInfo = new MainActivity.TagInfoReceiver(handler, urlFull); 33 ExecutorService executorService = Executors.newSingleThreadExecutor(); 34 executorService.submit(tagInfo); 35 } 36 37 //非同期でAPIにアクセスするためのクラス 38 private class TagInfoReceiver implements Runnable{ 39 //ハンドラオブジェクト 40 private final Handler _handler; 41 //情報取得のURL 42 private final String _urlFull; 43 44 //コンストラクタ(ハンドラオブジェクトの受け取り) 45 public TagInfoReceiver(Handler handler , String urlFull){ 46 _handler = handler; 47 _urlFull = urlFull; 48 } 49 50 @WorkerThread 51 @Override 52 public void run() { 53 //ここにWEBAPIにアクセスするコード 54 //HTTP接続を行うオブジェクト宣言 55 HttpURLConnection con = null; 56 //レスポンスデータを取得するInputStringオブジェクトを宣言 57 InputStream is = null; 58 //JSON文字列を格納 59 String result = ""; 60 61 try { 62 //URLオブジェクトを生成 63 java.net.URL url = new URL(_urlFull); 64 //URLオブジェクトからHttpURLConnectionオブジェクトを取得 65 con = (HttpURLConnection) url.openConnection(); 66 //各種タイム設定 67 con.setConnectTimeout(1000); 68 con.setReadTimeout(1000); 69 //GET通信に指定 70 con.setRequestMethod("GET"); 71 //接続開始 72 con.connect(); 73 //レスポンスデータを取得 74 is = con.getInputStream(); 75 //レスポンスデータのInputStringオブジェクトを文字列に変換 76 result = is2String(is); 77 } 78 catch (MalformedURLException ex) { 79 Log.e(DEBUG_TAG, "URL変換失敗", ex); 80 } 81 catch (SocketTimeoutException ex) { 82 Log.w(DEBUG_TAG, "通信タイムアウト", ex); 83 } 84 catch (IOException ex){ 85 Log.e(DEBUG_TAG, "通信失敗", ex); 86 } 87 finally { 88 if(con != null) { 89 con.disconnect(); 90 } 91 if(is != null) { 92 try { 93 is.close(); 94 } 95 catch (IOException ex) { 96 Log.e(DEBUG_TAG, "InputStream解放失敗", ex); 97 } 98 } 99 } 100 MainActivity.TagInfoPostExecutor postExecutor = new MainActivity.TagInfoPostExecutor(result); 101 _handler.post(postExecutor); 102 } 103 104 //InputStreamをStringに変換する定型文 105 private String is2String(InputStream is) throws IOException { 106 BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); 107 StringBuffer sb = new StringBuffer(); 108 char[] b = new char[1024]; 109 int line; 110 while (0 <= (line = reader.read(b))) { 111 sb.append(b, 0, line); 112 } 113 return sb.toString(); 114 } 115 } 116 117 private class TagInfoPostExecutor extends MainActivity implements Runnable { 118 119 //取得したJSON文字列 120 private final String _result; 121 //コンストラクタ 122 public TagInfoPostExecutor(String result) { 123 _result = result; 124 } 125 126//ここのコードに問題? 127 @UiThread 128 @Override 129 public void run(){ 130 //ここにUIスレッドで行う処理コード 131 String tag = ""; 132 ArrayList<String> taglist = new ArrayList<String>(); 133 try { 134 JSONArray rootJSON = new JSONArray(_result); 135 for(int i=0; i<rootJSON.length(); i++) { 136 tag = rootJSON.getJSONObject(i).getString("tag"); 137 taglist.add(tag); 138 } 139 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, taglist); 140 ListView lvtag = findViewById(R.id.lvtag); 141 lvtag.setAdapter(adapter); 142 } 143 catch (JSONException ex) { 144 Log.e(DEBUG_TAG, "JSON解析失敗", ex); 145 } 146 } 147 } 148 149 class ListItemClickListener implements AdapterView.OnItemClickListener{ 150 @Override 151 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 152 // リストデータの取得 153 154 //tagnameに選択したリストのtagを格納する処理 155 156 // インテント生成 157 Intent intent = new Intent(MainActivity.this, SelectActivity.class); 158 // 次画面に送るデータを格納 159 intent.putExtra("tagname", tagname); 160 // 次画面を起動 161 startActivity(intent); 162 } 163 } 164}

先のURLで処理しているコードです

python

1from flask import Flask, app, jsonify, g 2import sqlite3 3 4app = Flask(__name__) 5#JSONでの日本語の文字化け阻止 6app.config['JSON_AS_ASCII'] = False 7 8#DBに接続 9def get_db(): 10 if 'db' not in g: 11 g.db = sqlite3.connect("sample.sqlite3") 12 return g.db 13#DBとの接続を終了 14def close_db(e=None): 15 db = g.pop('db', None) 16 if db is not None: 17 db.close() 18 19 20@app.route('/', methods=["GET"]) 21def index(): 22 db = get_db() 23 cur = db.execute("select * from mydata") 24 cur.row_factory = sqlite3.Row 25 mydata = [dict(row) for row in cur.fetchall()] 26 return jsonify(mydata) 27 28if __name__ == "__main__": 29 app.run(host='ローカルURL', port=5000, debug=True)

分からないこと

現状、起きている不具合は「処理は動くがListviewに要素が表示されていない」という事象です。

表示されていないということは、taglistに要素が追加されていないと思うのですが、どのように改良すればよいのかわからない状態です。

これに加え、Listviewを選択した際に選択したtagの名前の情報を次の画面へ渡したいのですが、tagnameに選択したリストのtagを格納するコードがわかりません。。

上記の2点、ご教授いただければ幸いです。

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

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

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

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

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

hoshi-takanori

2021/06/09 06:33

ListView になにも表示されない原因はいくつか考えられます。 - Web API が結果を返してない - Android 側で API を叩く処理に失敗している、または結果をうまく受け取れてない - Android 側で結果を受け取ったが、表示に失敗している ので、まずをれを切り分けましょう。 とりあえず、TagInfoPostExecutor の run メソッドの for ループ終了後の taglist の中身を、デバッガや Logcat などを使って確認してみては。
tasojiro

2021/06/11 13:05

返信遅くなり申し訳ありません。 原因について調査しましたが、WEBAPIは結果を返していました。 2番目のAndroid側で結果をうまく受け取れていない可能性を探りましたが、 正直うまく調べられたか分かりません。が、「taglist」の内容はログで確認できませんでした。 (ログのタグ属性につけた名前も確認できなかったので、うまく調べられていないかも) 2番の可能性として原因究明と解決にあたっていますが、いまだにわかりません。。
tasojiro

2021/06/12 02:22 編集

いえ、使い方が分からなかったのです。。 しかし、調べて適応してみましたが、Logcatを使ってログを確認したところ、自分のつけたタグ情報が確認できませんでした。 これは、そもそも何らかの原因でrun()メソッド自体が実行されていないのでしょうか? (以下、追記です。) デバッガで確認したところ、TagInfoReceiverクラスのrun()メソッドでresultにWEBAPIから受け取ったJSONの文字列は取得しているようです。 しかし、 MainActivity.TagInfoPostExecutor postExecutor = new MainActivity.TagInfoPostExecutor(result); からステップアウトを_handler.post(postExecutor);にはいかずに急にデバッガが追えなくなってしまいました。(デバッグログを見ていても突然ステップイン/アウトが出来なくなった状態) やはり、TagInfoPostExecutorのrun()メソッドが実行できていないように思えます。
hoshi-takanori

2021/06/12 09:40 編集

動かしてみましたが、new MainActivity.TagInfoPostExecutor(result) で止まってますね。で、よく見てみたら、TagInfoPostExecutor が extends MainActivity してますが、これはありえないですね。 extends MainActivity を削除して、new ArrayAdapter の最初の引数を MainActivity.this にしましょう。
tasojiro

2021/06/12 11:13

extend MainActivityを削除し、MainActivity.thisにしたところ表示されました!ありがとうございます。 確かに、MainActivity自身をextendするのはおかしかったですね。。 当たり前ですが、onItemClickで//tagnameに選択したリストのtagを格納する処理」を入力していないので、リストを押下しても遷移しない状態です。(②の質問) 「tagname」にリストの文字情報(run()でtagに格納した文字列)を格納する方法はありますでしょうか。taglistをonItemClickで利用できるようにするところからだと思いますが、よければよろしくお願いいたします。
hoshi-takanori

2021/06/12 11:41

taglist を MainActivity のフィールドにして、onItemClick でその position 番目を取得すれば良いのでは。
tasojiro

2021/06/12 12:10

positionを使う考えに至らなかったです。。。正確に動作を確認しました。 本当にありがとうございました!
guest

回答1

0

自己解決

hosi-takanori様の改善案により、解決しました。

修正箇所を以下に示します。
->private class TagInfoPostExecutor extends MainActivity implements Runnable
+>private class TagInfoPostExecutor implements Runnable

->//tagnameに選択したリストのtagを格納する処理
+>String tagname = (String)parent.getItemAtPosition(position);

ありがとうございました。

投稿2021/06/12 12:14

tasojiro

総合スコア16

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問