دوره مجازی اندروید (جلسه 21): کار با AsyncTask و ذخیره فایل در SD card



visibility  
mode_comment   ۳۲

به نام خدا، دوستان سلام، در این جلسه می خواهیم پست ها را بعد از دریافت از سرور با استفاده از AsyncTask داخل Sqlite ذخیره کنیم. همچنین تصاویر پست ها را بعد از دریافت در حافظه sd card ذخیره کنیم. مطلب دیگری که در این جلسه آموزش داده ایم، درخواست و چک کردن دسترسی ها در اندروید مارشملو است.

مطالب مطرح شده در این جلسه عبارتند از :

  • معرفی AsyncTask
    • پیاده سازی AsyncTask
    • معرفی doInBackground
    • معرفی preExecute
    • معرفی onPostExecute
    • معرفی onProgressUpdate
  • آشنایی با دریافت و چک کردن permission ها از اندروید مارشملو به بعد
    • چک کردن موجود بودن permission
    • درخواست persmission از کاربر
    • معرفی تابع onRequestPermissionsResult
  • معرفی ProgressDialog
    • معرفی پارامترهای Constructor
    • پیاده سازی عنوان و متن در Progress Dialog
    • معرفی مفهوم indeterminate
    • تغییر استایل Progress Dialog
    • آپدیت کردن مقدار progress
info توجه

این مطلب یک جلسه از آموزش برنامه نویسی اندروید می باشد و برای مشاهده آن باید در دوره ثبت نام کنید.

ثبت نام در آموزش برنامه نویسی اندروید

comment دیدگاه کاربران
Nima Arian replyپاسخ

سلام فک می کنم فایل مشکل داره البته از دقیقه 26 به بعد تا دقیقه 26 مشکلی نداره اما یکدفعه استاپ میشه لطفا فایل رو بررسی کنید

لقمان آوند

احتمالا ناقص دانلود شده
مجددا دریافتش کنید.

Nima Arian replyپاسخ

الان که دوباره تست کردم متوجه شدم که لینک دانلود فایل ویدئویی فقط 47 مگ هستش در صورتی که حجم کل ویدئو با idm که دانلود از روی مدیا پلیر رو امکان پذیر میکنه 138 مگ هستش پس فایل درست آپلود نشده برای دانلود

لقمان آوند

فایل 138 مگی و کامل این جلسه به درستی آپلود شده و مشکلی نداره. احتمالا ناقص دانلود کردید.
مجددا دریافت کنید.

Amirhosein karimi replyپاسخ

سلام استاد من موقعی کع میخوام وصل شو به LocalHost این ارورو بهم میده …
com.android.volley.NoConnectionError: java.net.ConnectException: failed to connect to /192.168.163.1 (port 81) after 8000ms: isConnected failed: EHOSTUNREACH (No route to host)
البته من از genymotion استفاده نمیکنم من از USD DEBUG یک دستگاه اندرویدی Debug میکنم
————–
3جا این سوال پرسیدم هنوز جواب ندادید . چندین روزم ازش گذشته

سعید شاهینی

سلام، عذرخواهی می کنم من سوالاتون رو ندیده بودم، توی مرورگرتون همین آدرسی که توی اندروید استودیو وارد کردید رو بدید، ببینید سایتتون باز می شه.

Amirhosein karimi

بله باز میشه

سعید شاهینی

با Usb امکان دسترسی به شبکه نخواهید داشت، برای اینکه به کارت شبکه لب تاپتون وصل بشید باید wifi موبایلتون روشن باشه، و توی اپ Ip لب تاپتون رو بدید.

ali rahmanian replyپاسخ

سلام
آموزش شما عالی هستش،فقط لطفا سرعت انتشار جلسات رو بیشتر کنید

سعید شاهینی

سلام، طولانی شدن جلسات دلیلش بیشتر بالا بردن کیفیت جلسات هست ولی من تمام سعیم رو می کنم حتماً

ali rahmanian

من خیلی تدریس شما رو قبول دارم
تجربه خیلی بالایی هم دارید.امیدوارم خیلی خوب بتونیم از دانش شما استفاده کنیم

سعید شاهینی

سلام، ممنونم، شما لطف دارید.

theking replyپاسخ

سلام استاد شاهینی!
بنده به مشکلی برخوردم واون اینکه وقتی برنامه میره که تابع addposts(posts) رو اجرا میکنه!انگار داخل تابع addpostsنمیره و متد بعدی که اجرا میشه cursor.moveNext() هست درصورتی که این متد داخل تابع getPosts هست !من این مشکلات رو با دیباگ متوجه شدم ،چون حتی اصلا انگار تابع execute هست که اجرا نمیشه!حالااستاد به نظر شما مشکل میتونه از کجا باشه؟
با تشکر از آموزش خوبتون!

سعید شاهینی

سلام ، از f8 برای خط به خط دیباگ کردن استفاده می کنید؟

theking

