2

检查了许多类似的主题,但仍然无法找到正确的答案。

我正在尝试制作一个 Android 应用程序,用户可以在其中登录并连接到服务器以检索一些数据。可悲的是,我无法超越需要应用程序来维持应用程序和服务器之间的会话的部分。只是不知道如何正确地做到这一点。

据我阅读和理解,过程是这样的——用户点击登录按钮,向服务器发送请求。然后收到响应,其中包含带有会话 ID 的 cookie。我将会话 ID 保存在 SharedPreferences 中以供以后使用。加载下一个活动时,我从 SharedPreferences 中检索此 id,将其添加到下一个 HTTP 请求中,以便维护正确的会话。如我错了请纠正我。

问题在于将会话 ID 添加到 HTTP 请求。为了保持应用程序和服务器之间的会话,即使应用程序被破坏然后再次打开,应该在下面的代码中进行哪些更改?cookie 应该如何正确添加到请求中?看来我做得不对...

我的代码如下:

public class LoginScreen extends Activity {

    DefaultHttpClient httpclient = new DefaultHttpClient();
    SharedPreferences prefs;
    Editor editor;  
    Button login_button;
    String session_cookie;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);         
        setContentView(R.layout.activity_login_screen);

        prefs = this.getSharedPreferences("filetitlehere", Context.MODE_PRIVATE);
        editor = prefs.edit();      
        session_cookie = prefs.getString("sessionid", "not saved");

        if (session_cookie != "not saved") {
            // intent to another activity
        } else {            
            login_button = (Button)findViewById(R.id.button_login);
            login_button.setOnClickListener(new View.OnClickListener() { 
               @Override
               public void onClick(View v) {
                   ConnectivityManager connMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
                   NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();

                   if (networkInfo != null && networkInfo.isConnected()) {
                     new Login().execute("http://mywebpage.com/login");
                   } else {
                     // error
                   }                
               }
            });     
        }
    }

    private class Login extends AsyncTask<String, Void, String> {
        protected String doInBackground(String... url) {            
            try {
                return auth(url[0]);
            } catch (IOException e) {
                return "an error";
            }
        }       
        protected void onPostExecute(String result) {
            JSONObject jsonobj;
            Integer user_auth = 0;

            try {
                jsonobj = new JSONObject(result);
                user_auth = jsonobj.getInt("auth");             
            } catch (JSONException e) {
                // error
            }    

            if (user_auth == 0) { // in case user not logged in         
                List<Cookie> cookies = httpclient.getCookieStore().getCookies();
                for (Cookie ck : cookies) {
                    if (ck.getName() == "PHPSESSID") {
                        // saved in SharedPreferences for later use
                        prefs.edit().putString("sessionid", ck.getValue().toString()).commit();
                    }
                }
            } else {
                // user already logged in
                Intent intent = new Intent(getApplicationContext(), HomeScreen.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);  
            }
        }
    }

    private String auth(String myurl) throws IOException {      

        try {
            HttpPost httppost = new HttpPost(myurl);

            if (session_cookie == "not saved") {
                // without adding cookie, cause cookie not saved in SharedPreferences
                HttpResponse response = httpclient.execute(httppost);
            } else {
                // adding sessionid from SharedPreferences
                BasicCookieStore cstore = new BasicCookieStore();
                Cookie cookie = new BasicClientCookie("PHPSESSID",session_cookie);
                cstore.addCookie(cookie);
                HttpContext localContext = new BasicHttpContext();
                localContext.setAttribute(ClientContext.COOKIE_STORE, cstore);                          
                HttpResponse response = httpclient.execute(httppost, localContext);
            }

            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            StringBuilder resp = new StringBuilder();
            String line = null;            

            while((line = bufferedReader.readLine()) != null){
                resp.append(line);
            }
            return resp.toString();

        } catch (UnsupportedEncodingException e) {
            // error  
        } catch (ClientProtocolException e) {
            // error  
        } catch (IOException e) {
            // error  
        }     
    }   
}

其他一些问题:

  • 服务器是否仅在服务器端启动“session_start()”(例如使用 PHP)时(例如,当用户登录时)才发送会话 ID?
  • 如果服务器端的会话以某种方式被破坏,但我将之前保存的 cookie 添加到请求中怎么办?服务器将在标头中理解和发回什么?会不会有另一个 sessionid 或者什么都没有?

先感谢您!

4

1 回答 1

1

很久没问这个问题了。我没有自己编写会话管理,而是改用 loopj 的客户端 - http://loopj.com/android-async-http

解决了所有问题并出色地工作!

于 2014-04-28T09:56:52.207 回答