sexta-feira, 4 de novembro de 2011

Baixe arquivos com o DownloadManager

Olá povo,

Frequentemente alunos e colegas me perguntam qual é um bom livro sobre Android. E normalmente eu costumo indicar o livro do Ricardo Lecheta, Google Android (Editora Novatec), ou o Professional Android 2, do Reto Meyer. Vou adicionar nessa lista o Pro Android 2 da Editora Apress. Estava folheando esse livro quando achei um exemplo bem bacana: utilizar a classe DownloadManager para baixar arquivos. A utilização dela é bem simples, como podemos observar no exemplo abaixo:

public class ExDownldMngrActivity
extends Activity {

private DownloadManager dm;
private MeuReceiver receiver;
private ImageView imgView;
private long downloadId;

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

imgView = (ImageView)findViewById(
R.id.imageView1);

dm = (DownloadManager)
getSystemService(DOWNLOAD_SERVICE);

receiver = new MeuReceiver();
}

@Override
protected void onResume() {
super.onResume();

IntentFilter filter = new IntentFilter(
DownloadManager.
ACTION_DOWNLOAD_COMPLETE);

registerReceiver(receiver, filter);
}

@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}

public void baixarArquivoClick(View v){
String url = "http://developer.android.com/assets/"+
"images/home/honeycomb-android.png";

DownloadManager.Request request =
new DownloadManager.Request(Uri.parse(url));
request.setTitle("Meu download");
request.setDescription("Logo do Android");
request.setAllowedNetworkTypes(Request.NETWORK_MOBILE);

downloadId = dm.enqueue(request);
}

private class MeuReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
long id = intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, -1);

if (id == downloadId) {
try {
FileDescriptor fd = dm.openDownloadedFile(
downloadId).getFileDescriptor();

Bitmap image =
BitmapFactory.decodeFileDescriptor(fd);

imgView.setImageBitmap(image);

} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
}
}

Na classe acima, temos quatro atributos. O DownloadManager que realizará a solicitação de download. O atributo MeuReceiver receberá a notificação quando o download for concluído. No nosso exemplo, baixaremos uma imagem, e ela será exibida no ImageView declarado em seguida. O último atributo é o ID do download que a nossa aplicação iniciará. Esse atributo é importante para obtermos o arquivo que foi baixado.
No onCreate fazemos as inicializações necessárias, inclusive, a do DownloadManager, através do método getSystemService. No método onResume, registramos o nosso BroadcastReceiver para ser chamado quando a ação ACTION_DOWNLOAD_COMPLETE for disparada. Essa ação é disparada quando o download do arquivo é concluído. E no onDestroy, desregistamos o nosso receiver.
O método baixarArquivoClick é chamado quando o botão (que declarei no arquivo de layout) é clicado. Nesse método criamos um objeto da classe DownloadManager.Request passando a URL do arquivo. Em seguida, setamos o título e a descrição do download. Além disso, podemos restringir o tipo de rede usada para download, no nosso caso, informamos que podemos fazer com a rede de dados da operadora, mas poderíamos informar que o download só poderia ser feito via Wi-Fi.
Finalmente, enviamos a requisição de download e armazenamos o id do download no atributo downloadId.
Para tratar o fim do download, temos a classe MeuReceiver. Quando o download é concluído o método onReceive é chamado. Nosso broadcast será chamado mesmo se não for o nosso download que for concluído, então temos que checar se o id que foi concluído é igual ao atributo downloadId. Se for, obtemos o FileDescriptor do arquivo baixado, criamos a imagem e setamos no ImageView.

Abaixo, temos a imagem da nossa aplicação em execução.


4br4ços,
nglauber

2 comentários:

César Oliveira disse...

Boa tarde,

Função muito util, mas um pouco complexa.
Não existe uma solução mais simples para isso ?

Obrigado

Nelson Glauber disse...

Oi Cesar,

Cara eu não sei se tem algo mais simples, mas eu não acho complicado o uso do DownloadManager não :)

4br4ç05,
nglauber