diff --git a/.idea/dictionaries/PC.xml b/.idea/dictionaries/PC.xml index 430d0985c..15e1b09f1 100644 --- a/.idea/dictionaries/PC.xml +++ b/.idea/dictionaries/PC.xml @@ -47,6 +47,7 @@ quickapps română rummler + searchbox solarized srikanth stacktraces diff --git a/README.md b/README.md index 0f696bdbc..77cdb5db4 100644 --- a/README.md +++ b/README.md @@ -77,5 +77,8 @@ Low priority features |:-----------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------:| | C | D | E | F | +## Behind The Scenes +Designing of interface skeletons for Inure +![01](./assets/01.jpg) diff --git a/app/build.gradle b/app/build.gradle index c883c87e2..5724ba898 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ plugins { android { compileSdkVersion 33 - def appVersionCode = 41 + def appVersionCode = 42 def appVersionName = "build_$appVersionCode (alpha)" buildFeatures { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 838ae3606..090293f3d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -55,6 +55,10 @@ android:label="@string/perm_prepend_to_path" android:protectionLevel="dangerous" /> + + @@ -98,6 +101,7 @@ android:taskAffinity="app.simple.inure.terminal.Term" android:windowSoftInputMode="adjustResize" /> + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/html/changelogs.html b/app/src/main/assets/html/changelogs.html index 6e13ca2fc..15917bc0f 100644 --- a/app/src/main/assets/html/changelogs.html +++ b/app/src/main/assets/html/changelogs.html @@ -17,30 +17,47 @@ -

User Interface

+

Widgets

    -
  • 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