这是indexloc提供的服务,不要输入任何密码
Skip to content

Commit ed867bc

Browse files
Added: Add Termux:API app settings activity directly in the app itself so that the main Termux app is not required
Currently, it allows changing the log level.
1 parent 989a19b commit ed867bc

File tree

12 files changed

+400
-40
lines changed

12 files changed

+400
-40
lines changed

app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ dependencies {
7171
implementation "com.google.android.material:material:1.12.0"
7272
implementation "androidx.biometric:biometric:1.2.0-alpha05"
7373
implementation "androidx.media:media:1.7.0"
74+
implementation "androidx.preference:preference:1.2.1"
7475

7576
implementation "com.termux.termux-app:termux-shared:b0e1dbc3da"
7677
// Use if below libraries are published locally by termux-app with `./gradlew publishReleasePublicationToMavenLocal` and used with `mavenLocal()`.

app/src/main/AndroidManifest.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@
8585
</intent-filter>
8686
</activity-alias>
8787

88+
<activity
89+
android:name=".settings.activities.TermuxAPISettingsActivity"
90+
android:exported="true"
91+
android:label="@string/sets__root___val__activity_title"
92+
android:theme="@style/Theme.BaseActivity.DayNight.NoActionBar">
93+
</activity>
94+
8895
<activity android:name=".activities.TermuxApiPermissionActivity"
8996
android:theme="@android:style/Theme.NoDisplay"
9097
android:noHistory="true"

app/src/main/java/com/termux/api/activities/TermuxAPIMainActivity.java

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import android.content.Intent;
44
import android.os.Bundle;
5-
import android.os.Environment;
65
import android.view.Menu;
76
import android.view.MenuItem;
87
import android.widget.Button;
@@ -11,20 +10,16 @@
1110
import androidx.appcompat.app.AppCompatActivity;
1211

1312
import com.termux.api.TermuxAPIApplication;
13+
import com.termux.api.settings.activities.TermuxAPISettingsActivity;
1414
import com.termux.api.util.ViewUtils;
15-
import com.termux.shared.activities.ReportActivity;
1615
import com.termux.shared.activity.ActivityUtils;
1716
import com.termux.shared.activity.media.AppCompatActivityUtils;
18-
import com.termux.shared.android.AndroidUtils;
1917
import com.termux.shared.android.PackageUtils;
2018
import com.termux.shared.android.PermissionUtils;
2119
import com.termux.shared.data.IntentUtils;
22-
import com.termux.shared.file.FileUtils;
2320
import com.termux.shared.logger.Logger;
2421
import com.termux.shared.markdown.MarkdownUtils;
25-
import com.termux.shared.models.ReportInfo;
2622
import com.termux.shared.termux.TermuxConstants;
27-
import com.termux.shared.termux.TermuxUtils;
2823
import com.termux.shared.termux.theme.TermuxThemeUtils;
2924
import com.termux.shared.theme.NightMode;
3025
import com.termux.api.R;
@@ -92,40 +87,14 @@ public boolean onCreateOptionsMenu(Menu menu) {
9287
public boolean onOptionsItemSelected(MenuItem item) {
9388
int id = item.getItemId();
9489

95-
if (id == R.id.menu_info) {
96-
showInfo();
97-
return true;
98-
} else if (id == R.id.menu_settings) {
90+
if (id == R.id.menu_settings) {
9991
openSettings();
10092
return true;
10193
}
10294

10395
return super.onOptionsItemSelected(item);
10496
}
10597

106-
private void showInfo() {
107-
new Thread() {
108-
@Override
109-
public void run() {
110-
String title = "About";
111-
112-
StringBuilder aboutString = new StringBuilder();
113-
aboutString.append(TermuxUtils.getAppInfoMarkdownString(TermuxAPIMainActivity.this, TermuxUtils.AppInfoMode.TERMUX_AND_PLUGIN_PACKAGE));
114-
aboutString.append("\n\n").append(AndroidUtils.getDeviceInfoMarkdownString(TermuxAPIMainActivity.this));
115-
aboutString.append("\n\n").append(TermuxUtils.getImportantLinksMarkdownString(TermuxAPIMainActivity.this));
116-
117-
ReportInfo reportInfo = new ReportInfo(title,
118-
TermuxConstants.TERMUX_API_APP.TERMUX_API_MAIN_ACTIVITY_NAME, title);
119-
reportInfo.setReportString(aboutString.toString());
120-
reportInfo.setReportSaveFileLabelAndPath(title,
121-
Environment.getExternalStorageDirectory() + "/" +
122-
FileUtils.sanitizeFileName(TermuxConstants.TERMUX_APP_NAME + "-" + title + ".log", true, true));
123-
124-
ReportActivity.startReportActivity(TermuxAPIMainActivity.this, reportInfo);
125-
}
126-
}.start();
127-
}
128-
12998

13099

131100
private void checkIfBatteryOptimizationNotDisabled() {
@@ -242,7 +211,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
242211

243212

244213
private void openSettings() {
245-
ActivityUtils.startActivity(this, new Intent().setClassName(TermuxConstants.TERMUX_PACKAGE_NAME, TermuxConstants.TERMUX_APP.TERMUX_SETTINGS_ACTIVITY_NAME));
214+
ActivityUtils.startActivity(this, new Intent().setClass(this, TermuxAPISettingsActivity.class));
246215
}
247216

248217
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package com.termux.api.settings.activities;
2+
3+
import android.content.Context;
4+
import android.os.Bundle;
5+
import android.os.Environment;
6+
7+
import androidx.annotation.NonNull;
8+
import androidx.appcompat.app.AppCompatActivity;
9+
import androidx.preference.Preference;
10+
import androidx.preference.PreferenceFragmentCompat;
11+
12+
import com.termux.api.R;
13+
import com.termux.shared.activities.ReportActivity;
14+
import com.termux.shared.file.FileUtils;
15+
import com.termux.shared.models.ReportInfo;
16+
import com.termux.shared.interact.ShareUtils;
17+
import com.termux.shared.android.PackageUtils;
18+
import com.termux.shared.termux.settings.preferences.TermuxAPIAppSharedPreferences;
19+
import com.termux.shared.android.AndroidUtils;
20+
import com.termux.shared.termux.TermuxConstants;
21+
import com.termux.shared.termux.TermuxUtils;
22+
import com.termux.shared.activity.media.AppCompatActivityUtils;
23+
import com.termux.shared.theme.NightMode;
24+
25+
public class TermuxAPISettingsActivity extends AppCompatActivity {
26+
27+
@Override
28+
protected void onCreate(Bundle savedInstanceState) {
29+
super.onCreate(savedInstanceState);
30+
31+
AppCompatActivityUtils.setNightMode(this, NightMode.getAppNightMode().getName(), true);
32+
33+
setContentView(R.layout.activity_termux_api_settings);
34+
if (savedInstanceState == null) {
35+
getSupportFragmentManager()
36+
.beginTransaction()
37+
.replace(R.id.settings, new RootPreferencesFragment())
38+
.commit();
39+
}
40+
41+
AppCompatActivityUtils.setToolbar(this, com.termux.shared.R.id.toolbar);
42+
AppCompatActivityUtils.setShowBackButtonInActionBar(this, true);
43+
}
44+
45+
@Override
46+
public boolean onSupportNavigateUp() {
47+
onBackPressed();
48+
return true;
49+
}
50+
51+
public static class RootPreferencesFragment extends PreferenceFragmentCompat {
52+
@Override
53+
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
54+
Context context = getContext();
55+
if (context == null) return;
56+
57+
setPreferencesFromResource(R.xml.sets__termux, rootKey);
58+
59+
new Thread() {
60+
@Override
61+
public void run() {
62+
configureTermuxAPIPreference(context);
63+
configureAboutPreference(context);
64+
configureDonatePreference(context);
65+
}
66+
}.start();
67+
}
68+
69+
private void configureTermuxAPIPreference(@NonNull Context context) {
70+
Preference termuxAPIPreference = findPreference("sets__termux_api_app");
71+
if (termuxAPIPreference != null) {
72+
TermuxAPIAppSharedPreferences preferences = TermuxAPIAppSharedPreferences.build(context, false);
73+
// If failed to get app preferences, then likely app is not installed, so do not show its preference
74+
termuxAPIPreference.setVisible(preferences != null);
75+
}
76+
}
77+
78+
private void configureAboutPreference(@NonNull Context context) {
79+
Preference aboutPreference = findPreference("link__termux_about");
80+
if (aboutPreference != null) {
81+
aboutPreference.setOnPreferenceClickListener(preference -> {
82+
new Thread() {
83+
@Override
84+
public void run() {
85+
String title = "About";
86+
87+
StringBuilder aboutString = new StringBuilder();
88+
aboutString.append(TermuxUtils.getAppInfoMarkdownString(context, TermuxUtils.AppInfoMode.TERMUX_AND_PLUGIN_PACKAGE));
89+
aboutString.append("\n\n").append(AndroidUtils.getDeviceInfoMarkdownString(context, true));
90+
aboutString.append("\n\n").append(TermuxUtils.getImportantLinksMarkdownString(context));
91+
92+
ReportInfo reportInfo = new ReportInfo(title,
93+
TermuxConstants.TERMUX_API_APP.TERMUX_API_MAIN_ACTIVITY_NAME, title);
94+
reportInfo.setReportString(aboutString.toString());
95+
reportInfo.setReportSaveFileLabelAndPath(title,
96+
Environment.getExternalStorageDirectory() + "/" +
97+
FileUtils.sanitizeFileName(TermuxConstants.TERMUX_API_APP_NAME.replaceAll(":", "") +
98+
"-" + title + ".log", true, true));
99+
100+
ReportActivity.startReportActivity(context, reportInfo);
101+
}
102+
}.start();
103+
104+
return true;
105+
});
106+
}
107+
}
108+
109+
private void configureDonatePreference(@NonNull Context context) {
110+
Preference donatePreference = findPreference("link__termux_donate");
111+
if (donatePreference != null) {
112+
String signingCertificateSHA256Digest = PackageUtils.getSigningCertificateSHA256DigestForPackage(context);
113+
if (signingCertificateSHA256Digest != null) {
114+
// If APK is a Google Playstore release, then do not show the donation link
115+
// since Termux isn't exempted from the playstore policy donation links restriction
116+
// Check Fund solicitations: https://pay.google.com/intl/en_in/about/policy/
117+
String apkRelease = TermuxUtils.getAPKRelease(signingCertificateSHA256Digest);
118+
if (apkRelease == null || apkRelease.equals(TermuxConstants.APK_RELEASE_GOOGLE_PLAYSTORE_SIGNING_CERTIFICATE_SHA256_DIGEST)) {
119+
donatePreference.setVisible(false);
120+
return;
121+
} else {
122+
donatePreference.setVisible(true);
123+
}
124+
}
125+
126+
donatePreference.setOnPreferenceClickListener(preference -> {
127+
ShareUtils.openUrl(context, TermuxConstants.TERMUX_DONATE_URL);
128+
return true;
129+
});
130+
}
131+
}
132+
}
133+
134+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.termux.api.settings.fragments.termux_api_app;
2+
3+
import android.content.Context;
4+
import android.os.Bundle;
5+
6+
import androidx.annotation.Keep;
7+
import androidx.preference.PreferenceDataStore;
8+
import androidx.preference.PreferenceFragmentCompat;
9+
import androidx.preference.PreferenceManager;
10+
11+
import com.termux.api.R;
12+
import com.termux.shared.termux.settings.preferences.TermuxAPIAppSharedPreferences;
13+
14+
@Keep
15+
public class TermuxAPIPreferencesFragment extends PreferenceFragmentCompat {
16+
17+
@Override
18+
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
19+
Context context = getContext();
20+
if (context == null) return;
21+
22+
PreferenceManager preferenceManager = getPreferenceManager();
23+
preferenceManager.setPreferenceDataStore(TermuxAPIPreferencesDataStore.getInstance(context));
24+
25+
setPreferencesFromResource(R.xml.prefs__termux_api_app___prefs__app, rootKey);
26+
}
27+
28+
}
29+
30+
class TermuxAPIPreferencesDataStore extends PreferenceDataStore {
31+
32+
private final Context mContext;
33+
private final TermuxAPIAppSharedPreferences mPreferences;
34+
35+
private static TermuxAPIPreferencesDataStore mInstance;
36+
37+
private TermuxAPIPreferencesDataStore(Context context) {
38+
mContext = context;
39+
mPreferences = TermuxAPIAppSharedPreferences.build(context, true);
40+
}
41+
42+
public static synchronized TermuxAPIPreferencesDataStore getInstance(Context context) {
43+
if (mInstance == null) {
44+
mInstance = new TermuxAPIPreferencesDataStore(context);
45+
}
46+
return mInstance;
47+
}
48+
49+
}

0 commit comments

Comments
 (0)