안드로이드 개발 질문/답변
(글 수 45,052)
sdcard에서 이미지를 선택한 후 웹서버에 업로드 하는 부분을 검색하여 보고있습니다.
파일업로드 부분입니다.
mFileInputStream = new FileInputStream(fileName);
connectUrl = new URL("urlString);
Log.d("Test", "mFileInputStream is " + mFileInputStream);
Log.d("data", "connectUrl is " + connectUrl);
// open connection
HttpURLConnection conn = (HttpURLConnection) connectUrl
.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
// write data
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
int lastindex = 0;
lastindex = fileName.lastIndexOf("/");
fileName = fileName.substring(lastindex + 1, fileName.length());
dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\"; filename=\""
+ URLEncoder.encode(fileName, "utf-8").replace("+", "%20")
+ "\"" + lineEnd);
dos.writeBytes(lineEnd);
int bytesAvailable = mFileInputStream.available();
int maxBufferSize = 1024;
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bufferSize];
int bytesRead = mFileInputStream.read(buffer, 0, bufferSize);
float uploadsize = 0;
float bytesize = (float)100/(bytesAvailable/bufferSize); //버퍼사이즈의 전체파일사이즈에 대한 퍼센트
//read image
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
uploadsize += bytesize; // += 퍼센트
if ((int)uploadsize > 0 ) // 현재진행률이 0이상이라면
Total = (int)uploadsize; //ProgressDialog가 쓰레드로 돌면서 0.2초마다 Total값을 체크해서 setProgress로 진행
Log.d("-", "Total"+Total);
bytesAvailable = mFileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = mFileInputStream.read(buffer, 0, bufferSize);
}
if ((int)uploadsize < 100)
Total = 100; //퍼센트를 구하는 과정에서 버려지는 부분때문에 100이 안되는 경우 발생
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"title\""
+ lineEnd);
dos.writeBytes(lineEnd);
dos.writeBytes(txtTitle.toString());
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"contents\""
+ lineEnd);
dos.writeBytes(lineEnd);
dos.writeBytes(txtContents.toString());
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// close streams
Log.e("Test", "File is written");
mFileInputStream.close();
// dos.flush(); // finish upload...
// get response
InputStream is = conn.getInputStream();
Total = 200;
BufferedReader bfr = new BufferedReader(new InputStreamReader(is,"UTF-8"));
StringBuffer b = new StringBuffer();
String buf = null;
while ((buf = bfr.readLine()) != null) {
b.append(buf);
}
result = b.toString();
Log.e("Test", "result = " + result);
dos.close();
removeDialog(PROGRESS_DIALOG); ProgressDialo 부분입니다
protected Dialog onCreateDialog(int id) {
switch (id) {
case PROGRESS_DIALOG:
progressDialog = new ProgressDialog(async.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Uploading..");
progressThread = new ProgressThread(handler);
progressThread.start();
return progressDialog;
default:
return null;
}
}
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
int total = msg.getData().getInt("total");
progressDialog.setProgress(total);
progressThread.setState(1);
if (total >= 100) {
dismissDialog(PROGRESS_DIALOG);
progressThread.setState(ProgressThread.STATE_DONE);
}
}
};
private class ProgressThread extends Thread {
Handler mHandler;
final static int STATE_DONE = 0;
final static int STATE_RUNNING = 1;
int mState;
int total;
ProgressThread(Handler h) {
mHandler = h;
}
public void run() {
mState = STATE_RUNNING;
total = 0;
while (mState == STATE_RUNNING) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// 에러처리
}
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
b.putInt("total", total);
msg.setData(b);
mHandler.sendMessage(msg);
//total = Total;
}
}
// 현재의 상태를 설정하는 메소드
public void setState(int state) {
mState = state;
total= Total;
}
}방법과 효율을 둘째치더라도 일단 무선인터넷으로 실행했을때는 잘 되는 것처럼 보였습니다.
그러다가 3G로 접속해서 진행할때 ProgressDialog는 100%가 되었지만 웹서버에 파일은 업로드되지 않았으며
약간의(파일의 크기에따라서 짧게는 30초 길게는 1분여정도) 시간을 두고 파일이 업로드되는것을 확인하였습니다.
그리고 파일업로드에 대한 기본이 없는 저의 짧은 식견으로 파일업로드부분의 while문에서 dos.write(buffer, 0, bufferSize);
여기에서 파일을 쪼개서 전송하는것으로 알고있었습니다. 그래서 저 부분을 전역변수인 Total에 저장시켜서
ProgressDialog의 쓰레드에서 Total값을 참조시키는 방법을 썼습니다. 하지만 3G에서 확인하니 저 부분에서는 아예 데이터통신을
하지 않고 InputStream is = conn.getInputStream(); 이 부분에 와서야 데이터통신을 하는것 같았습니다.
위의 소스에서 실직적으로 파일이 업로드 되는 부분은 어디인가요?
혹은 위의 방법이 너무 비효율적이라면 수정방향을 쫌 제시해주세요; 부탁드립니다.
답변이 없어 댓글을 썼다가 다시 등록하는것입니다.
기존에 글은 동일하여 삭제하였습니다.




정말 궁금합니다...