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

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

ただいまの
回答率

87.61%

http.connectでエラー表示

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 112

score 12

Android Studio(java)でアプリ開発中です。
アプリ開発は全くの初めてではないのですが、ほぼそれに近い状態です。
ネットや書籍を購入していろいろ勉強しながらの開発をしています。
宜しくお願いします。

開発環境

---Android Studio Ver4.2.1 for Windows 64-bit
---Gradle Version 6.7.1
---API 30

やりたい事

社内Webサーバに接続し、アプリ側で使用する出荷予定データをファイルで取得したいと
考えています。

困り事の詳細内容

ネットでHTTPプロトコルによるサンプルコードを調査して
以下のコードになりましたが、
http.connect();
を実行すると
「Debug Console」に
/****************************************************
I/System.out: null
I/Choreographer: Skipped 741 frames!  The application may be doing too much work on its main thread.
W/View: couldn't find view with id 2131231119
/****************************************************
と表示され、エラーで終わります。
"I/System.out: null"がキーワードと思ってネットでいろいろと調べましたが
いろいろな勉強不足が重なっているようで、
どのように解決すればいいのかさっぱりの状態です。
ご助力いただけると助かります。

あるActivity内のコード
            public void onClick(View v) {
                // 書き込みファイル名
                String filename = "index.html";
                File filFolder = getFilesDir();
                if(filFolder.exists()){
                    filFolder.mkdir();
                }
                File file = new File(getFilesDir(), filename);
                try {
                    FileWriter fw = new FileWriter(file, false);
                    PrintWriter pw = new PrintWriter(new BufferedWriter(fw));
                    // URL文字列
                    String str = "http://vm-main/systems-test/MainMenu/index.html";
                    // ターゲット
                    URL url = new URL( str );
                    // 接続オブジェクト
                    HttpURLConnection http = (HttpURLConnection)url.openConnection();
                    // GET メソッド
                    http.setRequestMethod("GET");
                    // 接続 <<<===ここでエラー発生
                    http.connect();
                    // UTF-8 でリーダーを作成
                    InputStreamReader isr = new InputStreamReader(http.getInputStream(), "utf8");
                    // 行単位で読み込む為の準備
                    BufferedReader br = new BufferedReader(isr);
                    String line_buffer;
                    // BufferedReader は、readLine が null を返すと読み込み終了
                    while ( null != (line_buffer = br.readLine() ) ) {
                        pw.write(line_buffer + "\r\n");
                    }

                    // 閉じる
                    br.close();        // BufferedReader
                    isr.close();    // InputStreamReader
                    http.disconnect();        // HttpURLConnection
                    pw.close();        // BufferedWriter

                }
                catch( Exception e ) {
                    System.out.println( e.getMessage() );
                }
            }

尚、HTTP通信は
「Android 9 (API level 28) からはHTTP通信がデフォルトで無効になっている」
との事ですのでその対応策を以下の様にしています。

manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="jp.xxx.check_desuyo">
    <!-- 以下の uses-permission を追記 -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
・
・
・
        <!-- 以下の usesCleartextTraffic を追記 -->
        android:usesCleartextTraffic="true"
・
・
・
    </application>
</manifest>

■2021/06/30 追記

本現象は実機によるデバッグモードで発生していました。
なので、エミュレータではどうか?と思いやってみたところ同じ現象。
だが、エミュレータ内のブラウザで接続するとうまくいく。。。。
という事はWebサーバ環境が原因でない?

とりあえず0.1歩ぐらいは進んだかな・・・・

■2021/06/30 追記その2

えー...
上記ソース内の内容を若干修正しました。
公開しないほうが良さげなものや調べて追記したのに
記載をしていないものがあり、
少し文字の大きさを変化させて見やすくした・・・・つもりです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

自己解決!☆彡

HTTPの接続はActivityから直接はダメという事がわかりました。

参考の元になったページは以下です。

Hatena Blogの 711fumiさん が寄稿されている記事を参考にしました。

【Android】メインスレッド(要は画面処理)でhttpリクエスト投げようとしたら怒られた。 〜NetworkOnMainThreadException〜

要約すると

1.HTTP接続するクラスを別途作成
2.その別途作成したクラスをActivityから呼び出す

※言葉について・・・
私は初心者なので言葉を専門的に記載しません。(いや・・・できません)
専門的な言葉は上記 711fumiさん の記事に記載されています。

この二つで正常に接続できているようです。
詳しくテストしていくと他にもいろいろ設定が必要な項目や動作不順等
出てくる可能性ありますが、
以下コードでサーバにあるファイルの内容が取得できているので
とりあえずこの質問案件については自己解決です。

上記「1.HTTP接続するクラスを別途作成」で私が作成したクラス
package jp.upk.check_sipping;

import android.app.Activity;
import android.net.Uri;
import android.os.AsyncTask;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;

public class AsyncHttpRequest extends AsyncTask<Uri.Builder, Void, String> {

    private Activity mainActivity;
    public AsyncHttpRequest(Activity activity) {
        this.mainActivity = activity;// 呼び出し元のアクティビティ
    }

    @Override
    protected String doInBackground(Uri.Builder... builder) {
        try {
            URL url = new URL("http://vm-main/systems-test/MainMenu/index.html");
            HttpURLConnection coon = (HttpURLConnection) url.openConnection();
            coon.setRequestMethod("POST");
            coon.setRequestMethod("GET");// HTTPメソッド
            coon.setUseCaches(false);// キャッシュ利用
            coon.setDoOutput(false);// リクエストのボディの送信を許可(GETのときはfalse,POSTのときはtrueにする)
            coon.setDoInput(true);// レスポンスのボディの受信を許可
            coon.connect();

            InputStreamReader isr = new InputStreamReader(coon.getInputStream(), "utf8");                       // UTF-8 でリーダーを作成
            BufferedReader br = new BufferedReader(isr);                                                        // 行単位で読み込む為の準備
            String line_buffer;
            while ( null != (line_buffer = br.readLine() ) ) {                                                  // BufferedReader は、readLine が null を返すと読み込み終了
                System.out.println(line_buffer);
            }
            coon.disconnect();
        } catch (SocketTimeoutException e1) {
            // タイムアウト
        } catch (Exception e2) {
            // エラー処理
            System.out.println( e2.getMessage() );
            e2.printStackTrace();
        }
        return "";
    }
}
上記「2.別途作成したクラスをActivityから呼び出す」呼び出している箇所
         ・
         ・
         ・
           @Override
            public void onClick(View v) {

                // httpリクエストを入れる変数
                Uri.Builder builder = new Uri.Builder();
                AsyncHttpRequest task = new AsyncHttpRequest(<Activity名>.this);
                task.execute(builder);
         ・
         ・
         ・

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 87.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る