added incoming call showing on the external screen

This commit is contained in:
Talmid of Levi 2024-02-07 11:51:58 -05:00
parent 180c2b8cf6
commit bae2e134d3
21 changed files with 153 additions and 24 deletions

10
.idea/deploymentTargetDropDown.xml generated Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<value>
<entry key="app">
<State />
</entry>
</value>
</component>
</project>

10
.idea/migrations.xml generated Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

Binary file not shown.

View File

@ -4,6 +4,14 @@ plugins {
}
android {
signingConfigs {
getByName("debug") {
storeFile = file("/home/talmid/Downloads/keystore/platform.keystore")
storePassword = "password"
keyAlias = "platform"
keyPassword = "password"
}
}
namespace = "net.mezimmah.catflipscreen"
compileSdk = 34
@ -12,7 +20,7 @@ android {
minSdk = 30
targetSdk = 34
versionCode = 1
versionName = "1.0"
versionName = "1.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
@ -27,6 +35,7 @@ android {
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
signingConfig = signingConfigs.getByName("debug")
}
}
compileOptions {
@ -52,8 +61,8 @@ android {
dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.activity:activity-compose:1.8.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
implementation("androidx.activity:activity-compose:1.8.2")
implementation(platform("androidx.compose:compose-bom:2023.03.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
@ -61,7 +70,7 @@ dependencies {
implementation("androidx.compose.material3:material3")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.preference:preference-ktx:1.2.1")
implementation("com.google.android.material:material:1.10.0")
implementation("com.google.android.material:material:1.11.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")

Binary file not shown.

View File

@ -12,7 +12,7 @@
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "1.0",
"versionName": "1.1",
"outputFile": "app-release.apk"
}
],

View File

@ -11,6 +11,9 @@
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<application
android:name=".CatFlipScreenApplication"
@ -30,6 +33,7 @@
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
@ -44,12 +48,10 @@
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:showOnLockScreen="true"
android:theme="@style/Theme.AppCompat">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

View File

@ -28,6 +28,7 @@ class CatFlipScreenApplication : Application() {
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"
const val BROADCAST_TELEPHONY_ACTION = "BROADCAST_TELEPHONY_ACTION"
}
}

View File

@ -18,11 +18,11 @@ import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.localbroadcastmanager.content.LocalBroadcastManager
class FlipScreenService : Service() {
override fun onBind(intent: Intent): IBinder? {
TODO("Return the communication channel to the service.")
@Suppress("UNREACHABLE_CODE")
return null
}
@ -67,9 +67,9 @@ class FlipScreenService : Service() {
0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
)
val notification: Notification = NotificationCompat.Builder(this, CatFlipScreenApplication.CHANNEL_ID)
.setContentTitle("Auto Start Service")
.setContentTitle("External Screen")
.setContentText(input)
.setSmallIcon(android.R.drawable.ic_dialog_alert)
.setSmallIcon(R.drawable.icons8_phone_50)
.setContentIntent(pendingIntent)
.build()
val mNotificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
@ -109,8 +109,7 @@ class FlipScreenService : Service() {
} catch (e: Exception) {
Log.w(
"StatusBar",
"Couldn't show presentation! Display was removed in the meantime.",
e
"Couldn't show presentation! Display was removed in the meantime.", e
)
}
}

View File

@ -2,8 +2,11 @@ package net.mezimmah.catflipscreen
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.preference.PreferenceFragmentCompat
@ -21,7 +24,27 @@ class MainActivity : AppCompatActivity() {
startForegroundService(Intent(this, FlipScreenService::class.java))
}
override fun onResume() {
super.onResume()
askForPermission(android.Manifest.permission.READ_PHONE_STATE)
askForPermission(android.Manifest.permission.READ_CALL_LOG)
}
private fun askForPermission(permission: String) {
@Suppress("DEPRECATED_IDENTITY_EQUALS")
if (ContextCompat.checkSelfPermission(this@MainActivity,
permission) !==
PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this@MainActivity,
permission)) {
ActivityCompat.requestPermissions(this@MainActivity,
arrayOf(permission), 1)
} else {
ActivityCompat.requestPermissions(this@MainActivity,
arrayOf(permission), 1)
}
}
}
class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPreferenceChangeListener {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
@ -36,7 +59,5 @@ class MainActivity : AppCompatActivity() {
preferenceScreen.sharedPreferences
?.registerOnSharedPreferenceChangeListener(this)
}
}
}

View File

@ -4,14 +4,32 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.Intent.ACTION_BOOT_COMPLETED
import android.telephony.TelephonyManager
import android.util.Log
import androidx.localbroadcastmanager.content.LocalBroadcastManager
class MyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
ACTION_BOOT_COMPLETED -> startFlipScreenService(context)
if (intent.action.equals(ACTION_BOOT_COMPLETED)) {
startFlipScreenService(context)
return
}
val state = intent.getStringExtra(TelephonyManager.EXTRA_STATE)
when (state) {
TelephonyManager.EXTRA_STATE_RINGING -> {
val i = Intent(CatFlipScreenApplication.BROADCAST_TELEPHONY_ACTION)
@Suppress("DEPRECATION")
i.putExtra("number", intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER))
LocalBroadcastManager.getInstance(context)
.sendBroadcast(i)
}
TelephonyManager.EXTRA_STATE_IDLE -> {
val i = Intent(CatFlipScreenApplication.BROADCAST_TELEPHONY_ACTION)
i.putExtra("number", "")
LocalBroadcastManager.getInstance(context)
.sendBroadcast(i)
}
}
}

View File

@ -3,6 +3,8 @@ package net.mezimmah.catflipscreen
import android.app.Presentation
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Context.AUDIO_SERVICE
import android.content.Context.CONNECTIVITY_SERVICE
import android.content.Intent
import android.content.IntentFilter
import android.media.AudioManager
@ -15,6 +17,7 @@ import android.os.Bundle
import android.view.Display
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.localbroadcastmanager.content.LocalBroadcastManager
@ -29,6 +32,9 @@ class PresentationScreen(outerContext: Context?, display: Display?) :
private var networkIconView: ImageView? = null
private var wifiIconView: ImageView? = null
private var audioLevelIconView: ImageView? = null
private var missedCallsIconView: ImageView? = null
private var telephonyCalling: TextView? = null
private var telephonyLayout: LinearLayout? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -52,12 +58,15 @@ class PresentationScreen(outerContext: Context?, display: Display?) :
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)
telephonyCalling = findViewById(R.id.screen_telephony_number)
telephonyLayout = findViewById(R.id.screen_telephony_calling_layout)
missedCallsIconView = findViewById(R.id.screen_status_bar_missed_calls)
}
private fun getSystemServices() {
am = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager?
am = context.getSystemService(AUDIO_SERVICE) as AudioManager?
connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
}
private fun registerReceivers() {
@ -71,6 +80,9 @@ class PresentationScreen(outerContext: Context?, display: Display?) :
CatFlipScreenApplication.BROADCAST_AUDIO_MODE_CHANGED -> {
updateAudioMode()
}
CatFlipScreenApplication.BROADCAST_TELEPHONY_ACTION -> {
updateCallStatus(intent)
}
}
}
}
@ -78,6 +90,8 @@ class PresentationScreen(outerContext: Context?, display: Display?) :
.registerReceiver(broadCastReceiver, IntentFilter(CatFlipScreenApplication.BROADCAST_BATTERY_CHANGED))
LocalBroadcastManager.getInstance(context)
.registerReceiver(broadCastReceiver, IntentFilter(CatFlipScreenApplication.BROADCAST_AUDIO_MODE_CHANGED))
LocalBroadcastManager.getInstance(context)
.registerReceiver(broadCastReceiver, IntentFilter(CatFlipScreenApplication.BROADCAST_TELEPHONY_ACTION))
// Register receiver for the network updates
val networkRequest = NetworkRequest.Builder()
@ -170,4 +184,10 @@ class PresentationScreen(outerContext: Context?, display: Display?) :
}
}
}
private fun updateCallStatus(intent: Intent) {
val number = intent.getStringExtra("number")
telephonyCalling?.text = number
telephonyLayout?.visibility = if (number.isNullOrBlank()) View.INVISIBLE else View.VISIBLE
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 920 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 B

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="96dp"
android:layout_height="96dp"
android:background="@color/black"
@ -61,6 +62,15 @@
android:layout_marginRight="-3dp"
android:paddingTop="3dp"/>
<ImageView
android:contentDescription="@string/audio_level_icon"
android:id="@+id/screen_status_bar_missed_calls"
android:src="@drawable/icons8_missed_call_64"
android:layout_width="15dp"
android:layout_height="12dp"
android:visibility="invisible"
android:layout_marginRight="-3dp"
android:paddingTop="3dp"/>
</LinearLayout>
@ -80,4 +90,31 @@
android:textColor="@color/white"
android:textSize="10sp" />
<LinearLayout
android:id="@+id/screen_telephony_calling_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="5dp"
android:visibility="invisible"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_gravity="center"
android:contentDescription="@string/app_name"
android:src="@drawable/icons8_incoming_call_50" />
<TextView
android:id="@+id/screen_telephony_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="textStart"
android:textColor="@color/white"
android:textSize="10sp" />
</LinearLayout>
</LinearLayout>

View File

@ -5,5 +5,6 @@
<FrameLayout
android:id="@+id/settings"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent" >
</FrameLayout>
</LinearLayout>

View File

@ -21,6 +21,7 @@
<string name="enable_external_display">Turn on your external screen, this will restart your phone</string>
<string name="status_bar_percentage">%</string>
<string name="audio_level_icon">Audio Level Icon</string>
<string name="missed_calls_icon">Missed Calls Icon</string>
<string name="wifi_signal_icon">Wifi Signal Icon</string>
<string name="network_signal_icon">Network Signal Icon</string>
<string name="battery_status_icon">Battery Status Icon</string>

View File

@ -21,7 +21,7 @@
<Preference
app:selectable="false"
app:enabled="true"
app:title="Cat Flip Screen"
app:summary="This app makes the external screen to show the clock, batter, sound profile and connectivity status." />
app:title=""
app:summary="In order for this app to work properly please enable all permissions in the app settings." />
</PreferenceScreen>

View File

@ -1,5 +1,5 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.application") version "8.1.4" apply false
id("com.android.application") version "8.2.2" apply false
id("org.jetbrains.kotlin.android") version "1.8.10" apply false
}

View File

@ -1,6 +1,6 @@
#Wed Nov 22 10:46:25 EST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists