implemented status bar with battery, network, volume

This commit is contained in:
Talmid of Levi 2023-12-04 16:22:13 -05:00
parent 48f39281bd
commit 26256593de
18 changed files with 282 additions and 31 deletions

View File

@ -2,12 +2,14 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SYSTEM_EXEMPTED"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SYSTEM_EXEMPTED" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.USE_EXACT_ALARM"/>
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
@ -21,6 +23,7 @@
android:supportsRtl="true"
android:theme="@style/Theme.CatFlipScreen"
tools:targetApi="31">
<receiver
android:name=".MyReceiver"
android:enabled="true"
@ -33,14 +36,13 @@
<service
android:name=".FlipScreenService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="systemExempted"
android:stopWithTask="false"
android:exported="false" />
android:stopWithTask="false" />
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.AppCompat">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View File

@ -26,6 +26,8 @@ class CatFlipScreenApplication : Application() {
companion object {
const val CHANNEL_ID = "autoStartServiceChannel"
const val CHANNEL_NAME = "Auto Start Service Channel"
const val BROADCAST_BATTERY_CHANGED = "BROADCAST_BATTERY_CHANGED"
const val BROADCAST_AUDIO_MODE_CHANGED = "BROADCAST_AUDIO_MODE_CHANGED"
}
}

View File

@ -30,12 +30,12 @@ class FlipScreenService : Service() {
override fun onTaskRemoved(rootIntent: Intent?) {
val restartServiceIntent = Intent(applicationContext, FlipScreenService::class.java).also {
it.setPackage(packageName)
};
}
val restartServicePendingIntent: PendingIntent = PendingIntent.getService(this, 1, restartServiceIntent,
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE);
applicationContext.getSystemService(Context.ALARM_SERVICE);
val alarmService: AlarmManager = applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager;
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePendingIntent);
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE)
applicationContext.getSystemService(Context.ALARM_SERVICE)
val alarmService: AlarmManager = applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePendingIntent)
}
private fun showPresentationScreen() {
@ -59,6 +59,7 @@ class FlipScreenService : Service() {
}
private fun showNotification() {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel(
CatFlipScreenApplication.CHANNEL_ID,

View File

@ -1,11 +1,17 @@
package net.mezimmah.catflipscreen
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.media.AudioManager
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.preference.PreferenceFragmentCompat
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -17,8 +23,34 @@ class MainActivity : AppCompatActivity() {
.replace(R.id.settings, SettingsFragment())
.commit()
}
startService(Intent(this, FlipScreenService::class.java))
startForegroundService(Intent(this, FlipScreenService::class.java))
registerReceivers()
}
private fun registerReceivers() {
val broadCastReceiver = object : BroadcastReceiver() {
override fun onReceive(contxt: Context, intent: Intent) {
when (intent.action) {
Intent.ACTION_POWER_CONNECTED,
Intent.ACTION_POWER_DISCONNECTED,
Intent.ACTION_BATTERY_CHANGED -> {
LocalBroadcastManager.getInstance(contxt)
.sendBroadcast(Intent(CatFlipScreenApplication.BROADCAST_BATTERY_CHANGED))
}
AudioManager.RINGER_MODE_CHANGED_ACTION -> {
LocalBroadcastManager.getInstance(contxt)
.sendBroadcast(Intent(CatFlipScreenApplication.BROADCAST_AUDIO_MODE_CHANGED))
}
}
}
}
this.registerReceiver(broadCastReceiver, IntentFilter(Intent.ACTION_POWER_CONNECTED))
this.registerReceiver(broadCastReceiver, IntentFilter(Intent.ACTION_POWER_DISCONNECTED))
this.registerReceiver(broadCastReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
this.registerReceiver(broadCastReceiver, IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION))
}
class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPreferenceChangeListener {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)

View File

@ -3,13 +3,21 @@ package net.mezimmah.catflipscreen
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.Intent.ACTION_BOOT_COMPLETED
import android.util.Log
class MyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
ACTION_BOOT_COMPLETED -> startFlipScreenService(context)
}
}
private fun startFlipScreenService(context: Context) {
context.startService(Intent(context, FlipScreenService::class.java))
Log.i("Autostart", "started")
}
}

View File

