mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-06 10:45:23 +08:00
Added: Add isTermuxAppInstalled() and isTermuxAppAccessible() functions to TermuxUtils
The `TermuxUtils.isTermuxAppInstalled()` function can be used by external apps to check if termux app is installed and enabled. The `TermuxUtils.isTermuxAppAccessible()` function can be used by termux plugin apps to check if termux app is installed, enabled, accessible as per `sharedUserId` and `TERMUX_PREFIX_DIR_PATH` is accessible and has read, write and execute permission.
This commit is contained in:
@@ -3,11 +3,14 @@ package com.termux.shared.termux;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.termux.shared.R;
|
||||
import com.termux.shared.file.FileUtils;
|
||||
import com.termux.shared.file.TermuxFileUtils;
|
||||
import com.termux.shared.logger.Logger;
|
||||
import com.termux.shared.markdown.MarkdownUtils;
|
||||
@@ -101,6 +104,90 @@ public class TermuxUtils {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if Termux app is installed and enabled. This can be used by external apps that don't
|
||||
* share `sharedUserId` with the Termux app.
|
||||
*
|
||||
* If your third-party app is targeting sdk `30` (android `11`), then it needs to add `com.termux`
|
||||
* package to the `queries` element or request `QUERY_ALL_PACKAGES` permission in its
|
||||
* `AndroidManifest.xml`. Otherwise it will get `PackageSetting{...... com.termux/......} BLOCKED`
|
||||
* errors in `logcat` and `RUN_COMMAND` won't work.
|
||||
* Check [package-visibility](https://developer.android.com/training/basics/intents/package-visibility#package-name),
|
||||
* `QUERY_ALL_PACKAGES` [googleplay policy](https://support.google.com/googleplay/android-developer/answer/10158779
|
||||
* and this [article](https://medium.com/androiddevelopers/working-with-package-visibility-dc252829de2d) for more info.
|
||||
*
|
||||
* {@code
|
||||
* <manifest
|
||||
* <queries>
|
||||
* <package android:name="com.termux" />
|
||||
* </queries>
|
||||
* </manifest>
|
||||
* }
|
||||
*
|
||||
* @param currentPackageContext The context of current package.
|
||||
* @return Returns {@code errmsg} if termux package is not installed or disabled, otherwise {@code null}.
|
||||
*/
|
||||
public static String isTermuxAppInstalled(@NonNull final Context currentPackageContext) {
|
||||
String errmsg = null;
|
||||
|
||||
PackageManager packageManager = currentPackageContext.getPackageManager();
|
||||
|
||||
ApplicationInfo applicationInfo;
|
||||
try {
|
||||
applicationInfo = packageManager.getApplicationInfo(TermuxConstants.TERMUX_PACKAGE_NAME, 0);
|
||||
} catch (final PackageManager.NameNotFoundException e) {
|
||||
applicationInfo = null;
|
||||
}
|
||||
boolean termuxAppEnabled = (applicationInfo != null && applicationInfo.enabled);
|
||||
|
||||
// If Termux app is not installed or is disabled
|
||||
if (!termuxAppEnabled)
|
||||
errmsg = currentPackageContext.getString(R.string.error_termux_app_not_installed_or_disabled_warning);
|
||||
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Termux app is installed and accessible. This can only be used by apps that share
|
||||
* `sharedUserId` with the Termux app.
|
||||
*
|
||||
* This is done by checking if first checking if app is installed and enabled and then if
|
||||
* {@code currentPackageContext} can be used to get the {@link Context} of the app with
|
||||
* {@link TermuxConstants#TERMUX_PACKAGE_NAME} and then if
|
||||
* {@link TermuxConstants#TERMUX_PREFIX_DIR_PATH} exists and has
|
||||
* {@link FileUtils#APP_WORKING_DIRECTORY_PERMISSIONS} permissions. The directory will not
|
||||
* be automatically created and neither the missing permissions automatically set.
|
||||
*
|
||||
* @param currentPackageContext The context of current package.
|
||||
* @return Returns {@code errmsg} if failed to get termux package {@link Context} or
|
||||
* {@link TermuxConstants#TERMUX_PREFIX_DIR_PATH} is accessible, otherwise {@code null}.
|
||||
*/
|
||||
public static String isTermuxAppAccessible(@NonNull final Context currentPackageContext) {
|
||||
String errmsg = isTermuxAppInstalled(currentPackageContext);
|
||||
if (errmsg == null) {
|
||||
Context termuxPackageContext = TermuxUtils.getTermuxPackageContext(currentPackageContext);
|
||||
// If failed to get Termux app package context
|
||||
if (termuxPackageContext == null)
|
||||
errmsg = currentPackageContext.getString(R.string.error_termux_app_package_context_not_accessible);
|
||||
|
||||
if (errmsg == null) {
|
||||
// If TermuxConstants.TERMUX_PREFIX_DIR_PATH is not a directory or does not have required permissions
|
||||
Error error = TermuxFileUtils.isTermuxPrefixDirectoryAccessible(false, false);
|
||||
if (error != null)
|
||||
errmsg = currentPackageContext.getString(R.string.error_termux_prefix_dir_path_not_accessible,
|
||||
PackageUtils.getAppNameForPackage(currentPackageContext));
|
||||
}
|
||||
}
|
||||
|
||||
if (errmsg != null)
|
||||
return errmsg + " " + currentPackageContext.getString(R.string.msg_termux_app_required_by_app,
|
||||
PackageUtils.getAppNameForPackage(currentPackageContext));
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Send the {@link TermuxConstants#BROADCAST_TERMUX_OPENED} broadcast to notify apps that Termux
|
||||
* app has been opened.
|
||||
|
@@ -9,6 +9,7 @@
|
||||
<!ENTITY TERMUX_STYLING_APP_NAME "Termux:Styling">
|
||||
<!ENTITY TERMUX_TASKER_APP_NAME "Termux:Tasker">
|
||||
<!ENTITY TERMUX_WIDGET_APP_NAME "Termux:Widget">
|
||||
<!ENTITY TERMUX_PREFIX_DIR_PATH "/data/data/com.termux/files/usr">
|
||||
]>
|
||||
|
||||
<resources>
|
||||
@@ -71,6 +72,15 @@
|
||||
on github or other official termux community forums **will likely be automatically closed/deleted** and may
|
||||
even result in **temporary or permanent** ban. Check %1$s/wiki/Hacking for details.</string>
|
||||
|
||||
<string name="msg_termux_app_required_by_app">The &TERMUX_APP_NAME; is required by the %1$s app to run termux commands."</string>
|
||||
<string name="error_termux_app_not_installed_or_disabled_warning">The &TERMUX_APP_NAME; app is not installed or is disabled."</string>
|
||||
<string name="error_termux_app_package_context_not_accessible">The &TERMUX_APP_NAME; app (package context) is not accessible."</string>
|
||||
<string name="error_termux_prefix_dir_path_not_accessible">The &TERMUX_APP_NAME; app $PREFIX directory is not accessible by the %1$s app.
|
||||
This may be because you have not installed or setup &TERMUX_APP_NAME; app or
|
||||
&TERMUX_APP_NAME; app and %1$s app both have different APK signatures because you have managed to install both apps from different sources.
|
||||
It may also be because &TERMUX_APP_NAME; $PREFIX directory \"&TERMUX_PREFIX_DIR_PATH;\" does not exist or does not have read,
|
||||
write and execute permissions."</string>
|
||||
|
||||
|
||||
|
||||
<!-- Miscellaneous -->
|
||||
|
Reference in New Issue
Block a user