Ionic v1应用:检测闲置恢复/主按钮启动及动态路由PIN码页咨询
Hey there! Let's break this down step by step since I've tackled similar Ionic v1/Cordova projects before.
Should you show the PIN screen on resume/restart?
Short answer: Absolutely—both scenarios are critical for security. When the app restarts, all in-memory state is lost, so you need to re-verify the user. When resuming from idle, there's a risk someone else might access the device while the app was in the background, so requiring PIN entry here makes sense too.
Detecting restart and idle resume scenarios
Let's cover how to hook into Cordova's events to catch these cases, plus add logic to trigger the PIN screen.
1. Detect app restart
Cordova fires the deviceready event every time the app boots up—this is your starting point. We'll use local storage to track if a PIN is set and whether it's been verified in the current session.
document.addEventListener("deviceready", function() { // Use Ionic's $localStorage (or vanilla localStorage) to store PIN state var hasPinSet = !!$localStorage.pin; var isPinVerified = $localStorage.pinVerified || false; // If PIN is set but not verified yet, redirect to PIN screen if (hasPinSet && !isPinVerified) { $state.go('pin'); } }, false);
2. Detect idle resume
For resume from background, use Cordova's resume event. We'll also track user activity to only trigger the PIN if the app was idle for a set threshold (e.g., 5 minutes).
// Track last user activity time let lastActivityTime = Date.now(); // Reset activity time on any user interaction angular.element(document).on('click touchstart keydown', () => { lastActivityTime = Date.now(); }); // Listen for app resume document.addEventListener("resume", function() { var hasPinSet = !!$localStorage.pin; var isPinVerified = $localStorage.pinVerified || false; const idleThreshold = 5 * 60 * 1000; // 5 minutes (adjust as needed) // Only trigger PIN if idle time exceeds threshold and PIN isn't verified if (hasPinSet && !isPinVerified && (Date.now() - lastActivityTime) > idleThreshold) { $state.go('pin'); } }, false); // Reset PIN verification state when app goes to background document.addEventListener("pause", function() { if ($localStorage.pin) { $localStorage.pinVerified = false; } }, false);
Dynamically routing to PIN screen from the default home route
To handle cases where the user tries to navigate to the home route (or any other route) without verifying their PIN, use UI Router's $stateChangeStart event to intercept navigation.
angular.module('yourApp').run(function($rootScope, $state, $localStorage) { $rootScope.$on('$stateChangeStart', (event, toState, toParams) => { var hasPinSet = !!$localStorage.pin; var isPinVerified = $localStorage.pinVerified || false; const isPinPage = toState.name === 'pin'; // Block navigation to non-PIN pages if PIN is required but not verified if (hasPinSet && !isPinVerified && !isPinPage) { event.preventDefault(); // Stop the original route change // Pass the target route/params to the PIN screen so we can redirect after verification $state.go('pin', { redirectTo: toState.name, redirectParams: toParams }); } }); });
Then, in your PIN controller, after successful verification, redirect to the original target route (or home if none was specified):
angular.module('yourApp').controller('PinController', function($scope, $state, $stateParams, $localStorage) { $scope.verifyPin = function(inputPin) { if (inputPin === $localStorage.pin) { $localStorage.pinVerified = true; // Redirect to the originally requested route, or default to home const targetState = $stateParams.redirectTo || 'home'; const targetParams = $stateParams.redirectParams || {}; $state.go(targetState, targetParams); } else { $scope.errorMessage = 'Invalid PIN. Please try again.'; } }; });
Quick notes to avoid issues
- Avoid infinite loops: Always exclude the PIN screen itself from the route interception logic.
- Clear verification state: Make sure to reset
pinVerifiedwhen the user logs out or the app goes to background (we covered this in thepauseevent). - Test edge cases: Verify what happens if the user changes their PIN mid-session, or if local storage is cleared.
内容的提问来源于stack exchange,提问作者user1261710

