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