我在以下代码中的标题中提到了 IO 异常。请指教。这是一个 webviewclient,它在单击文件链接时下载文件。我已经提供了 logcat 以及代码。
package com.example.techmkmsworld;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Environment;
import android.os.StrictMode;
import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MyWebViewClient extends WebViewClient {
private static final String TAG = null;
private String loginCookie;
private Context mContext;
private WebView mWebView;
public MyWebViewClient(Context context, WebView webview) {
super();
mContext = context;
mWebView = webview;
}
@Override
public void onPageStarted( WebView view, String url, Bitmap favicon ) {
}
@Override
public void onPageFinished( WebView view, String url ) {
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setCookie(url, loginCookie);
}
@Override
public void onReceivedError( WebView view, int errorCode, String description, String failingUrl ) {
Toast.makeText(view.getContext(), "ƒy�[ƒW“Ç‚�?�ž‚�?ƒGƒ‰�[", Toast.LENGTH_LONG).show();
System.err.println(errorCode + " - " + description + "-" + failingUrl);
}
@Override
public void onLoadResource( WebView view, String url ){
CookieManager cookieManager = CookieManager.getInstance();
loginCookie = cookieManager.getCookie(url);
}
@Override
public boolean shouldOverrideUrlLoading( WebView view, String url ) {
if (url.contains(".pdf" )){
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectNetwork() // or .detectAll() for all detectable problems
.penaltyDialog() //show a dialog
.permitNetwork() //permit Network access
.build());
Toast.makeText(view.getContext(), "pdf", Toast.LENGTH_LONG).show();
String savedFile=Download(url);
}
return false;
}
public String Download(String Url)
{
String filepath=null;
try
{
//set the download URL, a url that points to a file on the internet
//this is the file to be downloaded
final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
// TODO Auto-generated method stub
return true;
}
};
HttpURLConnection conn = null;
URL url = new URL(Url);
if (url.getProtocol().toLowerCase().equals("https")) {
trustAllHosts();
HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
https.setHostnameVerifier(DO_NOT_VERIFY);
conn = https;
} else {
conn = (HttpURLConnection) url.openConnection();
}
//set up some things on the connection
conn.setRequestMethod("GET");
conn.setDoOutput(true);
//and connect!
conn.connect();
//set the path where we want to save the file
//in this case, going to save it on the root directory of the
//sd card.
File SDCardRoot = Environment.getExternalStorageDirectory();
//create a new file, specifying the path, and the filename
//which we want to save the file as.
String filename= "sample"; // you can download to any type of file ex:.jpeg (image) ,.txt(text file),.mp3 (audio file)
Log.i("Local filename:",""+filename);
File file = new File(SDCardRoot,filename);
file.createNewFile();
Log.i("file created"," "+filepath) ;
if(file.createNewFile())
{
file.createNewFile();
Log.i("file created"," "+filepath) ;
}
//this will be used to write the downloaded data into the file we created
FileOutputStream fileOutput = new FileOutputStream(filename);
//this will be used in reading the data from the internet
InputStream inputStream = conn.getInputStream();
//this is the total size of the file
int totalSize = conn.getContentLength();
//variable to store total downloaded bytes
int downloadedSize = 0;
//create a buffer...
byte[] buffer = new byte[4 * 1024];
int bufferLength = 0; //used to store a temporary size of the buffer
//now, read through the input buffer and write the contents to the file
while ( (bufferLength = inputStream.read(buffer)) > 0 )
{
//add the data in the buffer to the file in the file output stream (the file on the sd card
fileOutput.write(buffer, 0, bufferLength);
//add up the size so we know how much is downloaded
downloadedSize += bufferLength;
//this is where you would do something to report the prgress, like this maybe
Log.i("Progress:","downloadedSize:"+downloadedSize+"totalSize:"+ totalSize) ;
}
//close the output stream when done
fileOutput.close();
if(downloadedSize==totalSize) filepath=file.getPath();
//catch some possible errors...
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
filepath=null;
e.printStackTrace();
}
Log.i("filepath:is this error"," "+filepath) ;
return filepath;
}
private static void trustAllHosts() {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
} };
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection
.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onReceivedSslError( WebView view, SslErrorHandler handler, SslError error ) {
handler.proceed();
}
@Override
public void onReceivedHttpAuthRequest( WebView view, final HttpAuthHandler handler, final String host, final String realm ){
// ˆø��?host‚É‚�?setHttpAuthUsernamePassword‚Ì‘æ1ˆø��?‚Å��?’肵‚½•¶Žš—ñ‚ª“ü‚�?‚Ä‚«‚Ü‚·�B
// Android 4.*�i‚à‚µ‚©‚·‚é‚Æ3.*‚©‚ç�j‚Å‚�?‚È‚º‚©ˆø��?host‚É�ŸŽè‚Ƀ|�[ƒg�?Ô�†‚ª’Ç‹L‚³‚ê‚Ä‚µ‚Ü‚¢‚Ü‚·�B
// ‹ï‘Ì“I‚É‚�?�u:80�v‚ª’Ç‹L‚³‚ê‚Ä‚µ‚Ü‚¢‚Ü‚·�B
String userName = null;
String userPass = null;
if (handler.useHttpAuthUsernamePassword() && view != null) {
String[] haup = view.getHttpAuthUsernamePassword(host, realm);
if (haup != null && haup.length == 2) {
userName = haup[0];
userPass = haup[1];
}
}
if (userName != null && userPass != null) {
handler.proceed(userName, userPass);
}
else {
showHttpAuthDialog(handler, host, realm, null, null, null);
}
}
private void showHttpAuthDialog( final HttpAuthHandler handler, final String host, final String realm, final String title, final String name, final String password ) {
LinearLayout llayout = new LinearLayout((Activity)mContext);
final TextView textview1 = new TextView((Activity)mContext);
final EditText edittext1 = new EditText((Activity)mContext);
final TextView textview2 = new TextView((Activity)mContext);
final EditText edittext2 = new EditText((Activity)mContext);
llayout.setOrientation(LinearLayout.VERTICAL);
textview1.setText("username:");
textview2.setText("password:");
llayout.addView(textview1);
llayout.addView(edittext1);
llayout.addView(textview2);
llayout.addView(edittext2);
final Builder mHttpAuthDialog = new AlertDialog.Builder((Activity)mContext);
mHttpAuthDialog.setTitle("Enter your login details")
.setView(llayout)
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
EditText etUserName = edittext1;
String userName = etUserName.getText().toString();
EditText etUserPass = edittext2;
String userPass = etUserPass.getText().toString();
mWebView.setHttpAuthUsernamePassword(host, realm, name, password);
handler.proceed(userName, userPass);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
handler.cancel();
}
})
.create().show();
}
}
Here is the logcat :
08-15 17:17:14.292: I/Local filename:(16500): sample
08-15 17:17:14.292: I/file created(16500): null
08-15 17:17:14.302: W/System.err(16500): java.io.FileNotFoundException: /sample: open failed: EROFS (Read-only file system)
08-15 17:17:14.302: W/System.err(16500): at libcore.io.IoBridge.open(IoBridge.java:419)
08-15 17:17:14.302: W/System.err(16500): at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
08-15 17:17:14.302: W/System.err(16500): at java.io.FileOutputStream.<init>(FileOutputStream.java:128)
08-15 17:17:14.312: W/System.err(16500): at java.io.FileOutputStream.<init>(FileOutputStream.java:117)
08-15 17:17:14.312: W/System.err(16500): at com.example.techmkmsworld.MyWebViewClient.Download(MyWebViewClient.java:154)
08-15 17:17:14.312: W/System.err(16500): at com.example.techmkmsworld.MyWebViewClient.shouldOverrideUrlLoading(MyWebViewClient.java:97)
08-15 17:17:14.312: W/System.err(16500): at android.webkit.CallbackProxy.uiOverrideUrlLoading(CallbackProxy.java:224)
08-15 17:17:14.312: W/System.err(16500): at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:324)
08-15 17:17:14.322: W/System.err(16500): at android.os.Handler.dispatchMessage(Handler.java:99)
08-15 17:17:14.322: W/System.err(16500): at android.os.Looper.loop(Looper.java:137)
08-15 17:17:14.322: W/System.err(16500): at android.app.ActivityThread.main(ActivityThread.java:4448)
08-15 17:17:14.322: W/System.err(16500): at java.lang.reflect.Method.invokeNative(Native Method)
08-15 17:17:14.322: W/System.err(16500): at java.lang.reflect.Method.invoke(Method.java:511)
08-15 17:17:14.322: W/System.err(16500): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
08-15 17:17:14.322: W/System.err(16500): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
08-15 17:17:14.322: W/System.err(16500): at dalvik.system.NativeStart.main(Native Method)
08-15 17:17:14.332: W/System.err(16500): Caused by: libcore.io.ErrnoException: open failed: EROFS (Read-only file system)
08-15 17:17:14.332: W/System.err(16500): at libcore.io.Posix.open(Native Method)
08-15 17:17:14.332: W/System.err(16500): at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
08-15 17:17:14.332: W/System.err(16500): at libcore.io.IoBridge.open(IoBridge.java:403)
08-15 17:17:14.342: W/System.err(16500): ... 15 more
08-15 17:17:14.342: I/filepath:is this error(16500): null