سلام استاد متوجه شدم !زمانی که اینترنت متصل میشه دیگه نباید از دیتابیس ذخیره شده ،recyclerView تغذیه بشه وباید متدgetPostsّFromDataBase غیرفعال بشه تا متد addPosts کارکنه!

theking replyپاسخ

باسلام خدمت استاد شاهینی!
استاد میخواستم بدونم چگونه یک عکس رو با مشخص بودن مسیر ذخیره شده بدست بیاریم؟و اون رو داخل imageView لود کنیم؟
با تشکر از شما!

سعید شاهینی

سلام، با استفاده از Picasso می تونید به جای url، ادرس فایل رو بدید.

Intel replyپاسخ

آموزش های شما خیلی خوب هستن استاد

سید فاضل سدره نشین replyپاسخ

سلام استاد
ارور که نمایش میده رو براتون ایمیل کردم

سعید شاهینی

سلام، باشه پاسخ می دم

مهرداد قاسمیان replyپاسخ

در این جلسه با فایل های app_feature کار می کنید. این فایل ها و پروژه رو کی ساختین

سعید شاهینی

داخل ویدیوها نبوده٬ خودم قبل ضبط ساخته بودم

مهرداد قاسمیان replyپاسخ

با سلام و وقت بخیر خدمت استاد عزیز
در نسخه جدید آندروید استدیو فکر کنم ProgressDialog دیگه قابل استفاده نیست. چون ProgressDialog را به این صورت نشون میده که بینش یک خط هست . جایگزین ProgressDialog چی هست؟

سعید شاهینی

سلام٬ ProgressDialog ربطی به اندروید استودیو نداره و مربوط به ورژن SDK هست. در نسخه جدید SDK هم به درستی کار می کنه. احتمالا شما جایی رو اشتباه پیاده سازی کردید.

حامد replyپاسخ

سلام
استاد برنامه من بدون ارور بالا میاد
اما RecycleView
خیلی سنگین کار میکنه
تعدا عکس های داخل RecycleView
6-7
//
حدس خود من کلاس DataGenerator
هست که عکس ها باید ادد بشن

public class CarActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activity_car);

        RecyclerView recyclerView=(RecyclerView)findViewById(R.id.recycleView);
        CarAdapter carAdapter=new CarAdapter(this,DataGenerator.getData(this));
        recyclerView.setLayoutManager(new GridLayoutManager(this,2,StaggeredGridLayoutManager.HORIZONTAL,false));
        recyclerView.setAdapter(carAdapter);
    }
///
public class DataGenerator {
    public static List<Car> getData(Context context) {
        List<Car> cars = new ArrayList<>();

        for (int i = 1; i <= 7; i++) {
            Car car = new Car();
            car.setId(i);

            switch (i) {
                case 1:
                    car.setPositonImage(ResourcesCompat.getDrawable(context.getResources()
                            , R.drawable.motor, null));
                    car.setPositionTitle("نمای موتور");
                    break;
                case 2:
                    car.setPositonImage(ResourcesCompat.getDrawable(context.getResources()
                            , R.drawable.dakhel2, null));
                    car.setPositionTitle("نماس فضای داخل ");
                    break;
                case 3:
                    car.setPositonImage(ResourcesCompat.getDrawable(context.getResources()
                            , R.drawable.darb_bironi, null));
                    car.setPositionTitle("درب نمای بیرون");
                    break;
                case 4:
                    car.setPositonImage(ResourcesCompat.getDrawable(context.getResources()
                            , R.drawable.saghf, null));
                    car.setPositionTitle("نمای سقف");
                    break;
                case 5:
                    car.setPositonImage(ResourcesCompat.getDrawable(context.getResources()
                            , R.drawable.jelo_panjare, null));
                    car.setPositionTitle("نمای جلو پنجره");
                    break;
                case 6:
                    car.setPositonImage(ResourcesCompat.getDrawable(context.getResources()
                            , R.drawable.sandogh_aghab_bironi, null));
                    car.setPositionTitle("نمای صندوق عقب");
                    break;

            }
            cars.add(car);

        }
        return cars;


    }
سعید شاهینی

احتمالا حجم عکس هایی که گذاشتید زیاد هست، حجمشون بهتره از 20 کیلوبایت بیشتر نباشه

حامد replyپاسخ

نکته دیگه اینکه
انگار ViewHolder
نیازی نمیبینه که بعد از find کردن Cast انجام بده

 public class CarViewHolder extends RecyclerView.ViewHolder {
        private ImageView Car_Position_image;
        private TextView Car_Position_Title;

        public CarViewHolder(View itemView) {
            super(itemView);
            Car_Position_image = itemView.findViewById(R.id.Car_Position_image);
            Car_Position_Title = itemView.findViewById(R.id.Car_Position_Title);
            context = itemView.getContext();
سعید شاهینی

بله در نسخه های جدید اندروید استودیو دیگه لازم نیست

حامد replyپاسخ

حل شد ممنونم
حجم عکس ها بالا بود

علی رجبی replyپاسخ

سلام استاد
من یه کلاسی برای دانلود یه فایل از یه url زدم،کلاسم به درستی تو جایی که بخوام،فایل رو دانلود و کپی میکنه
فقط مشکلم اینه که پروگرس رو اپدیت نمیکنه حینه دانلود،اگه میشه یه نگاه کنین

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.content.ContextCompat;
import android.widget.Toast;

import com.yarolegovich.lovelydialog.LovelyStandardDialog;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

public class DownloadFile extends AsyncTask<String,Integer,String> {
    ProgressDialog dialog;

    private Context context;
    private String gamepath;
    private String GameName;
    private long sizeData;
    public DownloadFile(Context context, String gamepath,long DataSize,String GameName) {
        this.context = context;
        this.gamepath = gamepath;
        this.sizeData=DataSize;
        this.GameName=GameName;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        showDialog();

    }


    @Override
    protected String doInBackground(String … url) {

       downloadFileFromURL(url);


        return "";
    }



    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        dialog.dismiss();
        Toast.makeText(context, "دانلود شما با موفقیت به اتمام رسید", Toast.LENGTH_SHORT).show();
}


    @Override
    protected void onProgressUpdate(Integer… values) {
        super.onProgressUpdate(values);
        dialog.setProgress(values[0]);
    }

    private void showDialog(){
        dialog =new ProgressDialog(context);
        dialog.setMessage("لطفا تا پایان دانلود،صبر بفرمایید");
        dialog.setTitle("در حال دانلود …");
        dialog.setCancelable(false);
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.show();




    }

    private void downloadFileFromURL(String[] url) {
        try {
            URL myURL;
            myURL = new URL(url[0]);
            URLConnection connection=myURL.openConnection();
            connection.connect();
            int lengthOfFile=connection.getContentLength();
            copyFile(gamepath,myURL,sizeData);

        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(context, "دانلود دیتا با خطا مواجه شد", Toast.LENGTH_SHORT).show();
        }


    }

    private void copyFile(String dataPath,URL url,long sizeOfFile){
        File gameFolder=new File(dataPath);
        try {
            String nameIsoFile= GameName;
            InputStream inputStream=new BufferedInputStream(url.openStream(),1024*10);
            OutputStream outputStream=new FileOutputStream(new File(gameFolder,nameIsoFile));
            byte[] buffer =new byte[1024*10];

            for (int length=0;((length=inputStream.read(buffer))!=-1);length++){
                outputStream.write(buffer,0,length);
                publishProgress((length*100)/((int)sizeOfFile));
            }

            outputStream.flush();
            outputStream.close();
            inputStream.close();


        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(context, "کپی دیتا با خطا مواجه شد", Toast.LENGTH_SHORT).show();
        }


    }
}
سعید شاهینی

سلام، من که با خوندن این کد طولانی چیزی متوجه نمی شم، شما یک breakpoint داخل بدنه متد onProgressUpdate بگذار ببین این متد اصلا فراخونی می شه یا نه.

Saeed Hoseini replyپاسخ

استاد سلام عرض شد.
این ارور یعنی چی؟
10-15 04:18:36.349 660-710/com.example.world.test1 E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.world.test1, PID: 660
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:325)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.IllegalStateException: Unrecognized type of request: Request{192.168.1.105/7learn/uploads/pic1.jpg}
at com.squareup.picasso.BitmapHunter$2.load(BitmapHunter.java:66)
at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:206)
at com.squareup.picasso.RequestCreator.get(RequestCreator.java:385)
at com.example.world.test1.DownloadImageTask.doInBackground(DownloadImageTask.java:58)
at com.example.world.test1.DownloadImageTask.doInBackground(DownloadImageTask.java:21)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
at java.lang.Thread.run(Thread.java:761) 
10-15 04:18:37.043 660-660/com.example.world.test1 E/WindowManager: android.view.WindowLeaked: Activity com.example.world.test1.view.activity.Post1_Activity has leaked window DecorView@e328c3b[ذخیره سازی عکس ها] that was originally added here
at android.view.ViewRootImpl.(ViewRootImpl.java:418)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.app.Dialog.show(Dialog.java:322)
at com.example.world.test1.DownloadImageTask.onPreExecute(DownloadImageTask.java:45)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:620)
at android.os.AsyncTask.execute(AsyncTask.java:567)
at com.example.world.test1.view.activity.Post1_Activity.saveImageInSdcard(Post1_Activity.java:85)
at com.example.world.test1.view.activity.Post1_Activity.access$200(Post1_Activity.java:24)
at com.example.world.test1.view.activity.Post1_Activity$1.onRecieved(Post1_Activity.java:48)
at com.example.world.test1.ApiService$3.onResponse(ApiService.java:104)
at com.example.world.test1.ApiService$3.onResponse(ApiService.java:83)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:90)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

ارسال نظرات

کاربر گرامی، امکان ارسال نظر و پشتیبانی برای دوره های مجازی فقط برای دانشجویان این دوره امکان پذیر می باشد.