如何等待完成下载文件然后读取它

时间:2013-04-17 05:41:44

标签: android android-asynctask download

我想添加我的应用程序的功能,从互联网上下载文件,然后阅读其中一些或提取它们。这是我的整个代码

package co.tosca.persianpoem;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.app.Dialog;
import android.app.DownloadManager;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.AssetManager;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TabHost;
import android.widget.Toast;


public class Download_database extends Activity {

    Download_db_list_Adapter dataAdapter = null;
    Download_db_list_Adapter Database_list_adapter = null;
    ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
    ArrayList<HashMap<String, String>> selected_items_for_download = new ArrayList<HashMap<String, String>>();
    private ProgressDialog mProgressDialog;
    public static int DIALOG_DOWNLOAD_PROGRESS = 0;
    List<List<Map<String, String>>> childData = new ArrayList<List<Map<String, String>>>();
    List<Map<String, String>> children = new ArrayList<Map<String, String>>();
    persian_poem_class main=new persian_poem_class(this);
    public List<HashMap<String, String>> selected_databases = new ArrayList<HashMap<String, String>>();
    public ArrayList<String> downloaded_db_ids = new ArrayList<String>();
    public ArrayList<String> main_db_ids = new ArrayList<String>();
    ArrayList<String> Items_for_download = new ArrayList<String>();
    public ProgressDialog pd;
    XMLParser parser = new XMLParser();
    String xml = null;
    ListView list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_download_database);




        //T A B     H O S T
        TabHost tabs=(TabHost)findViewById(R.id.download_cat_tabhost);
        tabs.setup();
        TabHost.TabSpec spec=tabs.newTabSpec("down_tag1");
        spec.setContent(R.id.download_cat_01);
        spec.setIndicator(getString(R.string.txt_download_tab_download_sections));
        tabs.addTab(spec);
        spec=tabs.newTabSpec("down_tag2");
        spec.setContent(R.id.download_cat_02);
        spec.setIndicator(getString(R.string.txt_download_tab_downloaded_db_list));
        tabs.addTab(spec);


        File path=new File(ClubCP.SDcardPath+"/temp/database/");
        List<String>file_lists =    main.directoryPath(path,false);

        downloaded_db_ids = main.directoryPath(path,true);
        main_db_ids=main.getDBPoet_id();




        //S P I N E R
        Spinner spin = (Spinner) findViewById(R.id.spinner_cat_selector);
        String[] spineritems = { getString(R.string.radio_newgdb), getString(R.string.radio_programgdb), getString(R.string.radio_sitegdb)};
        ArrayAdapter<String> aa = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,spineritems);
        aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spin.setAdapter(aa);
        spin.setOnItemSelectedListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> container, View row,
            int position, long id) {

            if(position==0){
                xmlp("newgdbs.xml");

            }
            else if(position==1){
                xmlp("programgdbs.xml");

            }
            else{
                xmlp("sitegdbs.xml");


            }
            }

            @Override
            public void onNothingSelected(AdapterView<?> container) {
                Toast.makeText(Download_database.this, "At least select one database", Toast.LENGTH_SHORT).show();
            }
            });



        list=  (ListView)findViewById(R.id.ExpList);        


        //D A T A B A S E    L I S T    A D A P T E R

        Database_list_adapter=new Download_db_list_Adapter(this,R.layout.database_list_item, main.getDBonSDcard());
        ListView Database_list=(ListView)findViewById(R.id.list_db_list);
        Database_list.setAdapter(Database_list_adapter);






        // B U I L D    B U T T U N
        Button build =(Button)findViewById(R.id.btn_creat_db);
        build.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {   
                selected_databases=Database_list_adapter.getSelectedItems();
                if(selected_databases.isEmpty()!=true){
                    new bulid_database().execute();

                }
                else{
                    Toast.makeText(Download_database.this, "At least select one database", Toast.LENGTH_SHORT).show();
                }
            }

        });



        //  D O W N L O A D    B U T T U N
        Button download=(Button)findViewById(R.id.btn_download_db_start);
        download.setOnClickListener(new Button.OnClickListener() {

            @Override
            public void onClick(View v) {

                selected_items_for_download=dataAdapter.getSelectedItems();
                if(selected_items_for_download.size()!=0){
                    if(!isOnline()){

                        Toast.makeText(Download_database.this, "you are not connected to internet..Please check your connections", Toast.LENGTH_SHORT).show();
                    }
                    else{
Log.i("execute download", "execute download");
                        new download_db().execute();
                    }
                }
                else{
                    Toast.makeText(Download_database.this, "At least select one database", 1).show();
                }

            }
        });



        // H E L P    B U T T U N
        Button help=(Button)findViewById(R.id.btn_help);
        help.setOnClickListener(new Button.OnClickListener() {

                @Override
                public void onClick(View arg0) {
                    String msg="<h1>"+getString(R.string.radio_newgdb)+"</h1>"+getString(R.string.txt_download_hint_newgdb)
                        +"<h1>"+getString(R.string.radio_programgdb)+"</h1>"+   getString(R.string.txt_download_hint_programgdb)
                        +"<h1>"+getString(R.string.radio_sitegdb)+"</h1>"+  getString(R.string.txt_download_hint_sitedb);
                    main.createDialogBox(Download_database.this,msg,getString(R.string.txt_information ),R.drawable.bullet_info ).show();

                }

            });



    }



    /**

    P U B L I C readfromAssets

    */
    public String readfromAssets(String name){
         xml=null;
        AssetManager assetManager = getAssets();
      InputStream input;
      try {
     input = assetManager.open(name);

           int size = input.available();
             byte[] buffer = new byte[size];
           input.read(buffer);
            input.close();

            // byte buffer into a string
              String text = new String(buffer);
     return text;
          } catch (IOException e) {

       e.printStackTrace();
          }
    return null;
  }
    /**

    P U B L I C     V O I D  XMLP

    */
    private void xmlp(String xmlname){
        String xml = null ;
        if(isOnline()){
            new getxml().execute("http://ganjoor.sourceforge.net/"+xmlname);// getting XML new way

        }
        else{
            xml=readfromAssets(xmlname);
            Log.i("read from assets",xml);
            Toast.makeText(this, "Cant find any network connection,Persian poem is loading from offline files", Toast.LENGTH_SHORT).show();
        }

        menuItems.clear();
        Document doc = parser.getDomElement(xml); // getting DOM element
        NodeList nl = doc.getElementsByTagName(parser.KEY_gdb);
        // looping through all item nodes <item>
        for (int i = 0; i < nl.getLength(); i++) {
            // creating new HashMap
            HashMap<String, String> map = new HashMap<String, String>();
            Element e = (Element) nl.item(i);

            // adding each child node to HashMap key => value
            map.put(parser.KEY_CatName, parser.getValue(e, parser.KEY_CatName));
            map.put(parser.KEY_PoetID, parser.getValue(e, parser.KEY_PoetID));
            map.put(parser.KEY_DownloadUrl, parser.getValue(e, parser.KEY_DownloadUrl));
            map.put(parser.KEY_PubDate, parser.getValue(e, parser.KEY_PubDate));
            String size = " ";
             try{
            long s= Long.parseLong(parser.getValue(e,parser.KEY_FileSizeInByte));
                 size=getText(R.string.txt_download_db_size)+" "+humanReadableByteCount( s,true);

             }
              catch (Exception e1) 
            {

                 Log.i("error", e1.getMessage());
            }

             map.put(parser.KEY_FileSizeInByte,size);
             String Status="0";
             String Poet_id=parser.getValue(e, parser.KEY_PoetID);
             if(main.IsInlist(main_db_ids, Poet_id)){
                Status="1";
             }
             else if(downloaded_db_ids!=null&& main.IsInlist(downloaded_db_ids, Poet_id)){
                Status="2";
             }



             map.put("Status",Status);
             menuItems.add(map);

        }


        dataAdapter = new Download_db_list_Adapter(this,R.layout.database_list_item, menuItems);
        list.setAdapter(dataAdapter);



    }

    public class getxml extends AsyncTask<String, Void,String>{

        @Override
        protected String doInBackground(String... url) {
             xml=null;
            try {
                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(url[0]);

                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
                xml = EntityUtils.toString(httpEntity);

            } catch (UnsupportedEncodingException e) {
               // e.printStackTrace();
            } catch (ClientProtocolException e) {
               // e.printStackTrace();
            } catch (IOException e) {
               // e.printStackTrace();
            }

            Log.i("getxml", xml);
            return xml;
        }

    }
    public class download_db extends AsyncTask<String, Void,String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            DIALOG_DOWNLOAD_PROGRESS=100/selected_items_for_download.size();
            mProgressDialog = new ProgressDialog(Download_database.this);
            mProgressDialog.setMessage("Downloading file..");
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            mProgressDialog.setCancelable(false);
            mProgressDialog.show();

        }

        @Override
        protected String doInBackground(String...items) {
            if(isDownloadManagerAvailable(Download_database.this)){
             for(int i=0;i<selected_items_for_download.size();i++){
                    HashMap<String, String> item =selected_items_for_download.get(i);
                    String[] progress={String.valueOf(i+1),item.get(parser.KEY_PoetID)};
                    Log.i("download_manager", "download file"+progress);
                    download_file(item.get(parser.KEY_DownloadUrl),item.get(parser.KEY_CatName),"Downloading file,Please wait...",item.get(parser.KEY_PoetID));
                    Log.i("download_manager", "startextracting file");
                  //  publishProgress(progress);
                    unpackZip(ClubCP.SDcardPath+"/temp/database/",item.get(parser.KEY_PoetID)+ ".zip");
                    }
            }
            else{
                return null;
            }
            return null;
        }
        protected void onProgressUpdate(String...progress) {
             Log.d("ANDRO_ASYNC","progress update");
             mProgressDialog.setMessage("Extracting "+progress[1]+"...");
             mProgressDialog.setProgress(Integer.valueOf(DIALOG_DOWNLOAD_PROGRESS)*Integer.valueOf(progress[0]));
        }

        @Override
        protected void onPostExecute(String unused) {

            if (mProgressDialog.isShowing()) {
                mProgressDialog.dismiss();
                }
        }
    }

     /**
      * @param context used to check the device version and DownloadManager information
      * @return true if the download manager is available
      */
     public static boolean isDownloadManagerAvailable(Context context) {
         try {
             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
                 return false;
             }
             Intent intent = new Intent(Intent.ACTION_MAIN);
             intent.addCategory(Intent.CATEGORY_LAUNCHER);
             intent.setClassName("com.android.providers.downloads.ui", "com.android.providers.downloads.ui.DownloadList");
             List<ResolveInfo> list = context.getPackageManager().queryIntentActivities(intent,
                     PackageManager.MATCH_DEFAULT_ONLY);
             return list.size() > 0;
         } catch (Exception e) {
             return false;
         }
     }
     public void download_file(String download_link,String filename,String discribtion,String poet_id){
         String url = download_link;
         DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
         request.setDescription(discribtion);
         request.setTitle(filename);
         // in order for this if to run, you must use the android 3.2 to compile your app
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
             request.allowScanningByMediaScanner();
             request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
         }
         request.setDestinationInExternalPublicDir(ClubCP.SDcardPath+"/temp/database/", poet_id+".zip");

         // get download service and enqueue file
         DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
         manager.enqueue(request);

     }



     private boolean unpackZip(String path, String zipname)
     {       
          InputStream is;
          ZipInputStream zis;
          try 
          {
              String filename;
              is = new FileInputStream(path + zipname);
              zis = new ZipInputStream(new BufferedInputStream(is));          
              ZipEntry ze;
              byte[] buffer = new byte[1024];
              int count;

              while ((ze = zis.getNextEntry()) != null) 
              {
                  // zapis do souboru
                  filename = ze.getName();

                  // Need to create directories if not exists, or
                  // it will generate an Exception...
                  if (ze.isDirectory()) {
                     File fmd = new File(path + filename);
                     fmd.mkdirs();
                     continue;
                  }

                  FileOutputStream fout = new FileOutputStream(path + filename);

                  // cteni zipu a zapis
                  while ((count = zis.read(buffer)) != -1) 
                  {
                      fout.write(buffer, 0, count);             
                  }

                  fout.close();               
                  zis.closeEntry();
              }

              zis.close();
          } 
          catch(IOException e)
          {
              e.printStackTrace();
              return false;
          }

         return true;
     }

        private class bulid_database extends AsyncTask<String, Long, Void> {

            // Begin - can use UI thread here
            protected void onPreExecute() {
                  pd = ProgressDialog.show(Download_database.this,"","Please wait...", true,false);
            }
            // this is the SLOW background thread taking care of heavy tasks
            // cannot directly change UI
            protected Void doInBackground(final String... args) {
                // simulate here the slow activity
                main.emptyDB();
                main.creatDB(8);
                for (int i =0; i < selected_databases.size(); i++) {

                    HashMap<String, String> Database=selected_databases.get(i);

                    main.attachDatabase(Database.get("CatName"));
                    //publishProgress((long)i);
                }
                    return null;
                    }
            // periodic updates - it is OK to change UI
            @Override
            protected void onProgressUpdate(Long... value) {
                pd.setMessage("still working");
            }
            // End - can use UI thread here
            protected void onPostExecute(final Void unused) {
                if (pd!=null) {
                    pd.dismiss();
                    }
            }
            }

    public boolean isOnline() {
        ConnectivityManager cm =
            (ConnectivityManager) getSystemService(this.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnectedOrConnecting()) {
            return true;
        }
        return false;
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.download_database, menu);
        return true;
    }
    public static String humanReadableByteCount(long bytes, boolean si) {
        int unit = si ? 1000 : 1024;
        if (bytes < unit) return bytes + " B";
        int exp = (int) (Math.log(bytes) / Math.log(unit));
        String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i");
        return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
    }
}

