zoukankan      html  css  js  c++  java
  • android loginDemo +WebService用户登录验证

        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界面布局代码分析
    [html] view plain copy
    1. <merge xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     xmlns:tools="http://schemas.android.com/tools"  
    3.     tools:context=".LoginActivity" >  
    4.   
    5.     <!-- Login progress -->  
    6.     <!-- merge与FrameLayout布局相同,都是帧布局,不同的是,当LayoutInflater遇到这个标签时,它会跳过它,并将<merge />内的元素添加到<merge />的父元素里。 -->  
    7.    
    8.     <!-- 这个线性布局是验证等待对话框的根元素,这个线性布局包含一个环形进度条,和一个字符标签 -->  
    9.     <!-- 设置子元素在这个布局中心排布 -->  
    10.     <!-- 设置该布局在父布局及界面中心水平放置 -->  
    11.     <!-- 设置子布局纵向布局 -->  
    12.     <!-- 设置这个布局界面隐藏不可见 -->  
    13.     <LinearLayout              
    14.         android:id="@+id/login_status"    
    15.         android:layout_width="wrap_content"  
    16.         android:layout_height="wrap_content"  
    17.         android:layout_gravity="center"       
    18.         android:gravity="center_horizontal"   
    19.         android:orientation="vertical"        
    20.         android:visibility="gone" >            
    21.   
    22.         <ProgressBar  
    23.             style="?android:attr/progressBarStyleLarge"  
    24.             android:layout_width="wrap_content"  
    25.             android:layout_height="wrap_content"  
    26.             android:layout_marginBottom="8dp" />   
    27.   
    28.         <TextView  
    29.             android:id="@+id/login_status_message"  
    30.             android:layout_width="wrap_content"  
    31.             android:layout_height="wrap_content"  
    32.             android:layout_marginBottom="16dp"  
    33.             android:fontFamily="sans-serif-light"  
    34.             android:text="@string/login_progress_signing_in"  
    35.             android:textAppearance="?android:attr/textAppearanceMedium" />  
    36.     </LinearLayout>  
    37.   
    38.     <!-- Login form -->  
    39.     <!-- 根目录为滚动试图 -->  
    40.     <ScrollView  
    41.         android:id="@+id/login_form"  
    42.         android:layout_width="match_parent"  
    43.         android:layout_height="match_parent" >  
    44.         <!-- 线性纵向排布 -->  
    45.         <LinearLayout  
    46.             style="@style/LoginFormContainer"  
    47.             android:orientation="vertical" >  
    48.              <!--邮箱输入框  -->  
    49.             <!--hint:设置编辑框无输入显示,设置输入类型为Email型,设置为一行、单行模式  -->  
    50.             <EditText  
    51.                 android:id="@+id/email"  
    52.                 android:layout_width="match_parent"  
    53.                 android:layout_height="wrap_content"  
    54.                 android:hint="@string/prompt_email"  
    55.                 android:inputType="textEmailAddress"  
    56.                 android:maxLines="1"  
    57.                 android:singleLine="true" />  
    58.             <!-- 密码输入框 -->  
    59.             <!-- imeActionLabel设置编辑文本“下一步”的显示内容,imeActionId设置“下一步”的ID, 设置“完成”,设置输入格式显示***-->  
    60.             <EditText  
    61.                 android:id="@+id/password"  
    62.                 android:layout_width="match_parent"  
    63.                 android:layout_height="wrap_content"  
    64.                 android:hint="@string/prompt_password"  
    65.                 android:imeActionId="@+id/login"  
    66.                 android:imeActionLabel="@string/action_sign_in_short"  
    67.                 android:imeOptions="actionUnspecified"  
    68.                 android:inputType="textPassword"  
    69.                 android:maxLines="1"  
    70.                 android:singleLine="true" />  
    71.              <!-- 提交按钮 -->  
    72.             <!--paddingLeft设置左边距  -->  
    73.             <Button  
    74.                 android:id="@+id/sign_in_button"  
    75.                 android:layout_width="wrap_content"  
    76.                 android:layout_height="wrap_content"  
    77.                 android:layout_gravity="right"  
    78.                 android:layout_marginTop="16dp"  
    79.                 android:paddingLeft="32dp"  
    80.                 android:paddingRight="32dp"  
    81.                 android:text="@string/action_sign_in_register" />  
    82.         </LinearLayout>  
    83.     </ScrollView>  
    84.   
    85. </merge>  
    ②loginActivity.java源码分析
    [html] view plain copy
    1. protected void onCreate(Bundle savedInstanceState) {  
    2.         super.onCreate(savedInstanceState);  
    3.         setContentView(R.layout.activity_login);  
    4.         // Set up the login form.  
    5.         //获取引入的邮箱并显示  
    6.         mEmail = getIntent().getStringExtra(EXTRA_EMAIL);  
    7.         mEmailView = (EditText) findViewById(R.id.email);  
    8.         mEmailView.setText(mEmail);  
    9.         //在密码编辑界面判断软键盘的选择,做对应操作  
    10.         mPasswordView = (EditText) findViewById(R.id.password);  
    11.         mPasswordView  
    12.                 .setOnEditorActionListener(new TextView.OnEditorActionListener() {  
    13.                     @Override  
    14.                     public boolean onEditorAction(TextView textView, int id,  
    15.                             KeyEvent keyEvent) {  
    16.                         if (id == R.id.login || id == EditorInfo.IME_NULL) {//判断软件盘选择的内容  
    17.                             attemptLogin();  
    18.                             return true;  
    19.                         }  
    20.                         return false;  
    21.                     }  
    22.                 });  
    23.         mLoginFormView = findViewById(R.id.login_form);  
    24.         mLoginStatusView = findViewById(R.id.login_status);  
    25.         mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message);  
    26.         //提交按键响应处理  
    27.         findViewById(R.id.sign_in_button).setOnClickListener(  
    28.                 new View.OnClickListener() {  
    29.                     @Override  
    30.                     public void onClick(View view) {  
    31.                         attemptLogin();  
    32.                     }  
    33.                 });  
    34.     }  
                    -----以上代码是对界面相关设置
    [java] view plain copy
    1. public void attemptLogin() {  
    2.     if (mAuthTask != null) {  
    3.         return;  
    4.     }  
    5.     //设置输入框的错误提示为空  
    6.     mEmailView.setError(null);  
    7.     mPasswordView.setError(null);  
    8.     //获取输入框的邮箱和密码  
    9.     mEmail = mEmailView.getText().toString();  
    10.     mPassword = mPasswordView.getText().toString();  
    11.     boolean cancel = false;  
    12.     View focusView = null;  
    13.     // 设置密码输入框的格式(不能为空,不能小于4位)如果格式错误重新获得焦点,并提示错误内容  
    14.     if (TextUtils.isEmpty(mPassword)) {  
    15.         mPasswordView.setError(getString(R.string.error_field_required));  
    16.         focusView = mPasswordView;  
    17.         cancel = true;  
    18.     } else if (mPassword.length() < 4) {  
    19.         mPasswordView.setError(getString(R.string.error_invalid_password));  
    20.         focusView = mPasswordView;  
    21.         cancel = true;  
    22.     }  
    23.     // 设置邮箱格式  
    24.     if (TextUtils.isEmpty(mEmail)) {  
    25.         mEmailView.setError(getString(R.string.error_field_required));  
    26.         focusView = mEmailView;  
    27.         cancel = true;  
    28.     } else if (!mEmail.contains("@")) {  
    29.         mEmailView.setError(getString(R.string.error_invalid_email));  
    30.         focusView = mEmailView;  
    31.         cancel = true;  
    32.     }  
    33.     if (cancel) {  
    34.         //如果格式错误,输入框重新获得输入焦点  
    35.         focusView.requestFocus();  
    36.     } else {  
    37.         //如果输入的格式正确,显示验证等待对话框,并启动验证线程  
    38.         mLoginStatusMessageView.setText(R.string.login_progress_signing_in);  
    39.         showProgress(true);  
    40.         mAuthTask = new UserLoginTask();  
    41.         mAuthTask.execute((Void) null);  
    42.     }  
    43. }  
                    -----attemptLogin函数是登录验证的调用函数,按键和密码框的响应时间调用attemptLogin来做用户验证,他主要的功能是验证用户输入密码和邮箱的格式的正确与否,如果格式错误,在输入框中显示格式错误信息类型,格式正确后,调用showProgress显示用户验证延时等待对话框和启动mAuthTask异步处理用户信息验证。
    [java] view plain copy
    1. @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)//指出应用程序的API版本  
    2. private void showProgress(final boolean show) {  
    3.     //获取运行平台的版本与应用的版本对比实现功能的兼容性  
    4.     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {  
    5.         int shortAnimTime = getResources().getInteger(  
    6.                 android.R.integer.config_shortAnimTime);//获取系统定义的时间  
    7.   
    8.         mLoginStatusView.setVisibility(View.VISIBLE);//设置验证对话框为可显  
    9.         mLoginStatusView.animate().setDuration(shortAnimTime)//设置动画显示时间  
    10.                 .alpha(show ? 1 : 0)//设置动画渐变效果  
    11.                 .setListener(new AnimatorListenerAdapter() {  
    12.                     @Override  
    13.                     public void onAnimationEnd(Animator animation) {  
    14.                         mLoginStatusView.setVisibility(show ? View.VISIBLE  
    15.                                 : View.GONE);//跟据参数控制该控件显示或隐藏  
    16.                     }  
    17.                 });  
    18.         mLoginFormView.setVisibility(View.VISIBLE);//设置输入界面可显  
    19.         mLoginFormView.animate().setDuration(shortAnimTime)  
    20.                 .alpha(show ? 0 : 1)  
    21.                 .setListener(new AnimatorListenerAdapter() {  
    22.                     @Override  
    23.                     public void onAnimationEnd(Animator animation) {  
    24.                         mLoginFormView.setVisibility(show ? View.GONE  
    25.                                 : View.VISIBLE);  
    26.                     }  
    27.                 });  
    28.     } else {  
    29.         mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE);//跟据参数控制该控件显示或隐藏  
    30.         mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);  
    31.     }  
    32. }  
                    -----showProgress函数主要是用户登录验证时界面的显示工作,界面显示一个等待对话框。在这个函数里主要做了应用程序的API与系统平台的API对比并处理,关于系统信息的调用学习请参考(Build相关属性和调用系统信息的方法)。
    [java] view plain copy
    1. public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {  
    2.         @Override  
    3.         protected Boolean doInBackground(Void... params) {//后台运行线程  
    4.             try {  
    5.                 //模拟用户验证耗时  
    6.                 Thread.sleep(2000);  
    7.             } catch (InterruptedException e) {  
    8.                 return false;  
    9.             }  
    10.   
    11.             for (String credential : DUMMY_CREDENTIALS) {//遍历数组验证自定义用户及密码  
    12.                 String[] pieces = credential.split(":");//分割字符串,将密码个邮箱分离开  
    13.                 if (pieces[0].equals(mEmail)) {  
    14.                     return pieces[1].equals(mPassword);  
    15.                 }  
    16.             }  
    17.             return true;  
    18.         }  
    19.   
    20.         @Override  
    21.         protected void onPostExecute(final Boolean success) {//线程结束后的ui处理  
    22.             mAuthTask = null;  
    23.             showProgress(false);//隐藏验证延时对话框  
    24.   
    25.             if (success) {  
    26.                 finish();  
    27.             } else {//密码错误,输入框获得焦点,并提示错误  
    28.                 mPasswordView  
    29.                         .setError(getString(R.string.error_incorrect_password));  
    30.                 mPasswordView.requestFocus();  
    31.             }  
    32.         }  
    33.         //取消验证  
    34.         @Override  
    35.         protected void onCancelled() {  
    36.             mAuthTask = null;  
    37.             showProgress(false);  
    38.         }  
    39.     }  
    40. }  
                    -----UserLoginTask异步方法,该方法主要负责用户后台验证程序,在这里主要做了用户登录信息和预定义信息验证,并做验证后的操作。关于异步的学习可以参考AsyncTask(异步)和Thread(线程)的使用与对比.

     注意事项:这个demo为模块界面,其本身不是系统的默认启动界面,要想程序正常工作,要在AndroidManifest.xml中添加如下代码

    [html] view plain copy
    1. <intent-filter>  
    2.   
    3.             <action android:name="android.intent.action.MAIN" />  
    4.   
    5.             <category android:name="android.intent.category.LAUNCHER" />  
    6.   
    7.         </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相关函数代码
    [html] view plain copy
    1. /*******************************************/  
    2. final static String SERVICE_NS = "http://tempuri.org/"; //Webservice所在命名空间  
    3. final static String SERVICE_URL = "http://192.168.1.213:9006/WS_Base.asmx";//Webservice服务地址  
    4. final static String methodName = "AuthenticateLogin";//要使用的接口函数  
    5.   
    6. private HttpTransportSE ht; //该对象用于调用WebService操作  
    7. private SoapSerializationEnvelope envelope;//上一个类信息的载体  
    8. private SoapObject soapObject; //将参数传递给WebService  
    9. /**********************************************/  
            3、删除attemptLogin方法中的关于用户邮件验证的部分,(程序中有一些要删除的部分,根据理解)。
            4、在attemptLogin方法中更改异步方法mAuthTask参数的传递类型。
             mAuthTask = new UserLoginTask();
                mAuthTask.execute(mEmail,mPassword);
            5、重新修改异步方法实现用户登录验证(关于异步的学习可以参考AsyncTask(异步)和Thread(线程)的使用与对比.)
                
    [java] view plain copy
    1. public class UserLoginTask extends AsyncTask<String, Void, Boolean> {  
    2.     @Override  
    3.     protected Boolean doInBackground(String... params) {  
    4.         // TODO: attempt authentication against a network service.  
    5.         //set webservices attribute  
    6.         /***********************************************/  
    7.         //创建HttpTransportSE对象,该对象用于调用WebService操作  
    8.         ht = new HttpTransportSE(SERVICE_URL);  
    9.         ht.debug = true;  
    10.         //创建SoapSerializationEnvelope对象,它是HttpTransportSE调用WebService时消息  
    11.         //的载体;客户端需要传入的参数,需要通过SoapSerializationEnvelope对象的bodyOut属性  
    12.         //传给服务器;服务器响应生成的SOAP消息也通过该对象的bodyIn属性来获取。  
    13.         envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);//指明SOPA规范  
    14.         //创建SoapObject对象,创建对象时需要传入调用Web Service的命名空间、方法名。  
    15.         soapObject = new SoapObject(SERVICE_NS, methodName);  
    16.           
    17.         /************************************************************/  
    18.         //SoapObject 对象的addProperty(String name,Object value)方法将参数传递给服务端  
    19.         //该方法的name参数指定参数名;value参数指定参数值。  
    20.         //如果方法存在多个参数,多次调用addProperty即可。  
    21.         soapObject.addProperty("userName",params[0]);  
    22.         soapObject.addProperty("password",params[1]);  
    23.         envelope.bodyOut = soapObject;  
    24.         //设置WebService的开发类型  
    25.         envelope.dotNet = true;  
    26.         try   
    27.         {  
    28.             //调用远程WebService,call()方法的参数意义 第一个参数:命名空间+方法名,  
    29.             //第二个参数:SoapSerializationEnvelope对象  
    30.             ht.call(SERVICE_NS+methodName, envelope);  
    31.             if(envelope.getResponse()!=null)  
    32.             {  
    33.                 //SoapSerializationEnvelope对象的bodyIn属性返回一个SoapObject对象,  
    34.                 //该对象就代表了WebService的返回消息。  
    35.                 //WebService在服务器端返回值是String类型的数值的时候使用Object代替SoapObject  
    36.                 SoapObject result = (SoapObject)envelope.bodyIn;  
    37.                 Object detail1 = (Object) result.getProperty(0);                      
    38.                 return detail1.toString().equals("true");  
    39.             }  
    40.             return false;  
    41.         }  
    42.         catch (IOException e)  
    43.         {  
    44.             e.printStackTrace();  
    45.         }  
    46.         catch (XmlPullParserException e) {  
    47.             // TODO: handle exception  
    48.             e.printStackTrace();  
    49.         }  
    50.         return false;  
    51.     }  
    52.     @Override  
    53.     protected void onPostExecute(final Boolean success) {  
    54.         mAuthTask = null;  
    55.         showProgress(false);  
    56.   
    57.         if (success) {  
    58.             finish();  
    59.         } else {  
    60.             mPasswordView  
    61.                     .setError(getString(R.string.error_incorrect_password));  
    62.             mPasswordView.requestFocus();//设置密码框获得焦点  
    63.         }  
    64.     }  
    65.     @Override  
    66.     protected void onCancelled() {  
    67.         mAuthTask = null;  
    68.         showProgress(false);  
    69.     }  
    70. }  

    总结:“关于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、做这个东西和总结了这篇文章,主要是在寻找自己的学习方法,也希望在学习的过程中留下点东西。
  • 相关阅读:
    批量管理增量日志(seek、tell)
    字符串和编码
    5.activiti--完成任务
    4.activiti--代理任务Claiming the task
    3.activiti--待办任务
    2.activiti-启动流程实例
    1.activiti-流程图
    html 各种高度
    redis-过期时间、访问限制与缓存
    spring mvc controller 接收参数
  • 原文地址:https://www.cnblogs.com/android-blogs/p/5912585.html
Copyright © 2011-2022 走看看