لوگین به وبسایت؟
چطور میتونم برنامه ای بنویسم که داخل یک سایت لوگین کنم؟ ( بدون استفاده از وب ویو)
مثلا میخوام وارد حساب کاربری uncocoder ام بشم و تمام محتوای صفحه ی ناتیفیکیشن هام رو بخونم
خب از طریق DefaultHttpClient با کلید های "username" و "password" نام کاربری و رمز عبورم رو به این لینک میفرستم (با استفاده از متد post)
uncocoder.com/ورود?task=user.login
الان اگر لوگین شده باشم باید بتونم مثلا وارد صفحه ی ناتفیکیشنهام بشم و تمام سورس صفحه رو دانلود کنم اما این روش جواب نمیده!
راه حل چی هست؟
خوب ایده کلی این کار ساده و کارآمده. میتونه با یه سرویس پیغام خصوصی ها و/یا نوتیفیکیشن ها رو روی گوشیمون اطلاع رسانی کنه.
در کل نیاز به یه سرویسه که در مقاطع زمانی متناوبا سرور رو برای وجود این آیتم ها چک کنه.
اما اصل کار این چک کردنه. مرحله اول فرمیه که نام کاربری و رمز ورود کاربر رو دریافت میکنه و مثلا تو SP ذخیره میکنه. از اینجا به بعد اون چک کردن متناوب باید شروع بشه
بار اول برای چک کردن نیاز به لاگین هست. پس اطلاعات کاربر رو به آدرس ذکر شده post میکنیم. اما توقع بازگشت چیزی یا رشته ای رو نداریم.
از کل این تراکنش لاگین فقط کوکی هاش به درد ما میخوره. پس کوکی ها رو به صورت دلخواهمون تو یه فایل ذخیره میکنیم و از دفعات بعد نیازی به لاگین مجدد نداریم.
دفعات بعد با اضافه کردن کوکی ها به درخواستمون میتونیم رشته Json شبیه به این : {"nt":0,"pm":"7"} رو بدست بیاریم.
بقیه کارها هم که تا حدی سلیقه ای انجام میشه. این کلیات داستان!
** ادیتور موقع درج کد های طولانی به مشکل میخوره ، از طرفی هم جدا بودن تکه کد ها باعث پیگیری جداگانه مشکلات کد میشه. به هر حال توفیق اجباریه
مرحله اول : لاگین
public static void login(Context context) {
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
params.add(new BasicNameValuePair("username", preferences.getString("LOGIN_USERNAME","")));
params.add(new BasicNameValuePair("password", preferences.getString("LOGIN_PASSWORD","")));
params.add(new BasicNameValuePair("remember", "yes"));
String url = GlobalVariables.loginPostUrl;
HttpPost httpPost = new HttpPost(url);
HttpEntity entity = null;
try {
entity = new UrlEncodedFormEntity(params, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
httpPost.setEntity(entity);
DefaultHttpClient httpClient = new DefaultHttpClient();
try {
httpClient.execute(httpPost);
} catch (IOException e) {
e.printStackTrace();
}
CookieStore cookieStore = httpClient.getCookieStore();
for (Cookie cookie : cookieStore.getCookies())
CookieHelper.addCookie(cookie);
CookieHelper.saveCookie();
}
و کلاس مدیریت کوکی ها : CookieHelper
private static BasicCookieStore cookieStoreCache = null;
public static void addCookie(Cookie cookieObject) {
if (cookieStoreCache == null) {
cookieStoreCache = new BasicCookieStore();
}
cookieStoreCache.addCookie(cookieObject);
}
public static CookieStore getCookieStore(Context context) {
if (cookieStoreCache == null) {
try {
File file = new File(GlobalVariables.cookieFilePath);
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(file));
int size = inputStream.readInt();
for (int i = 0; i < size; i++) {
String[] parts = inputStream.readUTF().split("=");
BasicClientCookie cookie = new BasicClientCookie(parts[0], parts[1]);
cookie.setDomain(GlobalVariables.cookiesDomain);
addCookie(cookie);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (cookieStoreCache == null)
WebHelper.login(context);
}
return cookieStoreCache;
}
public static void saveCookie() {
File file = new File(GlobalVariables.cookieFilePath);
ObjectOutputStream outputStream = null;
try {
outputStream = new ObjectOutputStream(new FileOutputStream(file));
outputStream.writeInt(cookieStoreCache.getCookies().size());
for (Cookie cookie : cookieStoreCache.getCookies()) {
String cookieString = cookie.getName() + "=" + cookie.getValue();
outputStream.writeUTF(cookieString);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
طبق سناریو بالا و کد های درج شده واضح هستش که کلاس CookieHelper با دو تا متد یا داره کوکی ما رو تو یه فایل به صورت باینری درج میکنه یا اونها رو از فایل میخونه و به صورت CookieStore در اختیارمون میذاره
کل متغیر های مورد نیاز رو تو یه کلاس جداگانه نگهداری میکنم که میتونه با هر روش دیگه ای جایگزین بشه:
public class GlobalVariables {
public static String siteUrl = "http://uncocoder.com";
public static String url = "http://answers.uncocoder.com/user/getNotificationCount";
public static String loginPostUrl = "http://uncocoder.com/%D9%88%D8%B1%D9%88%D8%AF?task=user.login";
public static String forumUrl = "http://answers.uncocoder.com";
public static String cookiesDomain = ".uncocoder.com";
public static String sdCardPath = Environment.getExternalStorageDirectory().getAbsolutePath();
public static String appDirPath = sdCardPath + "/uncocoder/";
public static String cookieFilePath = appDirPath + "/cache.coo";
}
و در آخر هم همون رشته Json مورد نیاز رو از سرور میگیریم و چون از Gson استفاده میکنیم به یه ساختار جهت تجزیه رشتمون نیاز داریم:
public class NotificationStruct {
public int nt;
public int pm;
public NotificationStruct() {
this.nt = 0;
this.pm = 0;
}
}
این متد هستش که در فراصل زمانی متناوبا با ارسال درخواست به همراه کوکی ذخیره شده به سرور تعداد پیغامها و نوتیفیکیشن ها رو بر میگردونه
public static NotificationStruct getNotifications(Context context) {
DefaultHttpClient client = new DefaultHttpClient();
if (CookieHelper.getCookieStore(context) != null) {
client.setCookieStore(CookieHelper.getCookieStore(context));
}
HttpGet method = new HttpGet(GlobalVariables.url);
try {
HttpResponse response = client.execute(method);
InputStream inputStream = response.getEntity().getContent();
String result = convertInputStreamToString(inputStream);
Gson gson = new Gson();
return gson.fromJson(result, NotificationStruct.class);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return new NotificationStruct();
}
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .