ডাউনলোডম্যানেজার ব্যবহার করে ক্রিয়াকলাপের ভিতরে ডাউনলোডের অগ্রগতি দেখান


90

আমি ডাউনলোড ম্যানেজারটি আমার অ্যাপ্লিকেশনটির মধ্যে বিজ্ঞপ্তি বারে যে একই অগ্রগতি দেখায় তা পুনরুত্পাদন করার চেষ্টা করছি, তবে আমার অগ্রগতি কখনই প্রকাশিত হয় না। আমি রানওনউইথ্রেড () ব্যবহার করে এটি আপডেট করার চেষ্টা করছি, তবে কোনও কারণে এটি আপডেট হয়নি।

আমার ডাউনলোড:

String urlDownload = "https://dl.dropbox.com/s/ex4clsfmiu142dy/test.zip?token_hash=AAGD-XcBL8C3flflkmxjbzdr7_2W_i6CZ_3rM5zQpUCYaw&dl=1";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(urlDownload));

request.setDescription("Testando");
request.setTitle("Download");
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "teste.zip");

final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);

final long downloadId = manager.enqueue(request);

final ProgressBar mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);

new Thread(new Runnable() {

    @Override
    public void run() {

        boolean downloading = true;

        while (downloading) {

            DownloadManager.Query q = new DownloadManager.Query();
            q.setFilterById(downloadId);

            Cursor cursor = manager.query(q);
            cursor.moveToFirst();
            int bytes_downloaded = cursor.getInt(cursor
                    .getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
            int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));

            if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
                downloading = false;
            }

            final double dl_progress = (bytes_downloaded / bytes_total) * 100;

            runOnUiThread(new Runnable() {

                @Override
                public void run() {

                    mProgressBar.setProgress((int) dl_progress);

                }
            });

            Log.d(Constants.MAIN_VIEW_ACTIVITY, statusMessage(cursor));
            cursor.close();
        }

    }
}).start();

আমার স্ট্যাটাসমেসেজ পদ্ধতি:

private String statusMessage(Cursor c) {
    String msg = "???";

    switch (c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS))) {
    case DownloadManager.STATUS_FAILED:
        msg = "Download failed!";
        break;

    case DownloadManager.STATUS_PAUSED:
        msg = "Download paused!";
        break;

    case DownloadManager.STATUS_PENDING:
        msg = "Download pending!";
        break;

    case DownloadManager.STATUS_RUNNING:
        msg = "Download in progress!";
        break;

    case DownloadManager.STATUS_SUCCESSFUL:
        msg = "Download complete!";
        break;

    default:
        msg = "Download is nowhere in sight";
        break;
    }

    return (msg);
}

আমার লগ নিখুঁতভাবে কাজ করছে, যখন আমার ডাউনলোড চলমান আছে "ডাউনলোডের কাজ চলছে!" এবং যখন এটি সম্পূর্ণ হয় "ডাউনলোড সম্পূর্ণ!", তবে এটি আমার অগ্রগতির ক্ষেত্রে ঘটে না কেন? আমার সত্যিকার অর্থে কিছু সাহায্যের প্রয়োজন, অন্য লজিকগুলি সেগুলি করার জন্য সত্যই প্রশংসিত


এটি কি আপনার ফাইলটি খুব ছোট এবং অগ্রগতি প্রকাশের আগে ডাউনলোডটি সম্পূর্ণ হয়ে যায়? ডাউনলোড ক্যোয়ারী আপনার কাজে কী ফিরিয়ে দেয়? যদি কিছু সময় পরে টাস্কটি কার্যকর হয় তবে আপনার মূল থ্রেডে আরও কিছু দীর্ঘকালীন ক্রিয়াকলাপ থাকতে পারে।
পল ল্যামার্টসমা

আমি কোড আপডেট করেছি, আপনি কি এখনই একবার দেখতে পারেন? এবং ফাইলটি দৈর্ঘ্যের তুলনায় এটি খুব ছোট নয়, আমি বিজ্ঞপ্তি বারে ডাউনলোডের অগ্রগতিটি দেখতে পাচ্ছি
ভিক্টর লেয়ার্ট

উত্তর:


62

আপনি দুটি পূর্ণসংখ্যা ভাগ করছেন:

final double dl_progress = (bytes_downloaded / bytes_total) * 100;

হিসাবে bytes_downloadedকম bytes_total, (bytes_downloaded / bytes_total)0 হবে, এবং আপনার অগ্রগতি তাই সবসময় 0 হতে হবে।

আপনার হিসাবটি এতে পরিবর্তন করুন

final int dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);

পুরো (তল তবুও) পারসেন্টাইলগুলিতে অগ্রগতি অর্জন করতে।


@ এজেড_আপনার অবদানের জন্য ধন্যবাদ আমি আপনাকে আরও বিস্তৃত সমাধানের সাথে নিজের উত্তর যুক্ত করার পরামর্শ দিচ্ছি।
পল ল্যামার্তসমা

এটি ঠিক আছে আমি ইতিমধ্যে স্বীকৃত উত্তরের আর একটি উত্তর রাখতে চাই না কারণ এটি ব্যবহারকারীদের পক্ষে কঠিন হবে। আপনি আমার সম্পাদনাটি গ্রহণ না করা বেছে নিতে পারেন :)
এজেড_

4
যদি আপনার ক্রিয়াকলাপ শেষ হয়ে যায় এবং আপনি ডাউনলোডটি বাতিল করতে চান তবে আপনি division by zeroমারাত্মক ত্রুটি পাবেন। এজন্য আমি এটি পছন্দ করেছি final int dl_progress = ( bytes_total > 0 ? (int) ((bytes_downloaded * 100L) / bytes_total) : 0 );
KaHa6uc

17

পলের উত্তরটি সঠিক তবে বৃহত্তর ডাউনলোডগুলির সাথে আপনি সর্বাধিক দ্রুত হিট হবেন এবং নেতিবাচক অগ্রগতি পেতে শুরু করবেন। আমি সমস্যাটি সমাধানের জন্য এটি ব্যবহার করেছি:

final int dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);

তুমি ঠিক; অন্যরা যাতে ভুল না ঘটে তা নিশ্চিত করতে আমি আমার উত্তরটি পরিবর্তন করেছি ified
পল ল্যামার্টসমা

4

পল যেমন বলেছিল, আপনি দুটি পূর্ণসংখ্যা ভাগ করে চলেছেন, ফলাফল সর্বদা <1।

বিভাজনের আগে সর্বদা আপনার নম্বরটি ফেলে দিন , যা গণনা করে ফ্লোট-পয়েন্টে ফিরে আসে।

ডিভবিজারো পরিচালনা করতে ভুলবেন না।

final int dl_progress = (int) ((double)bytes_downloaded / (double)bytes_total * 100f);

4

যদি কারও কারও কারও কারও কাছে আরএক্সজেবার সাথে কোটলিনে @ ভিক্টর লেয়ার্টের প্রশ্ন থেকে ডাউনলোড অগ্রগতি অর্জনের বাস্তবায়ন প্রয়োজন হয় তবে আপনি এখানে যান:

ডাউনলোডস্টেটরেট্রাইভার.কটি

class DownloadStateRetriever(private val downloadManager: DownloadManager) {

    fun retrieve(id: Long) {
        var downloading = AtomicBoolean(true)

        val disposable = Observable.fromCallable {
            val query = DownloadManager.Query().setFilterById(id)
            val cursor = downloadManager.query(query)

            cursor.moveToFirst()

            val bytesDownloaded = cursor.intValue(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)
            val bytesTotal = cursor.intValue(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)

            if (isSuccessful(cursor)) downloading.set(false)
            cursor.close()

            if (bytesTotal == 0) 0.toInt() else ((bytesDownloaded * 100F) / bytesTotal).toInt()
        }
                .subscribeOn(Schedulers.newThread())
                .delay(1, TimeUnit.SECONDS)
                .repeatUntil { !downloading.get() }
                .subscribe {
                    Timber.i("Subscribed to $id. progress: $it")
                }
    }

    private fun isSuccessful(cursor: Cursor) = status(cursor) == DownloadManager.STATUS_SUCCESSFUL

    private fun status(cursor: Cursor) = cursor.intValue(DownloadManager.COLUMN_STATUS)
}

আরও কোডের স্বচ্ছতার জন্য আমি কার্সারে এক্সটেনশন যুক্ত করেছি:

কার্সর এক্সটেনশনস.কেটি

import android.database.Cursor

fun Cursor.column(which: String) = this.getColumnIndex(which)
fun Cursor.intValue(which: String): Int = this.getInt(column(which))
fun Cursor.floatValue(which: String): Float = this.getFloat(column(which))
fun Cursor.stringValue(which: String): String = this.getString(column(which))
fun Cursor.doubleValue(which: String): Double = this.getDouble(column(which))

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.