این کلاس آپلودری هست که من برای پروژه خودم نوشتم:
public class UploadManager {
private String destination;
private String source;
private ProgressDialog dialog;
public UploadManager setSource(String source) {
this.source = source;
return this;
}
public UploadManager setDestination(String destination) {
this.destination = destination;
return this;
}
public UploadManager setDialog(ProgressDialog dialog) {
this.dialog = dialog;
return this;
}
public String upload() {
final String[] result = {""};
final File sourceFile = new File(source);
if (!sourceFile.isFile()) {
dialog.dismiss();
} else {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
HttpURLConnection connection;
DataOutputStream dataOutputStream;
String lineEnd = "rn";
String twoHyphens = "--";
String boundary = "*****";
int bytesAvailable, bufferSize;
byte[] buffer;
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL(App.URL_UPLOAD);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setChunkedStreamingMode(App.BUFFER_SIZE);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-alive");
connection.setRequestProperty("Cache-Control", "no-cache");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
connection.setRequestProperty("photo", destination);
dataOutputStream = new DataOutputStream(connection.getOutputStream());
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream.writeBytes("Content-Disposition: form-data; name="photo";filename="" + destination + """ + lineEnd);
dataOutputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, App.BUFFER_SIZE);
buffer = new byte[bufferSize];
while (fileInputStream.read(buffer, 0, bufferSize) > 0) {
dataOutputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, App.BUFFER_SIZE);
}
dataOutputStream.writeBytes(lineEnd);
dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
fileInputStream.close();
dataOutputStream.flush();
dataOutputStream.close();
connection.connect();
InputStream inputStream = connection.getInputStream();
result[0] = HelperString.convertInputStreamToString(inputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
while (thread.isAlive()) ;
}
return result[0];
}
}
نقل قول:توضیح: App.URL_UPLOAD آدرس اسکریپتی در سرور هست که وظیفه مدیریت فایلهای آپلودشده رو بعهده داره. مثلاً mysite.com/upload.php با محتوای زیر:
if (isset($_FILES['photo'])) {
$photo = & $_FILES['photo'];
if ($photo['error'] == 0) {
if($im = ImageCreateFromJPEG($photo['tmp_name'])) {
$fileNameParts = explode('.', $photo['name']);
$result = ['code' => (ImageJPEG($im, 'photos/' . $fileNameParts[0] . '.jpg', 100) ? 1 : 0)];
} else {
$result = ['code' => 0];
}
}
}
App.BUFFER_SIZE هم میزان بافر برای انتقال اطلاعات هست که من 8 کیلوبایت درنظر گرفتم (8 * 1024 = 8192)
یه نکته دیگه اینکه setSource برای مشخصکردن مسیر فیزیکی فایل مبدأ و setDestination برای مشخصکردن اسمی که میخوایم فایل رو تحت اون آپلود کنیم (و توی سرور استفاده بشه) بکار میره.
بعنوان مثالی از نحوه استفاده، کلاس Async زیر رو درنظر بگیرین که عکس انتخابی رو آپلود میکنه:
public class AsyncUploadPhoto extends AsyncTask<String, String, String> {
private String source;
private String destination;
private ProgressDialog progressDialog;
public AsyncUploadPhoto(String source, String destination) {
this.source = source;
this.destination = destination;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(App.currentActivity);
progressDialog.setTitle("آپلود عکس به سرور");
progressDialog.setMessage("لطفاً صبر کنید...");
progressDialog.show();
}
@Override
protected String doInBackground(String... strings) {
return new UploadManager()
.setSource(source)
.setDestination(destination)
.setDialog(progressDialog)
.upload();
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
JSONObject json = new JSONObject(s);
int code = json.getInt("code");
if (code == 1) {
Toast.makeText(App.context, "تصویر با موفقیت روی سرور آپلود شد.", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(App.context, "در زمان آپلود تصویر به سرور خطایی رخ داد. مجدداً تلاش کنید.", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
progressDialog.dismiss();
}
}
و درنهایت نحوه استفاده از کلاس AsyncUploadPhoto برای اینکه تصویر در پسزمینه آپلود بشه (توی یک Thread جدا) تا برنامه اصلی موقع آپلود و گرفتن جواب از سرور هنگ نکنه:
new AsyncUploadLogo(imagePath, "photo.jpg").execute();
نقل قول:نکته: imagePath مسیری فیزیکی عکس روی موبایل هست و photo.jpg هم اسمی که میخوایم تحت اون نام برای سرور آپلود بشه (این اسم توی سرور بعنوان نام فایلی که برای آپلود انتخاب شده درنظر گرفته میشه. درست مثل اینکه کاربر توی فرم HTML فایل photo.jpg رو انتخاب کرده باشه).
اگه سؤالی بود در خدمتم. هر جاش رو متوجه نشدین بپرسین. فقط قبلش خط به خط بخونید و مطمئن بشین که متوجه نمیشین چون سعی کردم خیلی خوانا بنویسم.