我想为我的应用程序添加从互联网下载文件然后阅读其中一些文件或提取它们的功能..这是我的整个代码
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);
}
}
如您所见,活动开始时,我检查了 Internet 连接,然后尝试从 Internet 下载文件,然后读取该文件..如何确保已下载该文件,然后尝试读取它?这里有一段代码我曾经下载和阅读文件
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 的文件时继续?因为当我运行应用程序时出现空异常错误
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 文件,然后我 exteact 它..我在这里尝试了一个 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
在完成下载文件后运行..如何做到这一点?非常感谢你的帮助