LoginSignup
9
6

More than 3 years have passed since last update.

[Android]端末からサーバへ画像のアップロード

Last updated at Posted at 2020-01-22

はじめに

Androidで画像をPOSTし、サーバに保存する機能でてこずったため自分の備忘録兼、アウトプットとして書きます。プログラムのお仕事半年もしてないからいろいろおかしいかもしれないけど許してね。

追記

ご指摘を受けました。ありがとうございます!

OkHTTP2はobsoletes扱いです。最新の4.3.1を使うようにしましょう。

https://square.github.io/okhttp/changelog_3x/#version-300-rc1
https://square.github.io/okhttp/changelog/

環境

AndroidStudioでOkHttpを利用しています。

OkHttp導入

  • AndroidStudio画面左上の「Android」を「プロジェクト」に切り替え。
  • [app]内のbuild.gradleを開く。
  • dependencies内に implementation 'com.squareup.okhttp:okhttp:2.7.5' を追記。(2.7.5はvarsionによって変えてください。)
  • dependencies内にimplementation 'com.squareup.okhttp:okhttp:4.3.1' を追記。 (2020/1/24 変更)
build.gradle
//~~省略~~
dependencies{
  //~~省略~~
  implementation 'com.squareup.okhttp:okhttp:4.3.1'//追記
}

完了。

AsyncTask

Http通信で送るので非同期で行う。

OkHttpTask.java
import android.os.AsyncTask;
import android.util.Log;
import java.io.File;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class HttpTask extends AsyncTask<String, Void, String> {

    String responseBody;
    public HttpTask(){}

    @Override
    protected String doInBackground(String... params) {
        String url = "送るURL"; 
        MediaType media = MediaType.parse("multipart/form-data");
        try {
            File file = new File(params[0]);
            String FileName = file.getName();
            String boundary = String.valueOf(System.currentTimeMillis());

            RequestBody requestBody = new MultipartBody.Builder(boundary).setType(MultipartBody.FORM)
                    .addFormDataPart("file", FileName, RequestBody.create(media, file))
                    .build();

            Request request = new Request.Builder()
                    .url(url)
                    .post(requestBody)
                    .build();

            OkHttpClient client = new OkHttpClient();
            Response response = client.newCall(request).execute();
            responseBody = response.body().string();

            return responseBody;

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

    @Override
    protected void onPostExecute(String result) {
        Log.d("a",result);
    }
}

いろいろ変更したので書き直しました。また、変更に伴って
java.io.IOException: Cleartext HTTP traffic to example.com not permitted
のようなエラーが表示されることがあるかと思います。
これはデフォルトでHTTPS通信になったので、HTTP通信を許可する方法を書いておく必要があるからです。方法についてはこちらの方が詳しく書かれているのでどうぞ。

古いコード
OkHttpTask_old.java
/**削除
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.MultipartBuilder;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
*/
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class OkHttpTask extends AsyncTask<String, Void, String> {
  public OkHttpTask(){}

    @Override
    protected String doInBackground(String... params) {
        //ポスト先のURL
        String url = "http://";
        File file = new File(params[0]);

        /**削除
        *ここでPOSTする内容を設定
        RequestBody requestBody = new MultipartBuilder()
                .type(MultipartBuilder.FORM)
                .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/jpg"), file))
                .build();
        */

        //ここでPOSTする内容を設定(こっちに変更)
        RequestBody requestBody = new MultipartBody.Builder()
                .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/jpg"), file))
                .build();


        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();

        String result="";
        try {
            Response response = client.newCall(request).execute();
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            {
                result = response.body().string();
            }
        } catch (Exception e) {}

        return result;
    }

    @Override
    protected void onPostExecute(String result) {
        Log.d("end:",result);
    }
}
*/

MainActivity

MainActivity.java

public class MainActivity extends AppCompatActivity {
  //送る画像のURI
  private Uri _imageUri;
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //ここで呼び出し
        new OkHttpTask().execute(url);   
}

受け取る側

Postされたファイルを保存するだけ。

UpLoad.java
@WebServlet("/Upload")
@MultipartConfig(location = "保存場所")
public class upload extends HttpServlet {

    public void doPost(HttpServletRequest req,HttpServletResponse res) throws IOException, ServletException {
        String name="no_name";
        //multipart/form-dataによって提供されるこのリクエストのすべてのPart要素を取得
        for (Part part : req.getParts()) {
            //名前の取得
            for (String cd : part.getHeader("Content-Disposition").split(";")) {
                String str = cd.trim();
                if (str.startsWith("filename")) {
                    String str2 = str.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
                    File f = new File(str2);
                    name = f.getName();
                    part.write(name);
                }
            }
        }
    }
}

参考リンク

OkHttpを初めて使ってみた話
https://qiita.com/LyricalMaestro0/items/698c77f5a964b5658bbb

9
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6