Problem: Yazdığınız Android uygulamasında bir WebView widgetı var ve bu widget ile yüklenen web sitesinde kullanıcılar oturum açıp kapatabiliyorlar. Siz de tıpkı bir web tarayıcısında olduğu gibi uygulama kapatılıp açılsa dahi kullanıcının oturumunu tekrar giriş yapmadan açmak / devam ettirmek istiyorsunuz. Bunu başarmak için de cookieleri kullanmaya karar verdiniz. Fakat WebView size bunun bir kolayını sunmuyor. Peki bu durumda nasıl sessionı aktif tutacaksınız?
Çözüm
Görünen o ki webde birçok kişi bu probleme farklı çözümler sunmuş. Bu çözümleri doğrudan alıp denediğinizde bazı şeylerin ters gittiğini görüyorsunuz. Fakat her çözümde işe yarar birçok bilgi var. Benim yaptığım bu çözümleri birleştirerek (en azından şu an için) çalışır bir hale dönüştürmek oldu.
Android’de cookie yönetimi için CookieSyncManager ve CookieManager sınıfları mevcut. Lollipop ile birlikte CookieSyncManager’a (bizim yapmak istediğimiz şeyi baz alarak düşündüğümüzde) ihtiyaç kalmıyor. Fakat Lollipop ve üzeri versiyonlar kullananlar toplam Android kullanıcılarının yaklaşık %30’u olduğu için biz bu iki sınıfı da kullanacağız.
Aslında yapılması gereken şey mantık olarak çok basit. Kullanıcı oturum açtığında cookieleri bir yere kaydet, uygulama açıldığında da WebView’e sayfayı yüklemeden önce kaydedilen cookieleri ekle. Fakat siz her ne kadar WebView ile siteyi yüklemeden önce cookieleri belirleseniz de, CookieManager’dan cookieleri istediğinizde sizin belirlediğiniz cookieleri vermediğini göreceksiniz. CookieSyncManager’ın dökümantasyonunda şöyle diyor:
The sync interval is 5 minutes, so you will want to force syncs manually anyway, for instance in onPageFinished(WebView, String). Note that even sync() happens asynchronously, so don’t do it just as your activity is shutting down.
Yani siz her ne kadar cookieleri ayarlasanız da, sync olması 5 dakikayı bulabiliyor. Dolayısıyla sizin CookieSyncManager’ın sync() metodunu çağırarak, ayarladığınız cookielerin sync edilebilmesi için, CookieSyncManager’a bu işlemi hemen yapması gerektiğini söylemeniz gerekiyor. Yine yukarıda dediği gibi, siz sync() deseniz bile, bu metod da senkronize çalışmadığı için, WebView adresi yüklemeye başlamadan önce cookielerin sync olması çok küçük bir ihtimal. Şurada da anlatıldığı gibi, aslında tek yapmamız gereken WebView’e adresi yüklemesini söylemeden önce biraz beklemek. 1 saniye kadar beklemek yeterli oluyor. Bu bekleme işlemini de arkaplanda yaptırarak UI threadi bloke etmemiş oluyoruz. Neticede yapmamız gereken bir AsyncTask oluşturmak ve cookieleri onPreExecute metodunda ayarlayıp, doInBackground‘da 1 saniye kadar bekledikten sonra onPostExecute‘ta da WebView’e adresi yüklemesini söylemek.
Nasıl entegre ediyoruz şimdi?
Öncelikle cookieleri kaydetmemiz gerek. Ben SharedPreferences kullanarak kaydetmeyi tercih ettim.
public static final String SHARED_PREFS_COOKIES = "cookie_store";
public static final String SHARED_PREFS_COOKIES_COOKIE = "cookie";
public SharedPreferences getCookieSharedPrefs() {
return getActivity().getSharedPreferences(SHARED_PREFS_COOKIES, Context.MODE_PRIVATE);
}
CookieManager’ı tanımlıyoruz ve cookieManager‘dan aldığımız cookieleri kullanıcı oturum açtıktan sonra shared preferences olarak kaydediyoruz:
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
// Get and save cookies
String cookies = cookieManager.getCookie(DEFAULT_URL);
getCookieSharedPrefs().edit().putString(SHARED_PREFS_COOKIES_COOKIE, cookies).commit();
Kullanıcı oturumunu kapattıktan sonra da kaydettiğimiz cookieleri siliyoruz ve CookeSyncManager’ın sync() metodunu kullanarak değişiklikleri uygulamasını söylüyoruz:
getCookieSharedPrefs().edit().remove(SHARED_PREFS_COOKIES_COOKIE).commit();
CookieSyncManager cookieSyncManager = CookieSyncManager.createInstance(getActivity());
cookieSyncManager.sync();
Son olarak da yukarıda bahsettiğimiz AsyncTask’ı oluşturuyoruz.