SQLの窓

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 なのでそのまま使用可能です)





【2017 Android Studioの最新記事】
posted by lightbox at 2017-08-24 16:14 | Comment(0) | 2017 Android Studio | このブログの読者になる | 更新情報をチェックする
バッチ処理

Microsoft Office
container 終わり

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

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり