java - tutorial - why progress dialog is deprecated




Baixe um arquivo com Android e mostre o progresso em um ProgressDialog (8)

Enquanto eu estava começando a aprender desenvolvimento android, eu aprendi que ProgressDialog é o caminho a percorrer. Existe o método setProgress de ProgressDialog que pode ser invocado para atualizar o nível de progresso à medida que o arquivo é baixado.

O melhor que tenho visto em muitos aplicativos é que eles personalizam os atributos da caixa de diálogo de progresso para dar uma melhor aparência à caixa de diálogo de progresso do que a versão de estoque. Bom para manter o usuário envolvido com alguma animação de sapo, elefante ou gatos / cachorrinhos fofos. Qualquer animação com a caixa de diálogo de progresso atrai os usuários e eles não sentem vontade de ficar esperando por muito tempo.

Vou escrever um post no ProgressDialog e compartilhar aqui em breve.

Editar: Mostrar barra de progresso ao baixar um arquivo no android

Eu estou tentando escrever um aplicativo simples que é atualizado. Para isso eu preciso de uma função simples que pode baixar um arquivo e mostrar o progresso atual em um ProgressDialog . Eu sei como fazer o ProgressDialog , mas não sei como exibir o progresso atual e como baixar o arquivo em primeiro lugar.


Estou adicionando outra resposta para outra solução que estou usando agora porque o Android Query é muito grande e não é mantido para se manter saudável. Então eu mudei para este https://github.com/amitshekhariitbhu/Fast-Android-Networking .

    AndroidNetworking.download(url,dirPath,fileName).build()
      .setDownloadProgressListener(new DownloadProgressListener() {
        public void onProgress(long bytesDownloaded, long totalBytes) {
            bar.setMax((int) totalBytes);
            bar.setProgress((int) bytesDownloaded);
        }
    }).startDownload(new DownloadListener() {
        public void onDownloadComplete() {
            ...
        }

        public void onError(ANError error) {
            ...
        }
    });

Eu modifiquei a classe AsyncTask para manipular a criação de progressDialog no mesmo contexto. Acho que o código a seguir será mais reutilizável. (pode ser chamado de qualquer atividade apenas passar contexto, arquivo de destino, mensagem de diálogo)

public static class DownloadTask extends AsyncTask<String, Integer, String> {
    private ProgressDialog mPDialog;
    private Context mContext;
    private PowerManager.WakeLock mWakeLock;
    private File mTargetFile;
    //Constructor parameters :
    // @context (current Activity)
    // @targetFile (File object to write,it will be overwritten if exist)
    // @dialogMessage (message of the ProgresDialog)
    public DownloadTask(Context context,File targetFile,String dialogMessage) {
        this.mContext = context;
        this.mTargetFile = targetFile;
        mPDialog = new ProgressDialog(context);

        mPDialog.setMessage(dialogMessage);
        mPDialog.setIndeterminate(true);
        mPDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mPDialog.setCancelable(true);
        // reference to instance to use inside listener
        final DownloadTask me = this;
        mPDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                me.cancel(true);
            }
        });
        Log.i("DownloadTask","Constructor done");
    }

    @Override
    protected String doInBackground(String... sUrl) {
        InputStream input = null;
        OutputStream output = null;
        HttpURLConnection connection = null;
        try {
            URL url = new URL(sUrl[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();

            // expect HTTP 200 OK, so we don't mistakenly save error report
            // instead of the file
            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                return "Server returned HTTP " + connection.getResponseCode()
                        + " " + connection.getResponseMessage();
            }
            Log.i("DownloadTask","Response " + connection.getResponseCode());

            // this will be useful to display download percentage
            // might be -1: server did not report the length
            int fileLength = connection.getContentLength();

            // download the file
            input = connection.getInputStream();
            output = new FileOutputStream(mTargetFile,false);

            byte data[] = new byte[4096];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                // allow canceling with back button
                if (isCancelled()) {
                    Log.i("DownloadTask","Cancelled");
                    input.close();
                    return null;
                }
                total += count;
                // publishing the progress....
                if (fileLength > 0) // only if total length is known
                    publishProgress((int) (total * 100 / fileLength));
                output.write(data, 0, count);
            }
        } catch (Exception e) {
            return e.toString();
        } finally {
            try {
                if (output != null)
                    output.close();
                if (input != null)
                    input.close();
            } catch (IOException ignored) {
            }

            if (connection != null)
                connection.disconnect();
        }
        return null;
    }
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // take CPU lock to prevent CPU from going off if the user
        // presses the power button during download
        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                getClass().getName());
        mWakeLock.acquire();

        mPDialog.show();

    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);
        // if we get here, length is known, now set indeterminate to false
        mPDialog.setIndeterminate(false);
        mPDialog.setMax(100);
        mPDialog.setProgress(progress[0]);

    }

    @Override
    protected void onPostExecute(String result) {
        Log.i("DownloadTask", "Work Done! PostExecute");
        mWakeLock.release();
        mPDialog.dismiss();
        if (result != null)
            Toast.makeText(mContext,"Download error: "+result, Toast.LENGTH_LONG).show();
        else
            Toast.makeText(mContext,"File Downloaded", Toast.LENGTH_SHORT).show();
    }
}

Eu recomendo que você use o meu projeto Netroid , é baseado em Volley . Eu adicionei alguns recursos para ele, como retorno de chamada multi-eventos, gerenciamento de download de arquivos. Isso poderia ser de alguma ajuda.


Meu conselho pessoal é usar o Progress Dialog e construir antes da execução, ou iniciar no OnPreExecute() , publicar o progresso com freqüência se você usar o estilo horizontal da barra de progresso do diálogo de progresso. A parte restante é otimizar o algoritmo do doInBackground .


Não se esqueça de adicionar permissões ao seu arquivo de manifesto se você estiver baixando coisas da internet!

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloandroid"
    android:versionCode="1"
    android:versionName="1.0">

        <uses-sdk android:minSdkVersion="10" />

        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
        <uses-permission android:name="android.permission.INTERNET"></uses-permission>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
        <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>

        <application 
            android:icon="@drawable/icon" 
            android:label="@string/app_name" 
            android:debuggable="true">

        </application>

</manifest>

Sim, o código acima funcionará .Mas se você estiver atualizando sua onProgressUpdate de progressbar em onProgressUpdate de Asynctask e você pressionar o botão voltar ou terminar sua atividade, o AsyncTask sua trilha com sua interface .E quando voltar para sua atividade, mesmo se o download estiver sendo executado fundo você não verá nenhuma atualização na barra de progresso. Portanto, em OnResume() tente executar um thread como runOnUIThread com uma tarefa de timer que atualiza sua AsyncTask progressbar com atualização de valores do AsyncTask fundo executando o AsyncTask .

private void updateProgressBar(){
    Runnable runnable = new updateProgress();
    background = new Thread(runnable);
    background.start();
}

public class updateProgress implements Runnable {
    public void run() {
        while(Thread.currentThread()==background)
            //while (!Thread.currentThread().isInterrupted()) {
            try {
                Thread.sleep(1000); 
                Message msg = new Message();
                progress = getProgressPercentage();        
                handler.sendMessage(msg);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } catch (Exception e) {
        }
    }
}

private Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        progress.setProgress(msg.what);
    }
};

Não se esqueça de destruir o tópico quando a atividade não estiver visível.

private void destroyRunningThreads() {
    if (background != null) {
        background.interrupt();
        background=null;
    }
}

Use a biblioteca de consulta do Android, muito legal mesmo.Você pode alterá-lo para usar ProgressDialog como você vê em outros exemplos, este mostrará a visualização do progresso do seu layout e ocultá-lo após a conclusão.

File target = new File(new File(Environment.getExternalStorageDirectory(), "ApplicationName"), "tmp.pdf");
new AQuery(this).progress(R.id.progress_view).download(_competition.qualificationScoreCardsPdf(), target, new AjaxCallback<File>() {
    public void callback(String url, File file, AjaxStatus status) {
        if (file != null) {
            // do something with file  
        } 
    }
});






android-asynctask