آپلود فایل (چالش برانگیز - حل نشده)
سلام
- مشکل چیه ؟
بنده درگیر پروژه ای هستم که در آن نیاز به عملیات آپلود فایل در سرور دارم ، خُب در اینترنت هم جست و جو کردم و به نتایجی هم رسیدم و در حال حاظر آپلود فایل به سرور رو انجام میدم ، اما افکاری نظیر "آیا روش بهتری وجود داره؟" ، "اصلا اصولی این عملیت رو انجام میدم" و... باعث شد در انجمن طرح سوال کنم ، در زیر خروجی جست و جو های من و اطلاعات بیشتر رو می تونید ملاحضه کنید.
- برای حل این مشکل چیکار کردم ؟
1. در یک سایت ایرانی یک فیلم آموزش آپلود و دانلود را دیدیم که کدش رو یکی از بچه ها تو سایت گذاشته لینک
2. گوگل کردم و با روش کد کردن فایل (Base64) آشنا شدم که اگر در انجمن جست و جو کنید متوجه میشید که طبق گفته محمد حسین عزیز این روش زیاد اصولی نیست و حدود 20% به حجم فایل اضافه میشه. لینک(آموزش)
3. بعد متوجه شدم که با استفاده از کتابخانه ای که Apache منتشر کرده می تونم فایل رو بصورت Multipart آپلود کنم (این روش به نظر من بهترین روش باشه و من سیستم آپلود فعلی پروژه ام رو با همین روش نوشتم) ، اما این روش هم مشکلات خاصی داشت مثلا نمی شد درصد آپلود شده رو بدست آورد (که اونم یجورایی درست کردم ولی اصولی نبود) ، و مشکل بعدی اینکه بعضی از کلاس های این کتابخانه منسوخ شده و آموزش کلاس های جایگزین کم گیر میاد.
4. بعد از اینکه متوجه شدم استاد تلگرامشون رو راه اندازی کردند ، مزاحمشون شدم و در چند پیام خصوصی ماجرا را توضیح دادم ، جواب ایشون این بود : "هر روشی کاربرد خودش رو داره و ماهیت پروژه نوع روش رو تایین می کنه اما Multipart راحتتر هست و شاید در آینده آموزش داشته باشیم"
5. متوجه شدم که یک سایت ایرانی آموزشی برای ساخت نرم افزاری مثل "دیوار" را عرضه کرده است ، با مدرس آموزش که صحبت داشتم گفت از روش Base64 پروسه آپلود را عملی کرده است.
6. در آخر هم سوالی در انجمن مطرح کردم تا از تجربیات شما دوستان عزیز استفاده کنم.
با تشکر
حمید زمانی
روش Base64 اصلا پیشنهاد نمیشه، من چند وقت پیش یک نمونه آپلودر نوشتم. نمیتونم سورس کامل رو قرار بدم ولی یک نمونه اولیه قرار میدم خودتون میتونید کاملش کنید. اولین کاری که باید بکنید اصولی نوشتن این کلاسه (Design Pattern Builder پیشنهاد میشه). دوم اضافه کردن لیستنر هایی که میخواید. (توجه داشته باشید که این یک کلاسه و هرجا میخواید یک فایل رو آپلود کنید فقط کافیه یک Instance ازش بسازید و نباید چند بار اضافه شه.)
package helper; import android.content.Context; import android.os.AsyncTask; import android.util.Log; import android.view.View; import android.widget.ProgressBar; import android.widget.TextView; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import java.io.File; import java.io.IOException; /** * Created by Hajhosseini on 6/19/2015. */ public class UploadHelper extends AsyncTask<Void, Integer, String> { Context context; ProgressBar progressBar; TextView txtPercent; private String filePath = null; private String uploadUrl; long totalSize = 0; public UploadHelper(Context context, ProgressBar progressBar, TextView txtPercent,String url,String filePath){ this.context = context; this.progressBar = progressBar; this.txtPercent = txtPercent; uploadUrl = url; this.filePath = filePath; } @Override protected void onPreExecute() { // setting progress bar to zero progressBar.setProgress(0); super.onPreExecute(); } @Override protected void onProgressUpdate(Integer... progress) { // Making progress bar visible progressBar.setVisibility(View.VISIBLE); // updating progress bar value progressBar.setProgress(progress[0]); // updating percentage value txtPercent.setText(String.valueOf(progress[0]) + "%"); } @Override protected String doInBackground(Void... params) { return uploadFile(); } @SuppressWarnings("deprecation") private String uploadFile() { String responseString = null; HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(uploadUrl); try { AndroidMultiPartEntity entity = new AndroidMultiPartEntity( new AndroidMultiPartEntity.ProgressListener() { @Override public void transferred(long num) { publishProgress((int) ((num / (float) totalSize) * 100)); } }); File sourceFile = new File(filePath); // Adding file data to http body entity.addPart("image", new FileBody(sourceFile)); totalSize = entity.getContentLength(); httppost.setEntity(entity); // Making server call HttpResponse response = httpclient.execute(httppost); HttpEntity r_entity = response.getEntity(); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == 200) { // Server response responseString = EntityUtils.toString(r_entity); } else { responseString = "Error occurred! Http Status Code: " + statusCode; } } catch (ClientProtocolException e) { responseString = e.toString(); } catch (IOException e) { responseString = e.toString(); } return responseString; } @Override protected void onPostExecute(String result) { Log.e("TAG", "Response from server: " + result); // showing the server response in an alert dialog super.onPostExecute(result); } }
موفق باشی مرد جوان ;)
بهتره از کتابخانه های Apache استفاده نشه چون ممکنه با اندروید سازگاری نداشته باشه.
پیشنهاد من اینه که از OKHttp یا HttpUrlConnection استفاده بشه. اینجوری که از دوستان شنیدم با کتابخانه Volley هم میشه آپلود انجام داد که در این صورت بهترین روش همینه.
ولی به جای HttpClient یا HttpResponse میتونید از :
HttpURLConnection connection = (HttpURLConnection)url.openConnection(); connection.setRequestProperty("User-Agent", ""); connection.setRequestMethod("POST"); connection.setDoInput(true); connection.connect();
استفاده کنید. کلا گوگل به نسبت سیاست هایی که داره و کتابخانه هایی که میسازه، هر چند وقت یکبار کتابخانه هاشو منسوخ میکنه. این به این معنی نیست که استفاده ازشون مشکل سازه، به این معنیه که اگر شما میخواید از امکانات جدید استفاده کنید، آپدیت کنید. به نظر من بهتره توی پروژه های قبلی تغییری داده نشه ولی اگر پروژه جدیدی استارت میزنید، از جدید ترین روش استفاده کنید. کدهای بالا رو من چند ماه پیش نوشتم و در اون زمان گزینه خوبی بود، شما میتونید به نسبت زمانی که کد میزنید و به نسبت انتظاری که از برنامتون دارید، تغییرات رو اعمال کنید، ولی این تغییرات نباید مانعی در کدنویسیتون بشه، مثلا نباید چند روز صرف به روز رسانی چند خط کد کنید. یا اگر کتابخانه ای جدید اومده و داکیومنت درست درمون نداره، نیازی نیست اولین نفر باشید که ازش استفاده میکنید. همه چیز بستگی به نیاز شما داره.
این لینک رو هم بخونید بد نیست، بعضی وقت ها گوگل هم پشیمون میشه ;)
سلام دوست عزیز . خیلی تاپیک عالی ای بود استفاده کردیم.منم یک برنامه دارم مینویسم باید بگم تنها مشکلم همینه .آپلود فایل به سرور. مخصوصا زمانی که حجم فایل کمی بالا میره. حالا من در برنامم بیشتر هدف فایل نوشتاریه .ولی خب پی دی اف هایی هم هستند که حجمشون بالای هفت هشت مگابایته. یک کد ساده من نوشتم که فایل رو آپلود میکرد.حالا با async و کتابخوانه هایی که دوستان گفتند آشنا نیستم زیاد ولی کد من فایبل رو میفرستاد فقط. اومدم و progressbar هم براش گذاشتم و در حلقه ای مقدار فایل آپلود شده رو محاسبه میکرد اما مشکلم این بود که اگه حجم فایل بالای یک مگ میشد خیلی طول میکشه تا progressbar به آخر برسه و آخرش هم کرش میکنه
خواستم بگم که منم نیاز شدیدی به آموزش آپلود فایل دارم خیلی اصولی و تر و تمیز باید باشه چون اصلی ترین قسمت برنامم هست. ممنون میشم تجربیات خودتون رو بیشتر در اختیارمون بذارین
مچکرم
ای بابا ... منم چند وقته درگیر همین آپلود فایل (ویدیو) روی سرور هستم اما تا حالا هر راهی رفتم به در بسته خوردم ... جالبه تو همین انجمن هم خیلیا گیر همین مساله یعنی یه کد تمیز و مرتب برا آپلود فایل اند ... کاش استاد یه سری به این تاپیکا میزد و خودش وارد عمل میشد تا حداقل یه راهی جلو پای ما میذاشت ... آقای آقاجانی کمککککککککککککککککککککککککککککککککککککککککککککککککککککک ;( ;( ;(
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .