2010-06-14 39 views
15

OK, tôi có một ứng dụng Android có biểu mẫu trong đó, hai EditText, một spinner và nút đăng nhập. Người dùng chọn dịch vụ từ spinner, các loại trong tên người dùng và mật khẩu của họ, và nhấp chuột đăng nhập. Dữ liệu được gửi qua POST, phản hồi được trả về, nó được xử lý, một WebView mới được khởi chạy, chuỗi html được tạo ra từ phản hồi được tải và tôi có trang chủ của bất kỳ dịch vụ nào mà người dùng đã chọn.Duy trì phiên cookie trong Android

Đó là tất cả tốt và tốt. Bây giờ, khi người dùng nhấp vào liên kết, bạn không thể tìm thấy thông tin đăng nhập và trang yêu cầu người dùng đăng nhập lại. Phiên đăng nhập của tôi đang bị xóa ở đâu đó và tôi không chắc chắn cách chuyển thông tin từ lớp kiểm soát phần chính của ứng dụng của tôi đến lớp chỉ khởi chạy hoạt động xem trên web.

Các onClick handler từ nút mẫu đăng nhập:

private class FormOnClickListener implements View.OnClickListener { 

    public void onClick(View v) { 

     String actionURL, user, pwd, user_field, pwd_field; 

     actionURL = "thePageURL"; 
     user_field = "username"; //this changes based on selections in a spinner 
     pwd_field = "password"; //this changes based on selections in a spinner 
     user = "theUserLogin"; 
     pwd = "theUserPassword"; 

     List<NameValuePair> myList = new ArrayList<NameValuePair>(); 
     myList.add(new BasicNameValuePair(user_field, user)); 
     myList.add(new BasicNameValuePair(pwd_field, pwd)); 

     HttpParams params = new BasicHttpParams(); 
     DefaultHttpClient client = new DefaultHttpClient(params); 
     HttpPost post = new HttpPost(actionURL); 
     HttpResponse response = null; 
     BasicResponseHandler myHandler = new BasicResponseHandler(); 
     String endResult = null; 

     try { post.setEntity(new UrlEncodedFormEntity(myList)); } 
     catch (UnsupportedEncodingException e) { e.printStackTrace(); } 

     try { response = client.execute(post); } 
     catch (ClientProtocolException e) { e.printStackTrace(); } 
     catch (IOException e) { e.printStackTrace(); } 

     try { endResult = myHandler.handleResponse(response); } 
     catch (HttpResponseException e) { e.printStackTrace(); } 
     catch (IOException e) { e.printStackTrace(); } 

     List<Cookie> cookies = client.getCookieStore().getCookies(); 
     if (!cookies.isEmpty()) { 
      for (int i = 0; i < cookies.size(); i++) { 
       cookie = cookies.get(i); 
      } 
     } 

     Intent myWebViewIntent = new Intent(MsidePortal.this, MyWebView.class); 
     myWebViewIntent.putExtra("htmlString", endResult); 
     myWebViewIntent.putExtra("actionURL", actionURL); 
     startActivity(myWebViewIntent); 
    } 
} 

Và đây là lớp WebView để xử lý việc hiển thị câu trả lời:

public class MyWebView extends android.app.Activity { 

    private class MyWebViewClient extends WebViewClient { 

     @Override 
     public boolean shouldOverrideUrlLoading(WebView view, String url) { 
      view.loadUrl(url); 
      return true; 
     } 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
     setContentView(R.layout.web); 

     MyWebViewClient myClient = new MyWebViewClient(); 
     WebView webview = (WebView)findViewById(R.id.mainwebview); 
     webview.getSettings().setBuiltInZoomControls(true); 
     webview.getSettings().setJavaScriptEnabled(true); 
     webview.setWebViewClient(myClient); 

     Bundle extras = getIntent().getExtras(); 
     if(extras != null) 
     { 
      // Get endResult 
      String htmlString = extras.getString("htmlString"); 
      String actionURL = extras.getString("actionURL"); 

      Cookie sessionCookie = MsidePortal.cookie; 
      CookieSyncManager.createInstance(this); 
      CookieManager cookieManager = CookieManager.getInstance(); 
      if (sessionCookie != null) { 
       cookieManager.removeSessionCookie(); 
       String cookieString = sessionCookie.getName() 
         + "=" + sessionCookie.getValue() 
         + "; domain=" + sessionCookie.getDomain(); 
       cookieManager.setCookie(actionURL, cookieString); 
       CookieSyncManager.getInstance().sync(); 
      } 

      webview.loadDataWithBaseURL(actionURL, htmlString, "text/html", "utf-8", actionURL);} 
     } 
    } 
} 

Tôi đã thành công hỗn hợp thực hiện rằng giải pháp cookie. Dường như làm việc cho một dịch vụ mà tôi đăng nhập vào đó tôi biết giữ các cookie trên máy chủ (cũ, cổ, nhưng nó hoạt động và họ không muốn thay đổi nó.) Dịch vụ tôi đang cố yêu cầu người dùng giữ cookie trên máy cục bộ của họ và nó không hoạt động với thiết lập này.

Mọi đề xuất?

Trả lời

1

Bạn có thể lưu trữ cookie theo tùy chọn được chia sẻ và tải chúng khi cần trong các hoạt động khác.

Hoặc thử ý tưởng này từ similar question.

0

Tôi có vấn đề tương tự này cách đây vài tuần, đó là vì bạn tạo DefaultHttpClient mới mỗi khi bạn nhấp vào nút .. hãy thử tạo một DefaultHttpClient và sử dụng cùng một DefaultHttpClient cho mỗi yêu cầu bạn đang cố gắng gửi. nó giải quyết vấn đề của tôi

+2

Chắc chắn, nhưng đó là một sự lãng phí bộ nhớ để lưu trữ toàn bộ 'DefaultHttpClient' khi bạn chỉ cần cookie. – rds

0

dunno nếu bạn vẫn cần một câu trả lời, nhưng một lần nữa ở đây có một số thông tin bổ sung có thể giúp

nếu bạn muốn giữ cookie sync'ed

// ensure any cookies set by the dialog are saved 
CookieSyncManager.getInstance().sync(); 

và nếu bạn muốn Cookies rõ ràng

public static void clearCookies(Context context) { 
     // Edge case: an illegal state exception is thrown if an instance of 
     // CookieSyncManager has not be created. CookieSyncManager is normally 
     // created by a WebKit view, but this might happen if you start the 
     // app, restore saved state, and click logout before running a UI 
     // dialog in a WebView -- in which case the app crashes 
     @SuppressWarnings("unused") 
     CookieSyncManager cookieSyncMngr = 
      CookieSyncManager.createInstance(context); 
     CookieManager cookieManager = CookieManager.getInstance(); 
     cookieManager.removeAllCookie(); 
    } 
6

bạn cần phải giữ cookie từ một cuộc gọi khác. Thay vì tạo một DefaultHttpClient mới, hãy sử dụng trình tạo này:

private Object mLock = new Object(); 
private CookieStore mCookie = null; 
/** 
* Builds a new HttpClient with the same CookieStore than the previous one. 
* This allows to follow the http session, without keeping in memory the 
* full DefaultHttpClient. 
* @author Régis Décamps <[email protected]> 
*/ 
private HttpClient getHttpClient() { 
     final DefaultHttpClient httpClient = new DefaultHttpClient(); 
     synchronized (mLock) { 
       if (mCookie == null) { 
         mCookie = httpClient.getCookieStore(); 
       } else { 
         httpClient.setCookieStore(mCookie); 
       } 
     } 
     return httpClient; 
} 

Và giữ lớp Builder làm trường ứng dụng của bạn.

0

