Double Back to Close — NativePHP Mobile Plugin#

Prompts users to press the back button twice before the app exits.
On the first back press a native toast is shown ("Press back again to exit"). If the user presses back again within the timeout the app exits. If the timeout elapses the state resets and the next back press starts the cycle over.
Uses nativephp/mobile-dialog as a dependency so you can optionally surface the confirmation message as a rich dialog toast from PHP.
Requirements#
| Platform | Minimum version |
|---|---|
| Android | API 26 (Android 8) |
| iOS | 18.2 (feature is a no-op; iOS has no hardware back button) |
Installation#
composer require codingwithrk/double-back-to-close
Publish the plugins provider (first time only):
php artisan vendor:publish --tag=nativephp-plugins-provider
Register this plugin (adds the service provider to your NativePluginsServiceProvider):
php artisan native:plugin:register codingwithrk/double-back-to-close
Register the dependency plugin:
php artisan native:plugin:register nativephp/mobile-dialog
Verify:
php artisan native:plugin:list
PHP Usage#
use Codingwithrk\DoubleBackToClose\Facades\DoubleBackToClose; // Enable with defaults — message: "Press back again to exit", timeout: 2000 msDoubleBackToClose::enable(); // Enable with a custom message and timeoutDoubleBackToClose::enable('Tap back again to quit', 3000); // Update message / timeout while already activeDoubleBackToClose::configure('Press back to exit', 2500); // Disable (restores default back behaviour)DoubleBackToClose::disable(); // Show a toast via the mobile-dialog pluginDoubleBackToClose::showToast('Press back again to exit');
Typical Livewire setup#
use Livewire\Component;use Codingwithrk\DoubleBackToClose\Facades\DoubleBackToClose; class AppLayout extends Component{ public function mount(): void { DoubleBackToClose::enable(); }}
Events#
DoubleBackToCloseTriggered#
Dispatched on the first back press. The native Android Toast has already been shown; listen to this event if you want to show a dialog toast via mobile-dialog instead.
use Native\Mobile\Attributes\OnNative;use Codingwithrk\DoubleBackToClose\Events\DoubleBackToCloseTriggered;use Codingwithrk\DoubleBackToClose\Facades\DoubleBackToClose; #[OnNative(DoubleBackToCloseTriggered::class)]public function onFirstBackPress(string $message): void{ // Override with a dialog toast DoubleBackToClose::showToast($message);}
Payload
| Property | Type | Description |
|---|---|---|
message |
string |
The configured toast message |
AppExiting#
Dispatched on the second back press, immediately before activity.finish() is called.
use Native\Mobile\Attributes\OnNative;use Codingwithrk\DoubleBackToClose\Events\AppExiting; #[OnNative(AppExiting::class)]public function onAppExiting(): void{ // Last-moment cleanup}
JavaScript Usage#
import {DoubleBackToClose, Events} from '@codingwithrk/double-back-to-close';import {on, off} from '@nativephp/native'; // Enableawait DoubleBackToClose.enable({message: 'Press back again to exit', timeout: 2000}); // Update configawait DoubleBackToClose.configure({message: 'Back again to quit', timeout: 3000}); // Disableawait DoubleBackToClose.disable(); // Listen for first back pressconst onTriggered = ({message}) => console.log('First press:', message);on(Events.DoubleBackToCloseTriggered, onTriggered); // Listen for exitconst onExiting = () => console.log('Goodbye!');on(Events.AppExiting, onExiting); // Tear downoff(Events.DoubleBackToCloseTriggered, onTriggered);off(Events.AppExiting, onExiting);
How it works#
Android#
Enable registers an OnBackPressedCallback on the activity's onBackPressedDispatcher.
- First press: shows a native
Toast, dispatchesDoubleBackToCloseTriggered, starts aHandlertimer for the configured timeout. - Second press within timeout: cancels the timer, dispatches
AppExiting, callsactivity.finish(). - Timeout elapses: resets
backPressedOncetofalse; the next press is treated as a first press again.
Disable removes the callback and clears all state.
Configure updates the message/timeout in-place without re-registering the callback.
iOS#
iOS does not expose a hardware back button. The bridge functions accept and store configuration, and fire the same PHP events so cross-platform code stays consistent. Pair the feature with DoubleBackToClose::showToast() if you need visual feedback on iOS.
Support#
For questions or issues, email [email protected]
License#
The MIT License (MIT). Please see License File for more information.