2016-05-04 4 views
1

Ich habe über> 15 Stunden zu diesem Problem recherchiert: Ich baue eine Hybrid App, ich logge mich mit dem Volley Framework (native View) ein, sobald ich mich anmelde ich fetch die Antwort Header, entpacken Sie das Cookie und speichern Sie es in meine sharedprefs. Nach erfolgreicher Anmeldung habe ich einen nativen Hauptbildschirm, der Links zu mehreren Webviews enthält. Wie gebe ich den Cookie, den ich vom Login erhalten habe, an den Webview weiter? 90% der Antworten im Internet verwenden den CookieSyncManager, der veraltet ist. Ich habe den java.net.CookieManager auch ausprobiert, nichts davon funktioniert.Android Hybrid App + Volley, Cookies und WebView

Hier ist mein Code

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mWebView = new WebView(this); 

    setContentView(mWebView); 

    cookies = pref.getString(Const.COOKIE_KEY,"null"); 
    userID = pref.getString(Const.USER_ID_KEY,"null"); 
    mUrl = Const.PERFORMANCE_WEBVIEW_LINK + Const.USER_ID; 
    String cookieText = Const.COOKIE_KEY + "=" + cookies; 

    //Approach A Environment for the Cookies 
    //Does not work 
    cookieSync = CookieSyncManager.createInstance(this); 
    cookieManager = CookieManager.getInstance(); 
    cookieManager.removeSessionCookie(); 
    cookieManager.setCookie(mUrl, cookieText); 
    cookieSync.sync(); 

    SystemClock.sleep(10000); 

    /*APPROACH B, sending the Cookies with header 
     ##Did not Work## 
    final Map<String, String> headers = new HashMap<>(); 

    Log.d("cookie", cookieText); 
    headers.put("Cookie",cookieText); 
    */ 

    if(cookies.equals("null") || userID.equals("null")) { 
     Toast.makeText(PerformanceWebview.this, "Error", Toast.LENGTH_SHORT).show(); 
     //Logging Out 
     Intent intent = new Intent(this, LoginActivity.class); 
     startActivity(intent); 
    } 
    else { 
     //mWebView.loadUrl(mUrl,headers); 
     mWebView.loadUrl(mUrl); 
     Toast.makeText(PerformanceWebview.this,cookieText, Toast.LENGTH_SHORT).show(); 
     Log.d("URL", "URL: " + mUrl); 
    } 


} 

Ich habe auch versucht, einen WebClient auf die WebView vorbei und overrode es shouldOverrideURl Methode ist und übergeben die Header hinein. Ein weiterer Ansatz, den ich tat WebSettings wurde mit und Leiten eines ChromeClient ..

Keine der hier Antworten scheinen

+0

eine Lösung gefunden: namens Customer ihrem Backend-Entwickler zu sagen, einen Weg zu ermöglichen, Cookies zu vermeiden und meine Kundenanfragen zu akzeptieren – Makaveli

Antwort

0
class CookieStore_ implements CookieStore{ 
/** this map may have null keys! */ 
private final Map<URI, List<HttpCookie>> map = new HashMap<URI, List<HttpCookie>>(); 
private android.webkit.CookieManager manager; 

public CookieStore_() { 
    manager = android.webkit.CookieManager.getInstance(); 
} 

public synchronized void add(URI uri, HttpCookie cookie) { 
    if (cookie == null) { 
     throw new NullPointerException("cookie == null"); 
    } 

    uri = cookiesUri(uri); 
    //add cookie to the CookieManager,be sure you have called 
    //CookieSyncManager.createInstance(context) if your android version   
    //is lower than Lollipop 
    manager.setCookie(uri.toString(),cookie.toString()); 

    List<HttpCookie> cookies = map.get(uri); 
    if (cookies == null) { 
     cookies = new ArrayList<HttpCookie>(); 
     map.put(uri, cookies); 
    } else { 
     cookies.remove(cookie); 
    } 
    cookies.add(cookie); 
} 

private URI cookiesUri(URI uri) { 
    if (uri == null) { 
     return null; 
    } 
    try { 
     return new URI("http", uri.getHost(), null, null); 
    } catch (URISyntaxException e) { 
     return uri; // probably a URI with no host 
    } 
} 

public synchronized List<HttpCookie> get(URI uri) { 
    if (uri == null) { 
     throw new NullPointerException("uri == null"); 
    } 

    List<HttpCookie> result = new ArrayList<HttpCookie>(); 

    // get cookies associated with given URI. If none, returns an empty list 
    List<HttpCookie> cookiesForUri = map.get(uri); 
    if (cookiesForUri != null) { 
     for (Iterator<HttpCookie> i = cookiesForUri.iterator(); i.hasNext();) { 
      HttpCookie cookie = i.next(); 
      if (cookie.hasExpired()) { 
       i.remove(); // remove expired cookies 
      } else { 
       result.add(cookie); 
      } 
     } 
    } 

    // get all cookies that domain matches the URI 
    for (Map.Entry<URI, List<HttpCookie>> entry : map.entrySet()) { 
     if (uri.equals(entry.getKey())) { 
      continue; // skip the given URI; we've already handled it 
     } 

     List<HttpCookie> entryCookies = entry.getValue(); 
     for (Iterator<HttpCookie> i = entryCookies.iterator(); i.hasNext();) { 
      HttpCookie cookie = i.next(); 
      if (!HttpCookie.domainMatches(cookie.getDomain(), uri.getHost())) { 
       continue; 
      } 
      if (cookie.hasExpired()) { 
       i.remove(); // remove expired cookies 
      } else if (!result.contains(cookie)) { 
       result.add(cookie); 
      } 
     } 
    } 

    return Collections.unmodifiableList(result); 
} 

public synchronized List<HttpCookie> getCookies() { 
    List<HttpCookie> result = new ArrayList<HttpCookie>(); 
    for (List<HttpCookie> list : map.values()) { 
     for (Iterator<HttpCookie> i = list.iterator(); i.hasNext();) { 
      HttpCookie cookie = i.next(); 
      if (cookie.hasExpired()) { 
       i.remove(); // remove expired cookies 
      } else if (!result.contains(cookie)) { 
       result.add(cookie); 
      } 
     } 
    } 
    return Collections.unmodifiableList(result); 
} 

public synchronized List<URI> getURIs() { 
    List<URI> result = new ArrayList<URI>(map.keySet()); 
    result.remove(null); // sigh 
    return Collections.unmodifiableList(result); 
} 

public synchronized boolean remove(URI uri, HttpCookie cookie) { 
    if (cookie == null) { 
     throw new NullPointerException("cookie == null"); 
    } 

    List<HttpCookie> cookies = map.get(cookiesUri(uri)); 
    if (cookies != null) { 
     return cookies.remove(cookie); 
    } else { 
     return false; 
    } 
} 

public synchronized boolean removeAll() { 
    boolean result = !map.isEmpty(); 
    map.clear(); 
    return result; 
} 

public void clearCookies(){ 
    map.clear(); 
} 

}

