various ui tweaks

Signed-off-by: androidacy-user <opensource@androidacy.com>
pull/89/head
androidacy-user 3 years ago
parent 89e2d8014b
commit 857ab8d7ba

@ -557,11 +557,18 @@ android {
}
//noinspection GrDeprecatedAPIUsage
buildToolsVersion = "34.0.0"
kotlinOptions {
jvmTarget = "17"
}
@Suppress("DEPRECATION") packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}
java {

@ -1,9 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2023 to present Androidacy and contributors. Names, logos, icons, and the Androidacy name are all trademarks of Androidacy and may not be used without license. See LICENSE for more information.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="QueryAllPackagesPermission"
@ -15,16 +10,13 @@
<intent>
<action android:name="com.fox2code.mmm.utils.intent.action.OPEN_EXTERNAL" />
</intent>
</queries>
<!-- Wifi is not the only way to get an internet connection -->
</queries> <!-- Wifi is not the only way to get an internet connection -->
<uses-feature
android:name="android.hardware.wifi"
android:required="false" />
<!-- uses webview -->
android:required="false" /> <!-- uses webview -->
<uses-feature
android:name="android.software.webview"
android:required="true" />
<!-- uses opengl 1.2 -->
android:required="true" /> <!-- uses opengl 1.2 -->
<uses-feature
android:name="android.hardware.opengles.aep"
android:required="false" />
@ -51,28 +43,35 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- wake lock -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- request uninstall -->
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<!-- wifi -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:name=".MainApplication"
android:allowBackup="false"
android:hardwareAccelerated="true"
android:appCategory="productivity"
android:dataExtractionRules="@xml/data_extraction_rules"
android:enableOnBackInvokedCallback="true"
android:forceDarkAllowed="false"
android:fullBackupContent="@xml/full_backup_content"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name_v2"
android:memtagMode="async"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="@bool/lang_support_rtl"
android:testOnly="false"
android:appCategory="productivity"
android:memtagMode="async"
android:theme="@style/Theme.MagiskModuleManager"
android:usesCleartextTraffic="false"
android:forceDarkAllowed="false"
tools:ignore="ManifestResource"
tools:replace="android:supportsRtl"
tools:targetApi="tiramisu">
<activity
android:name=".ExpiredActivity"
android:exported="false" />
<activity
android:name=".UpdateActivity"
android:exported="false"
@ -105,19 +104,18 @@
<action android:name="android.intent.action.APPLICATION_PREFERENCES" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name_short_v2"
android:launchMode="singleTask"
android:theme="@style/Theme.MagiskModuleManager.NoActionBar" >
android:theme="@style/Theme.MagiskModuleManager.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".installer.InstallerActivity"
android:exported="false"
@ -131,13 +129,11 @@
<action android:name="${applicationId}.intent.action.INSTALL_MODULE_INTERNAL" />
</intent-filter>
-->
</activity>
<!-- We can handle zip files -->
</activity> <!-- We can handle zip files -->
<activity
android:name=".utils.ZipFileOpener"
android:exported="true"
android:theme="@style/Theme.MagiskModuleManager.NoActionBar" >
android:theme="@style/Theme.MagiskModuleManager.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@ -148,18 +144,16 @@
<data android:scheme="content" />
</intent-filter>
</activity>
<activity
android:name=".markdown.MarkdownActivity"
android:exported="false"
android:parentActivityName=".MainActivity"
android:theme="@style/Theme.MagiskModuleManager.NoActionBar" />
<activity
android:name=".androidacy.AndroidacyActivity"
android:exported="false"
android:parentActivityName=".MainActivity"
android:theme="@style/Theme.MagiskModuleManager.NoActionBar" >
android:theme="@style/Theme.MagiskModuleManager.NoActionBar">
<!--
<intent-filter>
@ -167,7 +161,6 @@
</intent-filter>
-->
</activity>
<activity
android:name="com.mikepenz.aboutlibraries.ui.LibsActivity"
tools:node="remove" />
@ -184,7 +177,6 @@
android:name="androidx.work.WorkManagerInitializer"
tools:node="remove" />
</provider>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.file-provider"
@ -200,29 +192,25 @@
android:value="false" />
<meta-data
android:name="io.sentry.dsn"
android:value="https://e199c2a54a1f49b1b5beb3244f2c2358@sentry.androidacy.com/77" />
<!-- enable view hierarchy for crashes -->
<meta-data android:name="io.sentry.attach-view-hierarchy" android:value="true" />
<!-- Sane value, but feel free to lower it -->
android:value="https://e199c2a54a1f49b1b5beb3244f2c2358@sentry.androidacy.com/77" /> <!-- enable view hierarchy for crashes -->
<meta-data
android:name="io.sentry.attach-view-hierarchy"
android:value="true" /> <!-- Sane value, but feel free to lower it -->
<meta-data
android:name="io.sentry.traces.sample-rate"
android:value="0.2" />
<!-- Doesn't actually monitor anything, just used to get the activities the user went through -->
android:value="0.2" /> <!-- Doesn't actually monitor anything, just used to get the activities the user went through -->
<meta-data
android:name="io.sentry.traces.user-interaction.enable"
android:value="true" />
<!-- Just a screenshot of ONLY the current activity at the time of the crash -->
android:value="true" /> <!-- Just a screenshot of ONLY the current activity at the time of the crash -->
<meta-data
android:name="io.sentry.attach-screenshot"
android:value="true" />
<!-- Just the current activity at the time of the crash -->
android:value="true" /> <!-- Just the current activity at the time of the crash -->
<meta-data
android:name="io.sentry.attach-stacktrace"
android:value="true" />
<!-- Performance profiling -->
android:value="true" /> <!-- Performance profiling -->
<meta-data
android:name="io.sentry.traces.profiling.sample-rate"
android:value="0.2" />
</application>
</manifest>
</manifest>

@ -0,0 +1,35 @@
package com.fox2code.mmm
import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import com.fox2code.foxcompat.app.FoxActivity
import com.google.android.material.button.MaterialButton
class ExpiredActivity : FoxActivity() {
@SuppressLint("RestrictedApi")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_expired)
// download_button leads to the download page and uninstall_button leads to the uninstall dialog
val downloadBtn = findViewById<MaterialButton>(R.id.download_button)
val uninstallBtn = findViewById<MaterialButton>(R.id.uninstall_button)
downloadBtn.setOnClickListener {
// open https://www.androidacy.com/downloads/?view=FoxMMM
startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse("https://www.androidacy.com/downloads/?view=FoxMMM")
)
)
}
uninstallBtn.setOnClickListener {
// open system uninstall dialog
val intent = Intent(Intent.ACTION_DELETE)
// discover our package name
intent.data = Uri.parse("package:$packageName")
startActivity(intent)
}
}
}

@ -135,20 +135,28 @@ class MainActivity : FoxActivity(), OnRefreshListener, SearchView.OnQueryTextLis
}
}.start()
val ts = Timestamp(System.currentTimeMillis() - 30L * 24 * 60 * 60 * 1000)
// check if this build has expired
val buildTime = Timestamp(BuildConfig.BUILD_TIME)
// if the build time is more than 30 days ago, throw an exception
if (BuildConfig.DEBUG) {
check(ts.time < buildTime.time) { getString(R.string.build_expired) }
if (ts.time > buildTime.time) {
val pm = packageManager
val intent = Intent(this, ExpiredActivity::class.java)
@Suppress("DEPRECATION") val resolveInfo = pm.queryIntentActivities(intent, 0)
if (resolveInfo.size > 0) {
startActivity(intent)
finish()
return
} else {
throw IllegalAccessError("This build has expired")
}
}
} else {
// non-debug builds expire after 1 year but only show a toast
val ts2 = Timestamp(System.currentTimeMillis() - 365L * 24 * 60 * 60 * 1000)
if (ts2.time > buildTime.time) {
Toast.makeText(this, R.string.build_expired, Toast.LENGTH_LONG).show()
}
}
setContentView(R.layout.activity_main)
this.setTitle(R.string.app_name)
this.setTitle(R.string.app_name_v2)
// set window flags to ignore status bar
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// ignore status bar space
@ -342,6 +350,14 @@ class MainActivity : FoxActivity(), OnRefreshListener, SearchView.OnQueryTextLis
}
true
}
// parse intent. if action is SHOW_ONLINE, show online modules
val action = intent.action
if (action == "android.intent.action.SHOW_ONLINE") {
// select online modules
bottomNavigationView.selectedItemId = R.id.online_menu_item
} else {
bottomNavigationView.selectedItemId = R.id.installed_menu_item
}
// update the padding of blur_frame to match the new bottom nav height
val blurFrame = findViewById<View>(R.id.blur_frame)
blurFrame.post {

@ -39,6 +39,7 @@ import org.apache.commons.io.FileUtils
import timber.log.Timber
import java.io.File
import java.io.IOException
import java.sql.Timestamp
import java.util.Objects
class SetupActivity : FoxActivity(), LanguageActivity {
@ -62,6 +63,27 @@ class SetupActivity : FoxActivity(), LanguageActivity {
}
val binding = ActivitySetupBinding.inflate(layoutInflater)
setContentView(binding.root)
val ts = Timestamp(System.currentTimeMillis() - 30L * 24 * 60 * 60 * 1000)
val buildTime = Timestamp(BuildConfig.BUILD_TIME)
if (BuildConfig.DEBUG) {
if (ts.time > buildTime.time) {
val pm = packageManager
val intent = Intent(this, ExpiredActivity::class.java)
@Suppress("DEPRECATION") val resolveInfo = pm.queryIntentActivities(intent, 0)
if (resolveInfo.size > 0) {
startActivity(intent)
finish()
return
} else {
throw IllegalAccessError("This build has expired")
}
}
} else {
val ts2 = Timestamp(System.currentTimeMillis() - 365L * 24 * 60 * 60 * 1000)
if (ts2.time > buildTime.time) {
Toast.makeText(this, R.string.build_expired, Toast.LENGTH_LONG).show()
}
}
val view: View = binding.root
(Objects.requireNonNull<Any>(view.findViewById(R.id.setup_background_update_check)) as MaterialSwitch).isChecked =
BuildConfig.ENABLE_AUTO_UPDATER

@ -12,6 +12,7 @@ import android.view.View
import android.webkit.CookieManager
import android.webkit.WebSettings
import android.webkit.WebView
import android.widget.Toast
import androidx.core.content.FileProvider
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewFeature
@ -28,6 +29,7 @@ import timber.log.Timber
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.sql.Timestamp
import java.util.Objects
class UpdateActivity : FoxActivity() {
@ -38,6 +40,27 @@ class UpdateActivity : FoxActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_update)
val ts = Timestamp(System.currentTimeMillis() - 30L * 24 * 60 * 60 * 1000)
val buildTime = Timestamp(BuildConfig.BUILD_TIME)
if (BuildConfig.DEBUG) {
if (ts.time > buildTime.time) {
val pm = packageManager
val intent = Intent(this, ExpiredActivity::class.java)
@Suppress("DEPRECATION") val resolveInfo = pm.queryIntentActivities(intent, 0)
if (resolveInfo.size > 0) {
startActivity(intent)
finish()
return
} else {
throw IllegalAccessError("This build has expired")
}
}
} else {
val ts2 = Timestamp(System.currentTimeMillis() - 365L * 24 * 60 * 60 * 1000)
if (ts2.time > buildTime.time) {
Toast.makeText(this, R.string.build_expired, Toast.LENGTH_LONG).show()
}
}
chgWv = findViewById(R.id.changelog_webview)
if (MainApplication.isMatomoAllowed()) {
TrackHelper.track().screen(this).with(MainApplication.INSTANCE!!.tracker)

@ -51,6 +51,7 @@ import com.fox2code.foxcompat.view.FoxViewCompat
import com.fox2code.mmm.AppUpdateManager.Companion.appUpdateManager
import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.Constants
import com.fox2code.mmm.ExpiredActivity
import com.fox2code.mmm.MainActivity
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.MainApplication.Companion.INSTANCE
@ -101,6 +102,7 @@ import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStreamReader
import java.sql.Timestamp
import java.util.Objects
import java.util.Random
import kotlin.system.exitProcess
@ -110,18 +112,26 @@ class SettingsActivity : FoxActivity(), LanguageActivity {
@SuppressLint("RestrictedApi")
private val onItemSelectedListener =
NavigationBarView.OnItemSelectedListener { item: MenuItem ->
val itemId = item.itemId
if (itemId == R.id.back) {
TrackHelper.track().event("view_list", "main_modules")
.with(INSTANCE!!.getTracker())
startActivity(Intent(this, MainActivity::class.java))
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
finish()
return@OnItemSelectedListener true
} else if (itemId == R.id.settings_menu_item) {
return@OnItemSelectedListener true
when (item.itemId) {
R.id.installed_menu_item -> {
// go back to main modules by opening main activity with installed action
val intent = Intent(this, MainActivity::class.java)
intent.action = "android.intent.action.SHOW_INSTALLED"
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(intent)
return@OnItemSelectedListener true
}
R.id.online_menu_item -> {
val intent = Intent(this, MainActivity::class.java)
intent.action = "android.intent.action.SHOW_ONLINE"
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(intent)
return@OnItemSelectedListener true
}
else -> {
return@OnItemSelectedListener false
}
}
false
}
@SuppressLint("RestrictedApi")
@ -130,7 +140,28 @@ class SettingsActivity : FoxActivity(), LanguageActivity {
super.onCreate(savedInstanceState)
TrackHelper.track().screen(this).with(INSTANCE!!.getTracker())
setContentView(R.layout.settings_activity)
setTitle(R.string.app_name)
setTitle(R.string.app_name_v2)
val ts = Timestamp(System.currentTimeMillis() - 30L * 24 * 60 * 60 * 1000)
val buildTime = Timestamp(BuildConfig.BUILD_TIME)
if (BuildConfig.DEBUG) {
if (ts.time > buildTime.time) {
val pm = packageManager
val intent = Intent(this, ExpiredActivity::class.java)
@Suppress("DEPRECATION") val resolveInfo = pm.queryIntentActivities(intent, 0)
if (resolveInfo.size > 0) {
startActivity(intent)
finish()
return
} else {
throw IllegalAccessError("This build has expired")
}
}
} else {
val ts2 = Timestamp(System.currentTimeMillis() - 365L * 24 * 60 * 60 * 1000)
if (ts2.time > buildTime.time) {
Toast.makeText(this, R.string.build_expired, Toast.LENGTH_LONG).show()
}
}
//hideActionBar();
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom_navigation)
bottomNavigationView.setOnItemSelectedListener(onItemSelectedListener)
@ -1237,7 +1268,7 @@ class SettingsActivity : FoxActivity(), LanguageActivity {
}
override fun onBackPressed(compatActivity: FoxActivity): Boolean {
compatActivity.setTitle(R.string.app_name)
compatActivity.setTitle(R.string.app_name_v2)
compatActivity.supportFragmentManager.beginTransaction().replace(R.id.settings, this)
.setTransition(
FragmentTransaction.TRANSIT_FRAGMENT_FADE
@ -1884,7 +1915,7 @@ class SettingsActivity : FoxActivity(), LanguageActivity {
true
}
} else {
findPreference<Preference>(preferenceName + "_support")!!.isVisible =
findPreference<Preference>("${preferenceName}_support")!!.isVisible =
false
}
if (repoData.getSubmitModule() != null) {

@ -280,39 +280,49 @@ class RuntimeUtils {
// reboot based on the reboot cmd from the enum we were passed
when (reboot) {
RebootMode.REBOOT -> {
showRebootDialog(mainActivity) {
showRebootDialog(mainActivity, false) {
Shell.cmd("/system/bin/svc power reboot || /system/bin/reboot").submit()
}
}
RebootMode.RECOVERY -> {
// KEYCODE_POWER = 26, hide incorrect "Factory data reset" message
showRebootDialog(mainActivity) {
showRebootDialog(mainActivity, false) {
Shell.cmd("/system/bin/input keyevent 26").submit()
}
}
RebootMode.BOOTLOADER -> {
showRebootDialog(mainActivity) {
showRebootDialog(mainActivity, false) {
Shell.cmd("/system/bin/svc power reboot bootloader || /system/bin/reboot bootloader")
.submit()
}
}
RebootMode.EDL -> {
showRebootDialog(mainActivity) {
showRebootDialog(mainActivity, true) {
Shell.cmd("/system/bin/reboot edl").submit()
}
}
}
}
private fun showRebootDialog(mainActivity: FoxActivity, function: () -> Unit) {
private fun showRebootDialog(
mainActivity: FoxActivity,
showExtraWarning: Boolean,
function: () -> Unit
) {
val message =
if (showExtraWarning) R.string.reboot_extra_warning else R.string.install_terminal_reboot_now_message
val dialog = MaterialAlertDialogBuilder(mainActivity)
.setTitle(R.string.reboot)
.setMessage(R.string.install_terminal_reboot_now_message)
.setPositiveButton(R.string.reboot) { _, _ ->
function()
}
.setNegativeButton(R.string.cancel) { _, _ -> }
.create()
dialog.setTitle(R.string.reboot)
dialog.setCancelable(false)
dialog.setMessage(message)
dialog.setPositiveButton(R.string.reboot) { _, _ ->
function()
}
dialog.setNegativeButton(R.string.cancel) { _, _ -> }
dialog.create()
dialog.show()
}
}

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ExpiredActivity">
<LinearLayout
android:id="@+id/mainexpiredlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center"
android:orientation="vertical">
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="96dp"
android:layout_height="96dp"
android:layout_gravity="center"
android:layout_margin="12dp"
android:src="@drawable/ic_baseline_warning_24" />
<com.google.android.material.textview.MaterialTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:gravity="center"
android:text="@string/expired"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall" />
<com.google.android.material.textview.MaterialTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:gravity="center"
android:text="@string/expired_message"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.Material3.BodyMedium" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="12dp"
android:gravity="center"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/uninstall_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dp"
android:text="@string/uninstall" />
<com.google.android.material.button.MaterialButton
android:id="@+id/download_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:text="@string/download_latest" />
</LinearLayout>
</LinearLayout>
<!-- bottom action bar with just app name -->
<com.google.android.material.bottomappbar.BottomAppBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/bottomAppBar"
android:layout_gravity="bottom"
app:fabAlignmentMode="center"
app:fabCradleMargin="10dp">
<com.google.android.material.textview.MaterialTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="@string/app_name_v2"
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall" />
</com.google.android.material.bottomappbar.BottomAppBar>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

@ -76,7 +76,6 @@
android:contentDescription="@string/reboot"
android:src="@drawable/baseline_restart_alt_24"
android:visibility="visible"
app:fabSize="mini"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/search_bar"
app:layout_constraintStart_toStartOf="parent"
@ -89,6 +88,7 @@
android:layout_height="56dp"
android:visibility="visible"
app:cardElevation="6dp"
android:alpha="1"
android:layout_marginBottom="2dp"
app:cardPreventCornerOverlap="true"
app:shapeAppearanceOverlay="@style/ShapeAppearance.Material3.Corner.Medium"

@ -28,5 +28,5 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_nav_menu_settings" />
app:menu="@menu/bottom_nav_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -375,4 +375,12 @@
<string name="reboot_edl">Reboot to EDL mode</string>
<string name="install_terminal_reboot_prevented">Reboot is disabled in app settings</string>
<string name="androidacy_api_error">Error while communicating with API: %d</string>
<string name="reboot_extra_warning">You are about to reboot to EDL mode, a special mode intended for OEMs to flash and fix low level problems. Unless you are sure you want to do this and have the necessary tools to get out of this mode or use it, we strongly encourage you to use the other reboot options.</string>
<string name="title_activity_expired">ExpiredActivity</string>
<string name="title_home">Home</string>
<string name="title_dashboard">Dashboard</string>
<string name="title_notifications">Notifications</string>
<string name="expired">This build has expired!</string>
<string name="expired_message">The build you are using is expired and will no longer run. Please update to the latest stable build.</string>
<string name="download_latest">Download latest</string>
</resources>

Loading…
Cancel
Save