乐于分享
好东西不私藏

Ruoyi-Android-App 启动页相关协议解析

Ruoyi-Android-App 启动页相关协议解析

简介

RuoYi Android App 移动解决方案,采用kotlin框架,实现了与RuoYi-Go 、RuoYi-Vue、RuoYi-Cloud完美对接的移动解决方案!目前已经实现登录、我的、工作台、编辑资料、头像修改、密码修改、常见问题、关于我们等基础功能。

  • 配套后端代码仓库地址RuoYi-Go 或 RuoYi-Vue 或 RuoYi-Cloud 版本。
  • 应用框架基于kotlin,支持Android。

启动页作为 Ruoyi-Android-App 的 “门面”,不仅是用户首次接触应用的视觉入口,更是应用上架各大应用市场的核心功能节点 —— 所有涉及用户隐私、设备权限的初始化操作(如推送、IM、地图、通讯录等),必须在用户明确同意相关协议后才能执行。本文将详细解析如何改造 Ruoyi-Android-App 的启动页,实现协议弹窗确认、权限初始化管控的核心功能,满足应用市场上架规范,同时保障用户隐私合规。

一、核心改造思路

本次改造的核心目标是:将应用首次启动页替换为自定义的 SplashActivity,通过 “协议同意状态判断→弹窗确认→权限 / 功能初始化” 的流程,实现合规化管控。具体逻辑如下:

  1. 首次启动应用时,优先展示 SplashActivity(配置为应用入口);
  2. 读取本地存储的 “协议同意状态”,未同意则弹出协议确认弹窗;
  3. 用户同意协议:记录状态,初始化推送、IM 等功能,跳转登录页;
  4. 用户不同意协议:直接退出应用;
  5. 非首次启动且已同意协议:跳过弹窗,直接初始化功能并跳转登录页。
界面

二、具体实现步骤

1. 配置 SplashActivity 为应用入口

首先创建自定义的 SplashActivity,并在 AndroidManifest.xml 中配置其为应用的启动页,替换原有入口。

(1)创建 SplashActivity 基础类

