1

我在以下代码中的标题中提到了 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
4

1 回答 1

0

打开输出流时出现错误:

FileOutputStream fileOutput = new FileOutputStream(filename); 

这将在您当前的目录(可能是/)中打开文件“sample”,而不是在 SD 卡上。您应该在文件本身打开流:

FileOutputStream fileOutput = new FileOutputStream(file); 
于 2013-08-15T13:31:29.113 回答