diese Klasse von CookieStoreImpl kopiert wurde, zu arbeiten und hat einen android.webkit .CookieManager drin, wenn add (URI uri, HttpCookie cookie) aufgerufen wird, fügen Sie das cookie dem cookieManager hinzu, dann wenn webview eine URL lädt, die eine Übereinstimmung in cookieManager hat, fügt webview passende Cookies zu den Headern der Anfrage hinzu.

unten ist eine Hilfsklasse

public class CookieUtil { 
private CookieManager manager; 
private CookieStore_ cookieStore_; 
private CookieSyncManager syncManager; 
private static CookieUtil cookieUtil; 
private boolean isInitialed = false; 

private CookieUtil(Context context) { 
    manager = CookieManager.getInstance(); 

    if (!Util.hasLollipop()){ 
     syncManager = CookieSyncManager.createInstance(context); 
    } 
    cookieStore_ = new CookieStore_(); 
} 

public void clearCookies(){ 
    if (manager.hasCookies()){ 
     if (Util.hasLollipop()){ 
      manager.removeAllCookies(null); 
     }else { 
      manager.removeAllCookie(); 
     } 
    } 
    cookieStore_.clearCookies(); 
} 

public static CookieUtil getCookieUtil(Context context){ 
    if (cookieUtil == null) 
     cookieUtil = new CookieUtil(context); 
    return cookieUtil; 
} 

public void sync(){ 
    if (Util.hasLollipop()){ 
     manager.flush(); 
    }else { 
     syncManager.sync(); 
    } 
} 

public void setThirdPartyCookieAcceptable(WebView webView){ 
    if (Util.hasLollipop()){ 
     manager.setAcceptThirdPartyCookies(webView,true); 
    } 
} 

public void initCookieHandler(){ 
    if (isInitialed) 
     return; 
    isInitialed = true; 
    CookieHandler.setDefault(new java.net.CookieManager(cookieStore_, CookiePolicy.ACCEPT_ORIGINAL_SERVER)); 
} 

}

, wenn Sie Cookies auf einen lokalen Speicher nicht speichern müssen, Sie Volley Cookies teilen können über eine einzige Leitung zur Webansicht

CookieUtil.getCookieUtil(context).initCookieHandler(); 

und vergessen Sie nicht, clearCookies() zu rufen, wenn Sie sich abmelden

1

Zuerst machen sicher Volley verwendet Cookies: (siehe https://stackoverflow.com/a/21271347)

// Make volley remember cookies 

// Do this only once on app startup, and keep the reference to the cookiemanager. 
// I'm saving it on an App class, but you can do something different. 

App.cookieManager = new CookieManager(); 
CookieHandler.setDefault(App.cookieManager); 

// Note, we are using the java.net.CookieManager above. 

Dann, nach einem Login Anruf in Volley zum Beispiel synchronisieren die Cookies WebView:

// Sync cookies to webview 
android.webkit.CookieManager webkitCookies = android.webkit.CookieManager.getInstance(); 

for (HttpCookie cookie : App.cookieManager.getCookieStore().getCookies()) { 
    webkitCookies.setCookie(cookie.getDomain(), cookie.getName() + "=" + cookie.getValue()); 
} 

if (Build.VERSION.SDK_INT >= 21) { 
    webkitCookies.flush(); 
} else { 
    CookieSyncManager.getInstance().sync(); 
}