studio - manual de programacion android pdf
Android: cómo descargar un archivo del servidor web (10)
Además de utilizar AsyncTask, puede poner la operación en ejecutable
Runnable r=new Runnable()
{
public void run()
{
///-------network operation code
}
};
//--------call r in this way--
Thread t=new Thread(r);`enter code here`
t.start();
Also put the UI work in a haldler..such as updating a textview etc..
en mi aplicación, estoy descargando el archivo kml del servidor web. He configurado el permiso de almacenamiento externo e internet en mi archivo de manifiesto de Android. Soy nuevo en Android, su ayuda es muy apreciada
MainActivity.java
package com.example.demo;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadFiles();
}
public void DownloadFiles(){
try {
URL u = new URL("http://www.qwikisoft.com/demo/ashade/20001.kml");
InputStream is = u.openStream();
DataInputStream dis = new DataInputStream(is);
byte[] buffer = new byte[1024];
int length;
FileOutputStream fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory() + "/" + "data/test.kml"));
while ((length = dis.read(buffer))>0) {
fos.write(buffer, 0, length);
}
} catch (MalformedURLException mue) {
Log.e("SYNC getUpdate", "malformed url error", mue);
} catch (IOException ioe) {
Log.e("SYNC getUpdate", "io error", ioe);
} catch (SecurityException se) {
Log.e("SYNC getUpdate", "security error", se);
}
}
}
Archivo de manifiesto de Android
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.demo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.demo.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Error de Logcat:
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.demo/com.example.demo.MainActivity}: android.os.NetworkOnMainThreadException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
at java.net.InetAddress.getAllByName(InetAddress.java:220)
at libcore.net.http.HttpConnection.<init>(HttpConnection.java:71)
at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351)
at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86)
at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)
at libcore.net.http.HttpEngine.connect(HttpEngine.java:303)
at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)
at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)
at java.net.URL.openStream(URL.java:462)
at com.example.demo.MainActivity.DownloadFiles(MainActivity.java:30)
at com.example.demo.MainActivity.onCreate(MainActivity.java:24)
at android.app.Activity.performCreate(Activity.java:4465)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
EDITAR
package com.example.demo;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
public class MainActivity extends Activity {
private ProgressDialog pDialog;
public static final int progress_bar_type = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadFileFromURL().execute("http://www.qwikisoft.com/demo/ashade/20001.kml");
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case progress_bar_type: // we set this to 0
pDialog = new ProgressDialog(this);
pDialog.setMessage("Downloading file. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setMax(100);
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialog.setCancelable(true);
pDialog.show();
return pDialog;
default:
return null;
}
}
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Bar Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
/**
* Downloading file in background thread
* */
@Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int lenghtOfFile = conection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream(),
8192);
// Output stream
OutputStream output = new FileOutputStream(Environment
.getExternalStorageDirectory().toString()
+ "/data/downloadedfile.kml");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
/**
* Updating progress bar
* */
protected void onProgressUpdate(String... progress) {
// setting progress percentage
pDialog.setProgress(Integer.parseInt(progress[0]));
}
/**
* After completing background task Dismiss the progress dialog
* **/
@Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
dismissDialog(progress_bar_type);
}
}
}
Cuando ejecuto este código en el emulador, el código aún no funciona ... el archivo no se descarga.
Comenzando desde el nivel 11 de api o desde Honeycomb, está prohibido realizar operaciones de red en el hilo principal. Use thread o asynctask. Para obtener más información, visite https://developer.android.com/reference/android/os/NetworkOnMainThreadException.html
Debería usar una AsyncTask (u otra forma de realizar una operación de red en segundo plano).
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//create and execute the download task
MyAsyncTask async = new MyAsyncTask();
async.execute();
}
private class MyAsyncTask extends AsyncTask<Void, Void, Void>{
//execute on background (out of the UI thread)
protected Long doInBackground(URL... urls) {
DownloadFiles();
}
}
Más información sobre AsyncTask en la documentación de Android
Espero eso ayude.
Ejecuta estos códigos en thread o AsyncTask. Para evitar llamadas duplicadas de la misma _url (una vez para getContentLength (), una vez de openStream ()), use IOUtils.toByteArray de Apache.
void downloadFile(String _url, String _name) {
try {
URL u = new URL(_url);
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = IOUtils.toByteArray(stream);
FileOutputStream fos = mContext.openFileOutput(_name, Context.MODE_PRIVATE);
fos.write(buffer);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
} catch (IOException e) {
e.printStackTrace();
return;
}
}
Es una mala práctica realizar operaciones de red en el hilo principal, razón por la cual está viendo la NetworkOnMainThreadException
. La política lo previene. Si realmente debe hacerlo para probar, coloque lo siguiente en su OnCreate:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Recuerde que esta es una práctica muy mala para hacer esto, y idealmente debería mover su código de red a AsyncTask
o a Thread
.
Mr.Iam4fun tu código responde aquí ... Usarás hilo ...
findViewById(R.id.download).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
DownloadFiles();
}
}).start();
Y entonces..
public void DownloadFiles(){
try {
URL u = new URL("http://www.qwikisoft.com/demo/ashade/20001.kml");
InputStream is = u.openStream();
DataInputStream dis = new DataInputStream(is);
byte[] buffer = new byte[1024];
int length;
FileOutputStream fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory() + "/" + "data/test.kml"));
while ((length = dis.read(buffer))>0) {
fos.write(buffer, 0, length);
}
} catch (MalformedURLException mue) {
Log.e("SYNC getUpdate", "malformed url error", mue);
} catch (IOException ioe) {
Log.e("SYNC getUpdate", "io error", ioe);
} catch (SecurityException se) {
Log.e("SYNC getUpdate", "security error", se);
}
}
}
Claro, estará funcionando ...
Usando la tarea Async . (Si no funciona en 4.0, agregue
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
)
llame cuando desee descargar el archivo: new DownloadFileFromURL().execute(file_url);
public class MainActivity extends Activity {
// Progress Dialog
private ProgressDialog pDialog;
public static final int progress_bar_type = 0;
// File url to download
private static String file_url = "http://www.qwikisoft.com/demo/ashade/20001.kml";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadFileFromURL().execute(file_url);
}
/**
* Showing Dialog
* */
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case progress_bar_type: // we set this to 0
pDialog = new ProgressDialog(this);
pDialog.setMessage("Downloading file. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setMax(100);
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialog.setCancelable(true);
pDialog.show();
return pDialog;
default:
return null;
}
}
/**
* Background Async Task to download file
* */
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Bar Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
/**
* Downloading file in background thread
* */
@Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int lenghtOfFile = conection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream(),
8192);
// Output stream
OutputStream output = new FileOutputStream(Environment
.getExternalStorageDirectory().toString()
+ "/2011.kml");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
/**
* Updating progress bar
* */
protected void onProgressUpdate(String... progress) {
// setting progress percentage
pDialog.setProgress(Integer.parseInt(progress[0]));
}
/**
* After completing background task Dismiss the progress dialog
* **/
@Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
dismissDialog(progress_bar_type);
}
}
}
Versión simple de kotlin
fun download(link: String, path: String) {
val input = URL(link).openStream()
val output = FileOutputStream(File(path))
input.use { _ ->
output.use { _ ->
input.copyTo(output)
}
}
}
Yo recomendaría usar Android DownloadManager
DownloadManager downloadmanager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse("http://www.example.com/myfile.mp3");
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setTitle("My File");
request.setDescription("Downloading");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setVisibleInDownloadsUi(false);
request.setDestinationUri(Uri.parse("file://" + folderName + "/myfile.mp3"));
downloadmanager.enqueue(request);
usa AsyncTask
y
ponga su código de archivo de descarga en doinbackground
de él ..
Android ya no permite realizar tareas pesadas en el hilo principal para evitar el error ANR (Aplicación no responde)