universal7885: Remove FMRadio
|
|
@ -1,18 +0,0 @@
|
||||||
android_app {
|
|
||||||
name: "CameraLightSensor",
|
|
||||||
srcs: [
|
|
||||||
"src/**/*.kt",
|
|
||||||
"src/**/I*.aidl",
|
|
||||||
],
|
|
||||||
platform_apis: true,
|
|
||||||
privileged: true,
|
|
||||||
certificate: "platform",
|
|
||||||
static_libs: ["androidx.core_core"],
|
|
||||||
required: ["privapp_whitelist_com.eurekateam.cameralightsensor.xml"],
|
|
||||||
}
|
|
||||||
|
|
||||||
prebuilt_etc {
|
|
||||||
name: "privapp_whitelist_com.eurekateam.cameralightsensor.xml",
|
|
||||||
src: "privapp_whitelist_com.eurekateam.cameralightsensor.xml",
|
|
||||||
sub_dir: "permissions",
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.eurekateam.cameralightsensor" android:sharedUserId="android.uid.system">
|
|
||||||
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
|
|
||||||
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
|
|
||||||
<uses-permission android:name="android.permission.CAMERA"/>
|
|
||||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
|
||||||
<uses-permission android:name="android.permission.CAMERA_OPEN_CLOSE_LISTENER"/>
|
|
||||||
<uses-feature android:name="android.hardware.camera"/>
|
|
||||||
<uses-feature android:name="android.hardware.camera2.full"/>
|
|
||||||
<uses-feature android:name="android.hardware.camera.autofocus"/>
|
|
||||||
<protected-broadcast android:name="com.android.systemui.doze.pulse"/>
|
|
||||||
<application android:allowBackup="true" android:label="@string/app_name" android:persistent="true">
|
|
||||||
<receiver android:name=".BootReceiver" android:defaultToDeviceProtectedStorage="true" android:directBootAware="true" android:enabled="true" android:exported="true">
|
|
||||||
<intent-filter android:priority="1000">
|
|
||||||
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
|
||||||
<category android:name="android.intent.category.DEFAULT"/>
|
|
||||||
</intent-filter>
|
|
||||||
</receiver>
|
|
||||||
<service android:name=".CameraLightSensorService" android:exported="true" android:foregroundServiceType="camera">
|
|
||||||
<intent-filter android:priority="1000">
|
|
||||||
<action android:name="android.intent.action.SCREEN_OFF"/>
|
|
||||||
<action android:name="android.intent.action.USER_PRESENT"/>
|
|
||||||
</intent-filter>
|
|
||||||
</service>
|
|
||||||
</application>
|
|
||||||
</manifest>
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
<!--
|
|
||||||
Copyright (C) 2021 Eureka Team
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<permissions>
|
|
||||||
<privapp-permissions package="com.eurekateam.cameralightsensor">
|
|
||||||
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
|
|
||||||
</privapp-permissions>
|
|
||||||
</permissions>
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
<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:color/black" android:pathData="M20,8.69L20,4h-4.69L12,0.69 8.69,4L4,4v4.69L0.69,12 4,15.31L4,20h4.69L12,23.31 15.31,20L20,20v-4.69L23.31,12 20,8.69zM18,14.48L18,18h-3.52L12,20.48 9.52,18L6,18v-3.52L3.52,12 6,9.52L6,6h3.52L12,3.52 14.48,6L18,6v3.52L20.48,12 18,14.48zM12,17c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5v10z"/>
|
|
||||||
</vector>
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
<resources>
|
|
||||||
<string name="app_name">CameraLightSensor</string>
|
|
||||||
</resources>
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
// IAutoBrightness.aidl - Copied from camera app
|
|
||||||
package com.eurekateam.camera;
|
|
||||||
|
|
||||||
interface IAutoBrightness {
|
|
||||||
boolean CameraIsFree();
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
package com.eurekateam.cameralightsensor
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
|
|
||||||
class BootReceiver : BroadcastReceiver() {
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
|
||||||
if (intent.action.equals(Intent.ACTION_BOOT_COMPLETED, ignoreCase = true)) {
|
|
||||||
val i = Intent(context, CameraLightSensorService::class.java)
|
|
||||||
context.startForegroundService(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,350 +0,0 @@
|
||||||
package com.eurekateam.cameralightsensor
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.*
|
|
||||||
import android.content.*
|
|
||||||
import android.content.pm.ServiceInfo
|
|
||||||
import android.database.ContentObserver
|
|
||||||
import android.graphics.Bitmap
|
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.ImageFormat
|
|
||||||
import android.hardware.camera2.*
|
|
||||||
import android.hardware.camera2.params.OutputConfiguration
|
|
||||||
import android.hardware.camera2.params.SessionConfiguration
|
|
||||||
import android.media.Image
|
|
||||||
import android.media.ImageReader
|
|
||||||
import android.os.*
|
|
||||||
import android.provider.Settings
|
|
||||||
import android.provider.Settings.SettingNotFoundException
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.core.app.NotificationCompat
|
|
||||||
import com.eurekateam.camera.IAutoBrightness
|
|
||||||
import java.util.concurrent.Executors
|
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
class CameraLightSensorService : Service() {
|
|
||||||
private lateinit var screenStateFilter: IntentFilter
|
|
||||||
private lateinit var mContext: Context
|
|
||||||
private lateinit var cameraDevice: CameraDevice
|
|
||||||
private lateinit var mSession: CameraCaptureSession
|
|
||||||
private val manager: CameraManager by lazy {
|
|
||||||
getSystemService(CAMERA_SERVICE) as CameraManager
|
|
||||||
}
|
|
||||||
private lateinit var mCameraHandler: Handler
|
|
||||||
private val mExecutor = Executors.newSingleThreadExecutor()
|
|
||||||
private fun pushNotification(): Notification {
|
|
||||||
val nm = mContext.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
val channel = NotificationChannel(
|
|
||||||
mContext.packageName,
|
|
||||||
"CameraLightSensor",
|
|
||||||
NotificationManager.IMPORTANCE_NONE
|
|
||||||
)
|
|
||||||
channel.isBlockable = true
|
|
||||||
nm.createNotificationChannel(channel)
|
|
||||||
val builder = NotificationCompat.Builder(mContext, mContext.packageName)
|
|
||||||
val notificationIntent = Intent(mContext, CameraLightSensorService::class.java)
|
|
||||||
val contentIntent = PendingIntent.getActivity(
|
|
||||||
mContext,
|
|
||||||
50,
|
|
||||||
notificationIntent,
|
|
||||||
PendingIntent.FLAG_IMMUTABLE
|
|
||||||
)
|
|
||||||
|
|
||||||
builder.setContentIntent(contentIntent)
|
|
||||||
builder.setSmallIcon(R.drawable.ic_brightness)
|
|
||||||
builder.setContentTitle("Camera Light Sensor Service")
|
|
||||||
builder.setChannelId(mContext.packageName)
|
|
||||||
return builder.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
if (DEBUG) Log.d(TAG, "Destroying service")
|
|
||||||
if (mRegistered) contentResolver!!.unregisterContentObserver(mSettingsObserver)
|
|
||||||
mRegistered = false
|
|
||||||
imageReader.close()
|
|
||||||
stopForeground(true)
|
|
||||||
unbindService(mConnection)
|
|
||||||
super.onDestroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBind(intent: Intent): IBinder? {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private var mIAutoBrightness: IAutoBrightness? = null
|
|
||||||
|
|
||||||
private val mConnection = object : ServiceConnection {
|
|
||||||
override fun onServiceConnected(p0: ComponentName?, service: IBinder?) {
|
|
||||||
mIAutoBrightness = IAutoBrightness.Stub.asInterface(service)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onServiceDisconnected(p0: ComponentName?) {
|
|
||||||
mIAutoBrightness = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val mScreenStateReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
|
||||||
if (intent.action == Intent.ACTION_USER_PRESENT) {
|
|
||||||
if (mPoolExecutor == null) {
|
|
||||||
mPoolExecutor = ScheduledThreadPoolExecutor(4)
|
|
||||||
mPoolExecutor!!.scheduleWithFixedDelay(
|
|
||||||
mScheduler,
|
|
||||||
0,
|
|
||||||
2,
|
|
||||||
TimeUnit.SECONDS
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (intent.action == Intent.ACTION_SCREEN_OFF) {
|
|
||||||
if (mPoolExecutor != null) {
|
|
||||||
mPoolExecutor!!.shutdown()
|
|
||||||
mPoolExecutor = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private val mScheduler = Runnable { readyCamera() }
|
|
||||||
|
|
||||||
// Make a listener for settings
|
|
||||||
private var mSettingsObserver: ContentObserver =
|
|
||||||
object : ContentObserver(Handler(Looper.getMainLooper())) {
|
|
||||||
override fun onChange(selfChange: Boolean) {
|
|
||||||
super.onChange(selfChange)
|
|
||||||
Log.i(TAG, "observer: Brightness Settings Changed")
|
|
||||||
try {
|
|
||||||
if (Settings.System.getInt(
|
|
||||||
contentResolver,
|
|
||||||
Settings.System.SCREEN_BRIGHTNESS_MODE
|
|
||||||
)
|
|
||||||
== Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
|
|
||||||
) {
|
|
||||||
registerReceiver(mScreenStateReceiver, screenStateFilter)
|
|
||||||
mRegistered = true
|
|
||||||
if (mPoolExecutor == null) {
|
|
||||||
mPoolExecutor = ScheduledThreadPoolExecutor(4)
|
|
||||||
mPoolExecutor!!.scheduleWithFixedDelay(
|
|
||||||
mScheduler,
|
|
||||||
0,
|
|
||||||
2,
|
|
||||||
TimeUnit.SECONDS
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (mRegistered) unregisterReceiver(mScreenStateReceiver)
|
|
||||||
mRegistered = false
|
|
||||||
if (mPoolExecutor != null) {
|
|
||||||
mPoolExecutor!!.shutdown()
|
|
||||||
mPoolExecutor = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: SettingNotFoundException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun deliverSelfNotifications(): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private var cameraStateCallback: CameraDevice.StateCallback =
|
|
||||||
object : CameraDevice.StateCallback() {
|
|
||||||
override fun onOpened(camera: CameraDevice) {
|
|
||||||
Log.d(TAG, "CameraDevice.StateCallback onOpened")
|
|
||||||
cameraDevice = camera
|
|
||||||
actOnReadyCameraDevice()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDisconnected(camera: CameraDevice) {
|
|
||||||
Log.w(TAG, "CameraDevice.StateCallback onDisconnected")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(camera: CameraDevice, error: Int) {
|
|
||||||
Log.e(TAG, "CameraDevice.StateCallback onError $error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private var sessionStateCallback: CameraCaptureSession.StateCallback =
|
|
||||||
object : CameraCaptureSession.StateCallback() {
|
|
||||||
override fun onReady(session: CameraCaptureSession) {
|
|
||||||
this@CameraLightSensorService.mSession = session
|
|
||||||
try {
|
|
||||||
if (createCaptureRequest() == null) return
|
|
||||||
try {
|
|
||||||
session.capture(createCaptureRequest()!!, null, mCameraHandler)
|
|
||||||
} catch (e: CameraAccessException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
} catch (e: IllegalStateException) {
|
|
||||||
Log.w(TAG, "onReady: Session is NULL")
|
|
||||||
}
|
|
||||||
cameraDevice.close()
|
|
||||||
session.close()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e(TAG, "Camera is in use")
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
override fun onConfigured(session: CameraCaptureSession) {}
|
|
||||||
override fun onConfigureFailed(session: CameraCaptureSession) {}
|
|
||||||
}
|
|
||||||
private var onImageAvailableListener =
|
|
||||||
ImageReader.OnImageAvailableListener { reader: ImageReader ->
|
|
||||||
if (DEBUG) Log.d(TAG, "onImageAvailable: Capturing")
|
|
||||||
val img = reader.acquireLatestImage()
|
|
||||||
if (img != null) {
|
|
||||||
try {
|
|
||||||
processImage(img)
|
|
||||||
} catch (e: SettingNotFoundException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
} catch (e: InterruptedException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
img.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
|
||||||
fun readyCamera() {
|
|
||||||
if (mIAutoBrightness != null) {
|
|
||||||
if (!mIAutoBrightness!!.CameraIsFree()) return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
manager.openCamera("1", cameraStateCallback, mCameraHandler)
|
|
||||||
imageReader.setOnImageAvailableListener(onImageAvailableListener, mCameraHandler)
|
|
||||||
if (DEBUG) Log.d(TAG, "imageReader created")
|
|
||||||
} catch (e: CameraAccessException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
|
||||||
val mCameraHandlerThread = HandlerThread("CameraLightSensor")
|
|
||||||
mCameraHandlerThread.start()
|
|
||||||
mCameraHandler = Handler(mCameraHandlerThread.looper)
|
|
||||||
mContext = this
|
|
||||||
bindService(
|
|
||||||
Intent(mContext, IAutoBrightness::class.java).apply {
|
|
||||||
setClassName("com.eurekateam.camera", "com.eurekateam.camera.CameraAIDL")
|
|
||||||
},
|
|
||||||
mConnection,
|
|
||||||
Context.BIND_AUTO_CREATE
|
|
||||||
)
|
|
||||||
@Suppress("SameParameterValue")
|
|
||||||
startForeground(50, pushNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA)
|
|
||||||
mRegistered = false
|
|
||||||
screenStateFilter = IntentFilter(Intent.ACTION_USER_PRESENT)
|
|
||||||
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF)
|
|
||||||
try {
|
|
||||||
if (Settings.System.getInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS_MODE)
|
|
||||||
== Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
|
|
||||||
) {
|
|
||||||
registerReceiver(mScreenStateReceiver, screenStateFilter)
|
|
||||||
mRegistered = true
|
|
||||||
}
|
|
||||||
} catch (e: SettingNotFoundException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
val setting = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE)
|
|
||||||
contentResolver?.registerContentObserver(setting, false, mSettingsObserver)
|
|
||||||
if (DEBUG) Log.d(TAG, "onStartCommand flags $flags startId $startId")
|
|
||||||
startForeground(50, pushNotification())
|
|
||||||
return START_STICKY
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate() {
|
|
||||||
if (DEBUG) Log.d(TAG, "onCreate service")
|
|
||||||
mContext = this
|
|
||||||
startForeground(50, pushNotification())
|
|
||||||
super.onCreate()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun actOnReadyCameraDevice() {
|
|
||||||
try {
|
|
||||||
cameraDevice.createCaptureSession(
|
|
||||||
SessionConfiguration(
|
|
||||||
SessionConfiguration.SESSION_REGULAR,
|
|
||||||
listOf(OutputConfiguration(imageReader.surface)),
|
|
||||||
mExecutor,
|
|
||||||
sessionStateCallback
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} catch (e: CameraAccessException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(SettingNotFoundException::class, InterruptedException::class)
|
|
||||||
private fun processImage(image: Image) {
|
|
||||||
val buffer = image.planes[0].buffer
|
|
||||||
val bytes = ByteArray(buffer.capacity())
|
|
||||||
buffer[bytes]
|
|
||||||
val bitmapImage = BitmapFactory.decodeByteArray(bytes, 0, bytes.size, null)
|
|
||||||
val brightness = calculateBrightnessEstimate(bitmapImage, 2)
|
|
||||||
adjustBrightness(brightness)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createCaptureRequest(): CaptureRequest? {
|
|
||||||
return try {
|
|
||||||
val builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD)
|
|
||||||
builder.addTarget(imageReader.surface)
|
|
||||||
builder.build()
|
|
||||||
} catch (e: CameraAccessException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private fun calculateBrightnessEstimate(bitmap: Bitmap, pixelSpacing: Int): Int {
|
|
||||||
var r = 0
|
|
||||||
var g = 0
|
|
||||||
var b = 0
|
|
||||||
val height = bitmap.height
|
|
||||||
val width = bitmap.width
|
|
||||||
var n = 0
|
|
||||||
val pixels = IntArray(width * height)
|
|
||||||
bitmap.getPixels(pixels, 0, width, 0, 0, width, height)
|
|
||||||
var i = 0
|
|
||||||
while (i < pixels.size) {
|
|
||||||
val color = pixels[i]
|
|
||||||
r += Color.red(color)
|
|
||||||
g += Color.green(color)
|
|
||||||
b += Color.blue(color)
|
|
||||||
n++
|
|
||||||
i += pixelSpacing
|
|
||||||
}
|
|
||||||
return (r + g + b) / (n * 3)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(SettingNotFoundException::class)
|
|
||||||
private fun adjustBrightness(brightness: Int) {
|
|
||||||
if (DEBUG) Log.i(TAG, "AdjustBrightness: Received Brightness Value $brightness")
|
|
||||||
val oldbrightness =
|
|
||||||
Settings.System.getInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS)
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.i(
|
|
||||||
TAG,
|
|
||||||
"AdjustBrightness: OldVal = " + oldbrightness + " NewVal = " +
|
|
||||||
brightness + " Adjusting.."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
var newbrightness = 2 * brightness - oldbrightness
|
|
||||||
if (newbrightness > 255) {
|
|
||||||
newbrightness = 255
|
|
||||||
} else if (newbrightness < 0) {
|
|
||||||
newbrightness = 0
|
|
||||||
}
|
|
||||||
Settings.System.putInt(
|
|
||||||
contentResolver,
|
|
||||||
Settings.System.SCREEN_BRIGHTNESS,
|
|
||||||
newbrightness
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val imageReader =
|
|
||||||
ImageReader.newInstance(50, 50, ImageFormat.JPEG, 2 /* images buffered */)
|
|
||||||
val TAG: String = CameraLightSensorService::class.java.simpleName
|
|
||||||
const val DEBUG = false
|
|
||||||
private var mPoolExecutor: ScheduledThreadPoolExecutor? = null
|
|
||||||
private var mRegistered = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
android_app {
|
|
||||||
name: "FMRadio",
|
|
||||||
srcs: [
|
|
||||||
"src/**/*.kt",
|
|
||||||
],
|
|
||||||
platform_apis: true,
|
|
||||||
certificate: "platform",
|
|
||||||
static_libs: [
|
|
||||||
"androidx.core_core",
|
|
||||||
"androidx.appcompat_appcompat",
|
|
||||||
"androidx.preference_preference",
|
|
||||||
"com.google.android.material_stable",
|
|
||||||
"androidx.transition_transition",
|
|
||||||
"androidx.coordinatorlayout_coordinatorlayout",
|
|
||||||
"vendor.eureka.hardware.fmradio-V3-java",
|
|
||||||
],
|
|
||||||
required: [
|
|
||||||
"vendor.eureka.hardware.fmradio-service",
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:sharedUserId="android.uid.system" package="com.eurekateam.fmradio">
|
|
||||||
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/Theme.Material3.DayNight.NoActionBar">
|
|
||||||
<activity android:name=".MainActivity" android:exported="true">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
|
||||||
<action android:name="android.intent.action.HEADSET_PLUG"/>
|
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<service android:name=".FMRadioService" android:exported="false">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="com.eurekateam.fmradio.STOP"/>
|
|
||||||
<category android:name="android.intent.category.DEFAULT"/>
|
|
||||||
</intent-filter>
|
|
||||||
</service>
|
|
||||||
</application>
|
|
||||||
</manifest>
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
android_library_import {
|
|
||||||
name: "com.google.android.material_stable",
|
|
||||||
aars: ["material-1.6.0.aar"],
|
|
||||||
sdk_version: "current",
|
|
||||||
min_sdk_version: "21",
|
|
||||||
static_libs: [
|
|
||||||
"androidx.annotation_annotation",
|
|
||||||
"androidx.appcompat_appcompat",
|
|
||||||
"androidx.cardview_cardview",
|
|
||||||
"androidx.coordinatorlayout_coordinatorlayout",
|
|
||||||
"androidx-constraintlayout_constraintlayout",
|
|
||||||
"androidx.core_core",
|
|
||||||
"androidx.dynamicanimation_dynamicanimation",
|
|
||||||
"androidx.annotation_annotation-experimental",
|
|
||||||
"androidx.fragment_fragment",
|
|
||||||
"androidx.lifecycle_lifecycle-runtime",
|
|
||||||
"androidx.recyclerview_recyclerview",
|
|
||||||
"androidx.transition_transition",
|
|
||||||
"androidx.vectordrawable_vectordrawable",
|
|
||||||
"androidx.viewpager2_viewpager2",
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 228 B |
|
Before Width: | Height: | Size: 296 B |
|
Before Width: | Height: | Size: 209 B |
|
Before Width: | Height: | Size: 289 B |
|
Before Width: | Height: | Size: 506 B |
|
Before Width: | Height: | Size: 206 B |
|
Before Width: | Height: | Size: 126 B |
|
Before Width: | Height: | Size: 349 B |
|
Before Width: | Height: | Size: 123 B |
|
Before Width: | Height: | Size: 225 B |
|
Before Width: | Height: | Size: 641 B |
|
Before Width: | Height: | Size: 466 B |
|
Before Width: | Height: | Size: 515 B |
|
Before Width: | Height: | Size: 294 B |
|
Before Width: | Height: | Size: 794 B |
|
Before Width: | Height: | Size: 543 B |
|
Before Width: | Height: | Size: 211 B |
|
Before Width: | Height: | Size: 425 B |
|
Before Width: | Height: | Size: 180 B |
|
Before Width: | Height: | Size: 226 B |
|
Before Width: | Height: | Size: 162 B |
|
Before Width: | Height: | Size: 226 B |
|
Before Width: | Height: | Size: 354 B |
|
Before Width: | Height: | Size: 161 B |
|
Before Width: | Height: | Size: 116 B |
|
Before Width: | Height: | Size: 245 B |
|
Before Width: | Height: | Size: 104 B |
|
Before Width: | Height: | Size: 183 B |
|
Before Width: | Height: | Size: 441 B |
|
Before Width: | Height: | Size: 341 B |
|
Before Width: | Height: | Size: 363 B |
|
Before Width: | Height: | Size: 224 B |
|
Before Width: | Height: | Size: 505 B |
|
Before Width: | Height: | Size: 378 B |
|
Before Width: | Height: | Size: 168 B |
|
Before Width: | Height: | Size: 295 B |
|
Before Width: | Height: | Size: 273 B |
|
Before Width: | Height: | Size: 317 B |
|
Before Width: | Height: | Size: 219 B |
|
Before Width: | Height: | Size: 310 B |
|
Before Width: | Height: | Size: 568 B |
|
Before Width: | Height: | Size: 220 B |
|
Before Width: | Height: | Size: 111 B |
|
Before Width: | Height: | Size: 415 B |
|
Before Width: | Height: | Size: 109 B |
|
Before Width: | Height: | Size: 265 B |
|
Before Width: | Height: | Size: 793 B |
|
Before Width: | Height: | Size: 541 B |
|
Before Width: | Height: | Size: 654 B |
|
Before Width: | Height: | Size: 314 B |
|
Before Width: | Height: | Size: 1 KiB |
|
Before Width: | Height: | Size: 706 B |
|
Before Width: | Height: | Size: 271 B |
|
Before Width: | Height: | Size: 520 B |
|
Before Width: | Height: | Size: 353 B |
|
Before Width: | Height: | Size: 458 B |
|
Before Width: | Height: | Size: 303 B |
|
Before Width: | Height: | Size: 469 B |
|
Before Width: | Height: | Size: 930 B |
|
Before Width: | Height: | Size: 302 B |
|
Before Width: | Height: | Size: 154 B |
|
Before Width: | Height: | Size: 636 B |
|
Before Width: | Height: | Size: 143 B |
|
Before Width: | Height: | Size: 360 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 825 B |
|
Before Width: | Height: | Size: 958 B |
|
Before Width: | Height: | Size: 491 B |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1 KiB |
|
Before Width: | Height: | Size: 352 B |
|
Before Width: | Height: | Size: 842 B |
|
Before Width: | Height: | Size: 442 B |
|
Before Width: | Height: | Size: 524 B |
|
Before Width: | Height: | Size: 363 B |
|
Before Width: | Height: | Size: 538 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 363 B |
|
Before Width: | Height: | Size: 128 B |
|
Before Width: | Height: | Size: 839 B |
|
Before Width: | Height: | Size: 127 B |
|
Before Width: | Height: | Size: 437 B |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 519 B |
|
Before Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |