Android用のWebブラウザを作成するためにwebviewを使用しています。ホワイトリスト (xml ファイルを生成する php ファイル) をサーバー内に保持しているので、必要なときにいつでも変更できます。私のアプリは、アクセスしようとしている URL がホワイトリストにあるかどうかを確認し、そうでない場合は、ダイアログ メッセージを表示します。最初にAndroid 2.3用に実装しましたが、すべてうまくいきました。Android 4.0で実装する必要がありますが、ホワイトリストを読み取ろうとすると失敗します。
これは私の WebView の宣言です
final WebView TBrowser = (WebView) findViewById(R.id.webView);
TBrowser.getSettings().setJavaScriptEnabled(true);
TBrowser.getSettings().setLoadWithOverviewMode(true);
TBrowser.getSettings().setUseWideViewPort(true);
TBrowser.setWebViewClient(new webViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
String host = Uri.parse(url).getHost();
boolean validUrl = false;
try{
URL website = new URL("http://www.mysite.com/whitelist.php);
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
HandlingXML whiteListHandler = new HandlingXML(host);
xr.setContentHandler(whiteListHandler);
xr.parse(new InputSource(website.openStream()));
validUrl = whiteListHandler.isValid();
}catch (Exception e){
e.printStackTrace();
}
if (validUrl) {
// This is my web site, so do not override; let my WebView load the page
return false;
}else{
new AlertDialog.Builder(view.getContext())
.setTitle("ERROR")
.setMessage("URL not supported. Click on START OVER")
.setCancelable(true)
.create()
.show();
return true;
}
}
});
これは、xml ハンドラーのコードです。
public class HandlingXML extends DefaultHandler{
boolean validationResult = false;
String hostName;
public HandlingXML(String hn){
hostName = hn;
}
public boolean isValid(){
return validationResult;
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (localName.equals("item") && !validationResult){
if (attributes.getValue("data").equals(hostName)){
validationResult = true;
} else {
validationResult = false;
}
}
}
}
これは、xml を生成する php です。
header("content-type: text/xml");
echo "<?xml version=\"1.0\" ?>\n";
echo "<whiteList>\n";
echo "<item data=\"www.facebook.com\"/>\n";
echo "<item data=\"m.facebook.com\"/>\n";
echo "<item data=\"api.twitter.com\"/>\n";
echo "<item data=\"plus.google.com\"/>\n";
echo "<item data=\"accounts.google.com\"/>\n";
echo "</whiteList>\n";
したがって、これは Android 2.3 では正常に機能しますが、4.0 では試行部分をスキップします (ホワイトリストの読み取りと処理時)。
私が見つけたのは、「... Android バージョン 3.0 以降ではアプリケーションがクラッシュするが、Android 2.x では正常に動作する理由は、HoneyComb と Ice Cream Sandwich が UI スレッドに対する悪用についてはるかに厳格であるためです...」
http://www.androiddesignpatterns.com/2012/06/app-force-close-honeycomb-ics.html
さて、誰かがこの問題を回避する方法を理解するのを手伝ってくれませんか???
記事では、AsyncTask の使用について言及しています... 私は以前、同様の問題を解決していました。
からの変更:
Thread timer = new Thread() {
public void run() {
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
Intent QuickRateIntent = new Intent(
"com.terillion.TERILLIONBROWSERACTIVITY");
startActivity(QuickRateIntent);
}
}
};
timer.start();
に:
new timerAsync().execute();
と:
public class timerAsync extends AsyncTask<Void,Void,Void>{
@Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
Thread timer = new Thread() {
public void run() {
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
Intent QuickRateIntent = new Intent(
"com.terillion.TERILLIONBROWSERACTIVITY");
startActivity(QuickRateIntent);
}
}
};
timer.start();
return null;
}
}
しかし、ここでそれを機能させる方法がわかりません。どのような変更を加える必要がありますか??? そしてどこに???