SQLの窓

2017年09月23日


ViewSwitcher を使用した2画面アプリ (2) : 画面部分の作成と画面切り替えテスト『画面の作成』

この内容は、ViewSwitcher を使用した2画面アプリ (1) : 画面部分の作成と画面切り替えテスト『メニューの作成』より続いています。
ViewSwitcher 上で二つのレイアウトを作成し、ViewSwitcher のメソッドを使用してそのレイアウトを切り替えます。そのまま全てを一つの画面定義に記述してもいいのでが、そうすると2画面目の内容を『デザイナ』で確認する事ができません。 ですから、2画面目は別の画面定義で作成して、include で ViewSwitcher の中から呼び出すようにします。 activity_main.xml 画面の切り替えは、一般的には ViewAnimator クラスの showNext() と showPrevious() を使うのですが、実行するのがメニューなので、どこで実行しても正しい画面が表示されるように、setDisplayedChild(int whichChild) を使用します( whichChild は 0 かまたは 1 ) 多少無駄な動きは存在しますが、簡単に正しく動作するはずです。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:padding="16dp">

    <ViewSwitcher
        android:id="@+id/viewSwitcher"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <ListView
                android:id="@+id/listView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

        </LinearLayout>

        <include
            android:id="@+id/entry"
            layout="@layout/entry"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </ViewSwitcher>

</LinearLayout>





entry.xml

editTextCode と textViewCode と  は、社員マスタのキー部分に使用します。機能としては、修正処理と新規登録処理の二つあるので、それぞれ editTextCode と textViewCode を使い、使用しないほうは setVisibility(View.GONE); で非表示にします
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <TextView
        android:id="@+id/textViewCode"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="4dp"
        android:textSize="30sp"/>

    <EditText
        android:id="@+id/editTextCode"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"/>

    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"/>

    <EditText
        android:id="@+id/editText2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"/>

    <Button
        android:id="@+id/buttonUpdate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="更新"/>

</LinearLayout>





posted by lightbox at 2017-09-23 14:33 | 2017 Android Studio | このブログの読者になる | 更新情報をチェックする

ViewSwitcher を使用した2画面アプリ (1) : 画面部分の作成と画面切り替えテスト『メニューの作成』

この内容は、ViewSwitcher を使用した2画面アプリ (2) : 画面部分の作成と画面切り替えテスト『画面の作成』に続いています。
2画面アプリと言えば、もう一つの Activity を作成して、Intent でデータを引き渡すタイプですが、初心者にとってちょっと敷居が高いので、ViewSwitcher を使用します。ViewSwitcher は2画面のみ対応ですが、同系統(ViewAnimator を継承)の ViewFlipper を使用すれば複数画面も簡単に作成できます。 この場合、見えている画面は一つでも常に同じ Activity で画面を参照できるので、大きな画面に全て表示されていると思って普通にコードが書けます。ですから、そこが楽なぶん、Helper クラスを作成して、画面の処理は全てそこにまかせるという工夫に力を入れたいと思います。 1) メニューの作成 メニューは、その場面で必要な画面切替えに使用します。画面上に機能に直接関係無いボタンを作りたく無いので作成します。Android Studio のテンプレートとしては 『Empty』を使用しますかので、メニュー部分は自分で作成する必要があります。 ▼ menu フォルダの作成 (最後に OK で menu フォルダがリソースに作成されます) ▼ メニューフォルダで、new => Menu resource file でメニュー定義を作成 メニューのファイル名は、何でもいいですが、通常の画面と同じく XML で作成されるので、小文字のアルファベットで、word 間は _(アンダーバー)を使います。ここでは、Android が一般的に使う 『menu_main』を使用しています メニューアイテムの追加 デザイナの画面に、MenuItem をドラッグ&ドロップして追加します。左下の『コンポーネント・ツリー』は動作しないので注意です。 次に右サイドの『プロパティ』で、id を入力します。icon と showAsAction は自由に選択してもいいのですが、ここでは以下のようにエディタで定義します
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/action_1"
        android:icon="@android:drawable/btn_dialog"
        android:title="戻る"
        app:showAsAction="always"/>

    <item
        android:id="@+id/action_2"
        android:title="新規登録"/>

</menu>



メニューの実行部分の作成

