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