インターネットからファイルをダウンロードし、それらの一部を読み取ったり、それらを抽出したりする機能をアプリに追加したい..ここに私のコード全体があります
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);
}
}
ご覧のとおり、アクティビティが開始されたときにインターネット接続を確認し、インターネットからファイルをダウンロードしてそのファイルを読み取ろうとしました..ファイルがダウンロードされたことを確認してから読み取ろうとする方法は?以前はファイルをダウンロードして読んでいました
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 を含むファイルをダウンロードしている間も続行されますか?アプリを実行すると null 例外エラーが発生するためです。
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ファイルをdoanloadしてから抽出したい..私は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
ここでも、ファイルのダウンロードが完了したら、実行を確認したい..これを行うには? 助けてくれてどうもありがとう