import android.animation.ValueAnimatorimport android.view.animation.LinearInterpolatorimport com.ruoyi.app.Appimport com.ruoyi.app.databinding.ActivitySplashBindingimport com.ruoyi.app.widget.SplashDialogimport com.ruoyi.app.widget.SplashDialog.SplashDialogClickListenerimport com.ruoyi.code.base.BaseBindingActivityimport com.ruoyi.code.utils.SpUtilsimport java.util.Timerimport java.util.TimerTaskclass SplashActivity : BaseBindingActivity<ActivitySplashBinding>() {    private var isAgreement by SpUtils("isAgreement"false)    private var timer: Timer? = null    override funinitView() {        if (!isAgreement) {            val splashDialog = SplashDialog(thisobject :SplashDialogClickListener{                override funonClick(type: Int) {                    if (type == 1) {                        isAgreement = true                        startActivity()                    }                    if (type == 2) {                        finish()                    }                }            } )            if (!splashDialog.isShowing) {                splashDialog.show()            }        } else {            startActivity()        }    }    override funinitData() {        val animator = ValueAnimator.ofFloat(0f1f)        animator.duration = 1500        animator.interpolator = LinearInterpolator()        animator.repeatCount = ValueAnimator.INFINITE        animator.addUpdateListener { animation: ValueAnimator ->            val value = animation.animatedValue as Float            // 计算缩放比例,模拟波浪起伏            val scale =                (1 + 0.1 * Math.sin(value * 2 * Math.PI)).toFloat()            binding.tvWelecome.setScaleX(scale)            binding.tvWelecome.setScaleY(scale)        }        animator.start()    }    private funstartActivity() {        val delayTask = object : TimerTask() {            override funrun() {                App.init()                LoginActivity.startActivity(this@SplashActivity)                this@SplashActivity.finish()            }        }        timer = Timer()        timer?.schedule(delayTask, 2000)    }    override funonDestroy() {        super.onDestroy()        timer?.cancel()        timer = null    }}

(2)配置 AndroidManifest.xml

将 SplashActivity 配置为应用的主入口,添加 <intent-filter> 标签:

<activity            android:name=".activity.SplashActivity"            android:exported="true" >            <intent-filter>                <actionandroid:name="android.intent.action.MAIN" />                <categoryandroid:name="android.intent.category.LAUNCHER" />            </intent-filter>            <!-- 声明支持的语言 -->            <meta-data                android:name="android.content.pm.ActivityInfo.META_DATA_SUPPORTED_LOCALES"                android:value="zh,en" />        </activity>        <activity            android:name=".activity.LoginActivity"            android:exported="false"            android:launchMode="singleTop" />

2. 封装初始化管理类(InitManager)

将推送、IM、地图、通讯录等功能的初始化逻辑封装到统一的管理类,便于维护:

配置
package com.ruoyi.android.utils;import android.content.Context;import android.Manifest;import android.content.pm.PackageManager;import androidx.core.app.ActivityCompat;/** * 功能初始化管理类:统一处理协议同意后的初始化逻辑 */public class InitManager {    /**     * 初始化所有核心功能     * @param context 上下文     */    public static void initAll(Context context) {        // 1. 初始化推送功能(如JPush、小米推送等)        initPush(context);        // 2. 初始化IM功能(如融云、环信等)        initIM(context);        // 3. 初始化地图功能(如高德、百度地图)        initMap(context);        // 4. 初始化通讯录权限(需动态申请)        initContact(context);    }    private static void initPush(Context context) {        // 推送SDK初始化代码示例        // JPushInterface.init(context);        // JPushInterface.setDebugMode(true);    }    private static void initIM(Context context) {        // IM SDK初始化代码示例        // RongIMClient.init(context, "你的IM AppKey");    }    private static void initMap(Context context) {        // 地图SDK初始化代码示例        // AMapLocationClient.updatePrivacyShow(context, true, true);        // AMapLocationClient.updatePrivacyAgree(context, true);    }    private static void initContact(Context context) {        // 动态申请通讯录权限(协议同意后才可申请)        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS)                != PackageManager.PERMISSION_GRANTED) {            ActivityCompat.requestPermissions((android.app.Activity) context,                    new String[]{Manifest.permission.READ_CONTACTS}, 1001);        }    }}
companion object {        lateinit var application: Application        funinit() {            ToastUtils.init(application)            MMKV.initialize(application)            OKHttpUtils.initialize(application)        }    }
3. 启动页布局(activity_splash.xml) 可根据需求自定义启动页视觉样式,主要是添加了一个动画。
弹窗
val splashDialog = SplashDialog(thisobject :SplashDialogClickListener{                override funonClick(type: Int) {                    if (type == 1) {                        isAgreement = true                        startActivity()                    }                    if (type == 2) {                        finish()                                            }                }            } )            if (!splashDialog.isShowing) {                splashDialog.show()            }

三、关键逻辑说明

  1. 1、协议状态持久化 :使用 SharedPreferences 存储协议同意状态,即使应用重启,已同意的状态也不会丢失,避免重复弹窗;
  2. 2、弹窗不可取消 :设置 setCancelable(false),确保用户必须选择 “同意” 或 “不同意”,符合应用市场合规要求;
  3. 3、功能初始化时机 :所有涉及设备权限、第三方 SDK 的初始化操作,均放在 “用户同意协议后” 执行,避免未授权情况下获取用户信息;
  4. 4、退出逻辑:用户不同意协议时,调用 finish() + System.exit(0) 彻底退出应用,符合合规要求。

四、上架适配注意事项

  1. 1、协议内容需完整:弹窗中需明确展示《用户协议》和《隐私政策》的完整内容(可通过跳转网页 / 内置文本实现),仅 “同意 / 不同意” 按钮无法通过应用市场审核;
  2. 2、权限申请合规:通讯录、定位等敏感权限,需在用户同意协议后再动态申请,且需说明权限使用场景;
  3. 3、状态回显:若用户后续在设置中取消协议同意,需重新触发弹窗逻辑(可在应用启动时再次检查状态)。

总结

本次 Ruoyi-Android-App 启动页改造的核心要点:

  1. 1、通过配置 <intent-filter> 将 SplashActivity 设为应用入口,掌控首次启动流程;
  2. 2、基于 SharedPreferences 实现协议同意状态的持久化判断,未同意则弹窗、同意则直接初始化;
  3. 3、所有权限 / 第三方 SDK 初始化操作需在用户同意协议后执行,满足应用市场上架合规要求;
  4. 4、封装 InitManager 统一管理初始化逻辑,提升代码可维护性。
本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » Ruoyi-Android-App 启动页相关协议解析

评论 抢沙发

2 + 2 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
×
订阅图标按钮