Add back gesture support

This commit is contained in:
olcxja 2026-05-17 21:46:12 +02:00
commit 38f8c147ae
1250 changed files with 39332 additions and 21 deletions

View file

@ -0,0 +1,2 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View file

@ -0,0 +1,185 @@
package com.capacitorjs.plugins.app;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.net.Uri;
import androidx.activity.OnBackPressedCallback;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.content.pm.PackageInfoCompat;
import androidx.core.os.LocaleListCompat;
import com.getcapacitor.JSObject;
import com.getcapacitor.Logger;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;
import com.getcapacitor.util.InternalUtils;
import java.util.Locale;
@CapacitorPlugin(name = "App")
public class AppPlugin extends Plugin {
private static final String EVENT_BACK_BUTTON = "backButton";
private static final String EVENT_URL_OPEN = "appUrlOpen";
private static final String EVENT_STATE_CHANGE = "appStateChange";
private static final String EVENT_RESTORED_RESULT = "appRestoredResult";
private static final String EVENT_PAUSE = "pause";
private static final String EVENT_RESUME = "resume";
private boolean hasPausedEver = false;
private OnBackPressedCallback onBackPressedCallback;
public void load() {
boolean disableBackButtonHandler = getConfig().getBoolean("disableBackButtonHandler", false);
bridge
.getApp()
.setStatusChangeListener((isActive) -> {
Logger.debug(getLogTag(), "Firing change: " + isActive);
JSObject data = new JSObject();
data.put("isActive", isActive);
notifyListeners(EVENT_STATE_CHANGE, data, false);
});
bridge
.getApp()
.setAppRestoredListener((result) -> {
Logger.debug(getLogTag(), "Firing restored result");
notifyListeners(EVENT_RESTORED_RESULT, result.getWrappedResult(), true);
});
this.onBackPressedCallback = new OnBackPressedCallback(!disableBackButtonHandler) {
@Override
public void handleOnBackPressed() {
if (!hasListeners(EVENT_BACK_BUTTON)) {
if (bridge.getWebView().canGoBack()) {
bridge.getWebView().goBack();
}
} else {
JSObject data = new JSObject();
data.put("canGoBack", bridge.getWebView().canGoBack());
notifyListeners(EVENT_BACK_BUTTON, data, true);
bridge.triggerJSEvent("backbutton", "document");
}
}
};
getActivity().getOnBackPressedDispatcher().addCallback(getActivity(), this.onBackPressedCallback);
}
@PluginMethod
public void exitApp(PluginCall call) {
unsetAppListeners();
call.resolve();
getBridge().getActivity().finish();
}
@PluginMethod
public void getInfo(PluginCall call) {
JSObject data = new JSObject();
try {
PackageInfo pinfo = InternalUtils.getPackageInfo(getContext().getPackageManager(), getContext().getPackageName());
ApplicationInfo applicationInfo = getContext().getApplicationInfo();
int stringId = applicationInfo.labelRes;
String appName = stringId == 0 ? applicationInfo.nonLocalizedLabel.toString() : getContext().getString(stringId);
data.put("name", appName);
data.put("id", pinfo.packageName);
data.put("build", Integer.toString((int) PackageInfoCompat.getLongVersionCode(pinfo)));
data.put("version", pinfo.versionName);
call.resolve(data);
} catch (Exception ex) {
call.reject("Unable to get App Info");
}
}
@PluginMethod
public void getLaunchUrl(PluginCall call) {
Uri launchUri = bridge.getIntentUri();
if (launchUri != null) {
JSObject d = new JSObject();
d.put("url", launchUri.toString());
call.resolve(d);
} else {
call.resolve();
}
}
@PluginMethod
public void getState(PluginCall call) {
JSObject data = new JSObject();
data.put("isActive", this.bridge.getApp().isActive());
call.resolve(data);
}
@PluginMethod
public void minimizeApp(PluginCall call) {
getActivity().moveTaskToBack(true);
call.resolve();
}
@PluginMethod
public void toggleBackButtonHandler(PluginCall call) {
if (this.onBackPressedCallback == null) {
call.reject("onBackPressedCallback is not set");
return;
}
Boolean enabled = call.getBoolean("enabled");
this.onBackPressedCallback.setEnabled(enabled);
call.resolve();
}
@PluginMethod
public void getAppLanguage(PluginCall call) {
JSObject ret = new JSObject();
LocaleListCompat appLocales = AppCompatDelegate.getApplicationLocales();
Locale appLocale = !appLocales.isEmpty() ? appLocales.get(0) : null;
ret.put("value", appLocale != null ? appLocale.getLanguage() : Locale.getDefault().getLanguage());
call.resolve(ret);
}
/**
* Handle ACTION_VIEW intents to store a URL that was used to open the app
* @param intent
*/
@Override
protected void handleOnNewIntent(Intent intent) {
super.handleOnNewIntent(intent);
// read intent
String action = intent.getAction();
Uri url = intent.getData();
if (!Intent.ACTION_VIEW.equals(action) || url == null) {
return;
}
JSObject ret = new JSObject();
ret.put("url", url.toString());
notifyListeners(EVENT_URL_OPEN, ret, true);
}
@Override
protected void handleOnPause() {
super.handleOnPause();
hasPausedEver = true;
notifyListeners(EVENT_PAUSE, null);
}
@Override
protected void handleOnResume() {
super.handleOnResume();
if (hasPausedEver) {
notifyListeners(EVENT_RESUME, null);
}
}
@Override
protected void handleOnDestroy() {
unsetAppListeners();
}
private void unsetAppListeners() {
bridge.getApp().setStatusChangeListener(null);
bridge.getApp().setAppRestoredListener(null);
}
}