@ -1,16 +1,173 @@
package net.mezimmah.catflipscreen
import android.app.Presentation
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.media.AudioManager
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.BatteryManager
import android.os.Bundle
import android.view.Display
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.localbroadcastmanager.content.LocalBroadcastManager
class PresentationScreen(outerContext: Context?, display: Display?) :
Presentation(outerContext, display) {
private var connectivityManager: ConnectivityManager? = null
private var am: AudioManager? = null
private var batteryTextView: TextView? = null
private var batteryIconView: ImageView? = null
private var networkIconView: ImageView? = null
private var wifiIconView: ImageView? = null
private var audioLevelIconView: ImageView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_screen)
findViews()
getSystemServices()
registerReceivers()
updateBatteryLevel()
updateNetworkConnectivity()
updateAudioMode()
}
private fun findViews() {
batteryTextView = findViewById(R.id.screen_status_bar_battery_level)
batteryIconView = findViewById(R.id.screen_status_bar_battery_icon)
networkIconView = findViewById(R.id.screen_status_bar_network_signal)
wifiIconView = findViewById(R.id.screen_status_bar_wifi_signal)
audioLevelIconView = findViewById(R.id.screen_status_bar_audio_level)
}
private fun getSystemServices() {
am = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager?
connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
}
private fun registerReceivers() {
// Register receiver for Battery Status Update from the main activity
val broadCastReceiver = object : BroadcastReceiver() {
override fun onReceive(contxt: Context, intent: Intent) {
when (intent.action) {
CatFlipScreenApplication.BROADCAST_BATTERY_CHANGED -> {
updateBatteryLevel()
}
CatFlipScreenApplication.BROADCAST_AUDIO_MODE_CHANGED -> {
updateAudioMode()
}
}
}
}
LocalBroadcastManager.getInstance(context)
.registerReceiver(broadCastReceiver, IntentFilter(CatFlipScreenApplication.BROADCAST_BATTERY_CHANGED))
LocalBroadcastManager.getInstance(context)
.registerReceiver(broadCastReceiver, IntentFilter(CatFlipScreenApplication.BROADCAST_AUDIO_MODE_CHANGED))
// Register receiver for the network updates
val networkRequest = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.build()
val networkCallback = object : ConnectivityManager.NetworkCallback() {
// network is available for use
override fun onAvailable(network: Network) {
updateNetworkConnectivity()
super.onAvailable(network)
}
// Network capabilities have changed for the network
override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities
) {
super.onCapabilitiesChanged(network, networkCapabilities)
updateNetworkConnectivity()
}
// lost network connection
override fun onLost(network: Network) {
super.onLost(network)
updateNetworkConnectivity()
}
}
connectivityManager?.requestNetwork(networkRequest, networkCallback)
}
private fun updateBatteryLevel() {
val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
context.registerReceiver(null, ifilter)
}
val status: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) ?: -1
val isCharging: Boolean = status == BatteryManager.BATTERY_STATUS_CHARGING
|| status == BatteryManager.BATTERY_STATUS_FULL
val batteryPct: Int = batteryStatus?.let { intent ->
val level: Int = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
level * 100 / scale
}!!
batteryTextView!!.text = batteryPct.toString()
if (isCharging) {
batteryIconView!!.setImageResource(R.drawable.icons8_battery_50)
} else {
if (batteryPct < 15) {
batteryIconView!!.setImageResource(R.drawable.icons8_empty_battery_50)
} else if (batteryPct < 25) {
batteryIconView!!.setImageResource(R.drawable.icons8_low_battery_50)
} else if (batteryPct < 50) {
batteryIconView!!.setImageResource(R.drawable.icons8_battery_level_50)
} else if (batteryPct < 80) {
batteryIconView!!.setImageResource(R.drawable.icons8_charged_battery_50)
} else {
batteryIconView!!.setImageResource(R.drawable.icons8_full_battery_50)
}
}
}
private fun updateNetworkConnectivity() {
networkIconView?.post { networkIconView?.visibility = View.GONE }
wifiIconView?.post { wifiIconView?.visibility = View.GONE }
if (connectivityManager != null) {
val capabilities =
connectivityManager?.getNetworkCapabilities(connectivityManager?.activeNetwork)
if (capabilities != null) {
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
networkIconView?.post { networkIconView?.visibility = View.VISIBLE }
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
wifiIconView?.post { wifiIconView?.visibility = View.VISIBLE }
}
}
}
}
private fun updateAudioMode() {
when (am!!.ringerMode) {
AudioManager.RINGER_MODE_SILENT -> {
audioLevelIconView?.setImageResource(R.drawable.icons8_no_sound_50)
}
AudioManager.RINGER_MODE_VIBRATE -> {
audioLevelIconView?.setImageResource(R.drawable.icons8_vibration_48)
}
AudioManager.RINGER_MODE_NORMAL -> {
audioLevelIconView?.setImageResource(R.drawable.icons8_sound_50)
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1022 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

View File

@ -5,30 +5,79 @@
android:background="@color/black"
android:orientation="vertical">
<TextView
android:id="@+id/screen_status_bar_text_view"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:textAlignment="center"
android:textColor="@color/white"
android:textSize="14sp" />
<TextView
android:id="@+id/screen_insert_sim_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:text=""
android:textColor="@color/white"
android:textSize="14sp" />
android:layoutDirection="rtl"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:text="@string/status_bar_percentage"
android:textSize="11sp"
android:textColor="@color/white"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/screen_status_bar_battery_level"
android:layout_width="wrap_content"
android:textSize="11sp"
android:textColor="@color/white"
android:layout_height="wrap_content"/>
<ImageView
android:contentDescription="@string/battery_status_icon"
android:id="@+id/screen_status_bar_battery_icon"
android:layout_width="25dp"
android:layout_height="15dp"
android:src="@drawable/icons8_battery_50"
android:layout_marginEnd="-3dp" />
<ImageView
android:contentDescription="@string/network_signal_icon"
android:id="@+id/screen_status_bar_network_signal"
android:layout_width="15dp"
android:src="@drawable/icons8_signal_48"
android:layout_height="12dp"
android:visibility="gone"
android:layout_marginEnd="-5dp"
android:paddingTop="3dp"/>
<ImageView
android:contentDescription="@string/wifi_signal_icon"
android:id="@+id/screen_status_bar_wifi_signal"
android:layout_width="15dp"
android:visibility="gone"
android:src="@drawable/icons8_wifi_50"
android:layout_height="12dp"
android:layout_marginEnd="-5dp"
android:paddingTop="3dp"/>
<ImageView
android:contentDescription="@string/audio_level_icon"
android:id="@+id/screen_status_bar_audio_level"
android:src="@drawable/icons8_vibration_48"
android:layout_width="15dp"
android:layout_height="12dp"
android:layout_marginEnd="-3dp"
android:paddingTop="3dp"/>
</LinearLayout>
<TextClock
android:id="@+id/screen_clock_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:format12Hour="hh:mm EEE, MMMM dd"
android:format12Hour="hh:mm"
android:textAlignment="center"
android:textColor="@color/white"
android:textSize="14sp" />
android:textSize="22sp" />
<TextClock
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:format12Hour="EEE, MMMM dd"
android:textAlignment="center"
android:textColor="@color/white"
android:textSize="11sp" />
</LinearLayout>