当你看到活动开始的时候我检查了互联网连接,然后我尝试从互联网下载一个文件,然后读取该文件。我如何确保文件已下载,然后我尝试阅读它?这里是pice我用来下载和读取文件的代码

    private void xmlp(String xmlname){
    String xml = null ;
    if(isOnline()){
        new getxml().execute("http://ganjoor.sourceforge.net/"+xmlname);// getting XML new way

    }
    else{
        xml=readfromAssets(xmlname);
        Log.i("read from assets",xml);
        Toast.makeText(this, "Cant find any network connection,Persian poem is loading from offline files", Toast.LENGTH_SHORT).show();
    }


and here is getxml() function
    public class getxml extends AsyncTask<String, Void,String>{

        @Override
        protected String doInBackground(String... url) {
             xml=null;
            try {
                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(url[0]);

                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
                xml = EntityUtils.toString(httpEntity);

            } catch (UnsupportedEncodingException e) {
               // e.printStackTrace();
            } catch (ClientProtocolException e) {
               // e.printStackTrace();
            } catch (IOException e) {
               // e.printStackTrace();
            }

            Log.i("getxml", xml);
            return xml;
        }

    }

我的问题上面的方法保证在下载文件后保证调用吗?或者在下载带有空xml的文件时它会继续吗?因为当我运行app时我得到null exeption错误

04-17 09:44:50.882: E/AndroidRuntime(14083): FATAL EXCEPTION: main
04-17 09:44:50.882: E/AndroidRuntime(14083): java.lang.NullPointerException
04-17 09:44:50.882: E/AndroidRuntime(14083):    at java.io.StringReader.<init>(StringReader.java:47)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at co.tosca.persianpoem.XMLParser.getDomElement(XMLParser.java:113)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at co.tosca.persianpoem.Download_database.xmlp(Download_database.java:264)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at co.tosca.persianpoem.Download_database.access$3(Download_database.java:251)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at co.tosca.persianpoem.Download_database$1.onItemSelected(Download_database.java:118)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at android.widget.AdapterView.fireOnSelected(AdapterView.java:882)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at android.widget.AdapterView.access$200(AdapterView.java:48)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:848)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at android.os.Handler.handleCallback(Handler.java:605)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at android.os.Handler.dispatchMessage(Handler.java:92)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at android.os.Looper.loop(Looper.java:137)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at android.app.ActivityThread.main(ActivityThread.java:4441)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at java.lang.reflect.Method.invokeNative(Native Method)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at java.lang.reflect.Method.invoke(Method.java:511)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
04-17 09:44:50.882: E/AndroidRuntime(14083):    at dalvik.system.NativeStart.main(Native Method)
04-17 09:45:31.374: W/dalvikvm(14083): threadid=12: thread exiting with uncaught exception (group=0x2b542210)

