美文网首页Android项目
仿京东商城系列14------用户登录以及app登录拦截

仿京东商城系列14------用户登录以及app登录拦截

作者: 小庄bb | 来源:发表于2017-08-25 15:01 被阅读294次

    本项目来自菜鸟窝,有兴趣者点击http://www.cniao5.com/course/

    项目已经做完,
    https://github.com/15829238397/CN5E-shop


    仿京东商城系列0------项目简介
    仿京东商城系列1------fragmentTabHost实现底部导航栏
    仿京东商城系列2------自定义toolbar
    仿京东商城系列3------封装Okhttp
    仿京东商城系列4------轮播广告条
    仿京东商城系列5------商品推荐栏
    仿京东商城系列6------下拉刷新上拉加载的商品列表
    仿京东商城系列7------商品分类页面
    仿京东商城系列8------自定义的数量控制器
    仿京东商城系列9------购物车数据存储器实现
    仿京东商城系列10------添加购物车,管理购物车功能实现
    仿京东商城系列11------商品排序功能以及布局切换实现(Tablayout)
    仿京东商城系列12------商品详细信息展示(nativie与html交互)
    仿京东商城系列13------商品分享(shareSDK)
    仿京东商城系列14------用户登录以及app登录拦截
    仿京东长城系列15------用户注册,SMSSDK集成
    仿京东商城系列16------支付SDK集成
    仿京东商城系列17------支付功能实现
    仿京东商城系列18------xml文件读取(地址选择器)
    仿京东商城系列19------九宫格订单展示
    仿京东商城系列20------终章


    前言

    本次将完成菜鸟商城的登录功能,以及app登陆拦截。登录想必大家都懂,那什么叫登录拦截呢?
    登陆拦截的意思就是,假如你还没有登录该app,但是你直接点击了我的订单功能,此时app就会自动跳转到登录界面让你完成登录,待登录完毕以后,再直接跳转到目标页面(也就是本例中的订单页面),效果图如下:

    用户登录.gif

    内容

    界面分析

    • 我的界面由一个自定义ToolBar与若干个Text,以及一个退出登录按钮。具体代码如下:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <com.example.cne_shop.widget.CnToolbar
            android:id="@+id/toolBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/actionBarSize"
            android:minWidth="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:titleTextColor="@color/white"
            app:isShowSearchView="false"
    
            ></com.example.cne_shop.widget.CnToolbar>
    
        <View
            style="@style/line_max_vertical"/>
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="5dp"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:id="@+id/my_list"
            android:text="  我的订单"
            android:gravity="center_vertical"
            android:background="@color/white"
            android:drawableLeft="@drawable/icon_list_o"
            />
        <View
            style="@style/line_vertical"
            ></View>
    
        <TextView
            android:id="@+id/my_favorite"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/white"
            android:drawableLeft="@drawable/icon_favorite"
            android:gravity="center_vertical"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:text="  我的收藏" />
    
        <View
            style="@style/line_vertical"
            ></View>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:paddingBottom="5dp"
            android:gravity="center_vertical"
            android:text="  收货地址"
            android:background="@color/white"
            android:drawableLeft="@drawable/icon_location"
            android:id="@+id/my_consignee"/>
    
        <View
            style="@style/line_max_vertical"/>
    
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="退出登录"
            android:id="@+id/loginOut"
            android:background="@color/red"
            android:visibility="gone"
            android:textColor="@color/white"/>
    
    </LinearLayout>
    
    • 用户登录界面就如所有的界面一样,不做赘述
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <com.example.cne_shop.widget.CnToolbar
            android:id="@+id/toolBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/actionBarSize"
            android:minWidth="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:leftButtonIcon="@drawable/icon_back_32px"
            app:title="@string/title_login"
            android:titleTextColor="@color/white"
            app:isShowSearchView="false"
            ></com.example.cne_shop.widget.CnToolbar>
    
        <View
            style="@style/line_max_vertical"
            ></View>
    
        <com.example.cne_shop.widget.MyEditText
            android:id="@+id/userId"
            android:layout_width="match_parent"
            android:layout_height="35dp"
            android:background="@color/white"
            android:hint="@string/text_user"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:enabled="true"
            android:textSize="14sp"
            android:drawableLeft="@drawable/icon_telphone_32"/>
        <View
            style="@style/line_vertical"/>
    
        <com.example.cne_shop.widget.MyEditText
            android:id="@+id/password"
            android:layout_width="match_parent"
            android:layout_height="35dp"
            android:background="@color/white"
            android:enabled="true"
            android:hint="@string/text_pass"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:drawableLeft="@drawable/icon_lock"
            android:textSize="14sp" />
        <View
            style="@style/line_max_vertical"
            ></View>
    
        <Button
            android:id="@+id/button_log"
            android:layout_width="match_parent"
            android:layout_height="35dp"
            android:background="@color/red"
            android:text="@string/but_login"
            android:textColor="@color/white" />
    
        <View
            style="@style/line_max_vertical"
            ></View>
        <RelativeLayout
    
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:clickable="true">
    
            <TextView
                android:paddingLeft="10dp"
                android:paddingTop="10dp"
                android:paddingBottom="10dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:id="@+id/register"
                android:textColor="@color/red"
                android:clickable="true"
                android:text="@string/but_regist"/>
            <TextView
                android:paddingRight="10dp"
                android:paddingTop="10dp"
                android:paddingBottom="10dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:id="@+id/forgetPass"
                android:clickable="true"
                android:textColor="@color/red"
                android:text="@string/but_forget_pass"/>
    
        </RelativeLayout>
    </LinearLayout>
    

    功能分析

    • 用户登录
      1.用户通过okhttp向服务器发出请求。
       String uri = Contents.API.LOGIN ;
            Map< String , String > params = new HashMap<String, String>() ;
            params.put("phone" , phoneNum ) ;
            params.put("password" , DESUtil.encode(Contents.DES_KEY , pwd)) ;
    
            okhttpHelper.doPost(uri, new loadingSpotsDialog<LoginRespMsg<User>>(LoginActivity.this ) {
                @Override
                public void onErroe(Response response, int responseCode, Exception e) throws IOException {
                    this.closeSpotsDialog();
                }
    
                @Override
                public void callBackSucces(Response response, LoginRespMsg<User> userLoginRespMsg) throws IOException {
                    this.closeSpotsDialog();
    
                    if(userLoginRespMsg.getStatus() == 1){
    
                        MyApplication.getInstance().putUser(userLoginRespMsg.getData() , userLoginRespMsg.getTocken());
                        closeKeyMode() ;
    
                        if (null == MyApplication.getInstance().getIntent()){
                            setResult(RESULT_OK);
                            finish();
                        }else {
                            MyApplication.jumpToTargetoActivity(LoginActivity.this);
                            finish();
                        }
    
                    }else {
                        showLoginErrorMsg() ;
                        phone.setText("");
                        password.setText("");
                    }
                }
            }, params);
    

    3.新建工具类,从SharedPreferences存取用户信息。

    package com.example.cne_shop.utils;
    
    import android.content.Context;
    import android.text.TextUtils;
    
    import com.example.cne_shop.bean.User;
    import com.example.cne_shop.contents.Contents;
    
    /**
     * Created by 博 on 2017/7/23.
     */
    
    public class UserLocalData {
    
        public static void putUser(Context context , User user){
    
            String user_json = JsonUtil.toJSON(user) ;
            PreferenceUtil.putString(context , Contents.USER_JSON , user_json);
        }
    
        public static void putToken(Context context , String token){
    
            PreferenceUtil.putString(context , Contents.TOKEN , token);
        }
    
        public static User getUser(Context context){
            String user_json = PreferenceUtil.getString(context , Contents.USER_JSON , null);
            if (!TextUtils.isEmpty(user_json)){
    
                return JsonUtil.fromJson(user_json , User.class) ;
            }
            return null ;
        }
    
        public static String getToken(Context context){
            String token = PreferenceUtil.getString(context , Contents.TOKEN , null);
            if (!TextUtils.isEmpty(token)){
    
                return JsonUtil.fromJson(token , String.class) ;
            }
            return null ;
        }
    
        public static void clearUser(Context context){
            PreferenceUtil.putString(context , Contents.USER_JSON , "");
        }
    
        public static void clearToken(Context context){
            PreferenceUtil.putString(context , Contents.TOKEN , "");
        }
    
    }
    
    

    2.服务器返回登陆结果,如果成功了就将用户信息存储到SharedPreferences中,并在Application类中建立私有变量,将SharedPreferences存储的用户信息,复制到Application的私有变量中。便于随时访问用户信息。

    package com.example.cne_shop.application;
    
    import android.app.Activity;
    import android.app.Application;
    import android.content.Context;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.widget.ImageView;
    
    import com.example.cne_shop.bean.User;
    import com.example.cne_shop.utils.UserLocalData;
    import com.facebook.drawee.backends.pipeline.Fresco;
    import com.squareup.picasso.Picasso;
    
    /**
     * Created by 博 on 2017/8/23.
     */
    
    public class MyApplication extends Application {
    
        public static final int START_FOR_RESULT  = 0 ;
        public static final int START_NO_RESULT  = 1 ;
    
        private User user ;
        private String token ;
        private static Intent intent ;
        private static  int startIntentStype ;
    
        public static int getStartIntentStype() {
            return startIntentStype;
        }
    
        public static void setStartIntentStype(int startIntentStype) {
            MyApplication.startIntentStype = startIntentStype;
        }
    
        public Intent getIntent() {
            return intent;
        }
    
        public void setIntent(Intent intent) {
            this.intent = intent;
        }
    
        public static MyApplication myApplication ;
    
        public static MyApplication getInstance(){
            return myApplication ;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            this.myApplication = this ;
            initUser();
            Fresco.initialize(this);
    //        NineGridView.setImageLoader(new PicassoImageLoader());
    
        }
    
        public void initUser(){
            this.user = UserLocalData.getUser(this );
            this.token = UserLocalData.getToken(this) ;
        }
    
        public User getUser(){
            return user ;
        }
    
        public String getToken(){
            return token ;
        }
    
        public void putUser(User user , String token){
    
            this.token = token ;
            this.user = user ;
            UserLocalData.putUser(this , user);
            UserLocalData.putToken(this , token);
        }
    
        public void clearUser(){
            this.user = null ;
            this.token = null ;
            UserLocalData.clearUser(this);
            UserLocalData.clearToken(this);
        }
    
        public static void jumpToTargetoActivity(Activity activity){
            activity.startActivity(intent);
            intent = null ;
        }
    
    }
    
    

    3.以后每次进入app都会自动检测application中有没有user值。如果有则获得,直接加载已经登录的用户界面。

     @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
            User user = MyApplication.getInstance().getUser() ;
            showUser(user) ;
        }
    
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        private void showUser(User user){
            if (user != null){
                cnToolbar.setUserPhotoIcon(this.getActivity() , user.getLogo_url() , R.drawable.default_head );
                cnToolbar.setUserNameText(user.getUsername());
                loginOut.setVisibility(View.VISIBLE);
                cnToolbar.setUserClickable(false);
    
            }else {
    
                cnToolbar.setUserNameText("点击登录");
                cnToolbar.setUserPhotoIcon(getContext() , R.drawable.default_head);
                loginOut.setVisibility(View.GONE);
                cnToolbar.setUserClickable(true);
            }
        }
    

    app登录拦截

    1.activity切换方面
    在打开需要用户权限的Activity时调用该方法。

     protected void startActivityWithLogin(Intent intent , boolean isNeedLogin , int startIntentStype){
    
            if (isNeedLogin){
    
                if(MyApplication.getInstance().getUser() == null){
    
                    Intent intent1 = new Intent(this , LoginActivity.class) ;
    
                    if (MyApplication.START_FOR_RESULT == startIntentStype){
                        startActivityForResult(intent1 , Contents.REQUEST_CODE);
                    }else if(MyApplication.START_NO_RESULT == startIntentStype){
                        MyApplication.getInstance().setIntent(intent);
                        startActivity(intent1);
                    }
    
                }else {
                    this.startActivity(intent);
                }
            }else {
                this.startActivity(intent);
            }
    }
    

    2.网络请求方面。在我们提交成功时会获得一个status变量,这个变量表述了我们当前的用户信息是否可用。在提交okhttp请求时,加上status参数。

    private String getUriWithParams( String uri ,Map<String , String> formData){
    
            if (formData == null){
                formData = new HashMap<>(1);
            }
    
            String symbol = null ;
            int signNum = 0 ;
    
            String token = MyApplication.getInstance().getToken() ;
            if (!TextUtils.isEmpty(token)){
                formData.put("token" , MyApplication.getInstance().getToken());
            }
    
            for(String key : formData.keySet()){
                symbol = (signNum++ == 0 )? "?" : "&" ;
                uri = uri+symbol+key+"="+formData.get(key) ;
            }
    
            return uri ;
    
        }
    

    验证status是否可用。

     else if (response.code() == TOKEN_ERROR ||response.code() == TOKEN_EXPRISE ||response.code() == TOKEN_MISSING  ){
                        callbackTokenError(callback , response) ;
                    }
    
    1. 如果不可用,那么要求用户进行登录。
     public void onTokenError(Response response, int responseCode) {
    
            Toast.makeText(mContext , "TokenError" , Toast.LENGTH_SHORT).show();
    
            Intent intent = new Intent(mContext , LoginActivity.class);
            mContext.startActivity(intent);
    
            MyApplication.getInstance().clearUser();
        }
    

    我们的app登录,以及登陆拦截已经完成。详细内容点击页首源码。

    相关文章

      网友评论

        本文标题:仿京东商城系列14------用户登录以及app登录拦截

        本文链接:https://www.haomeiwen.com/subject/ghpudxtx.html