編輯:Android開發實例
一、設計思路
Android客戶端訪問IIS服務器時,當沒有登陸時,ASP.NET通過Form集成驗證方法會返回一個登陸頁面。然後輸入正確的用戶名和密碼,就可以進入主程序了。
在Android客戶端訪問以IIS為宿主的ASP.NET服務器時,返回JSON格式來傳遞數據。客戶端中,根據返回數據的不同而判斷當前狀態是否已登陸。由於Form驗證是保存了Cookie,所示每次調用Http請求之前要先添加上次請求的Cookie。
二、ASP.NET服務器端
創建一個ASP.NET MVC網站項目。
首先,由於每次請求都返回JSON格式的數據,我們編寫一個Model類來承載數據。
public class ResponseResult
{
/// <summary>
/// 是否已登錄
/// </summary>
public bool IsAuthenticated { get; set; }
/// <summary>
/// 是否執行成功
/// </summary>
public bool IsSuccess { get; set; }
/// <summary>
/// 登錄賬號
/// </summary>
public string Identity { get; set; }
/// <summary>
/// 執行結果
/// </summary>
public object Result { get; set; }
}
接著,編寫HomeController:
public class HomeController : Controller
{
[Authorize]
public ActionResult Index()
{
return Json(new ResponseResult
{
Result = "登陸成功",
IsAuthenticated = true,
IsSuccess = true,
Identity = this.User.Identity.Name
}, "text/html", JsonRequestBehavior.AllowGet);
}
public ActionResult LogOn()
{
return Json(new ResponseResult
{
Result = "您尚未登錄",
IsSuccess = true
}, "text/html", JsonRequestBehavior.AllowGet);
}
public ActionResult Register(string account, string password)
{
if (account == "liudong" && password == "123")
{
FormsAuthentication.SetAuthCookie(account, false);
return Json(new ResponseResult
{
Result = "登錄成功",
IsSuccess = true,
IsAuthenticated = true,
Identity = account
}, "text/html", JsonRequestBehavior.AllowGet);
}
else
{
return Json(new ResponseResult
{
Result = "用戶名或密碼錯誤",
}, "text/html", JsonRequestBehavior.AllowGet);
}
}
Index Action為登陸認證後才能訪問的Action。
LogOn Action為未登陸時跳轉的Action。
Register Action為登陸Action,用戶名和密碼正確後就保存Form驗證的Cookie。
然後,在Web.config中配置Form驗證配置
<authentication mode="Forms">
<forms loginUrl="~/Home/LogOn" timeout="2880" />
</authentication>
最後,配置IIS,部署ASP.NET MV網站。
三、Android客戶端
首先,編寫一個調用Http請求的類。
package ld.com.authorize;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import android.util.Log;
public abstract class HttpHelper {
private final static String TAG = "HttpHelper";
private final static String SERVER_URL = "http://192.168.1.104:180/Home/";
private static CookieStore cookieStore;
public static String invoke(String actionName, List<NameValuePair> params) {
String result = null;
try {
String url = SERVER_URL + actionName + "/";
Log.d(TAG, "url is" + url);
HttpPost httpPost = new HttpPost(url);
if (params != null && params.size() > 0) {
HttpEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
httpPost.setEntity(entity);
}
DefaultHttpClient httpClient = new DefaultHttpClient();
// 添加Cookie
if (cookieStore != null) {
httpClient.setCookieStore(cookieStore);
}
HttpResponse httpResponse = httpClient.execute(httpPost);
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpResponse.getEntity().getContent()));
for (String s = reader.readLine(); s != null; s = reader.readLine()) {
builder.append(s);
}
result = builder.toString();
Log.d(TAG, "result is ( " + result + " )");
// 保存Cookie
cookieStore = ((AbstractHttpClient) httpClient).getCookieStore();
} catch (Exception e) {
Log.e(TAG, e.toString());
}
Log.d(TAG, "over");
return result;
}
public static String invoke(String actionName) {
return invoke(actionName, null);
}
}
注意的是,需要存儲一個全局的Cookie,在每次調用前添加上去,再在調用j結束後保存它。
接著,添加兩個布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:text="賬號" android:layout_width="fill_parent"
android:layout_height="20dip" />
<EditText android:layout_width="fill_parent" android:hint="請輸入賬號"
android:layout_height="40dip" android:id="@+id/edtAccount" />
<TextView android:text="密碼" android:layout_width="fill_parent"
android:layout_height="20dip" />
<EditText android:layout_width="fill_parent" android:hint="請輸入密碼"
android:password="true" android:layout_height="40dip" android:id="@+id/edtPassword" />
<Button android:text="登錄" android:layout_width="fill_parent"
android:layout_height="40dip" android:id="@+id/btnLogon" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:text="調用" android:id="@+id/btnInvoke"
android:layout_width="fill_parent" android:layout_height="wrap_content" />
</LinearLayout>
然後、編寫登陸和主Activity
package ld.com.authorize;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class LogonActivity extends Activity {
private final String TAG = this.getClass().getSimpleName();
private EditText edtAccount;
private EditText edtPassword;
private Button btnLogon;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.logon);
edtAccount = (EditText) this.findViewById(R.id.edtAccount);
edtPassword = (EditText) this.findViewById(R.id.edtPassword);
btnLogon = (Button) this.findViewById(R.id.btnLogon);
setButtonOnClick();
}
private void setButtonOnClick() {
this.btnLogon.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
private ProgressDialog progressDialog;
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
// super.onPostExecute(result);
progressDialog.cancel();
Log.d(TAG, result);
try {
JSONObject json = new JSONObject(result);
String msg = json.getString("Result");
// 是否登錄
if (json.getBoolean("IsSuccess")) {
Toast.makeText(LogonActivity.this, msg,
Toast.LENGTH_SHORT).show();
// 跳轉登錄Activity
Intent intent = new Intent();
intent.setClass(LogonActivity.this,
MainActivity.class);
LogonActivity.this.startActivity(intent);
} else {
Toast.makeText(LogonActivity.this, msg,
Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
Log.e(TAG, e.toString());
}
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
progressDialog = new ProgressDialog(LogonActivity.this);
progressDialog.setCancelable(false);
progressDialog
.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setTitle("登錄中,請稍後...");
progressDialog.show();
}
@Override
protected String doInBackground(Void... arg0) {
// TODO Auto-generated method stub
String account = edtAccount.getText().toString();
String password = edtPassword.getText().toString();
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("account", account));
params.add(new BasicNameValuePair("password", password));
try {
return HttpHelper.invoke("Register", params);
} catch (Exception e) {
Log.e(TAG, e.toString());
return null;
}
}
};
task.execute();
}
});
}
}
package ld.com.authorize;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
private final String TAG = this.getClass().getSimpleName();
private Button btnInvoke;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnInvoke = (Button) this.findViewById(R.id.btnInvoke);
setInvokeOnClick();
}
private void setInvokeOnClick() {
btnInvoke.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
private ProgressDialog progressDialog;
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
// super.onPostExecute(result);
progressDialog.cancel();
Log.d(TAG, result);
try {
JSONObject json = new JSONObject(result);
// 是否登錄
if (json.getBoolean("IsAuthenticated")) {
String msg = json.getString("Identity") + ":"
+ json.getString("Result");
Toast.makeText(MainActivity.this, msg,
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this,
json.getString("Result"),
Toast.LENGTH_SHORT).show();
// 跳轉登錄Activity
Intent intent = new Intent();
intent.setClass(MainActivity.this,
LogonActivity.class);
MainActivity.this.startActivity(intent);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
Log.e(TAG, e.toString());
}
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setCancelable(false);
progressDialog
.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setTitle("調用中,請稍後...");
progressDialog.show();
}
@Override
protected String doInBackground(Void... arg0) {
// TODO Auto-generated method stub
try {
return HttpHelper.invoke("Index");
} catch (Exception e) {
Log.e(TAG, e.toString());
return null;
}
}
};
task.execute();
}
});
}
}
最後,設置訪問權限:<uses-permission android:name="android.permission.INTERNET" />
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放
1、完整生命周期 上圖是Android Activity的生命周期圖,其中Resumed、Paused、Stopped狀態是靜態的,這三個狀態下的Activit
Android由於其代碼是放在dalvik虛擬機上的托管代碼,所以能夠很容易的將其反編譯為我們可以識別的代碼。 之前我寫過一篇文章反編譯Android的apk包到
JSON代表JavaScript對象符號。它是一個獨立的數據交換格式,是XML的最佳替代品。本章介紹了如何解析JSON文件,並從中提取所需的信息。Android提供了四個