• Kotlin高仿微信-第2篇-登录


    Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。

    Kotlin高仿微信-项目实践58篇,点击查看详情

    效果图:

    实现代码:

    
    
    
        
    
    
            
    
            
    
            
    
            
    
    
            
    
            
    
    
            
    
    
            
    
    
        
    

    /**
     * Author : wangning
     * Email : maoning20080809@163.com
     * Date : 2022/4/19 14:41
     * Description : 登录页面
     */
    class LoginFragment : BaseDataBindingFragment() , ServiceConnection {
    
        override fun getLayoutRes() = R.layout.wc_main_login
        private val userViewModel : UserViewModel by viewModels()
        private var account: String = ""
        private var password: String = ""
        private var xmppService: XmppService? = null
        private var navController : NavController? = null
        //是否在注册成功页面,注册成功返回
        private var isRegisterBack:Boolean = false
    
        override fun onAttach(context: Context) {
            super.onAttach(context)
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
        }
    
        override fun onActivityCreated(savedInstanceState: Bundle?) {
            super.onActivityCreated(savedInstanceState)
        }
    
        override fun onStart() {
            super.onStart()
        }
    
        override fun onConfigurationChanged(newConfig: Configuration) {
            super.onConfigurationChanged(newConfig)
        }
    
        override fun onHiddenChanged(hidden: Boolean) {
            super.onHiddenChanged(hidden)
            if(!hidden){
                getFocus();
            }
        }
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            initViews()
        }
    
        private fun initViews() {
            super.builder().setTitleContent(R.string.wc_base_top_login)
            base_top_back.setOnClickListener {
                System.exit(1)
            }
            navController = Navigation.findNavController(btn_register)
            navController?.previousBackStackEntry?.savedStateHandle?.getLiveData(CommonUtils.User.IS_REGISTER_BACK)?.observe(viewLifecycleOwner){
              isRegisterBack = it
            }
    
            var intent = Intent(requireActivity(), XmppService::class.java)
            requireActivity().bindService(intent, this , BIND_AUTO_CREATE)
    
            btn_register.setOnClickListener {
                Navigation.findNavController(it).navigate(R.id.action_register)
            }
    
            btn_login.setOnClickListener { login() }
    
            var accountTemp = DataStoreUtils.get(DataStoreParams.User.DS_ACCOUNT, "") as String
            var passwordTemp = DataStoreUtils.get(DataStoreParams.User.DS_PASSWORD, "") as String
            CoroutineScope(Dispatchers.Main).launch {
                delay(200)
                login_account.setText(accountTemp)
                login_password.setText(passwordTemp)
            }
    
            login_root_layout.setOnClickListener {
                TagUtils.d("点击根节点 Click ")
                SoftInputUtils.hideSoftInput(login_account)
            }
    
            userViewModel.insertUserData.observe(viewLifecycleOwner){
                //如果同步成功,则重新登录
                if(it){
                    DataStoreUtils.put(DataStoreParams.User.DS_OPENFILE_REGISTER, true)
                    login()
                } else {
                    ToastUtils.makeText(requireActivity(), BaseUtils.getString(R.string.wc_login_failure))
                    dismissLoadingDialog()
                }
            }
        }
    
    
        private var loadingUtils : BaseDialogUtils? = null
        //显示加载对话框
        private fun showLoadingDialog(){
            loadingUtils = BaseDialogUtils(requireActivity())
            loadingUtils!!.builder()
                .hideCancel()
                .hideConfirm()
                .setCancelable(true)
                .setOnLoadingClick(object : BaseDialogUtils.OnLoadingClick{
                    override fun onClickCancel() {
                        ToastUtils.makeText(requireActivity(), "对话框取消按钮")
                    }
    
                    override fun onClickConfirm() {
                        ToastUtils.makeText(requireActivity(), "对话框确定按钮")
                    }
                })
            loadingUtils?.show()
        }
    
        //隐藏加载对话框
        private fun dismissLoadingDialog(){
            loadingUtils?.dismiss()
        }
    
        //登录
        private fun login() {
            var isRegisterSuccess = DataStoreUtils.get(DataStoreParams.User.DS_OPENFILE_REGISTER, false) as Boolean
            TagUtils.d("login 开始 ${isRegisterSuccess}")
            account = login_account.text.toString()
            password = login_password.getText().toString()
            if (account?.length == 0 || password?.length == 0) {
                ToastUtils.makeText(requireActivity(), "帐号或密码不能为空")
                return
            } else if (!isRegisterSuccess && isRegisterBack){
                var name = DataStoreUtils.get(DataStoreParams.User.DS_NICKNAME, "") as String
                if(TextUtils.isEmpty(name)){
                    name = account
                }
                //如果在openfire注册成功,没有同步到web服务器,点击登录按钮,则重新同步
                var userBean = UserBean(account = account, name = name, nickName = name,  address = "", email = "",phone = "", avatar = "", birthday = "", note = "")
                userViewModel.insertUser(userBean)
            } else {
                SoftInputUtils.hideSoftInput(login_account)
                showLoadingDialog()
                try {
                    xmppService?.login(account, password)
                } catch (e : Exception) {
                    e.printStackTrace()
                    //ToastUtils.makeText(R.string.wc_login_failure)
                    dismissLoadingDialog()
                }
            }
        }
    
        /*private fun initCall() {
            //在前台了,发送广播 调起权限判断弹窗
            val viop = Intent()
            val intent: Intent = requireActivity().intent
            viop.putExtra("room", intent.getStringExtra("room"))
            viop.putExtra("audioOnly", intent.getBooleanExtra("audioOnly", false))
            viop.putExtra("inviteId", intent.getStringExtra("inviteId"))
            viop.putExtra("inviteUserName", intent.getStringExtra("inviteUserName"))
            //        viop.putExtra("msgId", intent.getLongExtra("msgId", 0));
            viop.putExtra("userList", intent.getStringExtra("userList"))
            viop.action = Utils.ACTION_VOIP_RECEIVER
            viop.component = ComponentName(WcApp.getInstance().getPackageName(), VoipReceiver::class.java.getName())
            WcApp.getInstance().sendBroadcast(viop)
        }*/
    
        private fun processLoginResult(type : Int) {
            CoroutineScope(Dispatchers.Main).launch {
                dismissLoadingDialog()
                if(type == 1){
                    ToastUtils.makeText(R.string.wc_login_success)
                    /*var isFromCall = requireActivity().intent.getBooleanExtra("isFromCall", false)
                    if (isFromCall) { //无权限,来电申请权限会走这里
                        initCall()
                    }*/
                    DataStoreUtils.get(DataStoreParams.Install.DS_FIRST_INSTALL, true)
                    loginSusscess()
                } else {
                    ToastUtils.makeText(R.string.wc_login_failure)
                }
            }
        }
    
        override fun onServiceConnected(p0: ComponentName?, binder: IBinder?) {
            TagUtils.d("LoginService 连接成功")
            var xmppBinder = binder as XmppService.XmppBinder
            xmppService = xmppBinder.service
            xmppService?.setCallback(object : XmppService.LoginCallback{
                override fun onFailure() {
                    //TagUtils.d("LoginFragment登录失败")
                    processLoginResult(2)
                }
    
                override fun onSuccess(account: String, password: String) {
                    TagUtils.d("LoginFragment登录成功")
                    processLoginSuccess()
                }
            })
        }
    
        override fun onServiceDisconnected(p0: ComponentName?) {
            TagUtils.d("LoginService onServiceDisconnected 断开连接")
        }
    
        private fun processLoginSuccess(){
            CoroutineScope(Dispatchers.IO).launch {
                DataStoreUtils.put(DataStoreParams.User.DS_ACCOUNT, account!!)
                DataStoreUtils.put(DataStoreParams.User.DS_PASSWORD, password!!)
                DataStoreUtils.put(DataStoreParams.User.DS_USER_EXIST, false)
    
                //登录成功, 保存本地信息
                var userBean = UserRepository.getUserByAccount(account!!)
                TagUtils.d("登录成功:${account} , ${password} , userBean = ${userBean}")
    
                // 设置用户名
                WcApp.getInstance().username  = account!!
                // 添加登录回调
                SocketManager.getInstance().addUserStateCallback(object : IUserState{
                    override fun userLogin() {
                        TagUtils.d("登录视频服务器成功login")
                    }
    
                    override fun userLogout() {
                        TagUtils.d("登录视频服务器失败logout")
                    }
                })
                // 连接socket:登录
                SocketManager.getInstance().connect(BaseUtils.WS, account!!, 0)
    
                processLoginResult(1)
            }
        }
    
    
        //登录成功
        private fun loginSusscess() {
            Navigation.findNavController(btn_login).popBackStack(R.id.main_start_dest, true)
            EventBus.getDefault().post(EventMsgBean(EventMsgBean.TYPE_LOGIN_SUCCESS))
        }
    
        override fun onResume() {
            super.onResume()
            getFocus()
        }
    
        private fun getFocus(){
            view?.isFocusableInTouchMode = true
            view?.requestFocus()
            view?.setOnKeyListener { view, keyCode, event ->
                if(event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){
                    System.exit(1)
                }
                true
            }
        }
    
    }
    fun login(account : String, password : String){
        CoroutineScope(Dispatchers.IO).launch {
            try {
                if(!xmppConnection.isAuthenticated){
                    xmppConnection.connect()
                    // 连接服务器
                    xmppConnection.login(account, password)
                    // 连接服务器成功,更改在线状态
                    val presence = Presence(Presence.Type.available)
                    xmppConnection.sendPacket(presence)
                    TagUtils.d("用户登录状态:${xmppConnection.isAuthenticated} , ${xmppConnection.isConnected}")
                }
                if(xmppConnection.isAuthenticated){
                    WcApp.setXmppConnection(xmppConnection)
                    ChatManagerUtils.getInstance().addChatListener()
                    AddFileListener.addFileListerer()
                    AddFriendsListener.addSubscriptionListener()
                    checkConnectionListener = CheckConnectionListener()
                    xmppConnection.addConnectionListener(checkConnectionListener)
    
                    TagUtils.d("xmpp 管理连接成功 ")
    
                    var result = UserService.getApi().getUser(account)
                    TagUtils.d("syncUser 用户返回数据:${result}")
                    if(result.isSuccess){
                        //插入本地数据库
                        UserRepository.insertUser(GsonUtils.getUserBean(result.data!!))
                        //处理同步信息
    
                    } else {
                        //如果在openfire注册成功,没有同步到web服务器,或者web服务器已经不存在该账户,只能重新创建
                        var userBean = UserBean(account = account, name = account, nickName = account,  address = "", email = "",phone = "", avatar = "", birthday = "", note = "")
                        var userStr = Gson().toJson(userBean)
                        UserRepository.insertUser(userBean)
                        UserRepository.insertUserServer(userStr)
                    }
    
                    loginCallback?.onSuccess(account, password)
                } else {
                    loginCallback?.onFailure()
                }
    
            } catch (e: Exception){
                //ToastUtils.makeText(R.string.wc_login_failure)
                TagUtils.d("用户登录状态:${e.message}")
                e.printStackTrace()
                loginCallback?.onFailure()
            }
        }
    }

    //登录成功,同步数据
    private fun showLoadingDialog(){
        var isFirstLogin = DataStoreUtils.get(DataStoreParams.User.DS_IS_FIRST_LOGIN, true) as Boolean
        //首次安装
        if(!isFirstLogin){
            return
        }
        var account = DataStoreUtils.getAccount()
        if(TextUtils.isEmpty(account)){
            return
        }
        var view = LayoutInflater.from(this).inflate(R.layout.wc_sync_first_data, null)
    
        loadingUtils = BaseDialogUtils(this)
        loadingUtils!!.builder()
            .showView(view)
            .hideCancel()
            .hideConfirm()
            .setCancelable(false)
        loadingUtils?.show()
        SyncRepository.syncFirst(account, packageName, object : ICommonCallback{
            override fun onFailure(obj: Any) {
                dismissLoadingDialog()
            }
    
            override fun onSuccess(obj: Any) {
                dismissLoadingDialog()
            }
        })
    }

  • 相关阅读:
    Linux性能测试之性能测试指标详解
    自组织是管理者和成员的双向奔赴
    C语言指针速成下篇
    数字电路和模拟电路-4基本逻辑门电路
    LabVIEW避免在使用functional global时内存中有多个大数组的拷贝
    Hadoop3教程(一):Hadoop的定义、组成及全生态概览
    深入理解 Python 虚拟机:字节(bytes)的实现原理及源码剖析
    python selenium 爬虫教程
    微服务架构学习与思考
    数据库内核面试中我不会的问题(4)
  • 原文地址:https://blog.csdn.net/maoning20080808/article/details/128089628