在第264行我有这个Document doc = parser.getDomElement(xml); // getting DOM element我认为它是因为一个空的xml文件(或文件仍在下载).. 我有这种问题在另一个地方..我想要加载一个zip文件然后我扩展它..我试过一个AsyncTask它在这里

public class download_db extends AsyncTask<String, Void,String> {
@Override
protected void onPreExecute() {
    super.onPreExecute();
    DIALOG_DOWNLOAD_PROGRESS=100/selected_items_for_download.size();
    mProgressDialog = new ProgressDialog(Download_database.this);
    mProgressDialog.setMessage("Downloading file..");
    mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    mProgressDialog.setCancelable(false);
    mProgressDialog.show();

}

@Override
protected String doInBackground(String...items) {
    if(isDownloadManagerAvailable(Download_database.this)){
     for(int i=0;i<selected_items_for_download.size();i++){
            HashMap<String, String> item =selected_items_for_download.get(i);
            String[] progress={String.valueOf(i+1),item.get(parser.KEY_PoetID)};
            Log.i("download_manager", "download file"+progress);
            download_file(item.get(parser.KEY_DownloadUrl),item.get(parser.KEY_CatName),"Downloading file,Please wait...",item.get(parser.KEY_PoetID));
            Log.i("download_manager", "startextracting file");
          //  publishProgress(progress);
            unpackZip(ClubCP.SDcardPath+"/temp/database/",item.get(parser.KEY_PoetID)+ ".zip");
            }
    }
    else{
        return null;
    }
    return null;
}
protected void onProgressUpdate(String...progress) {
     Log.d("ANDRO_ASYNC","progress update");
     mProgressDialog.setMessage("Extracting "+progress[1]+"...");
     mProgressDialog.setProgress(Integer.valueOf(DIALOG_DOWNLOAD_PROGRESS)*Integer.valueOf(progress[0]));
}

@Override
protected void onPostExecute(String unused) {

    if (mProgressDialog.isShowing()) {
        mProgressDialog.dismiss();
        }
}

}

这里我再次确保unpackZip在完成下载文件后运行。如何制作? 非常感谢您的帮助

1 个答案:

答案 0 :(得分:1)

但是代码太多了。我假设您使用doInBackground()方法下载文件。然后,您可以通过从unpackZip方法调用onPostExecute()来确保调用@Override protected String doInBackground(String...items) { // download your file here } @Override protected void onPostExecute(String unused) { //do your unpackZip here }

{{1}}