Khi bất kỳ hoạt động mới nào được khởi chạy (vì vậy tôi giả định điều này là giống nhau khi bạn khởi chạy một lần xem web mới), nó sẽ khởi chạy một chương trình mới từ đầu. Hoạt động mới này sẽ không có quyền truy cập vào dữ liệu từ bất kỳ hoạt động nào trước đó (trừ khi dữ liệu đó được thông qua bằng cách được đính kèm với mục đích).

2 giải pháp khả thi:

1) putExtra chỉ có thể được sử dụng để truyền dữ liệu nguyên thủy, vì vậy để vượt qua một cái gì đó phức tạp hơn bạn cần phải hoặc

  • a) Gói cấu trúc phức tạp hơn trong một lớp thực hiện giao diện
    Khớp nối, có thể được lưu trữ ở dạng phụ.

    b) Bọc cấu trúc phức tạp hơn trong một lớp thực hiện
    Giao diện có thể tuần tự hóa, có thể được lưu trữ thêm.

Một trong các cách tiếp cận này khá phức tạp và một chút công bằng.

2) Cá nhân tôi thích phương pháp tiếp cận được đề xuất bởi rds. Để làm rõ, khi rds nói:

giữ lớp Builder làm trường ứng dụng của bạn.

Tôi nghĩ rằng anh ấy có nghĩa là mở rộng lớp ứng dụng. Bất kỳ thuộc tính nào được lưu trữ có sẵn trên toàn cầu cho tất cả các hoạt động. Bài viết này giải thích rõ ràng cách thực hiện việc này: http://www.screaming-penguin.com/node/7746 Bạn có thể bỏ qua nội dung về AsyncTask (mặc dù tôi chắc chắn bạn sẽ tìm thấy nhu cầu đó) và chỉ tập trung vào việc mở rộng lớp ứng dụng .

1

Sử dụng này trong url Hoạt động đăng nhập

List<Cookie> cookies = client.getCookieStore().getCookies(); 
    if (!cookies.isEmpty()) { 
     for (int i = 0; i < cookies.size(); i++) { 
      cookie = cookies.get(i); 
     } 
    } 

    Cookie sessionCookie = cookie; 

    if (sessionCookie != null) { 
     String cookieString = sessionCookie.getName() + "=" 
       + sessionCookie.getValue() + "; domain=" 
       + sessionCookie.getDomain(); 
     cookieManager 
       .setCookie("www.mydomain.com", cookieString); 
     CookieSyncManager.getInstance().sync(); 
    } 
0

Bạn đã sử dụng dòng này -

if (sessionCookie != null) { 
     cookieManager.removeSessionCookie(); 
    } 

Để đảm bảo bạn nhận được mọi cookie mới.

Có vẻ như bạn đã trải qua cùng một vấn đề như tôi phải đối mặt, kiểm tra bên dưới liên kết -

removeSessionCookie() issue of android (code.google.,com)

nó nói rằng removeSessionCookie() được thực hiện trong một thread, vì vậy bất cứ khi nào nó được gọi là; một chủ đề bắt đầu và sau khi số setCookie(url, cookieString); của bạn được gọi, nó sẽ xóa cookie mới mà bạn vừa đặt. Vì vậy, đối với một số thiết bị, nó hoạt động tốt như removeSessionCookie() đã được thực hiện, trong khi, đối với một số, nó loại bỏ cookie, và chúng tôi nhận được vấn đề đó.

Tôi khuyên bạn nên xóa removeSessionCookie(); này vì bạn chỉ đang đặt một cookie, do đó, nó sẽ không xung đột với các cookie khác. Mã của bạn sẽ hoạt động liên tục.

0

Sử dụng nghiêm ngặt sessionID được lưu trữ trong cookie để xác định người dùng specfic.Every có một tên sessionID khác trong tiêu đề http. Bạn có thể sử dụng một số công cụ mạng hoặc trình duyệt để xem tên sessionID được gọi là gì.

Và cách khác, tôi GUESS, cách facebook và twitter, bạn sẽ xóa tất cả mã liên quan đến phiên, máy chủ sử dụng Mã thông báo truy cập để xác định người dùng.

Tôi có rõ ràng không?

Các vấn đề liên quan