Solve the problem that Android webview settings cookie and cookie are missing

  • 2021-11-30 01:20:36
  • OfStack

h5 is nested in Android page, and there is a user login page inside H5 page. It is found that the login function of h5 page cannot be used, and 1 direct login fails. After discussing with web for 1 meeting, I found that cookie written by js was lost. All Android needs to be written once in rewriting.


    mWebView = view.findViewById(R.id.mall_view);
    settings = mWebView.getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setLoadsImagesAutomatically(true);
    settings.setDomStorageEnabled(true);
    // Not caching 
    settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
    mWebView.setWebViewClient(new MyWebViewClient());

  class MyWebViewClient extends WebViewClient{
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
      if (url != "") {
        // Emphasis writing cookie
        HashMap<String, String> map = new HashMap<>();
        map.put("Referer", view.getUrl());
        view.loadUrl(url, map);
      }
      return true;
    }

    @Override
    public void onPageFinished(WebView view, String url) {
      // Gets the post-login cookie, See if it is written 
      CookieManager cookieManager = CookieManager.getInstance();
      String CookieStr = cookieManager.getCookie(url);
      super.onPageFinished(view, url);
    }
  }

The above solves the problem of landing failure!

There is also the synchronization of login status, which needs to save and set cookie


  /**
   *  Object in the interface cookie
   * @param loginUrl
   */
  private void syncCookie(final String loginUrl) {

    new Thread(new Runnable() {


      @Override
      public void run() {
        try {
          StringBuilder builder = new StringBuilder();
          URL url= null;
          byte[] data = builder.toString().getBytes("UTF-8");
          url = new URL(loginUrl);
          HttpURLConnection connection =
              (HttpURLConnection) url.openConnection();

          connection.setDoOutput(true);
          connection.setRequestProperty("Content-Type",
              "application/x-www-form-urlencoded");
          connection.setRequestProperty("Content-Length",
              Integer.toString(data.length));
          connection.setRequestMethod("GET");
          connection.setInstanceFollowRedirects(false);
          OutputStream os = connection.getOutputStream();
          os.write(data);
          os.close();
          int aRstCode = connection.getResponseCode();
          if (aRstCode == HttpURLConnection.HTTP_OK) {
            cookie = connection.getHeaderField("Set-Cookie");
          }

        } catch (MalformedURLException e) {
          e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
          e.printStackTrace();
        } catch (ProtocolException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }).start();
  }
    // Settings cookie
    if(cookie != null && cookie.length() > 0){
      android.webkit.CookieManager cookieManager =
          android.webkit.CookieManager.getInstance();
      cookieManager.setAcceptCookie(true);
      cookieManager.setCookie(SysParam.shoppingMall, cookie);
      CookieSyncManager.getInstance().sync();
    }

Additional knowledge: android webview with cookie accessing url

Problem description

In the mixed development of native and h5, you will encounter such a problem. When loading an url with webview, you only log in to the account with app, but the webpage does not, so you will be prohibited from accessing this url, and webview will display a white screen.

Therefore, to access this url, you need to bring cookie for access. This cookie is the cookie stored when logging in with app

Implementation method and 1 environment

Network request mode

HttpsUrlConnection

Since HttpsUrlConnection is used here, it shows that the url I loaded is https protocol

So webview will be white when loaded

Error message:

1

This is because the certificate does not match the domain name, my debugging environment is on the intranet server, and the certificate is bound to the domain name of the public network.

So you need webView to skip certificate verification,

Skip certificate verification


 webView.setWebViewClient(new WebViewClient() {
      @Override
      public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        Log.e("app_name",error.toString());
        handler.proceed();
      }
    });

Then set cookie

cookie is an cookie that is saved locally when app uses HttpsUrlConnect to initiate a login request

Save cookie to local after app login is successful


SharedPreferences sharedPreferences = getSharedPreferences("login",MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
String cookieval = conn.getHeaderField("Set-Cookie");
editor.putString("all_cookie",cookieval);

Is a value with the following structure:

SESSION=f19b09e9-69b2-4ab4-9daf-ea224523a092; Path=/; Secure; HttpOnly

Write to cookie


/**
*@param cookie  The retrieved above is stored locally cookie String 
*@param url  Page to load url
*/
 private void setCookie(String cookie,String url) {
    String StringCookie = cookie;
    CookieManager cookieManager = CookieManager.getInstance();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      cookieManager.removeSessionCookies(null);
      cookieManager.flush();
    } else {
      cookieManager.removeSessionCookie();
      CookieSyncManager.getInstance().sync();
    }
    cookieManager.setAcceptCookie(true);
    cookieManager.setCookie(url, StringCookie);
  }

All key codes


 SharedPreferences sharedPreferences = getSharedPreferences("login",MODE_PRIVATE);
 String cookie = sharedPreferences.getString("session","");
 String all_cookie = sharedPreferences.getString("all_cookie","");
 Log.e("weibiao",all_cookie);
 webView = findViewById(R.id.other_account_service_webview);
 webView.setWebViewClient(new WebViewClient() {
   @Override
   public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
     Log.e("weibiao",error.toString());
     handler.proceed();
   }
 });
 initWebViewSettings();//webview Adj. 1 Some settings 
 setCookie(all_cookie,url);// In loadurl Call this method before 
 webView.loadUrl(url);

Related articles: