From cf2dde4261a311406203a38d6bf1be72b4f9e8a7 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 10 Jul 2023 13:31:57 +0800 Subject: [PATCH] Update Android port * java/org/gnu/emacs/EmacsService.java (browseUrl): New argument SEND. Choose from a list of applications that want to share the URL if true. * lisp/net/browse-url.el (browse-url-android-share): New user option. (browse-url-default-android-browser): Respect said user option. * src/android.c (android_init_emacs_service) (android_browse_url): Expose new option. * src/android.h: Update prototypes. * src/androidselect.c (Fandroid_browse_url): Likewise. --- java/org/gnu/emacs/EmacsService.java | 65 +++++++++++++++++++--------- lisp/net/browse-url.el | 19 ++++++-- src/android.c | 16 ++++--- src/android.h | 2 +- src/androidselect.c | 16 ++++--- 5 files changed, 82 insertions(+), 36 deletions(-) diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index 0543c3a1bdd..22649167f8a 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java @@ -583,12 +583,18 @@ public final class EmacsService extends Service } } - /* Ask the system to open the specified URL. + /* Ask the system to open the specified URL in an application that + understands how to open it. + + If SEND, tell the system to also open applications that can + ``send'' the URL (through mail, for example), instead of only + those that can view the URL. + Value is NULL upon success, or a string describing the error upon failure. */ public String - browseUrl (String url) + browseUrl (String url, boolean send) { Intent intent; Uri uri; @@ -596,28 +602,47 @@ public final class EmacsService extends Service try { /* Parse the URI. */ - uri = Uri.parse (url); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) + if (!send) { - /* On Android 4.4 and later, check if URI is actually a - file name. If so, rewrite it into a content provider - URI, so that it can be accessed by other programs. */ - - if (uri.getScheme ().equals ("file") - && uri.getPath () != null) - uri - = DocumentsContract.buildDocumentUri ("org.gnu.emacs", - uri.getPath ()); + uri = Uri.parse (url); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) + { + /* On Android 4.4 and later, check if URI is actually + a file name. If so, rewrite it into a content + provider URI, so that it can be accessed by other + programs. */ + + if (uri.getScheme ().equals ("file") + && uri.getPath () != null) + uri + = DocumentsContract.buildDocumentUri ("org.gnu.emacs", + uri.getPath ()); + } + + Log.d (TAG, ("browseUri: browsing " + url + + " --> " + uri.getPath () + + " --> " + uri)); + + intent = new Intent (Intent.ACTION_VIEW, uri); + intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_GRANT_READ_URI_PERMISSION); } + else + { + intent = new Intent (Intent.ACTION_SEND); + intent.setType ("text/plain"); + intent.putExtra (Intent.EXTRA_SUBJECT, "Sharing link"); + intent.putExtra (Intent.EXTRA_TEXT, url); + + /* Display a list of programs able to send this URL. */ + intent = Intent.createChooser (intent, "Send"); - Log.d (TAG, ("browseUri: browsing " + url - + " --> " + uri.getPath () - + " --> " + uri)); + /* Apparently flags need to be set after a choser is + created. */ + intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK); + } - intent = new Intent (Intent.ACTION_VIEW, uri); - intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity (intent); } catch (Exception e) diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index 8036bbc8acc..daa46baf8f2 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -1307,18 +1307,31 @@ Default to the URL around or before point." (function-put 'browse-url-default-haiku-browser 'browse-url-browser-kind 'external) +(defcustom browse-url-android-share nil + "If non-nil, share URLs instead of opening them. +When non-nil, `browse-url-default-android-browser' will try to +share the URL being browsed through programs such as mail clients +and instant messengers instead of opening it in a web browser." + :type 'boolean + :version "30.1") + (declare-function android-browse-url "androidselect.c") ;;;###autoload (defun browse-url-default-android-browser (url &optional _new-window) "Browse URL with the system default browser. -Default to the URL around or before point." +If `browse-url-android-share' is non-nil, try to share URL using +an external program instead. Default to the URL around or before +point." (interactive (browse-url-interactive-arg "URL: ")) - (setq url (browse-url-encode-url url)) + (unless browse-url-android-share + ;; The URL shouldn't be encoded if it's being shared through + ;; another program. + (setq url (browse-url-encode-url url))) ;; Make sure the URL starts with an appropriate scheme. (unless (string-match "\\(.+\\):/" url) (setq url (concat "http://" url))) - (android-browse-url url)) + (android-browse-url url browse-url-android-share)) (function-put 'browse-url-default-android-browser 'browse-url-browser-kind 'external) diff --git a/src/android.c b/src/android.c index 5850b6079c9..4e9897f4648 100644 --- a/src/android.c +++ b/src/android.c @@ -2286,7 +2286,7 @@ android_init_emacs_service (void) FIND_METHOD (get_screen_height, "getScreenHeight", "(Z)I"); FIND_METHOD (detect_mouse, "detectMouse", "()Z"); FIND_METHOD (name_keysym, "nameKeysym", "(I)Ljava/lang/String;"); - FIND_METHOD (browse_url, "browseUrl", "(Ljava/lang/String;)" + FIND_METHOD (browse_url, "browseUrl", "(Ljava/lang/String;Z)" "Ljava/lang/String;"); FIND_METHOD (restart_emacs, "restartEmacs", "()V"); FIND_METHOD (update_ic, "updateIC", @@ -6959,12 +6959,15 @@ android_project_image_nearest (struct android_image *image, /* Other miscellaneous functions. */ -/* Ask the system to start browsing the specified encoded URL. Upon - failure, return a string describing the error. Else, value is - nil. */ +/* Ask the system to start browsing the specified URL. Upon failure, + return a string describing the error. Else, value is nil. URL + should be encoded unless SEND. + + If SEND, open the URL with applications that can ``send'' or + ``share'' the URL (through mail, for example.) */ Lisp_Object -android_browse_url (Lisp_Object url) +android_browse_url (Lisp_Object url, Lisp_Object send) { jobject value, string; Lisp_Object tem; @@ -6974,7 +6977,8 @@ android_browse_url (Lisp_Object url) value = (*android_java_env)->CallObjectMethod (android_java_env, emacs_service, service_class.browse_url, - string); + string, + (jboolean) !NILP (send)); android_exception_check (); ANDROID_DELETE_LOCAL_REF (string); diff --git a/src/android.h b/src/android.h index 33ca379e6ba..2323690fa25 100644 --- a/src/android.h +++ b/src/android.h @@ -178,7 +178,7 @@ struct android_battery_state int temperature; }; -extern Lisp_Object android_browse_url (Lisp_Object); +extern Lisp_Object android_browse_url (Lisp_Object, Lisp_Object); extern int android_query_battery (struct android_battery_state *); extern void android_display_toast (const char *); diff --git a/src/androidselect.c b/src/androidselect.c index d1f2ebb52f9..f5371280457 100644 --- a/src/androidselect.c +++ b/src/androidselect.c @@ -232,11 +232,15 @@ DEFUN ("android-clipboard-exists-p", Fandroid_clipboard_exists_p, } DEFUN ("android-browse-url", Fandroid_browse_url, - Sandroid_browse_url, 1, 1, 0, - doc: /* Start the system web browser. -Then, point the web browser to URL, which should be a URL-encoded -URL with a scheme specified. Signal an error upon failure. */) - (Lisp_Object url) + Sandroid_browse_url, 1, 2, 0, + doc: /* Open URL in an external application. URL should be a +URL-encoded URL with a scheme specified unless SEND is non-nil. +Signal an error upon failure. + +If SEND is nil, start a program that is able to display the URL, such +as a web browser. Otherwise, try to share URL using programs such as +email clients. */) + (Lisp_Object url, Lisp_Object send) { Lisp_Object value; @@ -244,7 +248,7 @@ URL with a scheme specified. Signal an error upon failure. */) error ("No Android display connection!"); CHECK_STRING (url); - value = android_browse_url (url); + value = android_browse_url (url, send); /* Signal an error upon failure. */ if (!NILP (value)) -- 2.39.2