機能的には一度作ってしまえば変更する事は殆ど無いので、MainActivity の最後に追加します。(helper のメソッドは後で作成するのでコメントにしています)
	// *******************************
	// メニュー
	// *******************************
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.menu_main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();

		if (id == R.id.action_1) {
			Log.i("lightbox","処理1");

			// helper.showFirstView();

			return true;
		}

		if (id == R.id.action_2) {
			Log.i("lightbox","処理2");

			// helper.showInsertView();

			return true;
		}

		return super.onOptionsItemSelected(item);
	}



posted by lightbox at 2017-09-23 13:10 | 2017 Android Studio | このブログの読者になる | 更新情報をチェックする

2017年09月09日


OkHttp を使用した HttpAccess クラスで Web 上の 画像をダウンロードして表示するテンプレート

▼ HttpAccess パッケージのダウンロード


( 解凍して、main\java フォルダの中に コピーして下さい )
※ OkHttp より 最新の Gradle の記述を取得して build.gradle の dependencies の最後に貼り付けて下さい
例) compile 'com.squareup.okhttp3:okhttp:3.8.1'

処理概要

ボタンをクリックした後、HttpAccess クラスでファイルをダウンロードする download メソッドを実行するテンプレートです。サンプルでは画像を使用して、ダウンロードした後に ImageView に表示していますが、ダウンロード処理だけならば、どのようなファイルでもかまいません。

ここでは、パッケージ内に保存していますが、OutputStream を引き渡すので、他の保存場所でも問題はありません。

※ onAsyncTaskListener の引数の文字列は、http のステータスコードなので、通常は 200 が返ります。インターネットのアクセスそのものが成功すれば、null 以外が返ります。

MainActivity
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.example.lightbox.web.HttpAccess;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class MainActivity extends AppCompatActivity {

	private HttpAccess httpAccess;
	private ImageView imageView;
	private String image_url;
	private OutputStream outputStream;

	private Bitmap bitmap;
	private BitmapFactory.Options options;

	private InputStream inputStream;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// ダウンロードでは、URL をメソッドで指定します
		httpAccess = new HttpAccess("");
		imageView = (ImageView) MainActivity.this.findViewById(R.id.imageView);
		image_url = "https://lightbox.sakura.ne.jp/demo/image/sample.jpg";

		// ボタンをクリック
		MainActivity.this.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {

				try {

					// 保存ファイル
					outputStream = MainActivity.this.openFileOutput("save.jpg", MODE_PRIVATE);
					// ダウンロード
					httpAccess.download(image_url,outputStream, new HttpAccess.OnAsyncTaskListener() {
						@Override
						public void onAsyncTaskListener(String s) {

							if ( s != null ) {
								Toast.makeText(MainActivity.this,"画像が保存されました",Toast.LENGTH_SHORT).show();

								// ステータスコード
								Log.i("lightbox", String.format("code = %s",s));

								// 画像を読み込む
								bitmap = null;
								try {
									options = new BitmapFactory.Options();
									inputStream = MainActivity.this.openFileInput("save.jpg");
									bitmap = BitmapFactory.decodeStream(inputStream, null, options);	// ここではオプションは未指定
									inputStream.close();

								} catch (IOException e) {
									e.printStackTrace();
								}

								// 表示
								if ( bitmap != null ) {
									imageView.setImageBitmap(bitmap);
								}
							}
						}
					});

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

}


画面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

※ android.permission.INTERNET が必要です
※ コピーして使いやすいように、ソースコードにパッケージに依存する記述が無いので注意して下さい。
(画面は、.MainActivity なのでそのまま使用可能です)



posted by lightbox at 2017-09-09 16:57 | 2017 Android Studio | このブログの読者になる | 更新情報をチェックする

2017年08月24日


OkHttp を使用した HttpAccess クラスで Web 上の PHP アプリに対してファイルをアップロードするテンプレート

▼ HttpAccess パッケージのダウンロード


( 解凍して、main\java フォルダの中に コピーして下さい )
※ OkHttp より 最新の Gradle の記述を取得して build.gradle の dependencies の最後に貼り付けて下さい
例) compile 'com.squareup.okhttp3:okhttp:3.8.1'

処理概要

assets フォルダにある画像ファイルを open して InputStream を取得し、PHP のファイルアップロード用のコードのある URL を呼び出して、ファイルをアップロードします。ファイルは、画像ファイルである必要はありませんが、確認作業が容易になるので画像を使用しています。

HttpAccess の sendUpload メソッドを使用しますが、InputStream を引き渡すようにしているので、元のデータはいろいろなところから用意する事ができるはずです。

引数は以下のようになっています。

1) String url
2) String field
3) String name
4) InputStream inputStream
5) String mime
6) OnAsyncTaskListener listener 

