android loginDemo +WebService用戶登錄驗證
本文是基於android4.0下的loginActivity Demo和android下的Webservice實現的。loginActivity是android4.0下的自帶演示例程,他自帶登錄界面、用戶名格式設定、輸入密碼和用戶名格式是否正確、用戶登錄時間進度條等功能,用戶可以在這個例程的基礎上延伸出自己login用戶登錄程序。在這里我沒有對這個程序做過多的延伸,只是增加Webservice驗證用戶登錄的功能,使其成為一個完整的網絡用戶登錄驗證的模塊程序。在這我會對這個Demo做全面的解析,使初學者可以理解並能夠使用這個Demo。
一、准備工作(以下的准備步驟都在本人專欄里有相應文章,可以參考下面的連接)
③
下載 android的WebService項目包(初學者可以參考android專欄下的
Webservice使用例程)。
二、創建並理解android自帶loginActivity demo
1、創建android項目,SDK版本為API16、android4.1。然后一直next,在create Activity 中選擇loginActivity並將create activity選中。項目創建完成。
2、loginActivity demo的各塊源碼理解
①activity_login.xml界面布局代碼分析
- <merge xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- tools:context=".LoginActivity" >
- <!-- Login progress -->
- <!-- merge與FrameLayout布局相同,都是幀布局,不同的是,當LayoutInflater遇到這個標簽時,它會跳過它,並將<merge />內的元素添加到<merge />的父元素里。 -->
- <!-- 這個線性布局是驗證等待對話框的根元素,這個線性布局包含一個環形進度條,和一個字符標簽 -->
- <!-- 設置子元素在這個布局中心排布 -->
- <!-- 設置該布局在父布局及界面中心水平放置 -->
- <!-- 設置子布局縱向布局 -->
- <!-- 設置這個布局界面隱藏不可見 -->
- <LinearLayout
- android:id="@+id/login_status"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:gravity="center_horizontal"
- android:orientation="vertical"
- android:visibility="gone" >
- <ProgressBar
- style="?android:attr/progressBarStyleLarge"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="8dp" />
- <TextView
- android:id="@+id/login_status_message"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:fontFamily="sans-serif-light"
- android:text="@string/login_progress_signing_in"
- android:textAppearance="?android:attr/textAppearanceMedium" />
- </LinearLayout>
- <!-- Login form -->
- <!-- 根目錄為滾動試圖 -->
- <ScrollView
- android:id="@+id/login_form"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <!-- 線性縱向排布 -->
- <LinearLayout
- style="@style/LoginFormContainer"
- android:orientation="vertical" >
- <!--郵箱輸入框 -->
- <!--hint:設置編輯框無輸入顯示,設置輸入類型為Email型,設置為一行、單行模式 -->
- <EditText
- android:id="@+id/email"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="@string/prompt_email"
- android:inputType="textEmailAddress"
- android:maxLines="1"
- android:singleLine="true" />
- <!-- 密碼輸入框 -->
- <!-- imeActionLabel設置編輯文本“下一步”的顯示內容,imeActionId設置“下一步”的ID, 設置“完成”,設置輸入格式顯示***-->
- <EditText
- android:id="@+id/password"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="@string/prompt_password"
- android:imeActionId="@+id/login"
- android:imeActionLabel="@string/action_sign_in_short"
- android:imeOptions="actionUnspecified"
- android:inputType="textPassword"
- android:maxLines="1"
- android:singleLine="true" />
- <!-- 提交按鈕 -->
- <!--paddingLeft設置左邊距 -->
- <Button
- android:id="@+id/sign_in_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="right"
- android:layout_marginTop="16dp"
- android:paddingLeft="32dp"
- android:paddingRight="32dp"
- android:text="@string/action_sign_in_register" />
- </LinearLayout>
- </ScrollView>
- </merge>
②loginActivity.java源碼分析
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_login);
- // Set up the login form.
- //獲取引入的郵箱並顯示
- mEmail = getIntent().getStringExtra(EXTRA_EMAIL);
- mEmailView = (EditText) findViewById(R.id.email);
- mEmailView.setText(mEmail);
- //在密碼編輯界面判斷軟鍵盤的選擇,做對應操作
- mPasswordView = (EditText) findViewById(R.id.password);
- mPasswordView
- .setOnEditorActionListener(new TextView.OnEditorActionListener() {
- @Override
- public boolean onEditorAction(TextView textView, int id,
- KeyEvent keyEvent) {
- if (id == R.id.login || id == EditorInfo.IME_NULL) {//判斷軟件盤選擇的內容
- attemptLogin();
- return true;
- }
- return false;
- }
- });
- mLoginFormView = findViewById(R.id.login_form);
- mLoginStatusView = findViewById(R.id.login_status);
- mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message);
- //提交按鍵響應處理
- findViewById(R.id.sign_in_button).setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- attemptLogin();
- }
- });
- }
-----以上代碼是對界面相關設置
- public void attemptLogin() {
- if (mAuthTask != null) {
- return;
- }
- //設置輸入框的錯誤提示為空
- mEmailView.setError(null);
- mPasswordView.setError(null);
- //獲取輸入框的郵箱和密碼
- mEmail = mEmailView.getText().toString();
- mPassword = mPasswordView.getText().toString();
- boolean cancel = false;
- View focusView = null;
- // 設置密碼輸入框的格式(不能為空,不能小於4位)如果格式錯誤重新獲得焦點,並提示錯誤內容
- if (TextUtils.isEmpty(mPassword)) {
- mPasswordView.setError(getString(R.string.error_field_required));
- focusView = mPasswordView;
- cancel = true;
- } else if (mPassword.length() < 4) {
- mPasswordView.setError(getString(R.string.error_invalid_password));
- focusView = mPasswordView;
- cancel = true;
- }
- // 設置郵箱格式
- if (TextUtils.isEmpty(mEmail)) {
- mEmailView.setError(getString(R.string.error_field_required));
- focusView = mEmailView;
- cancel = true;
- } else if (!mEmail.contains("@")) {
- mEmailView.setError(getString(R.string.error_invalid_email));
- focusView = mEmailView;
- cancel = true;
- }
- if (cancel) {
- //如果格式錯誤,輸入框重新獲得輸入焦點
- focusView.requestFocus();
- } else {
- //如果輸入的格式正確,顯示驗證等待對話框,並啟動驗證線程
- mLoginStatusMessageView.setText(R.string.login_progress_signing_in);
- showProgress(true);
- mAuthTask = new UserLoginTask();
- mAuthTask.execute((Void) null);
- }
- }
-----attemptLogin函數是登錄驗證的調用函數,按鍵和密碼框的響應時間調用attemptLogin來做用戶驗證,他主要的功能是驗證用戶輸入密碼和郵箱的格式的正確與否,如果格式錯誤,在輸入框中顯示格式錯誤信息類型,格式正確后,調用showProgress顯示用戶驗證延時等待對話框和啟動mAuthTask異步處理用戶信息驗證。
- @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)//指出應用程序的API版本
- private void showProgress(final boolean show) {
- //獲取運行平台的版本與應用的版本對比實現功能的兼容性
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
- int shortAnimTime = getResources().getInteger(
- android.R.integer.config_shortAnimTime);//獲取系統定義的時間
- mLoginStatusView.setVisibility(View.VISIBLE);//設置驗證對話框為可顯
- mLoginStatusView.animate().setDuration(shortAnimTime)//設置動畫顯示時間
- .alpha(show ? 1 : 0)//設置動畫漸變效果
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mLoginStatusView.setVisibility(show ? View.VISIBLE
- : View.GONE);//跟據參數控制該控件顯示或隱藏
- }
- });
- mLoginFormView.setVisibility(View.VISIBLE);//設置輸入界面可顯
- mLoginFormView.animate().setDuration(shortAnimTime)
- .alpha(show ? 0 : 1)
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mLoginFormView.setVisibility(show ? View.GONE
- : View.VISIBLE);
- }
- });
- } else {
- mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE);//跟據參數控制該控件顯示或隱藏
- mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
- }
- }
-----showProgress函數主要是用戶登錄驗證時界面的顯示工作,界面顯示一個等待對話框。在這個函數里主要做了應用程序的API與系統平台的API對比並處理,關於系統信息的調用學習請參考(
Build相關屬性和調用系統信息的方法)。
- public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
- @Override
- protected Boolean doInBackground(Void... params) {//后台運行線程
- try {
- //模擬用戶驗證耗時
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- return false;
- }
- for (String credential : DUMMY_CREDENTIALS) {//遍歷數組驗證自定義用戶及密碼
- String[] pieces = credential.split(":");//分割字符串,將密碼個郵箱分離開
- if (pieces[0].equals(mEmail)) {
- return pieces[1].equals(mPassword);
- }
- }
- return true;
- }
- @Override
- protected void onPostExecute(final Boolean success) {//線程結束后的ui處理
- mAuthTask = null;
- showProgress(false);//隱藏驗證延時對話框
- if (success) {
- finish();
- } else {//密碼錯誤,輸入框獲得焦點,並提示錯誤
- mPasswordView
- .setError(getString(R.string.error_incorrect_password));
- mPasswordView.requestFocus();
- }
- }
- //取消驗證
- @Override
- protected void onCancelled() {
- mAuthTask = null;
- showProgress(false);
- }
- }
- }
-----UserLoginTask異步方法,該方法主要負責用戶后台驗證程序,在這里主要做了用戶登錄信息和預定義信息驗證,並做驗證后的操作。關於異步的學習可以參考
AsyncTask(異步)和Thread(線程)的使用與對比.
注意事項:這個demo為模塊界面,其本身不是系統的默認啟動界面,要想程序正常工作,要在AndroidManifest.xml中添加如下代碼
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
三、添加WebService用戶登錄驗證代碼
本文為android loginDemo +WebService用戶登錄驗證的續篇,在這里我主要總結的是在LoginActivity的demo中添加webservice代碼實現用戶網絡驗證(本地驗證參考
android loginDemo +WebService用戶登錄驗證)。
1、添加用戶上網權限
在AndroidManifest.xml中添加用戶權限,添加如下代碼使用戶有上網的權限。
<uses-permission android:name="android.permission.INTERNET"/>
2、定義Webservice的命名空間和服務地址以及Webservice方法,定義android下webservice的相關對象。
Webservice的服務地址和命名空間及內部方法的獲得,請參考(Android 使用.net開發的webservice做用戶登錄驗證)中的WebService解析。關於android下webservice的使用請參考()webservice的入門學習。
定義Webservice相關函數代碼
- /*******************************************/
- final static String SERVICE_NS = "http://tempuri.org/"; //Webservice所在命名空間
- final static String SERVICE_URL = "http://192.168.1.213:9006/WS_Base.asmx";//Webservice服務地址
- final static String methodName = "AuthenticateLogin";//要使用的接口函數
- private HttpTransportSE ht; //該對象用於調用WebService操作
- private SoapSerializationEnvelope envelope;//上一個類信息的載體
- private SoapObject soapObject; //將參數傳遞給WebService
- /**********************************************/
3、刪除attemptLogin方法中的關於用戶郵件驗證的部分,(程序中有一些要刪除的部分,根據理解)。
4、在attemptLogin方法中更改異步方法mAuthTask參數的傳遞類型。
mAuthTask = new UserLoginTask();
mAuthTask.execute(mEmail,mPassword);
5、重新修改異步方法實現用戶登錄驗證(關於異步的學習可以參考
AsyncTask(異步)和Thread(線程)的使用與對比.)
- public class UserLoginTask extends AsyncTask<String, Void, Boolean> {
- @Override
- protected Boolean doInBackground(String... params) {
- // TODO: attempt authentication against a network service.
- //set webservices attribute
- /***********************************************/
- //創建HttpTransportSE對象,該對象用於調用WebService操作
- ht = new HttpTransportSE(SERVICE_URL);
- ht.debug = true;
- //創建SoapSerializationEnvelope對象,它是HttpTransportSE調用WebService時消息
- //的載體;客戶端需要傳入的參數,需要通過SoapSerializationEnvelope對象的bodyOut屬性
- //傳給服務器;服務器響應生成的SOAP消息也通過該對象的bodyIn屬性來獲取。
- envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);//指明SOPA規范
- //創建SoapObject對象,創建對象時需要傳入調用Web Service的命名空間、方法名。
- soapObject = new SoapObject(SERVICE_NS, methodName);
- /************************************************************/
- //SoapObject 對象的addProperty(String name,Object value)方法將參數傳遞給服務端
- //該方法的name參數指定參數名;value參數指定參數值。
- //如果方法存在多個參數,多次調用addProperty即可。
- soapObject.addProperty("userName",params[0]);
- soapObject.addProperty("password",params[1]);
- envelope.bodyOut = soapObject;
- //設置WebService的開發類型
- envelope.dotNet = true;
- try
- {
- //調用遠程WebService,call()方法的參數意義 第一個參數:命名空間+方法名,
- //第二個參數:SoapSerializationEnvelope對象
- ht.call(SERVICE_NS+methodName, envelope);
- if(envelope.getResponse()!=null)
- {
- //SoapSerializationEnvelope對象的bodyIn屬性返回一個SoapObject對象,
- //該對象就代表了WebService的返回消息。
- //WebService在服務器端返回值是String類型的數值的時候使用Object代替SoapObject
- SoapObject result = (SoapObject)envelope.bodyIn;
- Object detail1 = (Object) result.getProperty(0);
- return detail1.toString().equals("true");
- }
- return false;
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- catch (XmlPullParserException e) {
- // TODO: handle exception
- e.printStackTrace();
- }
- return false;
- }
- @Override
- protected void onPostExecute(final Boolean success) {
- mAuthTask = null;
- showProgress(false);
- if (success) {
- finish();
- } else {
- mPasswordView
- .setError(getString(R.string.error_incorrect_password));
- mPasswordView.requestFocus();//設置密碼框獲得焦點
- }
- }
- @Override
- protected void onCancelled() {
- mAuthTask = null;
- showProgress(false);
- }
- }
總結:“關於android loginDemo +WebService用戶登錄驗證”實驗中遇到的問題及知識點總結
1、@Override是什么意思
沒什么用,這是IDE編輯器為你自動加上去的一個標志,告訴你說下面這個方法是從父類/接口 繼承過來的,需要你重寫一次。
2、@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)。
說明應用的API版本,在代碼中獲得平台的SDK版本與這個版本對比,在代碼中判斷應用與平台的兼容性。
關於獲取及使用用戶信息的Bulid列的介紹及使用說明,
參考android專欄。
3、EditText:
①android:imeOptions 設置軟鍵盤的Enter鍵。有如下值可設置:normal,actionUnspecified,actionNone,actionGo,actionSearch,actionSend,actionNext,actionDone,flagNoExtractUi ,flagNoAccessoryAction,flagNoEnterAction。可用’|’設置多個。
設置 android:imeOptions=
"actionDone" ,軟鍵盤下方變成“完成”,點擊后光標保持在原來的輸入框上,並且軟鍵盤關閉。
android:imeOptions="actionSend" 軟鍵盤下方變成“發送”,點擊后光標移動下一個。
②setError(string);設置編輯框的提示,例如setError(“密碼不能為空”);
③focusView.requestFocus();設置編輯框獲得焦點,實例:
focusView = mEmailView;
focusView.requestFocus();
View:
①setVisibility設置空間在界面的可見性
1.View.VISIBLE,常量值為0,意思是可見的2.View.INVISIBLE,常量值是4,意思是不可見的3.View.GONE,常量值是8,意思是不可見的,並且不占用布局空間
XML:
①Android:Layout_gravity 設置該組件在其容器中的對其方式。
Android:Layout_gravity=” center“(在組件中心)。
android:gravity 設置組件的子組件在組件中的位置,可以同時制定多種對齊方式的組合
android:gravity="left|center_vertical"代表出現在屏幕左邊,而且垂直居中。
②android:inputType 設置文本的輸入類型
android:inputType =“textPassword”設置輸入類型為密碼。
③
<b> 標簽呈現粗體文本效果:
<string name="action_sign_in_register"><b>Sign in</b> or register</string>
String 類
①String.split
根據給定的正則表達式的匹配來拆分此字符串。
6、做這個東西和總結了這篇文章,主要是在尋找自己的學習方法,也希望在學習的過程中留下點東西。
