Build43
- Added lock screen widget
1
.idea/dictionaries/PC.xml
generated
@@ -47,6 +47,7 @@
|
||||
<w>quickapps</w>
|
||||
<w>română</w>
|
||||
<w>rummler</w>
|
||||
<w>searchbox</w>
|
||||
<w>solarized</w>
|
||||
<w>srikanth</w>
|
||||
<w>stacktraces</w>
|
||||
|
||||
@@ -77,5 +77,8 @@ Low priority features
|
||||
|:-----------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------:|
|
||||
| C | D | E | F |
|
||||
|
||||
## Behind The Scenes
|
||||
|
||||
Designing of interface skeletons for Inure
|
||||

|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ plugins {
|
||||
android {
|
||||
compileSdkVersion 33
|
||||
|
||||
def appVersionCode = 41
|
||||
def appVersionCode = 42
|
||||
def appVersionName = "build_$appVersionCode (alpha)"
|
||||
|
||||
buildFeatures {
|
||||
|
||||
@@ -55,6 +55,10 @@
|
||||
android:label="@string/perm_prepend_to_path"
|
||||
android:protectionLevel="dangerous" />
|
||||
|
||||
<uses-feature
|
||||
android:name="android.software.device_admin"
|
||||
android:required="false" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:hardwareAccelerated="true"
|
||||
@@ -75,7 +79,6 @@
|
||||
android:name=".activities.app.MainActivity"
|
||||
android:configChanges="uiMode"
|
||||
android:exported="true"
|
||||
android:taskAffinity="app.simple.inure"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
@@ -98,6 +101,7 @@
|
||||
android:taskAffinity="app.simple.inure.terminal.Term"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<!--suppress DeprecatedClassUsageInspection -->
|
||||
<activity
|
||||
android:name=".activities.launcher.TerminalLauncher"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation"
|
||||
@@ -569,6 +573,38 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
android:name="app.simple.inure.widgets.LockScreenWidget"
|
||||
android:description="@string/lock_screen_desc"
|
||||
android:exported="false"
|
||||
android:icon="@mipmap/ic_lock_screen"
|
||||
android:label="@string/lock_screen"
|
||||
android:roundIcon="@mipmap/ic_lock_screen_round">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/widget_lock_provider" />
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
android:name="app.simple.inure.receivers.AdminReceiver"
|
||||
android:description="@string/device_admin_desc"
|
||||
android:exported="false"
|
||||
android:label="@string/app_name_full"
|
||||
android:permission="android.permission.BIND_DEVICE_ADMIN">
|
||||
<meta-data
|
||||
android:name="android.app.device_admin"
|
||||
android:resource="@xml/device_admin_props" />
|
||||
<intent-filter>
|
||||
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
|
||||
<action android:name="android.app.action.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED" />
|
||||
<action android:name="android.app.action.ACTION_DEVICE_ADMIN_DISABLED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<meta-data
|
||||
android:name="com.sec.android.support.multiwindow"
|
||||
android:value="true" />
|
||||
|
||||
@@ -17,30 +17,47 @@
|
||||
|
||||
<!-- Write change logs here -->
|
||||
|
||||
<h4>User Interface</h4>
|
||||
<h4>Widgets</h4>
|
||||
|
||||
<ul>
|
||||
<li>Added <i>Music</i> shortcut <i>(on users' request).</i><br>
|
||||
<small>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.</small>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Bug Fixes</h4>
|
||||
|
||||
<ul>
|
||||
<li>Fixed app crashing when data is explicitly restored from cloud after factory reset or
|
||||
setting up a new device.
|
||||
</li>
|
||||
<li>Fixed launching terminal from shortcut launches the app if the app process is active in the
|
||||
memory.
|
||||
</li>
|
||||
<li>Fixed app crashing without any stack trace on many pre Android 13 devices.</li>
|
||||
<li>Fixed navigation bar overlapping issue on some views.</li>
|
||||
<li>Added <i>Lock Screen</i> widget.</li>
|
||||
</ul>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<div class="wrap-collapsible">
|
||||
<input id="build_42" class="toggle" type="checkbox">
|
||||
<label for="build_42" class="lbl-toggle">Build42</label>
|
||||
<div class="collapsible-content">
|
||||
<div class="content-inner">
|
||||
<h4>User Interface</h4>
|
||||
|
||||
<ul>
|
||||
<li>Added <i>Music</i> shortcut <i>(on users' request).</i><br>
|
||||
<small>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.</small>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Bug Fixes</h4>
|
||||
|
||||
<ul>
|
||||
<li>Fixed app crashing when data is explicitly restored from cloud after factory
|
||||
reset or
|
||||
setting up a new device.
|
||||
</li>
|
||||
<li>Fixed launching terminal from shortcut launches the app if the app process is
|
||||
active in the
|
||||
memory.
|
||||
</li>
|
||||
<li>Fixed app crashing without any stack trace on many pre Android 13 devices.</li>
|
||||
<li>Fixed navigation bar overlapping issue on some views.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="wrap-collapsible">
|
||||
<input id="build_41" class="toggle" type="checkbox">
|
||||
<label for="build_41" class="lbl-toggle">Build41</label>
|
||||
|
||||
BIN
app/src/main/ic_lock_screen-playstore.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
@@ -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 -> {
|
||||
|
||||
@@ -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 -> {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
100
app/src/main/java/app/simple/inure/widgets/LockScreenWidget.kt
Normal file
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
9
app/src/main/res/drawable/lock.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?android:attr/colorBackground"
|
||||
android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM9,8L9,6c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v2L9,8z" />
|
||||
</vector>
|
||||
15
app/src/main/res/layout/widget_lock.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/lock_screen"
|
||||
android:layout_width="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@mipmap/ic_lock_screen"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</FrameLayout>
|
||||
5
app/src/main/res/mipmap-anydpi-v26/ic_lock_screen.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_lock_screen_background" />
|
||||
<foreground android:drawable="@mipmap/ic_lock_screen_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_lock_screen_background" />
|
||||
<foreground android:drawable="@mipmap/ic_lock_screen_foreground" />
|
||||
</adaptive-icon>
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_lock_screen.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_lock_screen_foreground.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_lock_screen_round.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_lock_screen.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_lock_screen_foreground.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_lock_screen_round.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_lock_screen.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_lock_screen_foreground.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_lock_screen_round.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_lock_screen.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_lock_screen_foreground.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_lock_screen_round.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_lock_screen.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_lock_screen_foreground.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_lock_screen_round.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
4
app/src/main/res/values/ic_lock_screen_background.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_lock_screen_background">#FFFFFF</color>
|
||||
</resources>
|
||||
@@ -588,4 +588,7 @@
|
||||
<string name="count_done">%1$d Done</string>
|
||||
<string name="count_failed">%1$d Failed</string>
|
||||
<string name="count_queued">%1$d Queued</string>
|
||||
<string name="lock_screen">Lock Screen</string>
|
||||
<string name="lock_screen_desc">Allows the app to lock the screen of the device.</string>
|
||||
<string name="device_admin_desc">Allows the app to perform device level actions.</string>
|
||||
</resources>
|
||||
10
app/src/main/res/xml-v31/widget_lock_provider.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:description="@string/lock_screen_desc"
|
||||
android:initialLayout="@layout/widget_lock"
|
||||
android:minWidth="40dp"
|
||||
android:minHeight="40dp"
|
||||
android:previewImage="@mipmap/ic_lock_screen"
|
||||
android:resizeMode="horizontal|vertical"
|
||||
android:targetCellWidth="1"
|
||||
android:targetCellHeight="1"
|
||||
android:widgetCategory="home_screen|keyguard|searchbox" />
|
||||
6
app/src/main/res/xml/device_admin_props.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<device-admin>
|
||||
<uses-policies>
|
||||
<force-lock />
|
||||
</uses-policies>
|
||||
</device-admin>
|
||||
8
app/src/main/res/xml/widget_lock_provider.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:description="@string/lock_screen_desc"
|
||||
android:initialLayout="@layout/widget_lock"
|
||||
android:minWidth="40dp"
|
||||
android:minHeight="40dp"
|
||||
android:previewImage="@mipmap/ic_lock_screen"
|
||||
android:resizeMode="horizontal|vertical"
|
||||
android:widgetCategory="home_screen|keyguard|searchbox" />
|
||||
BIN
assets/01.jpg
Normal file
|
After Width: | Height: | Size: 1.6 MiB |