field は HTML で type="file" の INPUT 要素の name 属性の値になります。
name は ファイル名 で、mime は "image/jpeg" のようなものになります。

PHP からの戻りは、JSON 文字列ですが、ステータスとデバッグ用の情報なので、デシリアライズ用のクラスは作成せずにルートから解析してエラーコードを取得しています。そのエラーコードに対応する内容はあらかじめ assets に error.json として保存して読み込んでから、専用のプライベートクラス(ErrorText) を使用してデシリアライズして使用しています。

InputStream から テキストデータを一括で取得する為、HttpAccess 内に定義済みの static メソッドである readTextAll を 使用しています( okio 使用したコードです )

error.json
{
	"error": [
		"0 - 正常終了",
		"1 - アップロードされたファイルは、php.ini の upload_max_filesize ディレクティブの値を超えています",
		"2 - アップロードされたファイルは、HTML フォームで指定された MAX_FILE_SIZE を超えています",
		"3 - アップロードされたファイルは一部のみしかアップロードされていません",
		"4 - ファイルはアップロードされませんでした",
		"5 - 『アップロードに失敗しました』",
		"6 - テンポラリフォルダがありません。PHP 5.0.3 で導入されました",
		"7 - ディスクへの書き込みに失敗しました。PHP 5.1.0 で導入されました",
		"8 - PHP の拡張モジュールがファイルのアップロードを中止しました"
	]
}

PHP のコード
<?php
session_cache_limiter('nocache');
session_start();

header( "Content-Type: application/json; charset=utf-8" );

// *************************************
// 変数初期値
// *************************************
$debug = 1;
$upload_dir = "./upload";
if ( !$_FILES ) {
	// php.ini の upload_max_filesize を超えて、
	// Apache に制限が無いと $_FILE が空になる
	$_FILES['target']['error'] = 5;	// ユーザエラーメッセージ
}

// *************************************
// アップロード処理
// フィールド名 : target で固定
// *************************************
if ( $_SERVER['REQUEST_METHOD'] == "POST" ) {

	// 公開状態では実行しない
	if ( $debug == 1 ) {

		$upload = realpath ( $upload_dir );
		$upload .= ( DIRECTORY_SEPARATOR . $_FILES['target']['name'] );
		if ( move_uploaded_file(
			$_FILES['target']['tmp_name'], $upload ) ) {
			$_POST['result']  = "アップロードに成功しました";
		}
		else {
			if ( !$_FILES ) {
				$_FILES['target']['error'] = 5;	// ユーザエラーメッセージ
			}
			$_POST['result']  = "アップロードに失敗しました";
		}

	}
	else {
		if ( $_FILES['target']['error'] == 0 ) {
			$_POST['result']  = "アップロードに成功しました";
		}
		else {
			$_POST['result']  = "アップロードに失敗しました";
		}
	}

}
else {
	$_POST['result']  = "POST メソッドを使用して下さい";
}

$_POST['files'] = $_FILES;

// *************************************
// この JSON 文字列を HTML 内の json
// オブジェクト定義として埋め込みます
// *************************************
print json_encode($_POST, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE );
?>


activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button" />

</LinearLayout>


MainActivity
import android.content.res.AssetManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.example.lightbox.web.HttpAccess;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import java.io.InputStream;

public class MainActivity extends AppCompatActivity {

	private HttpAccess httpAccess;
	private AssetManager assetManager;
	private ErrorText errorText;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		httpAccess = new HttpAccess("");
		assetManager = MainActivity.this.getResources().getAssets();
		// PHP のエラーメッセージのテキストを定義した JSON 文字列の取得
		try {
			InputStream inputStream = assetManager.open("error.json");
			String json = HttpAccess.readTextAll(inputStream,"UTF-8");
			Gson gson = new Gson();
			errorText = gson.fromJson(json,ErrorText.class);
		} catch (Exception e) {
			e.printStackTrace();
		}

		MainActivity.this.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				try {
					InputStream inputStream = assetManager.open("image.jpg");
					httpAccess.sendUpload(
							// URL ( 必ず指定 )
							"http://10.0.2.2/r101/php_upload/file_upload.php",
							// フィールド名
							"target",
							// ファイル名
							"image.jpg",
							inputStream,
							// MIME
							"image/jpeg",
							new HttpAccess.OnAsyncTaskListener() {
								@Override
								public void onAsyncTaskListener(String s) {

									// JSON 文字列のツリー解析
									/* {
										"result": "アップロードに成功しました",
										"files": {
											"target": {
												"name": "image.jpg",
												"type": "image\/jpeg",
												"tmp_name": "",
												"error": 0,
												"size": 22652
											}
										}
									} */
									JsonParser parser = new JsonParser();
									JsonElement element = parser.parse(s);
									JsonObject root = element.getAsJsonObject();
									String result = root.get("result").getAsString();
									JsonObject files = root.get("files").getAsJsonObject();
									JsonObject target = files.get("target").getAsJsonObject();
									int error = target.get("error").getAsInt();

									String ErrorText = errorText.error[error];
									Log.i("lightbox", s);
									Log.i("lightbox", result);
									Log.i("lightbox", ErrorText);


								}
							}
					);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});

	}

	// *************************************
	// assets フォルダの error.json 用
	// *************************************
	private class ErrorText {
		String[] error;
	}

}



build.gradle( dependencies ) に追加する2行
    compile 'com.google.code.gson:gson:2.8.1'
    compile 'com.squareup.okhttp3:okhttp:3.8.1'


※ android.permission.INTERNET が必要です
※ コピーして使いやすいように、ソースコードにパッケージに依存する記述が無いので注意して下さい。
(画面は、.MainActivity なのでそのまま使用可能です)





posted by lightbox at 2017-08-24 16:14 | 2017 Android Studio | このブログの読者になる | 更新情報をチェックする

2017年08月23日


OkHttp を使用した HttpAccess クラスで Web 上の掲示板に投稿(POST)するテンプレート

▼ HttpAccess パッケージのダウンロード


( 解凍して、main\java フォルダの中に コピーして下さい )
※ OkHttp より 最新の Gradle の記述を取得して build.gradle の dependencies の最後に貼り付けて下さい
例) compile 'com.squareup.okhttp3:okhttp:3.8.1'

処理概要

本来ならば、直接JSON を返す PHP 側のアプリを呼び出すのですが、一般的な『掲示板』に実際 Android から POST して、HTML で返される結果はをアプリ内で Log.i() で表示します。但し、この掲示板のデータの保存形式を JSON にしていますので、投稿終了後再度データそのものを呼び出して ListView に表示しています。

掲示板アプリはこのテスト専用に作成したもので、最後の更新後5分でデータが削除されます。投稿と投稿の間には1分の間隔が必要で、固有コードを入力して、そのコード(スレッド)毎に内容を確認できるようにしています




WEB側の実行画面


簡易掲示板(5分限定)

※ このページはレスポンシブです



Android の実行画面



最初のフィールドは固有コードの入力で、自由な数字を入力して次のフィールドで本文を投稿します。そして、投稿後 WEB 側で 固有コードを入力して送信して確認します。

※ 入力された本文は、ListView に表示されます

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              xmlns:tools="http://schemas.android.com/tools"
              android:id="@+id/layout"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              tools:context=".MainActivity"
              android:weightSum="1">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/editTextCode"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ems="10"
            android:inputType="number"/>

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Button"/>

    </LinearLayout>

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="113dp"
        android:ems="10"
        android:gravity="top|left"
        android:inputType="textMultiLine"
        />

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>


MainActivity
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

import com.example.lightbox.web.HttpAccess;
import com.google.gson.Gson;

import java.util.HashMap;

public class MainActivity extends AppCompatActivity {

	// *******************************
	// データ定義
	// *******************************
	private String url = "https://lightbox.sakura.ne.jp/demo/template/lightbox/bbs-normal/bbs.php";
	private String jsonurl = "https://lightbox.sakura.ne.jp/demo/template/lightbox/bbs-normal/data/";

	// *******************************
	// 変数定義
	// *******************************
	private ArrayAdapter<WebData> arrayAdapter;
	private ListView listView;
	private HttpAccess httpAccess;

	// *******************************
	// 初期処理
	// *******************************
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// *******************************
		// ボタンのイベント
		// *******************************
		Button button = (Button) MainActivity.this.findViewById(R.id.button);
		button.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Log.i("lightbox", "クリックされました");
				CallPost();
			}
		});

		// *******************************
		// リストビューの準備
		// *******************************
		listView = (ListView) MainActivity.this.findViewById(R.id.listView);
		// データが入るオブジェクト
		arrayAdapter = new ArrayAdapter<WebData>(MainActivity.this, android.R.layout.simple_list_item_1);
		// 初期化
		arrayAdapter.clear();
		// リストビューにデータが入るオブジェクトをセット
		listView.setAdapter(arrayAdapter);

		// *******************************
		// 送信用オブジェクトを作成
		// *******************************
		httpAccess = new HttpAccess(url);

	}

	// *******************************
	// 送信処理
	// *******************************
	private void CallPost() {

		HashMap<String, String> hashMap = new HashMap<String, String>();

		// 投稿テキスト
		EditText editText = (EditText) MainActivity.this.findViewById(R.id.editText);
		String text = editText.getText().toString();
		hashMap.put("text", text);

		// 固有コード
		EditText editTextCode = (EditText) MainActivity.this.findViewById(R.id.editTextCode);
		String code = editTextCode.getText().toString();
		hashMap.put("mycode", code);

		httpAccess.setUrl(url);
		// 送信
		httpAccess.sendPost(hashMap, new HttpAccess.OnAsyncTaskListener() {
			@Override
			public void onAsyncTaskListener(String s) {
				Log.i("lightbox", s);

				// 固有コード
				EditText editTextCode = (EditText) MainActivity.this.findViewById(R.id.editTextCode);
				String code = editTextCode.getText().toString();

				// *******************************
				// 投稿(POST) 後、結果の JSON を取得する
				// *******************************
				httpAccess.setUrl(String.format("%s%s.json",jsonurl,code));
				httpAccess.sendGet(new HttpAccess.OnAsyncTaskListener() {
					@Override
					public void onAsyncTaskListener(String s) {
						Log.i("lightbox", s);

						// *******************************
						// JSON を ListView に表示する
						// *******************************
						Gson gson = new Gson();
						DataList dataList = gson.fromJson(s,DataList.class);
						// クリア
						arrayAdapter.clear();
						// データセット
						arrayAdapter.addAll(dataList.item);

					}
				});


			}
		});

	}

}



Google Gson 用のデータ格納用のクラス
package com.example.lightbox.posttest;

public class DataList {

	WebData[] item;

}

package com.example.lightbox.posttest;

public class WebData {

	String text;

	@Override
	public String toString() {
		return text;
	}
}




build.gradle( dependencies ) に追加する2行
compile 'com.google.code.gson:gson:2.8.1'
compile 'com.squareup.okhttp3:okhttp:3.8.1'


※ android.permission.INTERNET が必要です
※ コピーして使いやすいように、ソースコードにパッケージに依存する記述が無いので注意して下さい。
(画面は、.MainActivity なのでそのまま使用可能です)





posted by lightbox at 2017-08-23 20:17 | 2017 Android Studio | このブログの読者になる | 更新情報をチェックする

2017年08月17日


OkHttp を使用した HttpAccess クラスで Web 上のデータを取得(GET)して ListView を表示するテンプレート



コピーして使いやすいように、ソースコードにパッケージに依存する記述が無いので注意して下さい。
(画面は、.MainActivity なのでそのまま使用可能です)

ListView は、Android で定義済みの android.R.layout.simple_list_item_1 を使用しています。それに伴い、WebData クラスでは、toString を Override して 氏名が表示されるようにしています。

JSON データは、PHP でも使用し、コードの見通しを良くする為、プロバティは日本語(UTF8)で記述されています。
        {
            "社員コード": "0001",
            "氏名": "浦岡 友也",
            "フリガナ": "ウラオカ トモヤ",
            "所属": "0003",
            "性別": "0",
            "作成日": "2005-09-12 00:00:00",
            "更新日": "2005-11-28 00:00:00",
            "給与": "270000",
            "手当": "9000",
            "管理者": null,
            "生年月日": "2010-01-01",
            "削除区分": null,
            "所属名": "営業部第三"
        }
▼ HttpAccess パッケージのダウンロード


( 解凍して、main\java フォルダの中に コピーして下さい )
※ OkHttp より 最新の Gradle の記述を取得して build.gradle の dependencies の最後に貼り付けて下さい
例) compile 'com.squareup.okhttp3:okhttp:3.8.1'

JSON データへのリンク
※ fld_search=氏名の一部 で条件を指定できます

MainActivity
public class MainActivity extends AppCompatActivity {

	// *******************************
	// データ定義
	// *******************************
	private String url = "https://lightbox.sakura.ne.jp/demo/template/lightbox/syain-req-jquery-mysql/app-get.php";

	// *******************************
	// 変数定義
	// *******************************
	private ArrayAdapter<WebData> arrayAdapter;
	private ListView listView;
	private HttpAccess httpAccess;

	// *******************************
	// 初期処理
	// *******************************
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// リストビュー
		listView = (ListView) MainActivity.this.findViewById(R.id.listView);
		// リストビューの行をタップした時の処理
		listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

				// アダプターを取得
				ArrayAdapter<WebData> arrayAdapter = (ArrayAdapter<WebData>)parent.getAdapter();

				// 行データを取得
				WebData webData;
				webData = arrayAdapter.getItem(position);

				Log.i("lightbox", String.format("社員コード : %s",webData.社員コード));
				Log.i("lightbox", webData.氏名);
				Log.i("lightbox", webData.フリガナ);
				Log.i("lightbox", String.format("所属 : %s %s",webData.所属,webData.所属名));
				Log.i("lightbox", String.format("性別 : %s", webData.性別.equals("0") ? "男性" : "女性" ));
				NumberFormat numberFormat = NumberFormat.getNumberInstance();
				Log.i("lightbox", String.format("給与 : %s", numberFormat.format(webData.給与)));
				if ( webData.手当 == 0 ) {
					Log.i("lightbox", "手当てはありません");
				}
				else {
					Log.i("lightbox", String.format("手当 : %s", numberFormat.format(webData.手当)));
				}
				if ( webData.管理者 != null ) {
					Log.i("lightbox", String.format("管理者コード : %s",webData.管理者));
				}
				else {
					Log.i("lightbox", "管理者です");
				}
				if ( webData.生年月日 != null ) {
					Log.i("lightbox", String.format("生年月日 : %s",webData.生年月日));
				}
				else {
					Log.i("lightbox", "生年月日は登録されていません");
				}

			}
		});


		// データが入るオブジェクト
		arrayAdapter = new ArrayAdapter<WebData>(MainActivity.this, android.R.layout.simple_list_item_1);
		// 初期化
		arrayAdapter.clear();

		// リストビューにデータが入るオブジェクトをセット
		listView.setAdapter(arrayAdapter);

		// WEB アクセス用オブジェクト
		httpAccess = new HttpAccess(url + "?fld_search=村");

	}

	// *******************************
	// メニューの処理
	// *******************************
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.menu_main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();

		// *******************************
		// 全て表示
		// *******************************
		if (id == R.id.action_1) {

			httpAccess.setUrl(url);
			httpAccess.sendGet(new HttpAccess.OnAsyncTaskListener() {
				@Override
				public void onAsyncTaskListener(String s) {

					// Gson インスタンス
					Gson gson = new Gson();

					// Gson によるデシリアライズ
					DataList dataList = gson.fromJson(s,DataList.class);

					// dataList.row が WebData の配列
					for( WebData rowData : dataList.row) {
						Log.i("lightbox",rowData.氏名);
					}

					// クリア
					arrayAdapter.clear();
					// データセット
					arrayAdapter.addAll(dataList.row);

				}
			});
			return true;

		}

		// *******************************
		// 一部表示
		// *******************************
		if (id == R.id.action_2) {

			httpAccess.setUrl(url + "?fld_search=村");
			httpAccess.sendGet(new HttpAccess.OnAsyncTaskListener() {
				@Override
				public void onAsyncTaskListener(String s) {

					// Gson インスタンス
					Gson gson = new Gson();

					// Gson によるデシリアライズ
					DataList dataList = gson.fromJson(s,DataList.class);

					// dataList.row が WebData の配列
					for( WebData rowData : dataList.row) {
						Log.i("lightbox",rowData.氏名);
					}

					// クリア
					arrayAdapter.clear();
					// データセット
					arrayAdapter.addAll(dataList.row);

				}
			});
			return true;

		}


		return super.onOptionsItemSelected(item);
	}


}


activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>


menu_main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">

    <item
        android:id="@+id/action_1"
        android:orderInCategory="100"
        android:title="全て表示"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_2"
        android:orderInCategory="100"
        android:title="一部表示"
        app:showAsAction="never" />

</menu>


DataList.java
public class DataList {

	WebData[] row;

}


WebData.java
public class WebData {

	String 社員コード;
	String 氏名;
	String フリガナ;
	String 所属;
	String 性別;
	int 給与;
	int 手当;
	String 管理者;
	String 生年月日;
	String 所属名;

	@Override
	public String toString() {
		return 氏名;
	}
}


build.gradle
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    compile 'com.google.code.gson:gson:2.8.1'
    compile 'com.squareup.okhttp3:okhttp:3.8.1'
}






posted by lightbox at 2017-08-17 19:10 | 2017 Android Studio | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します
container 終わり



フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり