안드로이드 서버에 이미지 여러장 전송하기

Posted by ITPangPang
2016. 7. 28. 23:27 안드로이드(android)/개발중 생긴일


안드로이드 서버에 

이미지 여러장 전송하기


ㆍ 원래 이전에는 이미지 한장만 전송하거나

    텍스트+이미지를 전송하거나 했었는데 이번에

    이미지 2장을 보내야 해서 똑같이 해봤는데 안되더라..


ㆍ 그냥 여러가지 바꿔가면서 삽질을 했더니 성공했다.




원래 기존에는 

대충 아래와 같이

텍스트+이미지 한장을

보냈었다

public class ImageAsyncTask extends AsyncTask<String, Void, String>
{
...
String Add = "http://~~";
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int maxBufferSize = 1 * 1024 * 1024;
public static final int MAX_READ_TIME = 10000;
public static final int MAX_CONNECT_TIME = 15000;
int bufferSize;
@Override
protected String doInBackground(String... params)
{
InputStream is = null;
Cursor c = mContext.getContentResolver().query(Uri.parse(filePath.toString()), null, null, null, null);
c.moveToNext();
String absolutePath = c.getString(c.getColumnIndex(MediaStore.MediaColumns.DATA));
Log.d("TEST","file Path=>"+absolutePath);
c.close();
try
{
URL connectUrl = new URL(Add);
FileInputStream mFileInputStream = new FileInputStream(absolutePath);
HttpURLConnection conn = (HttpURLConnection) connectUrl.openConnection();
conn.setConnectTimeout(MAX_CONNECT_TIME);
conn.setReadTimeout(MAX_READ_TIME);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("cache-control", "no-cache");
conn.setRequestProperty("cache-length", "length");
conn.setRequestProperty("image", absolutePath);
conn.setRequestProperty("user-agent", "test");
conn.connect();
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
//text 전송
dos.writeBytes("\r\n--" + boundary + "\r\n");
dos.writeBytes("Content-Disposition: form-data; name=\"text\"\r\n\r\n" + str);
//Image 전송
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"image\";filename=\"" + absolutePath + "\"" + lineEnd);
dos.writeBytes(lineEnd);

int bytesAvailable = mFileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bufferSize];
int bytesRead = mFileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
dos.write(buffer, 0, bufferSize);
bytesAvailable = mFileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = mFileInputStream.read(buffer, 0, bufferSize);
dos.flush();
}
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

if (conn.getResponseCode() == HttpURLConnection.HTTP_OK)
{
//성공
}
else
{//실패


뭐 그래서 


이미지를 한장

더 추가해야 되니

Image 전송 밑에

하나를 꾸겨서 더 

넣었는데


//text 전송
dos.writeBytes("\r\n--" + boundary + "\r\n");
dos.writeBytes("Content-Disposition: form-data; name=\"text\"\r\n\r\n" + str);
//Image 전송
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"image\";filename=\"" + absolutePath + "\"" + lineEnd);
dos.writeBytes(lineEnd);

//Image2 전송
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"image2\";filename=\"" + absolutePath2 + "\"" + lineEnd);
dos.writeBytes(lineEnd);


전송이 안된다..


통신은 되는데

올바른 이미지가

안간다..


그래서 

1시간정도 이것저것

바꾸고 수정해서

보내는데 성공했다.


프로젝트에 쓰던거

짤라서 올리느라

풀코드는 못올리지만


전송하는 부분은

이렇게 하면 된다.

(나중에 서버까지 직접 짜면

파이썬-안드로이드 통신하는글을 써봐야겠다..)



conn.setRequestProperty("img_1", img1_path);
conn.setRequestProperty("img_2", img2_path);
conn.connect();

String name = "itpangpang";
dos = new DataOutputStream(conn.getOutputStream());

FileInputStream mFileInputStream = new FileInputStream(img1_path);

//name 전송
dos.writeBytes("\r\n--" + boundary + "\r\n");
dos.writeBytes("Content-Disposition: form-data; name=\"name\"\r\n\r\n" + name);




//Image 전송
dos.writeBytes("\r\n--" + boundary + "\r\n");
dos.writeBytes("Content-Disposition: form-data; name=\"img_1\";filename=\"" + img1_path + "\"" + lineEnd);
dos.writeBytes("Content-Type: application/octet-stream" + lineEnd);
dos.writeBytes(lineEnd);
int bytesAvailable = mFileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bufferSize];
int bytesRead = mFileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
dos.write(buffer, 0, bufferSize);
bytesAvailable = mFileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = mFileInputStream.read(buffer, 0, bufferSize);
}
mFileInputStream.close();

//Image2 전송

dos = new DataOutputStream(conn.getOutputStream());

mFileInputStream = new FileInputStream(img2_path);


dos.writeBytes("\r\n--" + boundary + "\r\n");
dos.writeBytes("Content-Disposition: form-data; name=\"img_2\";filename=\"" + img_2 + "\"" + lineEnd);
dos.writeBytes("Content-Type: application/octet-stream" + lineEnd);
dos.writeBytes(lineEnd);

int bytesAvailable = mFileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bufferSize];
int bytesRead = mFileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
dos.write(buffer, 0, bufferSize);
bytesAvailable = mFileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = mFileInputStream.read(buffer, 0, bufferSize);
}
mFileInputStream.close();

dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
dos.flush();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK)
{
//성공
}


뭐 보면 그냥 이미지 전송부분을

따로따로 분리해서 보내면 된다.


DataOutputStream과

FileInputStream 객체를

새로 생성해서 보냈더니

잘 전송됬다.


코드에서는

이미지가 2장뿐이라

key값이나 ImagePath도

고정이어서

반복문도 안썼는데


실제로 많은 앱에서는

이미지가 몇장 전송될지 모르니

for문을 쓰면 될 것 같다


dos생성하는 부분부터

mFileInputStream.close까지

반복문을 쓰면 된다 


ArrayList 또는 배열을 써서

서버에 보낼 Key값과

이미지 Path만 변경해주면서

나머지는 똑같이 돌리면

된다.