11package com .compassconnections .app ;
22
3- import android .Manifest ;
43import android .content .ContentResolver ;
54import android .content .ContentValues ;
65import android .content .Context ;
76import android .content .Intent ;
8- import android .content .pm .PackageManager ;
97import android .media .MediaScannerConnection ;
108import android .net .Uri ;
119import android .os .Build ;
1816import android .webkit .WebView ;
1917import android .widget .Toast ;
2018
21- import androidx .activity .result .ActivityResultLauncher ;
22- import androidx .activity .result .contract .ActivityResultContracts ;
2319import androidx .annotation .RequiresApi ;
24- import androidx .core .content .ContextCompat ;
2520
26- import com .capacitorjs .plugins .pushnotifications .PushNotificationsPlugin ;
2721import com .getcapacitor .BridgeActivity ;
28- import com .getcapacitor .BridgeWebViewClient ;
2922import com .getcapacitor .Plugin ;
3023import com .getcapacitor .PluginHandle ;
3124import com .google .android .play .core .appupdate .AppUpdateInfo ;
3528import com .google .android .play .core .install .model .AppUpdateType ;
3629import com .google .android .play .core .install .model .UpdateAvailability ;
3730
38- import org .json .JSONException ;
39- import org .json .JSONObject ;
40-
4131import java .io .File ;
4232import java .io .FileOutputStream ;
4333import java .io .IOException ;
4434import java .io .OutputStream ;
45- import java .net .URL ;
4635import java .nio .charset .StandardCharsets ;
4736
4837import ee .forgr .capacitor .social .login .GoogleProvider ;
4938import ee .forgr .capacitor .social .login .ModifiedMainActivityForSocialLoginPlugin ;
5039import ee .forgr .capacitor .social .login .SocialLoginPlugin ;
5140
41+ /**
42+ * Deliberately thin. Three things that used to live here are now handled on the JS side, where they
43+ * also work on iOS and — unlike native code running inside {@code onCreate} — can be sure the WebView
44+ * has actually loaded:
45+ *
46+ * <ul>
47+ * <li><b>Deep links</b> — {@code App.getLaunchUrl()} / the {@code appUrlOpen} listener in
48+ * {@code web/pages/_app.tsx}. Capacitor stashes the launch intent's Uri itself.</li>
49+ * <li><b>Notification taps</b> — {@code pushNotificationActionPerformed} in
50+ * {@code web/lib/service/native-push.ts}. Capacitor retains the event until a listener
51+ * consumes it, so a cold-start tap is not lost.</li>
52+ * <li><b>POST_NOTIFICATIONS</b> — {@code PushNotifications.requestPermissions()}, which asks at
53+ * login rather than at first launch.</li>
54+ * </ul>
55+ *
56+ * What is left is what Capacitor has no plugin for: the Downloads-folder writer and the in-app
57+ * update prompt.
58+ */
5259public class MainActivity extends BridgeActivity implements ModifiedMainActivityForSocialLoginPlugin {
5360
54- private String pendingDeepLink = null ;
55-
56- // Declare this at class level
57- private final ActivityResultLauncher <String > requestPermissionLauncher =
58- registerForActivityResult (new ActivityResultContracts .RequestPermission (), isGranted -> {
59- if (isGranted ) {
60- Log .i ("CompassApp" , "Permission granted" );
61- // Permission granted – you can show notifications
62- } else {
63- Log .i ("CompassApp" , "Permission denied" );
64- // Permission denied – handle gracefully
65- }
66- });
67-
68- private void askNotificationPermission () {
69- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .TIRAMISU ) { // API 33
70- if (ContextCompat .checkSelfPermission (this , Manifest .permission .POST_NOTIFICATIONS )
71- != PackageManager .PERMISSION_GRANTED ) {
72- // Permission not yet granted; request it
73- requestPermissionLauncher .launch (Manifest .permission .POST_NOTIFICATIONS );
74- }
75- }
76- }
77-
7861 public class WebAppInterface {
7962 private final Context context ;
8063
8164 public WebAppInterface (Context context ) {
8265 this .context = context ;
8366 }
8467
85- @ JavascriptInterface
86- public String getPendingDeepLink () {
87- String link = pendingDeepLink ;
88- pendingDeepLink = null ; // consume it
89- return link ;
90- }
91-
9268 @ JavascriptInterface
9369 public void downloadFile (String filename , String content ) {
9470 try {
@@ -183,38 +159,12 @@ private String getMimeType(String filename) {
183159 }
184160
185161
186- @ Override
187- protected void onNewIntent (Intent intent ) {
188- super .onNewIntent (intent );
189-
190- String endpoint = intent .getStringExtra ("endpoint" );
191- Log .i ("CompassApp" , "onNewIntent called with endpoint: " + endpoint );
192- if (endpoint != null ) {
193- Log .i ("CompassApp" , "redirecting to endpoint: " + endpoint );
194- try {
195- String payload = new JSONObject ().put ("endpoint" , endpoint ).toString ();
196- Log .i ("CompassApp" , "Handling notif click: " + payload );
197- bridge .getWebView ().post (() -> bridge .getWebView ().evaluateJavascript ("handleAppLink(" + payload + ");" , null ));
198- } catch (JSONException e ) {
199- Log .i ("CompassApp" , "Failed to encode JSON payload" , e );
200- }
201- } else {
202- Uri data = intent .getData ();
203- if (data != null ) {
204- handleDeepLink (data .toString ());
205- } else {
206- Log .i ("CompassApp" , "No relevant data" );
207- }
208- }
209- }
210-
211162 @ Override
212163 public void onCreate (Bundle savedInstanceState ) {
213164 Log .i ("CompassApp" , "onCreate called" );
214165 super .onCreate (savedInstanceState );
215166
216167 WebView webView = this .bridge .getWebView ();
217- webView .setWebViewClient (new BridgeWebViewClient (this .bridge ));
218168
219169 if (BuildConfig .ENABLE_WEBVIEW_DEBUG ) {
220170 WebView .setWebContentsDebuggingEnabled (true );
@@ -223,42 +173,15 @@ public void onCreate(Bundle savedInstanceState) {
223173 WebSettings settings = webView .getSettings ();
224174 settings .setUserAgentString (settings .getUserAgentString () + " CompassAppWebView" );
225175
226- settings .setJavaScriptEnabled (true );
227176 webView .addJavascriptInterface (new WebAppInterface (this ), "AndroidBridge" );
228177
229- registerPlugin (PushNotificationsPlugin .class );
230178 // Initialize the Bridge with Push Notifications plugin
231179// this.init(savedInstanceState, new ArrayList<Class<? extends Plugin>>() {{
232180// add(com.getcapacitor.plugin.PushNotifications.class);
233181// }});
234182
235- askNotificationPermission ();
236-
237183 appUpdateManager = AppUpdateManagerFactory .create (this );
238184 checkForUpdates ();
239-
240- Uri data = getIntent ().getData ();
241- if (data != null ) {
242- pendingDeepLink = data .toString ();
243- } else {
244- // Check for notification endpoint when app is opened from cold start via notification click
245- String endpoint = getIntent ().getStringExtra ("endpoint" );
246- if (endpoint != null ) {
247- Log .i ("CompassApp" , "onCreate found endpoint from notification: " + endpoint );
248- pendingDeepLink = endpoint ;
249- }
250- }
251- }
252-
253- private void handleDeepLink (String url ) {
254- try {
255- String path = new URL (url ).getPath ();
256- String payload = new JSONObject ().put ("url" , url ).put ("endpoint" , path ).toString ();
257- Log .i ("CompassApp" , "Handling deep link: " + url );
258- bridge .getWebView ().post (() -> bridge .getWebView ().evaluateJavascript ("handleAppLink(" + payload + ");" , null ));
259- } catch (Exception e ) {
260- Log .e ("CompassApp" , "Failed to handle deep link for " + url , e );
261- }
262185 }
263186
264187 @ Override
@@ -343,11 +266,5 @@ public void onResume() {
343266 }
344267 });
345268 }
346-
347- @ Override
348- public void onDestroy () {
349- super .onDestroy ();
350- appUpdateManager = null ;
351- }
352269}
353270
0 commit comments