web-dev-qa-db-fra.com

Android - Comment télécharger un fichier à partir du serveur Web

dans mon application, je télécharge le fichier kml à partir du serveur Web. J'ai activé l'autorisation de stockage externe et Internet dans mon fichier manifeste Android. Je suis nouveau sur Android, votre aide est grandement appréciée.

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);
              }
    }
}

Fichier de manifeste 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>

Erreur 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)

EDIT

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);

        }
    }
}

Quand je lance ce code dans l'émulateur, le code ne fonctionne toujours pas ... le fichier n'est pas téléchargé.

45
Iam4fun

Utilisation de tâche async . (si vous ne travaillez pas en 4.0, alors ajoutez

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy); 

)

appelez quand vous voulez télécharger le fichier: 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);

        }

    }
}
70
Nirav Ranpara

Je recommanderais d'utiliser 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);
19
Awsom3D

Version kotlin simple

fun download(link: String, path: String) {
    URL(link).openStream().use { input ->
        FileOutputStream(File(path)).use { output ->
            input.copyTo(output)
        }
    }
}

EDIT

ou comme extension

fun String.saveTo(path: String) {
    URL(link).openStream().use { input ->
        FileOutputStream(File(path)).use { output ->
            input.copyTo(output)
        }
    }
}

// ...

"http://example.site/document".saveTo("some/path/file")
18
Vlad

Il est déconseillé d’effectuer des opérations réseau sur le thread principal. C’est pourquoi vous voyez le NetworkOnMainThreadException. Il est empêché par la politique. Si vous devez vraiment le faire pour les tests, insérez ce qui suit dans votre OnCreate:

 StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
 StrictMode.setThreadPolicy(policy); 

N'oubliez pas que c'est une très mauvaise pratique et que, dans l'idéal, déplacez votre code de réseau vers un AsyncTask ou un Thread.

10
tristan2468

Mr.Iam4fun votre code de réponse ici..Vous allez utiliser le fil ...

   findViewById(R.id.download).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            new Thread(new Runnable() {
                public void run() {
                    DownloadFiles();
                }
            }).start();

Puis..

 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);
          }
}
}

Bien sûr, ça va marcher ..

1
Mathan Chinna

utiliser AsyncTask et

mettez votre code de fichier de téléchargement dans doinbackground de celui-ci ..

Android n'autorise plus les tâches lourdes sur le thread principal pour éviter l'erreur ANR (Application not respond)

0
DeltaCap019

En plus d'utiliser AsyncTask, vous pouvez placer l'opération dans runnable-

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..
0
user6823720

À partir de l'api niveau 11 ou de Honeycomb, il est interdit de réaliser des opérations réseau sur le thread principal. Utilisez thread ou asynctask. Pour plus d'informations, visitez le site https://developer.Android.com/reference/Android/os/NetworkOnMainThreadException.html

0
Bek

Exécutez ces codes en thread ou en AsyncTask. Afin d'éviter les appels dupliqués du même _url (une fois pour getContentLength (), une fois pour openStream ()), utilisez IOUtils.toByteArray of 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;
    }
}
0
TeeTracker