mirror of
https://github.com/chararomandroid/android_device_samsung_a20
synced 2026-08-21 11:55:31 -04:00
universal7885: fm-app: Refactor
This commit is contained in:
parent
b9c6e96e83
commit
1fd4442a64
12 changed files with 197 additions and 433 deletions
|
|
@ -8,12 +8,11 @@ android_app {
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"androidx.core_core",
|
"androidx.core_core",
|
||||||
"androidx.appcompat_appcompat",
|
"androidx.appcompat_appcompat",
|
||||||
|
"androidx.preference_preference",
|
||||||
"com.google.android.material_stable",
|
"com.google.android.material_stable",
|
||||||
"kotlinx_coroutines",
|
|
||||||
"androidx.transition_transition",
|
"androidx.transition_transition",
|
||||||
"kotlinx_coroutines_android",
|
|
||||||
"androidx.coordinatorlayout_coordinatorlayout",
|
"androidx.coordinatorlayout_coordinatorlayout",
|
||||||
"vendor.eureka.hardware.fmradio-V1-java",
|
"vendor.eureka.hardware.fmradio-V2-java",
|
||||||
],
|
],
|
||||||
required: [
|
required: [
|
||||||
"vendor.eureka.hardware.fmradio-service",
|
"vendor.eureka.hardware.fmradio-service",
|
||||||
|
|
|
||||||
|
|
@ -10,29 +10,23 @@ import android.media.MediaMetadata
|
||||||
import android.media.session.MediaSession
|
import android.media.session.MediaSession
|
||||||
import android.media.session.PlaybackState
|
import android.media.session.PlaybackState
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import com.eurekateam.fmradio.enums.OutputState
|
import androidx.preference.PreferenceManager
|
||||||
import com.eurekateam.fmradio.enums.PlayState
|
import com.eurekateam.fmradio.enums.PlayState
|
||||||
import com.eurekateam.fmradio.enums.PowerState
|
import com.eurekateam.fmradio.enums.PowerState
|
||||||
import com.eurekateam.fmradio.fragments.MainFragment
|
|
||||||
import com.eurekateam.fmradio.utils.Log
|
import com.eurekateam.fmradio.utils.Log
|
||||||
|
import vendor.eureka.hardware.fmradio.SetType
|
||||||
|
import vendor.eureka.hardware.fmradio.GetType
|
||||||
|
|
||||||
class FMRadioService : Service() {
|
class FMRadioService : Service() {
|
||||||
private lateinit var mContext: Context
|
private lateinit var mContext: Context
|
||||||
private lateinit var mAudioManager: AudioManager
|
private lateinit var mAudioManager: AudioManager
|
||||||
private lateinit var mTracks: IntArray
|
private val mNativeFMInterface = NativeFMInterface()
|
||||||
private lateinit var mNativeFMInterface: NativeFMInterface
|
|
||||||
override fun onBind(intent: Intent?): IBinder? {
|
override fun onBind(intent: Intent?): IBinder? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
Log.i("--- FMRadio Background (IN) ---")
|
Log.i("--- FMRadio Background (IN) ---")
|
||||||
fd = MainFragment.fd
|
|
||||||
mAudioManager = getSystemService(AUDIO_SERVICE) as AudioManager
|
mAudioManager = getSystemService(AUDIO_SERVICE) as AudioManager
|
||||||
mTracks = MainFragment.mTracks
|
|
||||||
mIndex = MainFragment.getIndex()
|
|
||||||
if (mTracks.isEmpty() || mIndex == -1) {
|
|
||||||
return super.onStartCommand(intent, flags, startId)
|
|
||||||
}
|
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
intent.action?.let { Log.i(it) }
|
intent.action?.let { Log.i(it) }
|
||||||
when (intent.action) {
|
when (intent.action) {
|
||||||
|
|
@ -47,51 +41,37 @@ class FMRadioService : Service() {
|
||||||
}
|
}
|
||||||
ACTION_BEFORE -> {
|
ACTION_BEFORE -> {
|
||||||
mPlayState = PlayState.STATE_PLAYING
|
mPlayState = PlayState.STATE_PLAYING
|
||||||
Log.i("mCurrentIndex $mIndex")
|
mNativeFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_BEFORE_CHANNEL)
|
||||||
if (mIndex > 0) {
|
|
||||||
mIndex -= 1
|
|
||||||
}
|
|
||||||
mNativeFMInterface.setFMFreq(fd, mTracks[mIndex].toInt())
|
|
||||||
MainFragment.mFreqCurrent = mTracks[mIndex].toInt()
|
|
||||||
}
|
}
|
||||||
ACTION_NEXT -> {
|
ACTION_NEXT -> {
|
||||||
mPlayState = PlayState.STATE_PLAYING
|
mPlayState = PlayState.STATE_PLAYING
|
||||||
Log.i("mCurrentIndex $mIndex")
|
mNativeFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_NEXT_CHANNEL)
|
||||||
if (mIndex < mTracks.size - 1) {
|
|
||||||
mIndex += 1
|
|
||||||
}
|
|
||||||
mNativeFMInterface.setFMFreq(fd, mTracks[mIndex].toInt())
|
|
||||||
MainFragment.mFreqCurrent = mTracks[mIndex].toInt()
|
|
||||||
}
|
}
|
||||||
ACTION_QUIT -> {
|
ACTION_QUIT -> {
|
||||||
mAudioManager = getSystemService(AUDIO_SERVICE) as AudioManager
|
mAudioManager = getSystemService(AUDIO_SERVICE) as AudioManager
|
||||||
Log.i("--- FMRadio Background (OUT) ---")
|
Log.i("--- FMRadio Background (OUT) ---")
|
||||||
|
mNativeFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_THREAD, 0)
|
||||||
|
mNativeFMInterface.mDevCtl.close()
|
||||||
mAudioManager.setParameters(PowerState.FM_POWER_OFF.mAudioParam)
|
mAudioManager.setParameters(PowerState.FM_POWER_OFF.mAudioParam)
|
||||||
mMediaSession.release()
|
mMediaSession.release()
|
||||||
stopSelf()
|
stopSelf()
|
||||||
}
|
}
|
||||||
ACTION_OUTPUT -> {
|
ACTION_OUTPUT -> {
|
||||||
changeOutputDevice(mOutput)
|
var mSpeaker = PreferenceManager.getDefaultSharedPreferences(mContext).getBoolean("speaker", false)
|
||||||
if (mOutput == OutputState.OUTPUT_HEADSET) {
|
mSpeaker = !mSpeaker
|
||||||
mOutput = OutputState.OUTPUT_SPEAKER
|
changeOutputDevice(mSpeaker)
|
||||||
} else if (mOutput == OutputState.OUTPUT_SPEAKER) {
|
PreferenceManager.getDefaultSharedPreferences(mContext).edit().putBoolean("speaker", mSpeaker).apply()
|
||||||
mOutput = OutputState.OUTPUT_HEADSET
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ACTION_START -> {
|
ACTION_START -> {
|
||||||
mMediaSession = MediaSession(this, "FMRadio")
|
mMediaSession = MediaSession(this, "FMRadio")
|
||||||
mNativeFMInterface = NativeFMInterface()
|
|
||||||
mContext = this
|
mContext = this
|
||||||
setPlaybackState()
|
setPlaybackState()
|
||||||
mMediaSession.isActive = true
|
mMediaSession.isActive = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sendMetaData("FM ${mTracks[mIndex].toFloat() / 1000} Mhz")
|
sendMetaData("FM ${mNativeFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_FREQ).toFloat() / 1000} Mhz")
|
||||||
startForeground(51, pushNotification())
|
startForeground(51, pushNotification())
|
||||||
if (mOutput == OutputState.OUTPUT_SPEAKER) {
|
|
||||||
changeOutputDevice(OutputState.OUTPUT_HEADSET)
|
|
||||||
}
|
|
||||||
Log.i("--- FMRadio Background (OUT) ---")
|
Log.i("--- FMRadio Background (OUT) ---")
|
||||||
return START_STICKY
|
return START_STICKY
|
||||||
}
|
}
|
||||||
|
|
@ -141,13 +121,10 @@ class FMRadioService : Service() {
|
||||||
val close = PendingIntent.getService(mContext, 0, Intent(ACTION_QUIT), PendingIntent.FLAG_IMMUTABLE)
|
val close = PendingIntent.getService(mContext, 0, Intent(ACTION_QUIT), PendingIntent.FLAG_IMMUTABLE)
|
||||||
val output = PendingIntent.getService(mContext, 0, Intent(ACTION_OUTPUT), PendingIntent.FLAG_IMMUTABLE)
|
val output = PendingIntent.getService(mContext, 0, Intent(ACTION_OUTPUT), PendingIntent.FLAG_IMMUTABLE)
|
||||||
val mOutputAction: Notification.Action = Notification.Action.Builder(
|
val mOutputAction: Notification.Action = Notification.Action.Builder(
|
||||||
when (mOutput) {
|
if (PreferenceManager.getDefaultSharedPreferences(mContext).getBoolean("speaker", false)) {
|
||||||
OutputState.OUTPUT_HEADSET -> {
|
Icon.createWithResource(this, R.drawable.ic_volume_up)
|
||||||
Icon.createWithResource(this, R.drawable.ic_volume_up)
|
} else {
|
||||||
}
|
Icon.createWithResource(this, R.drawable.ic_headphones)
|
||||||
OutputState.OUTPUT_SPEAKER -> {
|
|
||||||
Icon.createWithResource(this, R.drawable.ic_headphones)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"Output Configuration",
|
"Output Configuration",
|
||||||
output
|
output
|
||||||
|
|
@ -196,16 +173,9 @@ class FMRadioService : Service() {
|
||||||
private const val ACTION_QUIT = "$PACKAGENAME.QUIT"
|
private const val ACTION_QUIT = "$PACKAGENAME.QUIT"
|
||||||
private const val ACTION_OUTPUT = "$PACKAGENAME.OUTPUT"
|
private const val ACTION_OUTPUT = "$PACKAGENAME.OUTPUT"
|
||||||
private var mPlayState: PlayState = PlayState.STATE_PLAYING
|
private var mPlayState: PlayState = PlayState.STATE_PLAYING
|
||||||
private var mOutput: OutputState = MainFragment.mHeadset
|
|
||||||
private var fd: Int = -1
|
|
||||||
private var mIndex = -1
|
|
||||||
lateinit var mMediaSession: MediaSession
|
lateinit var mMediaSession: MediaSession
|
||||||
}
|
}
|
||||||
private fun changeOutputDevice(output: OutputState) {
|
private fun changeOutputDevice(speaker: Boolean) {
|
||||||
if (output == OutputState.OUTPUT_SPEAKER) {
|
mNativeFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_SPEAKER_ROUTE, if (speaker) 1 else 0)
|
||||||
mNativeFMInterface.setAudioRoute(false)
|
|
||||||
} else if (output == OutputState.OUTPUT_HEADSET) {
|
|
||||||
mNativeFMInterface.setAudioRoute(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ class MainActivity : AppCompatActivity() {
|
||||||
private lateinit var mAlertImage: AppCompatImageView
|
private lateinit var mAlertImage: AppCompatImageView
|
||||||
private lateinit var mAudioManager: AudioManager
|
private lateinit var mAudioManager: AudioManager
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
MainFragment.fd = mFMInterface.openFMDevice()
|
|
||||||
mAlertView = (getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater)
|
mAlertView = (getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater)
|
||||||
.inflate(R.layout.alertdialog, null)
|
.inflate(R.layout.alertdialog, null)
|
||||||
mAlertTitle = mAlertView.findViewById(R.id.alert_title)
|
mAlertTitle = mAlertView.findViewById(R.id.alert_title)
|
||||||
|
|
@ -55,27 +54,16 @@ class MainActivity : AppCompatActivity() {
|
||||||
mAlertDesc = mAlertView.findViewById(R.id.alert_desc)
|
mAlertDesc = mAlertView.findViewById(R.id.alert_desc)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_navigation)
|
setContentView(R.layout.activity_navigation)
|
||||||
if (MainFragment.fd == -1) {
|
|
||||||
Log.e("CANNOT OPEN /dev/radio0!!!")
|
|
||||||
mAlertTitle.text = getString(R.string.radio_io_error)
|
|
||||||
mAlertDesc.text = getString(R.string.radio_io_error_desc)
|
|
||||||
mAlertImage.setImageIcon(Icon.createWithResource(this, R.drawable.ic_error))
|
|
||||||
val mAlertDialog = AlertDialog.Builder(this)
|
|
||||||
mAlertDialog
|
|
||||||
.setCancelable(false)
|
|
||||||
.setView(mAlertView)
|
|
||||||
.setNegativeButton(R.string.ok) { _: DialogInterface, _: Int ->
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
DynamicColors.applyToActivitiesIfAvailable(application)
|
DynamicColors.applyToActivitiesIfAvailable(application)
|
||||||
|
mFMInterface.mDevCtl.open()
|
||||||
mAudioManager = getSystemService(AUDIO_SERVICE) as AudioManager
|
mAudioManager = getSystemService(AUDIO_SERVICE) as AudioManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detects whether wired headphones is connected to this device or no
|
* Detects whether wired headphones is connected to this device or no
|
||||||
* @see AudioManager.getDevices
|
* @see AudioManager.getDevices
|
||||||
*/
|
*/
|
||||||
val mAudioDeviceInfo = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
|
val mAudioDeviceInfo = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
|
||||||
|
|
||||||
for (i in mAudioDeviceInfo.indices) {
|
for (i in mAudioDeviceInfo.indices) {
|
||||||
if (mAudioDeviceInfo[i].type == AudioDeviceInfo.TYPE_WIRED_HEADSET ||
|
if (mAudioDeviceInfo[i].type == AudioDeviceInfo.TYPE_WIRED_HEADSET ||
|
||||||
mAudioDeviceInfo[i].type == AudioDeviceInfo.TYPE_WIRED_HEADPHONES
|
mAudioDeviceInfo[i].type == AudioDeviceInfo.TYPE_WIRED_HEADPHONES
|
||||||
|
|
@ -84,6 +72,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
Log.i("Wired Headphones detected")
|
Log.i("Wired Headphones detected")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MainFragment.mHeadSetPlugged != HeadsetState.HEADSET_STATE_CONNECTED) {
|
if (MainFragment.mHeadSetPlugged != HeadsetState.HEADSET_STATE_CONNECTED) {
|
||||||
mAlertTitle.text = getString(R.string.no_headphones_error)
|
mAlertTitle.text = getString(R.string.no_headphones_error)
|
||||||
mAlertDesc.text = getString(R.string.no_headphones_error_desc)
|
mAlertDesc.text = getString(R.string.no_headphones_error_desc)
|
||||||
|
|
@ -183,6 +172,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
super.onRestart()
|
super.onRestart()
|
||||||
stopService(mIntent)
|
stopService(mIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ACTION_START = "com.eurekateam.fmradio.START"
|
private const val ACTION_START = "com.eurekateam.fmradio.START"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,38 +3,15 @@ package com.eurekateam.fmradio
|
||||||
import android.os.ServiceManager
|
import android.os.ServiceManager
|
||||||
import vendor.eureka.hardware.fmradio.GetType
|
import vendor.eureka.hardware.fmradio.GetType
|
||||||
import vendor.eureka.hardware.fmradio.IFMDevControl
|
import vendor.eureka.hardware.fmradio.IFMDevControl
|
||||||
import vendor.eureka.hardware.fmradio.SetType
|
|
||||||
|
|
||||||
class NativeFMInterface {
|
class NativeFMInterface {
|
||||||
private val mDevCtl: IFMDevControl
|
val mDevCtl: IFMDevControl
|
||||||
private val mSysfsCtl: IFMDevControl
|
val mSysfsCtl: IFMDevControl
|
||||||
private val mDefaultCtl: IFMDevControl
|
val mDefaultCtl: IFMDevControl
|
||||||
|
|
||||||
init {
|
init {
|
||||||
mDevCtl = IFMDevControl.Stub.asInterface(ServiceManager.waitForDeclaredService("vendor.eureka.hardware.fmradio.IFMDevControl/default"))
|
mDevCtl = IFMDevControl.Stub.asInterface(ServiceManager.waitForDeclaredService("vendor.eureka.hardware.fmradio.IFMDevControl/default"))
|
||||||
mSysfsCtl = IFMDevControl.Stub.asInterface(ServiceManager.waitForDeclaredService("vendor.eureka.hardware.fmradio.IFMDevControl/support"))
|
mSysfsCtl = IFMDevControl.Stub.asInterface(ServiceManager.waitForDeclaredService("vendor.eureka.hardware.fmradio.IFMDevControl/support"))
|
||||||
mDefaultCtl = if (mSysfsCtl.getValue(GetType.GET_TYPE_FM_SYSFS_IF) == 0) mSysfsCtl else mDevCtl
|
mDefaultCtl = if (mSysfsCtl.getValue(GetType.GET_TYPE_FM_SYSFS_IF) == 0) mSysfsCtl else mDevCtl
|
||||||
}
|
}
|
||||||
|
|
||||||
fun openFMDevice(): Int {
|
|
||||||
mDevCtl.open()
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getFMFreq(a: Int): Long = mDevCtl.getValue(GetType.GET_TYPE_FM_FREQ).toLong()
|
|
||||||
fun setFMFreq(a: Int, freq: Int) = mDevCtl.setValue(SetType.SET_TYPE_FM_FREQ, freq)
|
|
||||||
fun setFMVolume(a: Int, volume: Int) = mDevCtl.setValue(SetType.SET_TYPE_FM_VOLUME, volume)
|
|
||||||
fun setFMMute(a: Int, mute: Boolean) = mDevCtl.setValue(SetType.SET_TYPE_FM_MUTE, if (mute) 1 else 0)
|
|
||||||
fun getFmUpper(a: Int): Int = mDevCtl.getValue(GetType.GET_TYPE_FM_UPPER_LIMIT)
|
|
||||||
fun getFMLower(a: Int): Int = mDevCtl.getValue(GetType.GET_TYPE_FM_LOWER_LIMIT)
|
|
||||||
fun getRMSSI(a: Int): Int = mDevCtl.getValue(GetType.GET_TYPE_FM_RMSSI)
|
|
||||||
fun getFMTracks(fd: Int): IntArray = mDefaultCtl.getFreqsList()
|
|
||||||
fun setFMThread(a: Int, run: Boolean) = mDevCtl.setValue(SetType.SET_TYPE_FM_THREAD, if (run) 1 else 0)
|
|
||||||
fun getNextChannel(a: Int): Int = mDefaultCtl.getValue(GetType.GET_TYPE_FM_NEXT_CHANNEL)
|
|
||||||
fun getBeforeChannel(a: Int): Int = mDefaultCtl.getValue(GetType.GET_TYPE_FM_BEFORE_CHANNEL)
|
|
||||||
fun stopSearching(a: Int) = mDevCtl.setValue(SetType.SET_TYPE_FM_SEARCH_CANCEL, 0)
|
|
||||||
fun setFMRSSI(a: Int, rssi: Long) = mDevCtl.setValue(SetType.SET_TYPE_FM_RMSSI, rssi.toInt())
|
|
||||||
fun closeFMDevice(fd: Int) = mDevCtl.close()
|
|
||||||
fun getSysfsSupport(): Boolean = mSysfsCtl.getValue(GetType.GET_TYPE_FM_SYSFS_IF) == 0
|
|
||||||
fun setAudioRoute(speaker: Boolean) = mDevCtl.setValue(SetType.SET_TYPE_FM_SPEAKER_ROUTE, if (speaker) 1 else 0)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,26 +7,28 @@ import android.view.ViewGroup
|
||||||
import android.widget.BaseAdapter
|
import android.widget.BaseAdapter
|
||||||
import androidx.appcompat.widget.AppCompatImageView
|
import androidx.appcompat.widget.AppCompatImageView
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import com.eurekateam.fmradio.*
|
import androidx.preference.PreferenceManager
|
||||||
import com.eurekateam.fmradio.NativeFMInterface
|
import com.eurekateam.fmradio.NativeFMInterface
|
||||||
import com.eurekateam.fmradio.fragments.MainFragment
|
|
||||||
import com.eurekateam.fmradio.utils.FileUtilities
|
|
||||||
import com.eurekateam.fmradio.utils.Log
|
import com.eurekateam.fmradio.utils.Log
|
||||||
|
import com.eurekateam.fmradio.R
|
||||||
import com.google.android.material.textview.MaterialTextView
|
import com.google.android.material.textview.MaterialTextView
|
||||||
|
import vendor.eureka.hardware.fmradio.GetType
|
||||||
|
import vendor.eureka.hardware.fmradio.SetType
|
||||||
|
|
||||||
class ListViewAdapter(private val mContext: Context) : BaseAdapter() {
|
class ListViewAdapter(private val mContext: Context) : BaseAdapter() {
|
||||||
private val mFMInterface = NativeFMInterface()
|
private val mFMInterface = NativeFMInterface()
|
||||||
|
private val mListChannel = mFMInterface.mDefaultCtl.getFreqsList()
|
||||||
private var mListofViews = HashMap<Int, View>(30)
|
private var mListofViews = HashMap<Int, View>(30)
|
||||||
override fun getCount(): Int {
|
override fun getCount(): Int {
|
||||||
return MainFragment.mTracks.size
|
return 30
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItem(p0: Int): Any {
|
override fun getItem(p: Int): Any {
|
||||||
return MainFragment.mTracks[p0]
|
return mListChannel[p]
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemId(p0: Int): Long {
|
override fun getItemId(p: Int): Long {
|
||||||
return p0.toLong()
|
return p.toLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getView(id: Int, mConvertView: View?, parent: ViewGroup?): View {
|
override fun getView(id: Int, mConvertView: View?, parent: ViewGroup?): View {
|
||||||
|
|
@ -39,16 +41,10 @@ class ListViewAdapter(private val mContext: Context) : BaseAdapter() {
|
||||||
mAnotherConvertView.findViewById<MaterialTextView>(R.id.channel_list_title).text =
|
mAnotherConvertView.findViewById<MaterialTextView>(R.id.channel_list_title).text =
|
||||||
String.format(
|
String.format(
|
||||||
mContext.getString(R.string.fm_radio_freq),
|
mContext.getString(R.string.fm_radio_freq),
|
||||||
MainFragment.mTracks[id].toFloat() / 1000
|
mListChannel[id].toFloat() / 1000
|
||||||
)
|
)
|
||||||
mAnotherConvertView.findViewById<MaterialTextView>(R.id.channel_list_title).setOnClickListener {
|
mAnotherConvertView.findViewById<MaterialTextView>(R.id.channel_list_title).setOnClickListener {
|
||||||
mFMInterface.setFMFreq(MainFragment.fd, MainFragment.mTracks[id].toInt())
|
mFMInterface.mDefaultCtl.setValue(SetType.SET_TYPE_FM_FREQ, mListChannel[id])
|
||||||
MainFragment.mFreqCurrent = MainFragment.mTracks[id].toInt()
|
|
||||||
FileUtilities.writeToFile(
|
|
||||||
FileUtilities.mFMFreqFileName,
|
|
||||||
MainFragment.mFreqCurrent.toString(),
|
|
||||||
mContext
|
|
||||||
)
|
|
||||||
setCurrentFMChannel(id)
|
setCurrentFMChannel(id)
|
||||||
}
|
}
|
||||||
mAnotherConvertView.findViewById<AppCompatImageView>(R.id.star_button_list).let {
|
mAnotherConvertView.findViewById<AppCompatImageView>(R.id.star_button_list).let {
|
||||||
|
|
@ -58,17 +54,17 @@ class ListViewAdapter(private val mContext: Context) : BaseAdapter() {
|
||||||
R.drawable.ic_star_filled,
|
R.drawable.ic_star_filled,
|
||||||
mContext.theme
|
mContext.theme
|
||||||
)
|
)
|
||||||
val mIndex = MainFragment.mTracks[id].toInt()
|
val mIndex = mListChannel[id]
|
||||||
if (MainFragment.mFavStats[mIndex] == null) {
|
val mSharedPref = PreferenceManager.getDefaultSharedPreferences(mContext)
|
||||||
MainFragment.mFavStats.putIfAbsent(mIndex, false)
|
val mBefore = mSharedPref.getBoolean("fav_$mIndex", false)
|
||||||
}
|
if (mBefore) {
|
||||||
if (MainFragment.mFavStats[mIndex]!!) {
|
|
||||||
it.setImageDrawable(mStarFilled)
|
|
||||||
} else {
|
|
||||||
it.setImageDrawable(mStar)
|
it.setImageDrawable(mStar)
|
||||||
|
} else {
|
||||||
|
it.setImageDrawable(mStarFilled)
|
||||||
}
|
}
|
||||||
|
mSharedPref.edit().putBoolean("fav_$mIndex", !mBefore).apply()
|
||||||
}
|
}
|
||||||
if (MainFragment.mFreqCurrent == MainFragment.mTracks[id].toInt()) {
|
if (mFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_FREQ) == mListChannel[id]) {
|
||||||
setCurrentFMChannel(id)
|
setCurrentFMChannel(id)
|
||||||
}
|
}
|
||||||
mListofViews[id] = mAnotherConvertView!!
|
mListofViews[id] = mAnotherConvertView!!
|
||||||
|
|
@ -89,7 +85,7 @@ class ListViewAdapter(private val mContext: Context) : BaseAdapter() {
|
||||||
mListofViews[mPosition]?.setBackgroundColor(
|
mListofViews[mPosition]?.setBackgroundColor(
|
||||||
ResourcesCompat.getColor(
|
ResourcesCompat.getColor(
|
||||||
mContext.resources,
|
mContext.resources,
|
||||||
android.R.color.system_accent3_400,
|
android.R.color.system_accent2_400,
|
||||||
mContext.theme
|
mContext.theme
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -6,38 +6,34 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.BaseAdapter
|
import android.widget.BaseAdapter
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
import com.eurekateam.fmradio.NativeFMInterface
|
import com.eurekateam.fmradio.NativeFMInterface
|
||||||
import com.eurekateam.fmradio.PebbleTextView
|
import com.eurekateam.fmradio.PebbleTextView
|
||||||
import com.eurekateam.fmradio.R
|
import com.eurekateam.fmradio.R
|
||||||
import com.eurekateam.fmradio.fragments.MainFragment
|
import vendor.eureka.hardware.fmradio.SetType
|
||||||
import com.eurekateam.fmradio.utils.FileUtilities
|
|
||||||
|
|
||||||
class PebbleLayoutAdapter(private val mContext: Context) : BaseAdapter() {
|
class PebbleLayoutAdapter(private val mContext: Context) : BaseAdapter() {
|
||||||
private val mFavoriteList: MutableList<Int> = emptyList<Int>().toMutableList()
|
private var mFavoriteList: List<Int> = emptyList()
|
||||||
|
private val mFMInterface = NativeFMInterface()
|
||||||
|
private val mListChannel = mFMInterface.mDefaultCtl.getFreqsList()
|
||||||
|
private val mSharedPref = PreferenceManager.getDefaultSharedPreferences(mContext)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
for (mItem in MainFragment.mFavStats) {
|
for (k in mListChannel) {
|
||||||
if (mItem.value) {
|
if (mSharedPref.getBoolean("fav_$k", false)) mFavoriteList += k
|
||||||
mFavoriteList.add(mItem.key)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mFavoriteList.sort()
|
|
||||||
var mData = ""
|
|
||||||
for (i in mFavoriteList) {
|
|
||||||
mData += "$i\n"
|
|
||||||
}
|
|
||||||
FileUtilities.writeToFile(FileUtilities.mFavouriteChannelFileName, mData, mContext)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCount(): Int {
|
override fun getCount(): Int {
|
||||||
return mFavoriteList.size
|
return mFavoriteList.size
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItem(p0: Int): Any {
|
override fun getItem(p: Int): Any {
|
||||||
return mFavoriteList[p0]
|
return mFavoriteList[p]
|
||||||
}
|
}
|
||||||
|
|
||||||
private val mFMInterface = NativeFMInterface()
|
override fun getItemId(p: Int): Long {
|
||||||
override fun getItemId(p0: Int): Long {
|
return p.toLong()
|
||||||
return p0.toLong()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getView(id: Int, mConvertView: View?, parent: ViewGroup?): View {
|
override fun getView(id: Int, mConvertView: View?, parent: ViewGroup?): View {
|
||||||
|
|
@ -55,13 +51,7 @@ class PebbleLayoutAdapter(private val mContext: Context) : BaseAdapter() {
|
||||||
mContext.theme
|
mContext.theme
|
||||||
)
|
)
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
mFMInterface.setFMFreq(MainFragment.fd, mFavoriteList[id])
|
mFMInterface.mDefaultCtl.setValue(SetType.SET_TYPE_FM_FREQ, mFavoriteList[id])
|
||||||
MainFragment.mFreqCurrent = mFavoriteList[id]
|
|
||||||
FileUtilities.writeToFile(
|
|
||||||
FileUtilities.mFMFreqFileName,
|
|
||||||
MainFragment.mFreqCurrent.toString(),
|
|
||||||
mContext
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mAnotherConvertView
|
return mAnotherConvertView
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package com.eurekateam.fmradio.enums
|
|
||||||
|
|
||||||
/***
|
|
||||||
* [OUTPUT_SPEAKER] : Output to speaker
|
|
||||||
*
|
|
||||||
* [OUTPUT_HEADSET] : Output to headset
|
|
||||||
*/
|
|
||||||
enum class OutputState {
|
|
||||||
OUTPUT_SPEAKER,
|
|
||||||
OUTPUT_HEADSET
|
|
||||||
}
|
|
||||||
|
|
@ -5,23 +5,27 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.view.WindowManager
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import android.widget.ListView
|
import android.widget.ListView
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import com.eurekateam.fmradio.MainActivity
|
import com.eurekateam.fmradio.NativeFMInterface
|
||||||
import com.eurekateam.fmradio.R
|
import com.eurekateam.fmradio.R
|
||||||
|
import com.eurekateam.fmradio.MainActivity
|
||||||
import com.eurekateam.fmradio.adapters.ListViewAdapter
|
import com.eurekateam.fmradio.adapters.ListViewAdapter
|
||||||
|
import com.eurekateam.fmradio.utils.IWaitUntil
|
||||||
|
import com.eurekateam.fmradio.utils.WaitUntil
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
import kotlinx.coroutines.Dispatchers
|
import vendor.eureka.hardware.fmradio.SetType
|
||||||
import kotlinx.coroutines.GlobalScope
|
import vendor.eureka.hardware.fmradio.GetType
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
|
|
||||||
class ChannelListFragment :
|
class ChannelListFragment :
|
||||||
Fragment(R.layout.activity_channel_list),
|
Fragment(R.layout.activity_channel_list),
|
||||||
View.OnClickListener {
|
View.OnClickListener {
|
||||||
private lateinit var mListView: ListView
|
private lateinit var mListView: ListView
|
||||||
private lateinit var mFloatingActionButton: FloatingActionButton
|
private lateinit var mFloatingActionButton: FloatingActionButton
|
||||||
|
private val mNativeIF = NativeFMInterface()
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
|
|
@ -51,17 +55,21 @@ class ChannelListFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick(v: View?) {
|
override fun onClick(v: View?) {
|
||||||
GlobalScope.launch {
|
mNativeIF.mDefaultCtl.setValue(SetType.SET_TYPE_FM_SEARCH_START, 0)
|
||||||
withContext(Dispatchers.IO) {
|
requireActivity().window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
|
||||||
MainFragment.mRefreshTracks()
|
WaitUntil.setTimer(
|
||||||
}
|
requireActivity(),
|
||||||
withContext(Dispatchers.Main) {
|
object : IWaitUntil {
|
||||||
(requireActivity() as MainActivity).getMySupportFragmentManager().apply {
|
override fun cond(): Boolean = mNativeIF.mDefaultCtl.getValue(GetType.GET_TYPE_FM_MUTEX_LOCKED) == 0
|
||||||
beginTransaction().remove(this@ChannelListFragment).commit()
|
override fun todo() {
|
||||||
executePendingTransactions()
|
(requireActivity() as MainActivity).getMySupportFragmentManager().apply {
|
||||||
beginTransaction().add(R.id.container_view, this@ChannelListFragment).commit()
|
beginTransaction().remove(this@ChannelListFragment).commit()
|
||||||
|
executePendingTransactions()
|
||||||
|
beginTransaction().add(R.id.container_view, this@ChannelListFragment).commit()
|
||||||
|
}
|
||||||
|
requireActivity().window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.eurekateam.fmradio.fragments
|
package com.eurekateam.fmradio.fragments
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.graphics.drawable.Icon
|
import android.graphics.drawable.Icon
|
||||||
|
|
@ -9,25 +10,25 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.view.WindowManager
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import android.widget.SeekBar
|
import android.widget.SeekBar
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.widget.AppCompatSeekBar
|
import androidx.appcompat.widget.AppCompatSeekBar
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
import com.eurekateam.fmradio.NativeFMInterface
|
import com.eurekateam.fmradio.NativeFMInterface
|
||||||
import com.eurekateam.fmradio.R
|
import com.eurekateam.fmradio.R
|
||||||
import com.eurekateam.fmradio.enums.HeadsetState
|
import com.eurekateam.fmradio.enums.HeadsetState
|
||||||
import com.eurekateam.fmradio.enums.OutputState
|
|
||||||
import com.eurekateam.fmradio.enums.PowerState
|
import com.eurekateam.fmradio.enums.PowerState
|
||||||
import com.eurekateam.fmradio.utils.FileUtilities
|
import com.eurekateam.fmradio.utils.IWaitUntil
|
||||||
import com.eurekateam.fmradio.utils.Log
|
import com.eurekateam.fmradio.utils.Log
|
||||||
|
import com.eurekateam.fmradio.utils.WaitUntil
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
import com.google.android.material.textview.MaterialTextView
|
import com.google.android.material.textview.MaterialTextView
|
||||||
import kotlinx.coroutines.Dispatchers
|
import vendor.eureka.hardware.fmradio.SetType
|
||||||
import kotlinx.coroutines.GlobalScope
|
import vendor.eureka.hardware.fmradio.GetType
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
|
|
||||||
class MainFragment :
|
class MainFragment :
|
||||||
|
|
@ -48,6 +49,9 @@ class MainFragment :
|
||||||
private lateinit var mAudioManager: AudioManager
|
private lateinit var mAudioManager: AudioManager
|
||||||
private lateinit var mStar: Drawable
|
private lateinit var mStar: Drawable
|
||||||
private lateinit var mStarFilled: Drawable
|
private lateinit var mStarFilled: Drawable
|
||||||
|
private lateinit var mFavList: List<Int>
|
||||||
|
private lateinit var mSharedPref: SharedPreferences
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
|
|
@ -83,6 +87,7 @@ class MainFragment :
|
||||||
mNextChannelBtn.setOnClickListener(this)
|
mNextChannelBtn.setOnClickListener(this)
|
||||||
mOutputSwitch.setOnClickListener(this)
|
mOutputSwitch.setOnClickListener(this)
|
||||||
mFavButton.setOnClickListener(this)
|
mFavButton.setOnClickListener(this)
|
||||||
|
mSharedPref = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||||
var mIsLight = true
|
var mIsLight = true
|
||||||
val nightModeFlags = requireContext().resources.configuration.uiMode and
|
val nightModeFlags = requireContext().resources.configuration.uiMode and
|
||||||
Configuration.UI_MODE_NIGHT_MASK
|
Configuration.UI_MODE_NIGHT_MASK
|
||||||
|
|
@ -108,96 +113,33 @@ class MainFragment :
|
||||||
setBackgroundColor(resources.getColor(android.R.color.system_accent1_700, requireContext().theme))
|
setBackgroundColor(resources.getColor(android.R.color.system_accent1_700, requireContext().theme))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GlobalScope.launch {
|
val mVolume = mSharedPref.getInt("volume", 8)
|
||||||
withContext(Dispatchers.IO) {
|
mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_VOLUME, mVolume)
|
||||||
if (FileUtilities.checkIfExistFile(FileUtilities.mFavouriteChannelFileName, requireContext())) {
|
mSeekBar.min = 1
|
||||||
val mFavData = FileUtilities.readFromFile(
|
mSeekBar.max = 15
|
||||||
FileUtilities.mFavouriteChannelFileName,
|
mSeekBar.progress = mVolume
|
||||||
requireContext()
|
val mRestoreFreq = mSharedPref.getInt("freq", mFMInterface.mDevCtl.getValue(GetType.GET_TYPE_FM_LOWER_LIMIT))
|
||||||
)
|
mFMInterface.mDefaultCtl.setValue(SetType.SET_TYPE_FM_FREQ, mRestoreFreq)
|
||||||
for (mItem in mFavData.split("\\r?\\n".toRegex())) {
|
mFMFreq.text = mCleanFormat.format(mRestoreFreq.toFloat() / 1000)
|
||||||
if (mItem.isNotBlank()) {
|
mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_THREAD, 1)
|
||||||
mFavStats[mItem.toInt()] = true
|
Toast.makeText(requireContext(), "Updating freqs list... Please wait", Toast.LENGTH_LONG).show()
|
||||||
}
|
requireActivity().window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
|
||||||
}
|
mFMInterface.mDefaultCtl.setValue(SetType.SET_TYPE_FM_SEARCH_START, 0)
|
||||||
}
|
WaitUntil.setTimer(
|
||||||
var mMute = false
|
requireActivity(),
|
||||||
if (mFreqCurrent == -1) {
|
object : IWaitUntil {
|
||||||
mAudioManager.setParameters(PowerState.FM_POWER_OFF.mAudioParam)
|
override fun cond(): Boolean = mFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_MUTEX_LOCKED) == 0
|
||||||
withContext(Dispatchers.Main) {
|
override fun todo() {
|
||||||
mUpdateEnableDisable(false, mRootView)
|
val mList = mFMInterface.mDefaultCtl.getFreqsList()
|
||||||
}
|
for (i in mList) {
|
||||||
mMute = true
|
if (mSharedPref.getBoolean("fav_$i", false)) mFavList += i
|
||||||
}
|
|
||||||
|
|
||||||
if (FileUtilities.checkIfExistFile(FileUtilities.mFMFreqFileName, requireContext())) {
|
|
||||||
mFreqCurrent = FileUtilities.readFromFile(
|
|
||||||
FileUtilities.mFMFreqFileName,
|
|
||||||
requireContext()
|
|
||||||
).toInt()
|
|
||||||
mFMInterface.setFMFreq(fd, mFreqCurrent)
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
mFMFreq.text = mCleanFormat.format(mFreqCurrent.toFloat() / 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (FileUtilities.checkIfExistFile(FileUtilities.mFMVolumeFileName, requireContext())) {
|
|
||||||
mVolume = FileUtilities.readFromFile(
|
|
||||||
FileUtilities.mFMVolumeFileName,
|
|
||||||
requireContext()
|
|
||||||
).toInt()
|
|
||||||
mFMInterface.setFMVolume(fd, mVolume)
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
mSeekBar.progress = mVolume
|
|
||||||
}
|
|
||||||
}
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
mSeekBar.min = 1
|
|
||||||
mSeekBar.max = 15
|
|
||||||
}
|
|
||||||
withContext(Dispatchers.IO) {
|
|
||||||
if (mVolume == -1) {
|
|
||||||
mVolume = 8
|
|
||||||
mFMInterface.setFMVolume(fd, mVolume)
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
mSeekBar.progress = mVolume
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!mMute) {
|
|
||||||
mFMInterface.setFMMute(fd, true)
|
|
||||||
}
|
|
||||||
mFMInterface.setFMFreq(fd, mFMInterface.getFMLower(fd))
|
|
||||||
mRefreshTracks()
|
|
||||||
if (mFreqCurrent != -1) {
|
|
||||||
mFMInterface.setFMFreq(fd, mFreqCurrent)
|
|
||||||
} else {
|
|
||||||
mFreqCurrent = mFMInterface.getFMLower(fd)
|
|
||||||
}
|
|
||||||
mFreqCurrent = mFMInterface.getFMFreq(fd).toInt()
|
|
||||||
mFMInterface.setFMFreq(fd, mFreqCurrent)
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
mFMFreq.text = mCleanFormat.format(mFreqCurrent.toFloat() / 1000)
|
|
||||||
}
|
|
||||||
if (!mMute) {
|
|
||||||
mFMInterface.setFMMute(fd, false)
|
|
||||||
}
|
|
||||||
if (mFreqCurrent == -1) {
|
|
||||||
mFMInterface.setFMThread(fd, true)
|
|
||||||
}
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
mFavButton.let {
|
|
||||||
if (mFavStats[mFreqCurrent] == null) {
|
|
||||||
mFavStats.putIfAbsent(mFreqCurrent, false)
|
|
||||||
}
|
|
||||||
if (mFavStats[mFreqCurrent]!!) {
|
|
||||||
it.setImageDrawable(mStarFilled)
|
|
||||||
} else {
|
|
||||||
it.setImageDrawable(mStar)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
requireActivity().window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
|
||||||
|
Toast.makeText(requireContext(), "Done", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
|
// Update track list and fav button
|
||||||
return mRootView
|
return mRootView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,85 +199,55 @@ class MainFragment :
|
||||||
override fun onClick(v: View) {
|
override fun onClick(v: View) {
|
||||||
when (v.id) {
|
when (v.id) {
|
||||||
mOutputSwitch.id -> {
|
mOutputSwitch.id -> {
|
||||||
if (mHeadset == OutputState.OUTPUT_HEADSET) {
|
val mCurrent = mSharedPref.getBoolean("speaker", false)
|
||||||
|
if (!mCurrent) {
|
||||||
mOutputSwitch.setImageIcon(
|
mOutputSwitch.setImageIcon(
|
||||||
Icon.createWithResource(
|
Icon.createWithResource(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
R.drawable.ic_volume_up
|
R.drawable.ic_volume_up
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val ret = mFMInterface.setAudioRoute(true)
|
mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_SPEAKER_ROUTE, 1)
|
||||||
Log.i("mFMInterface.setAudioRoute return $ret")
|
} else {
|
||||||
} else if (mHeadset == OutputState.OUTPUT_SPEAKER) {
|
|
||||||
mOutputSwitch.setImageIcon(
|
mOutputSwitch.setImageIcon(
|
||||||
Icon.createWithResource(
|
Icon.createWithResource(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
R.drawable.ic_headphones
|
R.drawable.ic_headphones
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val ret = mFMInterface.setAudioRoute(false)
|
mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_SPEAKER_ROUTE, 0)
|
||||||
Log.i("mFMInterface.setAudioRoute return $ret")
|
|
||||||
}
|
|
||||||
if (mHeadset == OutputState.OUTPUT_HEADSET) {
|
|
||||||
mHeadset = OutputState.OUTPUT_SPEAKER
|
|
||||||
} else if (mHeadset == OutputState.OUTPUT_SPEAKER) {
|
|
||||||
mHeadset = OutputState.OUTPUT_HEADSET
|
|
||||||
}
|
}
|
||||||
|
mSharedPref.edit().putBoolean("speaker", !mCurrent).apply()
|
||||||
}
|
}
|
||||||
mVolumeUp.id -> {
|
mVolumeUp.id -> {
|
||||||
if (mVolume < 15) {
|
var mCurrentVolume = mSharedPref.getInt("volume", 8)
|
||||||
mVolume += 1
|
if (mCurrentVolume < 15) {
|
||||||
|
mCurrentVolume = mCurrentVolume + 1
|
||||||
}
|
}
|
||||||
mFMInterface.setFMVolume(fd, mVolume)
|
mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_VOLUME, mCurrentVolume)
|
||||||
mSeekBar.progress = mVolume
|
mSeekBar.progress = mCurrentVolume
|
||||||
Toast.makeText(requireContext(), "Volume set to $mVolume", Toast.LENGTH_SHORT).show()
|
Toast.makeText(requireContext(), "Volume set to $mCurrentVolume", Toast.LENGTH_SHORT).show()
|
||||||
FileUtilities.writeToFile(
|
mSharedPref.edit().putInt("volume", mCurrentVolume).apply()
|
||||||
FileUtilities.mFMVolumeFileName,
|
|
||||||
mVolume.toString(),
|
|
||||||
requireContext()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
mVolumeDown.id -> {
|
mVolumeDown.id -> {
|
||||||
if (mVolume > 0) {
|
var mCurrentVolume = mSharedPref.getInt("volume", 8)
|
||||||
mVolume -= 1
|
if (mCurrentVolume > 0) {
|
||||||
|
mCurrentVolume = mCurrentVolume - 1
|
||||||
}
|
}
|
||||||
mFMInterface.setFMVolume(fd, mVolume)
|
mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_VOLUME, mCurrentVolume)
|
||||||
mSeekBar.progress = mVolume
|
mSeekBar.progress = mCurrentVolume
|
||||||
Toast.makeText(requireContext(), "Volume set to $mVolume", Toast.LENGTH_SHORT).show()
|
Toast.makeText(requireContext(), "Volume set to $mCurrentVolume", Toast.LENGTH_SHORT).show()
|
||||||
FileUtilities.writeToFile(
|
mSharedPref.edit().putInt("volume", mCurrentVolume).apply()
|
||||||
FileUtilities.mFMVolumeFileName,
|
|
||||||
mVolume.toString(),
|
|
||||||
requireContext()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
mBeforeChannelBtn.id -> {
|
mBeforeChannelBtn.id -> {
|
||||||
mFMInterface.setFMMute(fd, true)
|
mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_MUTE, 1)
|
||||||
val mTempFreq = mFMInterface.getBeforeChannel(fd)
|
val mNewFreq = mFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_BEFORE_CHANNEL)
|
||||||
if (mTempFreq > mFMInterface.getFMLower(fd) && mTempFreq < mFMInterface.getFmUpper(
|
mFMFreq.text = mCleanFormat.format(mNewFreq.toFloat() / 1000)
|
||||||
fd
|
mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_MUTE, 0)
|
||||||
)
|
if (mSharedPref.getBoolean("fav_$mNewFreq", false)) {
|
||||||
) {
|
mFavButton.setImageDrawable(mStarFilled)
|
||||||
mFreqCurrent = mTempFreq
|
|
||||||
}
|
|
||||||
if (!mFMInterface.getSysfsSupport()) {
|
|
||||||
mFMInterface.setFMFreq(fd, mFreqCurrent)
|
|
||||||
}
|
|
||||||
mFMInterface.setFMMute(fd, false)
|
|
||||||
FileUtilities.writeToFile(
|
|
||||||
FileUtilities.mFMFreqFileName,
|
|
||||||
mFreqCurrent.toString(),
|
|
||||||
requireContext()
|
|
||||||
)
|
|
||||||
mFavButton.let {
|
|
||||||
if (mFavStats[mFreqCurrent] == null) {
|
|
||||||
mFavStats.putIfAbsent(mFreqCurrent, false)
|
|
||||||
}
|
|
||||||
if (mFavStats[mFreqCurrent]!!) {
|
|
||||||
it.setImageDrawable(mStarFilled)
|
|
||||||
} else {
|
|
||||||
it.setImageDrawable(mStar)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
mSharedPref.edit().putInt("freq", mNewFreq).apply()
|
||||||
}
|
}
|
||||||
mPowerBtn.id -> {
|
mPowerBtn.id -> {
|
||||||
if (mFMPower) {
|
if (mFMPower) {
|
||||||
|
|
@ -343,89 +255,40 @@ class MainFragment :
|
||||||
mFMFreq.text = getText(R.string.inital_freq)
|
mFMFreq.text = getText(R.string.inital_freq)
|
||||||
} else {
|
} else {
|
||||||
mAudioManager.setParameters(PowerState.FM_POWER_ON.mAudioParam)
|
mAudioManager.setParameters(PowerState.FM_POWER_ON.mAudioParam)
|
||||||
mFMFreq.text = mCleanFormat.format(mFreqCurrent.toFloat() / 1000)
|
mFMFreq.text = mCleanFormat.format(mFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_FREQ).toFloat() / 1000)
|
||||||
}
|
}
|
||||||
mUpdateEnableDisable(!mFMPower)
|
mUpdateEnableDisable(!mFMPower)
|
||||||
mFMPower = !mFMPower
|
mFMPower = !mFMPower
|
||||||
}
|
}
|
||||||
mNextChannelBtn.id -> {
|
mNextChannelBtn.id -> {
|
||||||
mFMInterface.setFMMute(fd, true)
|
mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_MUTE, 1)
|
||||||
val mTempFreq = mFMInterface.getNextChannel(fd)
|
val mNewFreq = mFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_NEXT_CHANNEL)
|
||||||
if (mTempFreq > mFMInterface.getFMLower(fd) && mTempFreq < mFMInterface.getFmUpper(
|
mFMFreq.text = mCleanFormat.format(mNewFreq.toFloat() / 1000)
|
||||||
fd
|
mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_MUTE, 0)
|
||||||
)
|
if (mSharedPref.getBoolean("fav_$mNewFreq", false)) {
|
||||||
) {
|
mFavButton.setImageDrawable(mStarFilled)
|
||||||
mFreqCurrent = mTempFreq
|
|
||||||
}
|
|
||||||
if (!mFMInterface.getSysfsSupport()) {
|
|
||||||
mFMInterface.setFMFreq(fd, mFreqCurrent)
|
|
||||||
}
|
|
||||||
mFMInterface.setFMMute(fd, false)
|
|
||||||
FileUtilities.writeToFile(
|
|
||||||
FileUtilities.mFMFreqFileName,
|
|
||||||
mFreqCurrent.toString(),
|
|
||||||
requireContext()
|
|
||||||
)
|
|
||||||
mFavButton.let {
|
|
||||||
if (mFavStats[mFreqCurrent] == null) {
|
|
||||||
mFavStats.putIfAbsent(mFreqCurrent, false)
|
|
||||||
}
|
|
||||||
if (mFavStats[mFreqCurrent]!!) {
|
|
||||||
it.setImageDrawable(mStarFilled)
|
|
||||||
} else {
|
|
||||||
it.setImageDrawable(mStar)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
mSharedPref.edit().putInt("freq", mNewFreq).apply()
|
||||||
}
|
}
|
||||||
mFavButton.id -> {
|
mFavButton.id -> {
|
||||||
val mIndex = mFreqCurrent
|
val mCurrFreq = mFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_FREQ)
|
||||||
if (mFavStats[mIndex] == null) {
|
val mCurr = mSharedPref.getBoolean("fav_$mCurrFreq", false)
|
||||||
mFavStats.putIfAbsent(mIndex, false)
|
if (mCurr) { mFavButton.setImageDrawable(mStar) } else { mFavButton.setImageDrawable(mStarFilled) }
|
||||||
}
|
mSharedPref.edit().putBoolean("fav_$mCurrFreq", !mCurr).apply()
|
||||||
mFavStats[mIndex] = !mFavStats[mIndex]!!
|
|
||||||
mFavButton.let {
|
|
||||||
if (mFavStats[mIndex]!!) {
|
|
||||||
it.setImageDrawable(mStarFilled)
|
|
||||||
} else {
|
|
||||||
it.setImageDrawable(mStar)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log.d(
|
|
||||||
"Fav stats for $mIndex changed. " +
|
|
||||||
"Current value ${mFavStats[mIndex]}"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mFMFreq.text = mCleanFormat.format(mFreqCurrent.toFloat() / 1000)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
|
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
|
||||||
mFMInterface.setFMVolume(fd, p1)
|
mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_VOLUME, p1)
|
||||||
FileUtilities.writeToFile(FileUtilities.mFMVolumeFileName, p1.toString(), requireContext())
|
mSharedPref.edit().putInt("volume", p1).apply()
|
||||||
mVolume = p1
|
|
||||||
}
|
}
|
||||||
override fun onStartTrackingTouch(p0: SeekBar?) {}
|
override fun onStartTrackingTouch(p0: SeekBar?) {}
|
||||||
override fun onStopTrackingTouch(p0: SeekBar?) {
|
override fun onStopTrackingTouch(p0: SeekBar?) {}
|
||||||
Toast.makeText(requireContext(), "Volume set to $mVolume", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
companion object {
|
companion object {
|
||||||
private var mVolume = -1
|
var mFMPower = false
|
||||||
var fd = -1
|
|
||||||
var mHeadset = OutputState.OUTPUT_SPEAKER
|
|
||||||
var mFreqCurrent = -1
|
|
||||||
private var mFMPower = false
|
|
||||||
var mHeadSetPlugged: HeadsetState = HeadsetState.HEADSET_STATE_DISCONNECTED
|
var mHeadSetPlugged: HeadsetState = HeadsetState.HEADSET_STATE_DISCONNECTED
|
||||||
var mTracks: IntArray = emptyArray<Int>().toIntArray()
|
|
||||||
fun mRefreshTracks() {
|
|
||||||
NativeFMInterface().setFMFreq(fd, NativeFMInterface().getFMLower(fd))
|
|
||||||
mTracks = NativeFMInterface().getFMTracks(fd)
|
|
||||||
mTracks = MainFragment().removeZeros(mTracks)
|
|
||||||
(mFreqCurrent != -1).let { NativeFMInterface().setFMFreq(fd, mFreqCurrent) }
|
|
||||||
}
|
|
||||||
fun getIndex(): Int {
|
|
||||||
return mTracks.indexOf(mFreqCurrent)
|
|
||||||
}
|
|
||||||
val mFavStats = HashMap<Int, Boolean>(30)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
package com.eurekateam.fmradio.utils
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import java.io.*
|
|
||||||
|
|
||||||
object FileUtilities {
|
|
||||||
const val mFMFreqFileName = "fm_freq_current"
|
|
||||||
const val mFMVolumeFileName = "fm_volume_current"
|
|
||||||
const val mFavouriteChannelFileName = "fm_fav_freqs"
|
|
||||||
|
|
||||||
fun writeToFile(fileName: String, data: String, mContext: Context) {
|
|
||||||
var os: OutputStream? = null
|
|
||||||
try {
|
|
||||||
os = FileOutputStream(File(mContext.filesDir.absolutePath + "/" + fileName))
|
|
||||||
os.write(data.toByteArray(), 0, data.length)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
os?.close()
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fun readFromFile(fileName: String, mContext: Context): String {
|
|
||||||
val mFile = File(mContext.filesDir.absolutePath + "/" + fileName)
|
|
||||||
var os: InputStream? = null
|
|
||||||
val mByteArray = ByteArray(mFile.length().toInt())
|
|
||||||
try {
|
|
||||||
os = FileInputStream(mFile)
|
|
||||||
os.read(mByteArray)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
os?.close()
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return String(mByteArray)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun checkIfExistFile(fileName: String, mContext: Context): Boolean {
|
|
||||||
return File(mContext.filesDir.absolutePath + "/" + fileName).exists()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.eurekateam.fmradio.utils
|
||||||
|
|
||||||
|
interface IWaitUntil {
|
||||||
|
fun cond(): Boolean
|
||||||
|
fun todo()
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.eurekateam.fmradio.utils
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
|
||||||
|
import java.util.Timer
|
||||||
|
import java.util.TimerTask
|
||||||
|
|
||||||
|
object WaitUntil {
|
||||||
|
fun setTimer(act: Activity, todo: IWaitUntil, timeout: Long = 15000) {
|
||||||
|
Timer().schedule(
|
||||||
|
object : TimerTask() {
|
||||||
|
override fun run() {
|
||||||
|
act.runOnUiThread({
|
||||||
|
if (todo.cond()) {
|
||||||
|
todo.todo()
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
timeout
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue