Added Music shortcut (on users' request).
- Music is not an intrinsic part of the app, therefore it should be used as it is and
- any further development will not be done for that..
-
-
-
-
Bug Fixes
-
-
-
Fixed app crashing when data is explicitly restored from cloud after factory reset or
- setting up a new device.
-
-
Fixed launching terminal from shortcut launches the app if the app process is active in the
- memory.
-
-
Fixed app crashing without any stack trace on many pre Android 13 devices.
-
Fixed navigation bar overlapping issue on some views.
+
Added Lock Screen widget.
+
+
+
+
+
+
User Interface
+
+
+
Added Music shortcut (on users' request).
+ Music is not an intrinsic part of the app, therefore it should be used as
+ it is and
+ any further development will not be done for that..
+
+
+
+
Bug Fixes
+
+
+
Fixed app crashing when data is explicitly restored from cloud after factory
+ reset or
+ setting up a new device.
+
+
Fixed launching terminal from shortcut launches the app if the app process is
+ active in the
+ memory.
+
+
Fixed app crashing without any stack trace on many pre Android 13 devices.
+
Fixed navigation bar overlapping issue on some views.
+
+
+
+
+
diff --git a/app/src/main/ic_lock_screen-playstore.png b/app/src/main/ic_lock_screen-playstore.png
new file mode 100644
index 000000000..3edfb8ac5
Binary files /dev/null and b/app/src/main/ic_lock_screen-playstore.png differ
diff --git a/app/src/main/java/app/simple/inure/activities/app/MainActivity.kt b/app/src/main/java/app/simple/inure/activities/app/MainActivity.kt
index 08d5dddba..a16f49f41 100644
--- a/app/src/main/java/app/simple/inure/activities/app/MainActivity.kt
+++ b/app/src/main/java/app/simple/inure/activities/app/MainActivity.kt
@@ -1,5 +1,7 @@
package app.simple.inure.activities.app
+import android.app.admin.DevicePolicyManager
+import android.content.ComponentName
import android.content.Intent
import android.content.SharedPreferences
import android.content.res.Configuration
@@ -16,6 +18,7 @@ import app.simple.inure.decorations.theme.ThemeCoordinatorLayout
import app.simple.inure.extensions.activities.BaseActivity
import app.simple.inure.preferences.AppearancePreferences
import app.simple.inure.preferences.DevelopmentPreferences
+import app.simple.inure.receivers.AdminReceiver
import app.simple.inure.terminal.Term
import app.simple.inure.themes.manager.Theme
import app.simple.inure.themes.manager.ThemeManager
@@ -46,6 +49,12 @@ class MainActivity : BaseActivity() {
content.setBackgroundColor(ThemeManager.theme.viewGroupTheme.background)
ThemeUtils.setAppTheme(resources)
+ val intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
+ intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, ComponentName(applicationContext, AdminReceiver::class.java))
+ intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Additional text explaining why this needs to be added.")
+ applicationContext.startActivity(intent)
+
if (savedInstanceState.isNull()) {
when (intent.action) {
ShortcutConstants.ANALYTICS_ACTION -> {
diff --git a/app/src/main/java/app/simple/inure/constants/ServiceConstants.kt b/app/src/main/java/app/simple/inure/constants/ServiceConstants.kt
index 2e37eaa8f..f280ca0fc 100644
--- a/app/src/main/java/app/simple/inure/constants/ServiceConstants.kt
+++ b/app/src/main/java/app/simple/inure/constants/ServiceConstants.kt
@@ -38,6 +38,11 @@ object ServiceConstants {
const val actionPackageInfo = "$appPackageName.package.info"
const val actionSessionStatus = "$appPackageName.session.status"
+ // Widgets
+ const val actionWidgetLockScreen = "$appPackageName.widget.lock_screen"
+ const val actionDeviceAdminDisabled = "${appPackageName}.device_admin_action_disabled"
+ const val actionDeviceAdminEnabled = "${appPackageName}.device_admin_action_enabled"
+
fun getMediaErrorString(extra: Int): String {
return when (extra) {
MediaPlayer.MEDIA_ERROR_IO -> {
diff --git a/app/src/main/java/app/simple/inure/receivers/AdminReceiver.java b/app/src/main/java/app/simple/inure/receivers/AdminReceiver.java
new file mode 100644
index 000000000..ae0f110fc
--- /dev/null
+++ b/app/src/main/java/app/simple/inure/receivers/AdminReceiver.java
@@ -0,0 +1,22 @@
+package app.simple.inure.receivers;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+import app.simple.inure.constants.ServiceConstants;
+
+public class AdminReceiver extends DeviceAdminReceiver {
+ @Override
+ public void onDisabled(Context context, Intent intent) {
+ super.onDisabled(context, intent);
+ LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent(ServiceConstants.actionDeviceAdminDisabled));
+ }
+
+ @Override
+ public void onEnabled(Context context, Intent intent) {
+ super.onEnabled(context, intent);
+ LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent(ServiceConstants.actionDeviceAdminEnabled));
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/app/simple/inure/widgets/LockScreenWidget.kt b/app/src/main/java/app/simple/inure/widgets/LockScreenWidget.kt
new file mode 100644
index 000000000..4cdbc6537
--- /dev/null
+++ b/app/src/main/java/app/simple/inure/widgets/LockScreenWidget.kt
@@ -0,0 +1,100 @@
+package app.simple.inure.widgets
+
+import android.app.PendingIntent
+import android.app.admin.DevicePolicyManager
+import android.appwidget.AppWidgetManager
+import android.appwidget.AppWidgetProvider
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.os.PowerManager
+import android.widget.RemoteViews
+import android.widget.Toast
+import app.simple.inure.R
+import app.simple.inure.constants.ServiceConstants
+import app.simple.inure.receivers.AdminReceiver
+
+class LockScreenWidget : AppWidgetProvider() {
+ override fun onUpdate(context: Context?, appWidgetManager: AppWidgetManager?, appWidgetIds: IntArray?) {
+ super.onUpdate(context, appWidgetManager, appWidgetIds)
+
+ /**
+ * Loop for every App Widget instance that belongs to this provider.
+ * Noting, that is, a user might have multiple instances of the same
+ * widget on their home screen.
+ */
+ for (appWidgetID in appWidgetIds!!) {
+ val remoteViews = RemoteViews(context!!.packageName, R.layout.widget_lock)
+ remoteViews.setOnClickPendingIntent(R.id.lock_screen, getPendingSelfIntent(context, ServiceConstants.actionWidgetLockScreen))
+ appWidgetManager!!.updateAppWidget(appWidgetID, remoteViews)
+ }
+ }
+
+ override fun onEnabled(context: Context?) {
+ super.onEnabled(context)
+ }
+
+ override fun onDeleted(context: Context?, appWidgetIds: IntArray?) {
+ super.onDeleted(context, appWidgetIds)
+ }
+
+ override fun onReceive(context: Context, intent: Intent?) {
+ super.onReceive(context, intent)
+ try {
+ if (intent!!.action == ServiceConstants.actionWidgetLockScreen) {
+ lock(context)
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ private fun getPendingSelfIntent(context: Context, action: String): PendingIntent? {
+ val intent = Intent(context, this.javaClass)
+ intent.action = action
+ return PendingIntent.getBroadcast(context, 123, intent, PendingIntent.FLAG_IMMUTABLE)
+ }
+
+ /**
+ * A general technique for calling the onUpdate method,
+ * requiring only the context parameter.
+ *
+ * @author John Bentley, based on Android-er code.
+ * @see [Android-er > 2010-10-19 > Update Widget in onReceive]
+ * (http://android-er.blogspot.com.au/2010/10/update-widget-in-onreceive-method.html)
+ */
+ private fun onUpdate(context: Context) {
+ val appWidgetManager = AppWidgetManager.getInstance(context)
+
+ /**
+ * Uses getClass().getName() rather than MyWidget.class.getName() for
+ * portability into any App Widget Provider Class
+ */
+ val thisAppWidgetComponentName = ComponentName(context.packageName, javaClass.name)
+ val appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidgetComponentName)
+ onUpdate(context, appWidgetManager, appWidgetIds)
+ }
+
+ private fun lock(context: Context) {
+ val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager?
+ if (pm!!.isInteractive) {
+ val policy = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager?
+ try {
+ policy!!.lockNow()
+ } catch (ex: SecurityException) {
+ ex.printStackTrace()
+ try {
+ Toast.makeText(context, "must enable device administrator", Toast.LENGTH_LONG).show()
+ with(Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)) {
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, ComponentName(context, AdminReceiver::class.java))
+ putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Additional text explaining why this needs to be added.")
+ context.startActivity(this)
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/lock.xml b/app/src/main/res/drawable/lock.xml
new file mode 100644
index 000000000..b18034409
--- /dev/null
+++ b/app/src/main/res/drawable/lock.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/widget_lock.xml b/app/src/main/res/layout/widget_lock.xml
new file mode 100644
index 000000000..34105f7d2
--- /dev/null
+++ b/app/src/main/res/layout/widget_lock.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_lock_screen.xml b/app/src/main/res/mipmap-anydpi-v26/ic_lock_screen.xml
new file mode 100644
index 000000000..3434e95e8
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_lock_screen.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_lock_screen_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_lock_screen_round.xml
new file mode 100644
index 000000000..3434e95e8
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_lock_screen_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_lock_screen.png b/app/src/main/res/mipmap-hdpi/ic_lock_screen.png
new file mode 100644
index 000000000..47ac23260
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_lock_screen.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_lock_screen_foreground.png b/app/src/main/res/mipmap-hdpi/ic_lock_screen_foreground.png
new file mode 100644
index 000000000..42ea38c89
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_lock_screen_foreground.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_lock_screen_round.png b/app/src/main/res/mipmap-hdpi/ic_lock_screen_round.png
new file mode 100644
index 000000000..eb1e3ccb5
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_lock_screen_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_lock_screen.png b/app/src/main/res/mipmap-mdpi/ic_lock_screen.png
new file mode 100644
index 000000000..7215f8bab
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_lock_screen.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_lock_screen_foreground.png b/app/src/main/res/mipmap-mdpi/ic_lock_screen_foreground.png
new file mode 100644
index 000000000..c02e08f9d
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_lock_screen_foreground.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_lock_screen_round.png b/app/src/main/res/mipmap-mdpi/ic_lock_screen_round.png
new file mode 100644
index 000000000..78eaea9c3
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_lock_screen_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_lock_screen.png b/app/src/main/res/mipmap-xhdpi/ic_lock_screen.png
new file mode 100644
index 000000000..9309c1174
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_lock_screen.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_lock_screen_foreground.png b/app/src/main/res/mipmap-xhdpi/ic_lock_screen_foreground.png
new file mode 100644
index 000000000..7bae9c5a3
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_lock_screen_foreground.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_lock_screen_round.png b/app/src/main/res/mipmap-xhdpi/ic_lock_screen_round.png
new file mode 100644
index 000000000..54d4f66df
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_lock_screen_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_lock_screen.png b/app/src/main/res/mipmap-xxhdpi/ic_lock_screen.png
new file mode 100644
index 000000000..5c055ef50
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_lock_screen.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_lock_screen_foreground.png b/app/src/main/res/mipmap-xxhdpi/ic_lock_screen_foreground.png
new file mode 100644
index 000000000..1a913989c
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_lock_screen_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_lock_screen_round.png b/app/src/main/res/mipmap-xxhdpi/ic_lock_screen_round.png
new file mode 100644
index 000000000..c1e0ec2db
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_lock_screen_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_lock_screen.png b/app/src/main/res/mipmap-xxxhdpi/ic_lock_screen.png
new file mode 100644
index 000000000..ec5c51337
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_lock_screen.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_lock_screen_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_lock_screen_foreground.png
new file mode 100644
index 000000000..f24fbcbc1
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_lock_screen_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_lock_screen_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_lock_screen_round.png
new file mode 100644
index 000000000..6121329e6
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_lock_screen_round.png differ
diff --git a/app/src/main/res/values/ic_lock_screen_background.xml b/app/src/main/res/values/ic_lock_screen_background.xml
new file mode 100644
index 000000000..af1f25285
--- /dev/null
+++ b/app/src/main/res/values/ic_lock_screen_background.xml
@@ -0,0 +1,4 @@
+
+
+ #FFFFFF
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d8eccbf1b..793b981ff 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -588,4 +588,7 @@
%1$d Done%1$d Failed%1$d Queued
+ Lock Screen
+ Allows the app to lock the screen of the device.
+ Allows the app to perform device level actions.
\ No newline at end of file
diff --git a/app/src/main/res/xml-v31/widget_lock_provider.xml b/app/src/main/res/xml-v31/widget_lock_provider.xml
new file mode 100644
index 000000000..027465056
--- /dev/null
+++ b/app/src/main/res/xml-v31/widget_lock_provider.xml
@@ -0,0 +1,10 @@
+
diff --git a/app/src/main/res/xml/device_admin_props.xml b/app/src/main/res/xml/device_admin_props.xml
new file mode 100644
index 000000000..43d582639
--- /dev/null
+++ b/app/src/main/res/xml/device_admin_props.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/widget_lock_provider.xml b/app/src/main/res/xml/widget_lock_provider.xml
new file mode 100644
index 000000000..317fa638a
--- /dev/null
+++ b/app/src/main/res/xml/widget_lock_provider.xml
@@ -0,0 +1,8 @@
+
diff --git a/assets/01.jpg b/assets/01.jpg
new file mode 100644
index 000000000..b42632c02
Binary files /dev/null and b/assets/01.jpg differ