哈哈鱼
软件 pin 应用密码

如何仅为我的应用设置密码 / PIN

我正在开发一个需要通过为用户设置 passcode/password/pin 来设置安全性功能的应用程序,以便每当他们从后台打开应用程序时,该应用程序都会要求输入 passcode/password/pin 。

我已经设置了将 passcode/pin 保存为共享首选项的逻辑,但是我不确定何时询问。我知道我们无法用 passcode/pin 活动来替换初始屏幕,因为有时从应用程序的homeScreen / MainActivity中,用户按下主屏幕按钮,当他们再次从最近的应用程序中打开该应用程序时,该应用程序应该要求密码/固定密码来恢复应用使用。

任何帮助,将不胜感激。

分享
  • 在下炳尚 2 风险管理(专业级)RM/PL 高级信息系统项目管理师
    在下炳尚2 风险管理(专业级)RM/PL 高级信息系统项目管理师

    这是一个有趣的问题,我将分享我对这个问题的想法并给出解决方案。

    术语:

    应用锁类型:密码/密码/密码/密码等的通用名称(在以下部分中,我将使用密码名称进行演示)

    PinActivity:一个屏幕,用户可以在其中输入自己的密码以验证自己

    故事:

    对于需要用户输入图钉的应用,他们通常希望确保敏感信息不会被其他人泄露/窃取。因此,我们将应用程序活动分为两类。

    • 正常活动:通常不包含任何敏感信息,通常在用户登录到应用程序之前,例如SplashActivity,LoginActivity,RegistrationActivity,PinActivity等。

    • 安全活动:通常在用户登录后包含敏感信息,例如MainActivity,HomeActivity,UserInfoActivity等。

    条件:

    对于安全活动,我们必须通过显示PinActivity确保用户在查看内容之前始终输入他们的密码。在以下情况下将显示此活动:

    • [1]当用户打开安全活动时,形成一个正常活动,例如从SplashActivity到MainActivity

    • [2]当用户通过点击通知打开安全活动时,例如他们点击通知以打开MainActivity

    • [3]当用户从“最近”屏幕中点击应用程序时

    • [4]当应用从其他地方(如服务,广播接收器等)开始安全活动时。

    实现方式:

    对于情况[1] [2]和[4],在开始安全活动之前,我们将向原始意图添加额外的内容。我将创建一个名为IntentUtils.kt的文件

    IntentUtils.kt

    const val EXTRA_IS_PIN_REQUIRED = "EXTRA_IS_PIN_REQUIRED"  fun Intent.secured(): Intent {     return this.apply {         putExtra(EXTRA_IS_PIN_REQUIRED, true)     } }

    从正常活动,通知,服务等中使用此类。

    startActivity(Intent(this, MainActivity::class.java).secured())

    对于情况[3],我将使用2个API:

    • ProcessLifecycleOwner:检测应用程序是否进入后台。典型的情况是用户单击设备上的Home / Menu键。

    • ActivityLifecycleCallbacks:通过依赖onActivityResumed(activity)方法来检测是否恢复活动。

    首先,我创建一个基础活动,所有正常的活动性炎症都必须从此类开始

    BaseActivity.kt

    open class BaseActivity : AppCompatActivity() {      // This method indicates that a pin is required if      // users want to see the content inside.     open fun isPinRequired() = false }

    其次,我创建一个安全活动,所有安全活动都必须从此类扩展

    SecuredActivity.kt

    open class SecuredActivity : BaseActivity() {     override fun isPinRequired() = true      // This is useful when launch a secured activity with      // singleTop, singleTask, singleInstance launch mode     override fun onNewIntent(intent: Intent?) {         super.onNewIntent(intent)         setIntent(intent)     } }

    第三,我创建一个从Application扩展的类,所有逻辑都在该类内部

    MyApplication.kt

    class MyApplication : Application() {      private var wasEnterBackground = false      override fun onCreate() {         super.onCreate()         registerActivityLifecycleCallbacks(ActivityLifecycleCallbacksImpl())         ProcessLifecycleOwner.get().lifecycle.addObserver(LifecycleObserverImpl())     }      private fun showPinActivity() {         startActivity(Intent(this, PinActivity::class.java))     }      inner class LifecycleObserverImpl : LifecycleObserver {          @OnLifecycleEvent(Lifecycle.Event.ON_STOP)         fun onEnterBackground() {             wasEnterBackground = true         }     }      inner class ActivityLifecycleCallbacksImpl : ActivityLifecycleCallbacks {          override fun onActivityResumed(activity: Activity) {             val baseActivity = activity as BaseActivity             if (!wasEnterBackground) {                 // Handle case [1] [2] and [4]                 val removed = removeIsPinRequiredKeyFromActivity(activity)                 if (removed) {                     showPinActivity()                 }             } else {                 // Handle case [3]                 wasEnterBackground = false                 if (baseActivity.isPinRequired()) {                     removeIsPinRequiredKeyFromActivity(activity)                     showPinActivity()                 }             }         }          private fun removeIsPinRequiredKeyFromActivity(activity: Activity): Boolean {             val key = EXTRA_IS_PIN_REQUIRED             if (activity.intent.hasExtra(key)) {                 activity.intent.removeExtra(key)                 return true             }             return false         }          override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}         override fun onActivityStarted(activity: Activity) {}         override fun onActivityPaused(activity: Activity) {}         override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}         override fun onActivityStopped(activity: Activity) {}         override fun onActivityDestroyed(activity: Activity) {}     } }

    结论:

    该解决方案适用于我之前提到的情况,但是我尚未测试以下情况:

    • 启动时,安全活动具有启动模式singleTop | singleTask | singleInstance
    • 当应用程序被低内存的系统杀死时
    • 某人可能遇到的其他情况(如果是,请在评论部分让我知道)。
  • 写回答