Moving to version 2.0
This commit is contained in:
@ -1,27 +0,0 @@
|
||||
package com.tommasoberlose.anotherwidget.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import android.content.SharedPreferences
|
||||
import android.preference.PreferenceManager
|
||||
import android.util.Log
|
||||
import com.tommasoberlose.anotherwidget.`object`.Constants
|
||||
import com.tommasoberlose.anotherwidget.util.MyMigration
|
||||
import com.tommasoberlose.anotherwidget.util.Util
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
|
||||
class AWApplication : Application() {
|
||||
@SuppressLint("ApplySharedPref")
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
Realm.init(this)
|
||||
val config = RealmConfiguration.Builder()
|
||||
.schemaVersion(2)
|
||||
.migration(MyMigration())
|
||||
.deleteRealmIfMigrationNeeded()
|
||||
.build()
|
||||
Realm.setDefaultConfiguration(config)
|
||||
}
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.activities
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import android.content.Intent
|
||||
import android.content.pm.ApplicationInfo
|
||||
import com.tommasoberlose.anotherwidget.components.events.ApplicationListEvent
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.widget.ImageView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.databinding.Observable
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.transition.MaterialFadeThrough
|
||||
import com.tommasoberlose.anotherwidget.components.events.AppInfoSavedEvent
|
||||
import com.tommasoberlose.anotherwidget.databinding.ActivityChooseApplicationBinding
|
||||
import com.tommasoberlose.anotherwidget.databinding.FragmentClockSettingsBinding
|
||||
import com.tommasoberlose.anotherwidget.global.Constants
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.ChooseApplicationViewModel
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||
import com.tommasoberlose.anotherwidget.utils.toast
|
||||
import kotlinx.android.synthetic.main.activity_choose_application.*
|
||||
import kotlinx.android.synthetic.main.activity_choose_application.list_view
|
||||
import kotlinx.coroutines.*
|
||||
import net.idik.lib.slimadapter.SlimAdapter
|
||||
|
||||
|
||||
class ChooseApplicationActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var adapter: SlimAdapter
|
||||
private lateinit var viewModel: ChooseApplicationViewModel
|
||||
private val pm by lazy { packageManager }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
viewModel = ViewModelProvider(this).get(ChooseApplicationViewModel::class.java)
|
||||
val binding = DataBindingUtil.setContentView<ActivityChooseApplicationBinding>(this, R.layout.activity_choose_application)
|
||||
|
||||
list_view.setHasFixedSize(true)
|
||||
val mLayoutManager = LinearLayoutManager(this)
|
||||
list_view.layoutManager = mLayoutManager
|
||||
|
||||
adapter = SlimAdapter.create()
|
||||
adapter
|
||||
.register<String>(R.layout.application_info_layout) { _, injector ->
|
||||
injector
|
||||
.text(R.id.text, getString(R.string.default_name))
|
||||
.image(R.id.icon, R.drawable.round_add_to_home_screen)
|
||||
.with<ImageView>(R.id.icon) {
|
||||
it.scaleX = 0.8f
|
||||
it.scaleY = 0.8f
|
||||
it.setColorFilter(ContextCompat.getColor(this, R.color.colorPrimaryText), android.graphics.PorterDuff.Mode.MULTIPLY)
|
||||
}
|
||||
.clicked(R.id.item) {
|
||||
val resultIntent = Intent()
|
||||
resultIntent.putExtra(Constants.RESULT_APP_NAME, "")
|
||||
resultIntent.putExtra(Constants.RESULT_APP_PACKAGE, "")
|
||||
setResult(Activity.RESULT_OK, resultIntent)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
.register<ApplicationInfo>(R.layout.application_info_layout) { item, injector ->
|
||||
injector
|
||||
.text(R.id.text, pm.getApplicationLabel(item).toString())
|
||||
|
||||
try {
|
||||
injector.image(R.id.icon, item.loadIcon(pm))
|
||||
} catch (ignore: Exception) {
|
||||
}
|
||||
|
||||
injector.clicked(R.id.item) {
|
||||
saveApp(item)
|
||||
}
|
||||
}
|
||||
.attachTo(list_view)
|
||||
|
||||
setupListener()
|
||||
subscribeUi(binding, viewModel)
|
||||
|
||||
search.requestFocus()
|
||||
}
|
||||
|
||||
private var filterJob: Job? = null
|
||||
|
||||
private fun subscribeUi(binding: ActivityChooseApplicationBinding, viewModel: ChooseApplicationViewModel) {
|
||||
binding.viewModel = viewModel
|
||||
viewModel.appList.observe(this, Observer {
|
||||
adapter.updateData(listOf("Default") + it)
|
||||
loader.visibility = View.INVISIBLE
|
||||
})
|
||||
|
||||
viewModel.searchInput.observe(this, Observer { search ->
|
||||
loader.visibility = View.VISIBLE
|
||||
filterJob?.cancel()
|
||||
filterJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||
delay(200)
|
||||
val list = if (search == null || search == "") {
|
||||
viewModel.appList.value!!
|
||||
} else {
|
||||
viewModel.appList.value!!.filter {
|
||||
pm.getApplicationLabel(
|
||||
it
|
||||
).toString().contains(search, true)
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
adapter.updateData(listOf("Default") + list)
|
||||
loader.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun setupListener() {
|
||||
action_back.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveApp(app: ApplicationInfo) {
|
||||
val resultIntent = Intent()
|
||||
resultIntent.putExtra(Constants.RESULT_APP_NAME, pm.getApplicationLabel(app).toString())
|
||||
resultIntent.putExtra(Constants.RESULT_APP_PACKAGE, app.packageName)
|
||||
setResult(Activity.RESULT_OK, resultIntent)
|
||||
finish()
|
||||
}
|
||||
}
|
@ -0,0 +1,161 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.activities
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.location.Address
|
||||
import android.location.Geocoder
|
||||
import android.os.Bundle
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.chibatching.kotpref.bulk
|
||||
import com.google.android.material.transition.MaterialFadeThrough
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import com.karumi.dexter.Dexter
|
||||
import com.karumi.dexter.MultiplePermissionsReport
|
||||
import com.karumi.dexter.PermissionToken
|
||||
import com.karumi.dexter.listener.PermissionRequest
|
||||
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
|
||||
import com.tommasoberlose.anotherwidget.components.events.CustomLocationEvent
|
||||
import com.tommasoberlose.anotherwidget.databinding.ActivityChooseApplicationBinding
|
||||
import com.tommasoberlose.anotherwidget.databinding.ActivityCustomLocationBinding
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.ChooseApplicationViewModel
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.CustomLocationViewModel
|
||||
import kotlinx.android.synthetic.main.activity_custom_location.*
|
||||
import kotlinx.coroutines.*
|
||||
import net.idik.lib.slimadapter.SlimAdapter
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
|
||||
class CustomLocationActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var adapter: SlimAdapter
|
||||
private lateinit var viewModel: CustomLocationViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
viewModel = ViewModelProvider(this).get(CustomLocationViewModel::class.java)
|
||||
val binding = DataBindingUtil.setContentView<ActivityCustomLocationBinding>(this, R.layout.activity_custom_location)
|
||||
|
||||
|
||||
list_view.setHasFixedSize(true)
|
||||
val mLayoutManager = LinearLayoutManager(this)
|
||||
list_view.layoutManager = mLayoutManager
|
||||
|
||||
adapter = SlimAdapter.create()
|
||||
adapter
|
||||
.register<String>(R.layout.custom_location_item) { _, injector ->
|
||||
injector
|
||||
.text(R.id.text, getString(R.string.custom_location_gps))
|
||||
.clicked(R.id.text) {
|
||||
requirePermission()
|
||||
}
|
||||
}
|
||||
.register<Address>(R.layout.custom_location_item) { item, injector ->
|
||||
injector.text(R.id.text, item.getAddressLine(0))
|
||||
injector.clicked(R.id.text) {
|
||||
Preferences.bulk {
|
||||
customLocationLat = item.latitude.toString()
|
||||
customLocationLon = item.longitude.toString()
|
||||
customLocationAdd = item.getAddressLine(0)
|
||||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
.attachTo(list_view)
|
||||
|
||||
|
||||
viewModel.addresses.observe(this, Observer {
|
||||
adapter.updateData(listOf("Default") + it)
|
||||
})
|
||||
|
||||
setupListener()
|
||||
subscribeUi(binding, viewModel)
|
||||
|
||||
location.requestFocus()
|
||||
|
||||
}
|
||||
private var searchJob: Job? = null
|
||||
|
||||
private fun subscribeUi(binding: ActivityCustomLocationBinding, viewModel: CustomLocationViewModel) {
|
||||
binding.viewModel = viewModel
|
||||
viewModel.addresses.observe(this, Observer {
|
||||
adapter.updateData(listOf("Default") + it)
|
||||
loader.visibility = View.INVISIBLE
|
||||
})
|
||||
|
||||
viewModel.locationInput.observe(this, Observer { location ->
|
||||
loader.visibility = View.VISIBLE
|
||||
searchJob?.cancel()
|
||||
searchJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||
delay(200)
|
||||
val list = if (location == null || location == "") {
|
||||
viewModel.addresses.value!!
|
||||
} else {
|
||||
val coder = Geocoder(this@CustomLocationActivity)
|
||||
try {
|
||||
coder.getFromLocationName(location, 10) as ArrayList<Address>
|
||||
} catch (ignored: Exception) {
|
||||
emptyList<Address>()
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
viewModel.addresses.value = list
|
||||
loader.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun requirePermission() {
|
||||
Dexter.withContext(this)
|
||||
.withPermissions(
|
||||
Manifest.permission.ACCESS_FINE_LOCATION
|
||||
).withListener(object: MultiplePermissionsListener {
|
||||
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
||||
report?.let {
|
||||
if (report.areAllPermissionsGranted()){
|
||||
Preferences.bulk {
|
||||
remove(Preferences::customLocationLat)
|
||||
remove(Preferences::customLocationLon)
|
||||
remove(Preferences::customLocationAdd)
|
||||
}
|
||||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun onPermissionRationaleShouldBeShown(
|
||||
permissions: MutableList<PermissionRequest>?,
|
||||
token: PermissionToken?
|
||||
) {
|
||||
// Remember to invoke this method when the custom rationale is closed
|
||||
// or just by default if you don't want to use any custom rationale.
|
||||
token?.continuePermissionRequest()
|
||||
}
|
||||
})
|
||||
.check()
|
||||
}
|
||||
|
||||
private fun setupListener() {
|
||||
action_back.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.activities
|
||||
|
||||
import android.animation.ValueAnimator
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.view.View
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.TypedValue
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.animation.addListener
|
||||
import androidx.core.animation.doOnEnd
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.tommasoberlose.anotherwidget.global.Actions
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.global.RequestCode
|
||||
import com.tommasoberlose.anotherwidget.ui.adapters.ViewPagerAdapter
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||
import com.tommasoberlose.anotherwidget.utils.*
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
||||
import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver
|
||||
import com.tommasoberlose.anotherwidget.ui.widgets.TheWidget
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
|
||||
class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
private var mAppWidgetId: Int = -1
|
||||
private lateinit var viewModel: MainViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
|
||||
|
||||
controlExtras(intent)
|
||||
|
||||
// Viewpager
|
||||
pager.adapter = ViewPagerAdapter(this)
|
||||
pager.offscreenPageLimit = 4
|
||||
TabLayoutMediator(tabs, pager) { tab, position ->
|
||||
tab.text = when (position) {
|
||||
0 -> getString(R.string.settings_general_title)
|
||||
1 -> getString(R.string.settings_calendar_title)
|
||||
2 -> getString(R.string.settings_weather_title)
|
||||
3 -> getString(R.string.settings_clock_title)
|
||||
4 -> getString(R.string.advanced_settings_title)
|
||||
else -> ""
|
||||
}
|
||||
}.attach()
|
||||
|
||||
Preferences.preferences.registerOnSharedPreferenceChangeListener(this)
|
||||
subscribeUi(viewModel)
|
||||
updateUI()
|
||||
}
|
||||
|
||||
private fun updateUI() {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val generatedView = TheWidget.generateWidgetView(this@MainActivity, preview.measuredWidth)
|
||||
generatedView.measure(0, 0)
|
||||
val bitmap = Util.getBitmapFromView(generatedView, generatedView.measuredWidth, generatedView.measuredHeight)
|
||||
withContext(Dispatchers.Main) {
|
||||
// Clock
|
||||
clock.setTextColor(Util.getFontColor())
|
||||
clock.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(this@MainActivity))
|
||||
clock.format12Hour = "hh:mm"
|
||||
|
||||
if ((Preferences.showClock && !clock.isVisible) || (!Preferences.showClock && clock.isVisible)) {
|
||||
if (Preferences.showClock) {
|
||||
clock.layoutParams = clock.layoutParams.apply {
|
||||
height = RelativeLayout.LayoutParams.WRAP_CONTENT
|
||||
}
|
||||
clock.measure(0, 0)
|
||||
}
|
||||
val initialHeight = clock.measuredHeight
|
||||
ValueAnimator.ofFloat(
|
||||
if (Preferences.showClock) 0f else 1f,
|
||||
if (Preferences.showClock) 1f else 0f
|
||||
).apply {
|
||||
duration = 500L
|
||||
addUpdateListener {
|
||||
val animatedValue = animatedValue as Float
|
||||
clock.layoutParams = clock.layoutParams.apply {
|
||||
height = (initialHeight * animatedValue).toInt()
|
||||
}
|
||||
}
|
||||
addListener(
|
||||
onStart = {
|
||||
if (Preferences.showClock) {
|
||||
clock.isVisible = true
|
||||
}
|
||||
},
|
||||
onEnd = {
|
||||
if (!Preferences.showClock) {
|
||||
clock.isVisible = false
|
||||
}
|
||||
}
|
||||
)
|
||||
}.start()
|
||||
|
||||
ValueAnimator.ofInt(
|
||||
preview.measuredHeight,
|
||||
160.toPixel(this@MainActivity) + if (Preferences.showClock) 100.toPixel(this@MainActivity) else 0
|
||||
).apply {
|
||||
duration = 500L
|
||||
addUpdateListener {
|
||||
val animatedValue = animatedValue as Int
|
||||
val layoutParams = preview.layoutParams
|
||||
layoutParams.height = animatedValue
|
||||
preview.layoutParams = layoutParams
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
widget_bitmap.setImageBitmap(bitmap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun subscribeUi(viewModel: MainViewModel) {
|
||||
viewModel.showWallpaper.observe(this, Observer {
|
||||
widget_bg.setImageDrawable(if (it) Util.getCurrentWallpaper(this) else null)
|
||||
})
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (mAppWidgetId > 0) {
|
||||
addNewWidget()
|
||||
} else {
|
||||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
|
||||
if (intent != null) {
|
||||
controlExtras(intent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun controlExtras(intent: Intent) {
|
||||
val extras = intent.extras
|
||||
if (extras != null) {
|
||||
mAppWidgetId = extras.getInt(
|
||||
AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||
AppWidgetManager.INVALID_APPWIDGET_ID)
|
||||
|
||||
if (mAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
|
||||
action_add_widget.visibility = View.VISIBLE
|
||||
action_add_widget.setOnClickListener {
|
||||
addNewWidget()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (extras.containsKey(Actions.ACTION_EXTRA_OPEN_WEATHER_PROVIDER)) {
|
||||
startActivityForResult(Intent(this, WeatherProviderActivity::class.java), RequestCode.WEATHER_PROVIDER_REQUEST_CODE.code)
|
||||
}
|
||||
if (extras.containsKey(Actions.ACTION_EXTRA_DISABLE_GPS_NOTIFICATION)) {
|
||||
Preferences.showGpsInformation = false
|
||||
sendBroadcast(Intent(Actions.ACTION_WEATHER_UPDATE))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addNewWidget() {
|
||||
val resultValue = Intent()
|
||||
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId)
|
||||
setResult(Activity.RESULT_OK, resultValue)
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
Preferences.preferences.unregisterOnSharedPreferenceChangeListener(this)
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(preferences: SharedPreferences, p1: String) {
|
||||
updateUI()
|
||||
Util.updateWidget(this)
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.activities
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.location.Address
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.android.billingclient.api.*
|
||||
import com.android.billingclient.api.BillingClient.BillingResponseCode.OK
|
||||
import com.android.billingclient.api.BillingClient.BillingResponseCode.USER_CANCELED
|
||||
import com.chibatching.kotpref.bulk
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.databinding.ActivitySupportDevBinding
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.SupportDevViewModel
|
||||
import com.tommasoberlose.anotherwidget.utils.toast
|
||||
import kotlinx.android.synthetic.main.activity_support_dev.*
|
||||
import net.idik.lib.slimadapter.SlimAdapter
|
||||
|
||||
class SupportDevActivity : AppCompatActivity(), PurchasesUpdatedListener {
|
||||
|
||||
private val BILLING_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAox5CcxuoLJ6CmNS7s6lVQzJ253njKKGF8MoQ/gQ5gEw2Fr03fBvtHpiVMpnjhNLw5NMeIpzRvkVqeQ7BfkC7c0BLCJUqf/fFA11ArQe8na6QKt5O4d+v4sbHtP7mm3GQNPOBaqRzcpFZaiAbfk6mnalo+tzM47GXrQFt5bNSrMctCs7bbChqJfH2cyMW0F8DHWEEeO5xElBmH3lh4FVpwIUTPYJIV3n0yhE3qqRA0WXkDej66g/uAt/rebmMZLmwNwIive5cObU4o41YyKRv2wSAicrv3W40LftzXAOOordIbmzDFN8ksh3VrnESqwCDGG97nZVbPG/+3LD0xHWiRwIDAQAB"
|
||||
private lateinit var viewModel: SupportDevViewModel
|
||||
private lateinit var adapter: SlimAdapter
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
viewModel = ViewModelProvider(this).get(SupportDevViewModel::class.java)
|
||||
viewModel.billingClient = BillingClient.newBuilder(this).enablePendingPurchases().setListener(this).build()
|
||||
val binding = DataBindingUtil.setContentView<ActivitySupportDevBinding>(this, R.layout.activity_support_dev)
|
||||
|
||||
|
||||
list_view.setHasFixedSize(true)
|
||||
val mLayoutManager = LinearLayoutManager(this)
|
||||
list_view.layoutManager = mLayoutManager
|
||||
|
||||
adapter = SlimAdapter.create()
|
||||
adapter
|
||||
.register<SkuDetails>(R.layout.inapp_product_layout) { item, injector ->
|
||||
injector
|
||||
.text(R.id.product_title, item.title.replace("(Another Widget)", ""))
|
||||
.text(R.id.product_price, item.price)
|
||||
.clicked(R.id.item) {
|
||||
viewModel.purchase(this, item)
|
||||
}
|
||||
}
|
||||
.attachTo(list_view)
|
||||
|
||||
viewModel.openConnection()
|
||||
subscribeUi(viewModel)
|
||||
|
||||
action_back.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
private fun subscribeUi(viewModel: SupportDevViewModel) {
|
||||
viewModel.products.observe(this, Observer {
|
||||
if (it.isNotEmpty()) {
|
||||
loader.isVisible = false
|
||||
}
|
||||
adapter.updateData(it.sortedWith(compareBy(SkuDetails::getPriceAmountMicros)))
|
||||
})
|
||||
}
|
||||
|
||||
override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) {
|
||||
if (billingResult.responseCode == OK && purchases != null) {
|
||||
for (purchase in purchases) {
|
||||
if (purchase.purchaseState == Purchase.PurchaseState.PURCHASED) {
|
||||
viewModel.handlePurchase(purchase)
|
||||
toast(getString(R.string.thanks))
|
||||
}
|
||||
}
|
||||
} else if (billingResult.responseCode == USER_CANCELED) {
|
||||
// DO nothing
|
||||
} else {
|
||||
toast(getString(R.string.error))
|
||||
}
|
||||
}
|
||||
|
||||
public override fun onDestroy() {
|
||||
viewModel.closeConnection()
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.activities
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.content.DialogInterface
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.Html
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.utils.Util
|
||||
import com.tommasoberlose.anotherwidget.utils.WeatherUtil
|
||||
import com.tommasoberlose.anotherwidget.utils.openURI
|
||||
import kotlinx.android.synthetic.main.activity_weather_provider.*
|
||||
|
||||
class WeatherProviderActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_weather_provider)
|
||||
|
||||
action_back.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
|
||||
action_save.setOnClickListener {
|
||||
Preferences.weatherProviderApi = api_key.editText?.text.toString()
|
||||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
|
||||
action_open_provider.setOnClickListener {
|
||||
openURI("https://home.openweathermap.org/users/sign_up")
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
last_info.text = Html.fromHtml(getString(R.string.api_key_info_all_set), Html.FROM_HTML_MODE_LEGACY)
|
||||
} else {
|
||||
last_info.text = Html.fromHtml(getString(R.string.api_key_info_all_set))
|
||||
}
|
||||
api_key.editText?.setText(Preferences.weatherProviderApi)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (api_key.editText?.text.toString() == "") {
|
||||
AlertDialog.Builder(this)
|
||||
.setMessage(getString(R.string.error_weather_api_key))
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(android.R.string.yes) { _, _ ->
|
||||
super.onBackPressed()
|
||||
}
|
||||
.show()
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.activity
|
||||
|
||||
import android.app.Activity
|
||||
import android.location.Address
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.`object`.Constants
|
||||
import com.tommasoberlose.anotherwidget.`object`.CustomLocationEvent
|
||||
import kotlinx.android.synthetic.main.activity_choose_application.*
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import android.content.Intent
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import com.tommasoberlose.anotherwidget.`object`.ApplicationListEvent
|
||||
import android.content.pm.PackageManager
|
||||
import android.location.Geocoder
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.tommasoberlose.anotherwidget.`object`.AppInfoSavedEvent
|
||||
import com.tommasoberlose.anotherwidget.ui.adapter.ApplicationInfoAdapter
|
||||
|
||||
|
||||
class ChooseApplicationActivity : AppCompatActivity() {
|
||||
lateinit var adapter: ApplicationInfoAdapter
|
||||
val appList = ArrayList<ApplicationInfo>()
|
||||
val appListFiltered = ArrayList<ApplicationInfo>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_choose_application)
|
||||
val pm = packageManager
|
||||
|
||||
action_default.setOnClickListener {
|
||||
selectDefaultApp()
|
||||
}
|
||||
|
||||
action_back.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
|
||||
action_none.setOnClickListener {
|
||||
removeClickAction()
|
||||
}
|
||||
|
||||
list_view.setHasFixedSize(true);
|
||||
val mLayoutManager = LinearLayoutManager(this);
|
||||
list_view.layoutManager = mLayoutManager;
|
||||
|
||||
adapter = ApplicationInfoAdapter(this, appListFiltered);
|
||||
list_view.setAdapter(adapter);
|
||||
|
||||
location.addTextChangedListener(object: TextWatcher {
|
||||
override fun afterTextChanged(text: Editable?) {
|
||||
Thread().run {
|
||||
val appsFiltered = if (text == null || text.equals("")) appList else appList.filter { pm.getApplicationLabel(it).toString().contains(text.toString(), true) }
|
||||
EventBus.getDefault().post(ApplicationListEvent(appsFiltered, true))
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
fun selectDefaultApp() {
|
||||
val resultIntent = Intent()
|
||||
resultIntent.putExtra(Constants.RESULT_APP_NAME, "")
|
||||
resultIntent.putExtra(Constants.RESULT_APP_PACKAGE, "")
|
||||
setResult(Activity.RESULT_OK, resultIntent)
|
||||
finish()
|
||||
}
|
||||
|
||||
fun removeClickAction() {
|
||||
val resultIntent = Intent()
|
||||
resultIntent.putExtra(Constants.RESULT_APP_NAME, getString(R.string.action_none))
|
||||
resultIntent.putExtra(Constants.RESULT_APP_PACKAGE, "_")
|
||||
setResult(Activity.RESULT_OK, resultIntent)
|
||||
finish()
|
||||
}
|
||||
|
||||
fun multiEventAction() {
|
||||
val resultIntent = Intent()
|
||||
resultIntent.putExtra(Constants.RESULT_APP_NAME, getString(R.string.action_go_to_next_event))
|
||||
resultIntent.putExtra(Constants.RESULT_APP_PACKAGE, Constants.PREF_SHOW_NEXT_EVENT)
|
||||
setResult(Activity.RESULT_OK, resultIntent)
|
||||
finish()
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||
fun saveApp(e: AppInfoSavedEvent) {
|
||||
val pm = packageManager
|
||||
val resultIntent = Intent()
|
||||
resultIntent.putExtra(Constants.RESULT_APP_NAME, pm.getApplicationLabel(e.app).toString())
|
||||
resultIntent.putExtra(Constants.RESULT_APP_PACKAGE, e.app.packageName)
|
||||
setResult(Activity.RESULT_OK, resultIntent)
|
||||
finish()
|
||||
}
|
||||
|
||||
public override fun onStart() {
|
||||
super.onStart()
|
||||
EventBus.getDefault().register(this)
|
||||
}
|
||||
|
||||
public override fun onResume() {
|
||||
super.onResume()
|
||||
Thread().run {
|
||||
val pm = packageManager
|
||||
val apps = pm.getInstalledApplications(0)
|
||||
EventBus.getDefault().post(ApplicationListEvent(apps, false))
|
||||
}
|
||||
}
|
||||
|
||||
public override fun onStop() {
|
||||
EventBus.getDefault().unregister(this)
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||
fun onMessageEvent(event: ApplicationListEvent) {
|
||||
if (!event.filtered) {
|
||||
appList.clear()
|
||||
event.apps.mapTo(appList, {it})
|
||||
}
|
||||
appListFiltered.clear()
|
||||
event.apps.mapTo(appListFiltered, {it})
|
||||
adapter.changeData(appListFiltered)
|
||||
}
|
||||
}
|
@ -1,117 +0,0 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.location.Address
|
||||
import android.location.Geocoder
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
import android.transition.Slide
|
||||
import android.view.Gravity
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import android.support.v4.view.ViewCompat.setAlpha
|
||||
import android.support.v4.view.ViewCompat.animate
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.ListView
|
||||
import android.widget.Toast
|
||||
import com.tommasoberlose.anotherwidget.`object`.Constants
|
||||
import com.tommasoberlose.anotherwidget.`object`.CustomLocationEvent
|
||||
import com.tommasoberlose.anotherwidget.util.WeatherUtil
|
||||
import kotlinx.android.synthetic.main.activity_custom_location.*
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CustomLocationActivity : AppCompatActivity() {
|
||||
lateinit var adapter: ArrayAdapter<String>
|
||||
val addressesList = ArrayList<Address>()
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_custom_location)
|
||||
|
||||
val SP = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
|
||||
adapter = ArrayAdapter(this, R.layout.custom_location_item, addressesList.map { it.getAddressLine(0) })
|
||||
list_view.adapter = adapter
|
||||
|
||||
list_view.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
|
||||
SP.edit()
|
||||
.putString(Constants.PREF_CUSTOM_LOCATION_LAT, addressesList[position].latitude.toString())
|
||||
.putString(Constants.PREF_CUSTOM_LOCATION_LON, addressesList[position].longitude.toString())
|
||||
.putString(Constants.PREF_CUSTOM_LOCATION_ADD, addressesList[position].getAddressLine(0))
|
||||
.commit()
|
||||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
|
||||
action_geolocation.setOnClickListener {
|
||||
SP.edit()
|
||||
.remove(Constants.PREF_CUSTOM_LOCATION_LAT)
|
||||
.remove(Constants.PREF_CUSTOM_LOCATION_LON)
|
||||
.remove(Constants.PREF_CUSTOM_LOCATION_ADD)
|
||||
.commit()
|
||||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
|
||||
location.addTextChangedListener(object: TextWatcher {
|
||||
override fun afterTextChanged(text: Editable?) {
|
||||
if (text != null && !text.equals("")) {
|
||||
Thread().run {
|
||||
val coder = Geocoder(this@CustomLocationActivity)
|
||||
try {
|
||||
val addresses = coder.getFromLocationName(text.toString(), 10) as ArrayList<Address>
|
||||
EventBus.getDefault().post(CustomLocationEvent(addresses))
|
||||
} catch (ignored: Exception) {
|
||||
EventBus.getDefault().post(CustomLocationEvent(ArrayList<Address>()))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
EventBus.getDefault().post(CustomLocationEvent(ArrayList<Address>()))
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
public override fun onStart() {
|
||||
super.onStart()
|
||||
EventBus.getDefault().register(this)
|
||||
}
|
||||
|
||||
public override fun onStop() {
|
||||
EventBus.getDefault().unregister(this)
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||
fun onMessageEvent(event: CustomLocationEvent) {
|
||||
adapter.clear()
|
||||
addressesList.clear()
|
||||
event.addresses.mapTo(addressesList, {it})
|
||||
for (a:Address in addressesList) {
|
||||
adapter.add(a.getAddressLine(0))
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
@ -1,882 +0,0 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.activity
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.content.pm.PackageManager
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.ActivityCompat
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.*
|
||||
import android.preference.PreferenceManager
|
||||
import android.view.View
|
||||
import com.tommasoberlose.anotherwidget.`object`.Constants
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.util.Util
|
||||
import com.tommasoberlose.anotherwidget.receiver.WeatherReceiver
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import android.content.Intent
|
||||
import android.content.BroadcastReceiver
|
||||
import com.tommasoberlose.anotherwidget.util.CalendarUtil
|
||||
import com.tommasoberlose.anotherwidget.util.WeatherUtil
|
||||
import android.content.DialogInterface
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.support.design.widget.BottomSheetDialog
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.text.Html
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.style.RelativeSizeSpan
|
||||
import android.util.Log
|
||||
import android.util.TypedValue
|
||||
import android.widget.Toast
|
||||
import com.crashlytics.android.Crashlytics
|
||||
import com.pes.androidmaterialcolorpickerdialog.ColorPicker
|
||||
import com.tommasoberlose.anotherwidget.`object`.CalendarSelector
|
||||
import com.tommasoberlose.anotherwidget.receiver.UpdatesReceiver
|
||||
import io.fabric.sdk.android.Fabric
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import kotlinx.android.synthetic.main.key_time_wait_layout.view.*
|
||||
import kotlinx.android.synthetic.main.main_menu_layout.view.*
|
||||
import kotlinx.android.synthetic.main.the_widget.*
|
||||
import kotlinx.android.synthetic.main.the_widget.view.*
|
||||
import java.io.File
|
||||
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
private var mAppWidgetId: Int = -1
|
||||
private lateinit var SP: SharedPreferences
|
||||
|
||||
private val receiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
updateUI()
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
Fabric.with(this, Crashlytics())
|
||||
sendBroadcast(Intent(Constants.ACTION_CALENDAR_UPDATE))
|
||||
sendBroadcast(Intent(Constants.ACTION_WEATHER_UPDATE))
|
||||
|
||||
SP = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
|
||||
controlExtras(intent)
|
||||
|
||||
action_menu.setOnClickListener {
|
||||
val mBottomSheetDialog = BottomSheetDialog(this)
|
||||
val menuView: View = getLayoutInflater().inflate(R.layout.main_menu_layout, null)
|
||||
|
||||
menuView.action_share.setOnClickListener(object: View.OnClickListener {
|
||||
override fun onClick(p0: View?) {
|
||||
Util.share(this@MainActivity)
|
||||
mBottomSheetDialog.dismiss()
|
||||
}
|
||||
})
|
||||
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_WIDGET_PREVIEW, true)) {
|
||||
menuView.widget_preview_icon.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_action_hide_preview))
|
||||
menuView.widget_preview_label.text = getString(R.string.action_hide_widget_preview)
|
||||
menuView.action_toggle_widget_preview.setOnClickListener {
|
||||
SP.edit()
|
||||
.putBoolean(Constants.PREF_SHOW_WIDGET_PREVIEW, false)
|
||||
.commit()
|
||||
updateUI()
|
||||
mBottomSheetDialog.dismiss()
|
||||
}
|
||||
} else {
|
||||
menuView.widget_preview_icon.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_action_show_preview))
|
||||
menuView.widget_preview_label.text = getString(R.string.action_show_widget_preview)
|
||||
menuView.action_toggle_widget_preview.setOnClickListener {
|
||||
SP.edit()
|
||||
.putBoolean(Constants.PREF_SHOW_WIDGET_PREVIEW, true)
|
||||
.commit()
|
||||
updateUI()
|
||||
mBottomSheetDialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
menuView.action_rate.setOnClickListener(object: View.OnClickListener {
|
||||
override fun onClick(p0: View?) {
|
||||
Util.rateApp(this@MainActivity, "https://play.google.com/store/apps/details?id=com.tommasoberlose.anotherwidget")
|
||||
mBottomSheetDialog.dismiss()
|
||||
}
|
||||
})
|
||||
|
||||
menuView.action_feedback.setOnClickListener(object: View.OnClickListener {
|
||||
override fun onClick(p0: View?) {
|
||||
Util.sendEmail(this@MainActivity)
|
||||
mBottomSheetDialog.dismiss()
|
||||
}
|
||||
})
|
||||
|
||||
menuView.action_refresh.setOnClickListener {
|
||||
WeatherUtil.updateWeather(this)
|
||||
CalendarUtil.updateEventList(this)
|
||||
Util.updateWidget(this)
|
||||
mBottomSheetDialog.dismiss()
|
||||
}
|
||||
|
||||
menuView.action_support.setOnClickListener {
|
||||
startActivity(Intent(this, SupportDevActivity::class.java))
|
||||
mBottomSheetDialog.dismiss()
|
||||
}
|
||||
|
||||
mBottomSheetDialog.setContentView(menuView)
|
||||
mBottomSheetDialog.show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (mAppWidgetId > 0) {
|
||||
addNewWidget()
|
||||
} else {
|
||||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
|
||||
if (intent != null) {
|
||||
controlExtras(intent)
|
||||
}
|
||||
}
|
||||
|
||||
fun controlExtras(intent: Intent) {
|
||||
val extras = intent.extras
|
||||
if (extras != null) {
|
||||
mAppWidgetId = extras.getInt(
|
||||
AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||
AppWidgetManager.INVALID_APPWIDGET_ID)
|
||||
|
||||
if (mAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
|
||||
action_add_widget.visibility = View.VISIBLE
|
||||
|
||||
action_add_widget.setOnClickListener {
|
||||
addNewWidget()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (extras.containsKey(Constants.ACTION_EXTRA_OPEN_WEATHER_PROVIDER)) {
|
||||
startActivityForResult(Intent(this, WeatherProviderActivity::class.java), Constants.WEATHER_PROVIDER_REQUEST_CODE)
|
||||
}
|
||||
if (extras.containsKey(Constants.ACTION_EXTRA_DISABLE_GPS_NOTIFICATION)) {
|
||||
SP.edit()
|
||||
.putBoolean(Constants.PREF_SHOW_GPS_NOTIFICATION, false)
|
||||
.apply()
|
||||
sendBroadcast(Intent(Constants.ACTION_WEATHER_UPDATE))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addNewWidget() {
|
||||
val resultValue = Intent()
|
||||
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId)
|
||||
setResult(Activity.RESULT_OK, resultValue)
|
||||
finish()
|
||||
sendBroadcast(Intent(Constants.ACTION_CALENDAR_UPDATE))
|
||||
sendBroadcast(Intent(Constants.ACTION_WEATHER_UPDATE))
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
val filter = IntentFilter()
|
||||
filter.addAction(Constants.ACTION_SOMETHING_HAPPENED);
|
||||
registerReceiver(receiver, filter);
|
||||
updateUI()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
unregisterReceiver(receiver);
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
|
||||
grantResults: IntArray) {
|
||||
when (requestCode) {
|
||||
Constants.CALENDAR_REQUEST_CODE -> if (!(permissions.size != 1 || grantResults.size != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED)) {
|
||||
sendBroadcast(Intent(Constants.ACTION_CALENDAR_UPDATE))
|
||||
updateAppWidget()
|
||||
updateSettings()
|
||||
}
|
||||
Constants.LOCATION_REQUEST_CODE -> if (!(permissions.size != 1 || grantResults.size != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED)) {
|
||||
val SP = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
sendBroadcast(Intent(Constants.ACTION_WEATHER_UPDATE))
|
||||
updateAppWidget()
|
||||
updateSettings()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateUI() {
|
||||
updateSettings()
|
||||
updateAppWidget()
|
||||
updateClockView()
|
||||
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_WIDGET_PREVIEW, true)) {
|
||||
val displayMetrics = Resources.getSystem().displayMetrics
|
||||
var width = displayMetrics.widthPixels
|
||||
if (width <= 0) {
|
||||
width = Util.convertDpToPixel(300f, this).toInt()
|
||||
}
|
||||
var height = Util.convertDpToPixel(120f, this).toInt()
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_CLOCK, false)) {
|
||||
height += Util.convertSpToPixels(SP.getFloat(Constants.PREF_TEXT_CLOCK_SIZE, 90f), this).toInt() + Util.convertDpToPixel(16f, this).toInt()
|
||||
}
|
||||
if (SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f) + SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) > 50) {
|
||||
height += Util.convertDpToPixel(24f, this).toInt()
|
||||
}
|
||||
widget_bitmap.setImageBitmap(Util.getBitmapFromView(main_layout, width, height - Util.convertDpToPixel(32f, this).toInt()))
|
||||
widget.layoutParams.height = height + Util.convertDpToPixel(16f, this).toInt()
|
||||
|
||||
widget.visibility = View.VISIBLE
|
||||
} else {
|
||||
widget.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal fun updateAppWidget() {
|
||||
val wallpaper: Drawable? = Util.getCurrentWallpaper(this)
|
||||
if (wallpaper != null) {
|
||||
widget_bg.setImageDrawable(wallpaper)
|
||||
}
|
||||
widget_bg.setBackgroundColor(Color.WHITE)
|
||||
updateCalendarView()
|
||||
updateLocationView()
|
||||
updateClockView()
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (requestCode == Constants.RESULT_CODE_CUSTOM_LOCATION && resultCode == Activity.RESULT_OK) {
|
||||
sendBroadcast(Intent(Constants.ACTION_WEATHER_UPDATE))
|
||||
updateSettings()
|
||||
} else if (requestCode == Constants.CALENDAR_APP_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) {
|
||||
SP.edit()
|
||||
.putString(Constants.PREF_CALENDAR_APP_NAME, if (data.getStringExtra(Constants.RESULT_APP_NAME) != "") data.getStringExtra(Constants.RESULT_APP_NAME) else getString(R.string.default_calendar_app))
|
||||
.putString(Constants.PREF_CALENDAR_APP_PACKAGE, data.getStringExtra(Constants.RESULT_APP_PACKAGE))
|
||||
.commit()
|
||||
Util.updateWidget(this)
|
||||
updateSettings()
|
||||
} else if (requestCode == Constants.WEATHER_APP_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) {
|
||||
SP.edit()
|
||||
.putString(Constants.PREF_WEATHER_APP_NAME, if (data.getStringExtra(Constants.RESULT_APP_NAME) != "") data.getStringExtra(Constants.RESULT_APP_NAME) else getString(R.string.default_weather_app))
|
||||
.putString(Constants.PREF_WEATHER_APP_PACKAGE, data.getStringExtra(Constants.RESULT_APP_PACKAGE))
|
||||
.commit()
|
||||
Util.updateWidget(this)
|
||||
updateSettings()
|
||||
} else if (requestCode == Constants.EVENT_APP_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) {
|
||||
SP.edit()
|
||||
.putString(Constants.PREF_EVENT_APP_NAME, if (data.getStringExtra(Constants.RESULT_APP_NAME) != "") data.getStringExtra(Constants.RESULT_APP_NAME) else getString(R.string.default_event_app))
|
||||
.putString(Constants.PREF_EVENT_APP_PACKAGE, data.getStringExtra(Constants.RESULT_APP_PACKAGE))
|
||||
.commit()
|
||||
Util.updateWidget(this)
|
||||
updateSettings()
|
||||
} else if (requestCode == Constants.CLOCK_APP_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) {
|
||||
SP.edit()
|
||||
.putString(Constants.PREF_CLOCK_APP_NAME, if (data.getStringExtra(Constants.RESULT_APP_NAME) != "") data.getStringExtra(Constants.RESULT_APP_NAME) else getString(R.string.default_clock_app))
|
||||
.putString(Constants.PREF_CLOCK_APP_PACKAGE, data.getStringExtra(Constants.RESULT_APP_PACKAGE))
|
||||
.commit()
|
||||
Util.updateWidget(this)
|
||||
updateSettings()
|
||||
} else if (requestCode == Constants.WEATHER_PROVIDER_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
|
||||
WeatherReceiver().setOneTimeUpdate(this)
|
||||
sendBroadcast(Intent(Constants.ACTION_WEATHER_UPDATE))
|
||||
updateSettings()
|
||||
} else if (requestCode == Constants.CUSTOM_FONT_CHOOSER_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) {
|
||||
/*val uri = data.data
|
||||
Log.d("AW", "File Uri: " + uri.toString())
|
||||
val path = Util.getPath(this, uri)
|
||||
Log.d("AW", "File Path: " + path)
|
||||
SP.edit()
|
||||
.putString(Constants.PREF_CUSTOM_FONT_FILE, path)
|
||||
.commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE))
|
||||
updateSettings()*/
|
||||
}
|
||||
}
|
||||
|
||||
fun updateClockView() {
|
||||
if (!SP.getBoolean(Constants.PREF_SHOW_CLOCK, false)) {
|
||||
time.visibility = View.GONE
|
||||
} else {
|
||||
time.visibility = View.VISIBLE
|
||||
}
|
||||
val now = Calendar.getInstance()
|
||||
if (SP.getString(Constants.PREF_HOUR_FORMAT, "12") == "12") {
|
||||
// time.format12Hour = "hh:mm a"
|
||||
// val textBadHour = SpannableString(Constants.badHourFormat.format(time.))
|
||||
// textBadHour.setSpan(RelativeSizeSpan(0.4f), textBadHour.length - 2,
|
||||
// textBadHour.length, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
|
||||
//
|
||||
// time.text = textBadHour
|
||||
} else {
|
||||
// time.format24Hour = "HH:mm"
|
||||
// time.text = Constants.goodHourFormat.format(now.timeInMillis)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateCalendarView() {
|
||||
val now = Calendar.getInstance()
|
||||
val calendarLayout = SP.getBoolean(Constants.PREF_SHOW_EVENTS, true) && Util.checkGrantedPermission(this, Manifest.permission.READ_CALENDAR)
|
||||
|
||||
empty_layout.visibility = View.VISIBLE
|
||||
calendar_layout.visibility = View.GONE
|
||||
var dateStringValue: String = Util.getCapWordString(Constants.engDateFormat.format(now.time))
|
||||
if (SP.getBoolean(Constants.PREF_ITA_FORMAT_DATE, false)) {
|
||||
dateStringValue = Util.getCapWordString(Constants.itDateFormat.format(now.time))
|
||||
}
|
||||
empty_date.text = dateStringValue
|
||||
|
||||
if (calendarLayout) {
|
||||
val e = CalendarUtil.getNextEvent(this)
|
||||
|
||||
if (e.id != 0.toLong()) {
|
||||
next_event.text = e.title
|
||||
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_NEXT_EVENT, false) && CalendarUtil.getEventsCount(this) > 1) {
|
||||
multiple_events.visibility = View.VISIBLE
|
||||
} else {
|
||||
multiple_events.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_DIFF_TIME, true)) {
|
||||
next_event_difference_time.text = Util.getDifferenceText(this, now.timeInMillis, e.startDate)
|
||||
next_event_difference_time.visibility = View.VISIBLE
|
||||
} else {
|
||||
next_event_difference_time.visibility = View.GONE
|
||||
}
|
||||
|
||||
|
||||
if (SP.getInt(Constants.PREF_SECOND_ROW_INFORMATION, 0) == 2 && Util.getNextAlarm(this) != null) {
|
||||
second_row_icon.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_action_alarm))
|
||||
next_event_date.text = Util.getNextAlarm(this)
|
||||
} else if (!e.address.equals("") && SP.getInt(Constants.PREF_SECOND_ROW_INFORMATION, 0) == 1) {
|
||||
second_row_icon.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_action_location))
|
||||
next_event_date.text = e.address
|
||||
} else {
|
||||
second_row_icon.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_action_calendar))
|
||||
if (!e.allDay) {
|
||||
val startHour: String = if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) Constants.badHourFormat.format(e.startDate) else Constants.goodHourFormat.format(e.startDate)
|
||||
val endHour: String = if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) Constants.badHourFormat.format(e.endDate) else Constants.goodHourFormat.format(e.endDate)
|
||||
var dayDiff = TimeUnit.MILLISECONDS.toDays(e.endDate - e.startDate)
|
||||
|
||||
val startCal = Calendar.getInstance()
|
||||
startCal.timeInMillis = e.startDate
|
||||
|
||||
val endCal = Calendar.getInstance()
|
||||
endCal.timeInMillis = e.endDate
|
||||
|
||||
if (startCal.get(Calendar.HOUR_OF_DAY) > endCal.get(Calendar.HOUR_OF_DAY)) {
|
||||
dayDiff++
|
||||
} else if (startCal.get(Calendar.HOUR_OF_DAY) == endCal.get(Calendar.HOUR_OF_DAY) && startCal.get(Calendar.MINUTE) >= endCal.get(Calendar.MINUTE)) {
|
||||
dayDiff++
|
||||
}
|
||||
var multipleDay: String = ""
|
||||
if (dayDiff > 0) {
|
||||
multipleDay = String.format(" (+%s%s)", dayDiff, getString(R.string.day_char))
|
||||
}
|
||||
next_event_date.text = String.format("%s - %s%s", startHour, endHour, multipleDay)
|
||||
} else {
|
||||
next_event_date.text = dateStringValue
|
||||
}
|
||||
}
|
||||
|
||||
empty_layout.visibility = View.GONE
|
||||
calendar_layout.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
empty_date.setTextColor(Util.getFontColor(SP))
|
||||
divider1.setTextColor(Util.getFontColor(SP))
|
||||
temp.setTextColor(Util.getFontColor(SP))
|
||||
next_event.setTextColor(Util.getFontColor(SP))
|
||||
next_event_difference_time.setTextColor(Util.getFontColor(SP))
|
||||
next_event_date.setTextColor(Util.getFontColor(SP))
|
||||
divider2.setTextColor(Util.getFontColor(SP))
|
||||
calendar_temp.setTextColor(Util.getFontColor(SP))
|
||||
second_row_icon.setColorFilter(Util.getFontColor(SP))
|
||||
// time.setTextColor(Util.getFontColor(SP))
|
||||
|
||||
|
||||
empty_date.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f))
|
||||
divider1.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f))
|
||||
temp.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f))
|
||||
next_event.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f))
|
||||
next_event_difference_time.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f))
|
||||
next_event_date.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f))
|
||||
divider2.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f))
|
||||
calendar_temp.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f))
|
||||
// time.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_CLOCK_SIZE, 90f))
|
||||
|
||||
second_row_icon.scaleX = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 18f
|
||||
second_row_icon.scaleY = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 18f
|
||||
|
||||
weather_icon.scaleX = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 18f
|
||||
weather_icon.scaleY = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 18f
|
||||
|
||||
empty_weather_icon.scaleX = SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f) / 24f
|
||||
empty_weather_icon.scaleY = SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f) / 24f
|
||||
|
||||
multiple_events.scaleX = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 16f
|
||||
multiple_events.scaleY = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 16f
|
||||
|
||||
val shadowRadius = when (SP.getInt(Constants.PREF_TEXT_SHADOW, 1)) {
|
||||
0 -> 0f
|
||||
1 -> 5f
|
||||
2 -> 4f
|
||||
else -> 5f
|
||||
}
|
||||
val shadowColor = when (SP.getInt(Constants.PREF_TEXT_SHADOW, 1)) {
|
||||
0 -> Color.TRANSPARENT
|
||||
1 -> R.color.black_50
|
||||
2 -> Color.BLACK
|
||||
else -> R.color.black_50
|
||||
}
|
||||
val shadowDy = when (SP.getInt(Constants.PREF_TEXT_SHADOW, 1)) {
|
||||
0 -> 0f
|
||||
1 -> 0f
|
||||
2 -> 1f
|
||||
else -> 0f
|
||||
}
|
||||
empty_date.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
divider1.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
temp.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
next_event.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
next_event_difference_time.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
next_event_date.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
divider2.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
calendar_temp.setShadowLayer(shadowRadius, 0f, 0f, shadowColor)
|
||||
// time.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
|
||||
if (SP.getInt(Constants.PREF_CUSTOM_FONT, Constants.CUSTOM_FONT_PRODUCT_SANS) == Constants.CUSTOM_FONT_PRODUCT_SANS) {
|
||||
val product_sans: Typeface = Typeface.createFromAsset(assets, "fonts/product_sans_regular.ttf")
|
||||
val product_sans_light: Typeface = Typeface.createFromAsset(assets, "fonts/product_sans_light.ttf")
|
||||
|
||||
|
||||
/*if (SP.getString(Constants.PREF_CUSTOM_FONT_FILE, "") != "") {
|
||||
val file = File(SP.getString(Constants.PREF_CUSTOM_FONT_FILE, ""))
|
||||
if (file.exists()) {
|
||||
Log.d("AW", "OK")
|
||||
}
|
||||
// product_sans = Typeface.createFromFile("")
|
||||
}*/
|
||||
empty_date.typeface = product_sans
|
||||
divider1.typeface = product_sans
|
||||
temp.typeface = product_sans
|
||||
next_event.typeface = product_sans
|
||||
next_event_difference_time.typeface = product_sans
|
||||
next_event_date.typeface = product_sans
|
||||
divider2.typeface = product_sans
|
||||
calendar_temp.typeface = product_sans
|
||||
//time.typeface = product_sans_light
|
||||
} else {
|
||||
empty_date.typeface = Typeface.DEFAULT
|
||||
divider1.typeface = Typeface.DEFAULT
|
||||
temp.typeface = Typeface.DEFAULT
|
||||
next_event.typeface = Typeface.DEFAULT
|
||||
next_event_difference_time.typeface = Typeface.DEFAULT
|
||||
next_event_date.typeface = Typeface.DEFAULT
|
||||
divider2.typeface = Typeface.DEFAULT
|
||||
calendar_temp.typeface = Typeface.DEFAULT
|
||||
//time.typeface = Typeface.DEFAULT
|
||||
}
|
||||
}
|
||||
|
||||
fun updateLocationView() {
|
||||
val locationLayout = SP.getBoolean(Constants.PREF_SHOW_WEATHER, true)
|
||||
|
||||
if (locationLayout && SP.contains(Constants.PREF_WEATHER_TEMP) && SP.contains(Constants.PREF_WEATHER_ICON)) {
|
||||
weather.visibility = View.VISIBLE
|
||||
calendar_weather.visibility = View.VISIBLE
|
||||
val currentTemp = String.format(Locale.getDefault(), "%.0f °%s", SP.getFloat(Constants.PREF_WEATHER_TEMP, 0f), SP.getString(Constants.PREF_WEATHER_REAL_TEMP_UNIT, "F"))
|
||||
|
||||
|
||||
weather_icon.visibility = View.VISIBLE
|
||||
empty_weather_icon.visibility = View.VISIBLE
|
||||
val icon: String = SP.getString(Constants.PREF_WEATHER_ICON, "")
|
||||
if (icon.equals("")) {
|
||||
weather_icon.visibility = View.GONE
|
||||
empty_weather_icon.visibility = View.GONE
|
||||
} else {
|
||||
weather_icon.setImageResource(WeatherUtil.getWeatherIconResource(icon))
|
||||
empty_weather_icon.setImageResource(WeatherUtil.getWeatherIconResource(icon))
|
||||
}
|
||||
|
||||
temp.text = currentTemp
|
||||
calendar_temp.text = currentTemp
|
||||
} else {
|
||||
weather.visibility = View.GONE
|
||||
calendar_weather.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
fun updateSettings() {
|
||||
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_CLOCK, false)) {
|
||||
clock_settings.visibility = View.VISIBLE
|
||||
action_show_clock.setOnClickListener {
|
||||
SP.edit()
|
||||
.putBoolean(Constants.PREF_SHOW_CLOCK, false)
|
||||
.commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE))
|
||||
}
|
||||
show_clock_label.text = getString(R.string.show_clock_visible)
|
||||
} else {
|
||||
clock_settings.visibility= View.GONE
|
||||
action_show_clock.setOnClickListener {
|
||||
SP.edit()
|
||||
.putBoolean(Constants.PREF_SHOW_CLOCK, true)
|
||||
.commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE))
|
||||
}
|
||||
show_clock_label.text = getString(R.string.show_clock_not_visible)
|
||||
}
|
||||
|
||||
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_EVENTS, true) && Util.checkGrantedPermission(this, Manifest.permission.READ_CALENDAR)) {
|
||||
calendar_settings.visibility = View.VISIBLE
|
||||
action_show_events.setOnClickListener {
|
||||
SP.edit()
|
||||
.putBoolean(Constants.PREF_SHOW_EVENTS, false)
|
||||
.commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_CALENDAR_UPDATE))
|
||||
updateSettings()
|
||||
updateAppWidget()
|
||||
}
|
||||
show_events_label.text = getString(R.string.show_events_visible)
|
||||
} else {
|
||||
calendar_settings.visibility= View.GONE
|
||||
action_show_events.setOnClickListener {
|
||||
if (Util.checkGrantedPermission(this, Manifest.permission.READ_CALENDAR)) {
|
||||
SP.edit()
|
||||
.putBoolean(Constants.PREF_SHOW_EVENTS, true)
|
||||
.commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_CALENDAR_UPDATE))
|
||||
updateSettings()
|
||||
updateAppWidget()
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(this@MainActivity, arrayOf(Manifest.permission.READ_CALENDAR), Constants.CALENDAR_REQUEST_CODE)
|
||||
}
|
||||
}
|
||||
show_events_label.text = if (Util.checkGrantedPermission(this, Manifest.permission.READ_CALENDAR)) getString(R.string.show_events_not_visible) else getString(R.string.description_permission_calendar)
|
||||
}
|
||||
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_WEATHER, true) && Util.checkGrantedPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
|
||||
weather_settings.visibility = View.VISIBLE
|
||||
action_show_weather.setOnClickListener {
|
||||
SP.edit()
|
||||
.putBoolean(Constants.PREF_SHOW_WEATHER, false)
|
||||
.commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_WEATHER_UPDATE))
|
||||
updateSettings()
|
||||
updateAppWidget()
|
||||
}
|
||||
show_weather_label.text = getString(R.string.show_weather_visible)
|
||||
} else {
|
||||
weather_settings.visibility= View.GONE
|
||||
action_show_weather.setOnClickListener {
|
||||
if (Util.checkGrantedPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
|
||||
SP.edit()
|
||||
.putBoolean(Constants.PREF_SHOW_WEATHER, true)
|
||||
.commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_WEATHER_UPDATE))
|
||||
updateSettings()
|
||||
updateAppWidget()
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(this@MainActivity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), Constants.LOCATION_REQUEST_CODE)
|
||||
}
|
||||
}
|
||||
show_weather_label.text = if (Util.checkGrantedPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)) getString(R.string.show_weather_not_visible) else getString(R.string.description_permission_location)
|
||||
}
|
||||
|
||||
temp_unit.text = if (SP.getString(Constants.PREF_WEATHER_TEMP_UNIT, "F").equals("F")) getString(R.string.fahrenheit) else getString(R.string.celsius)
|
||||
action_change_unit.setOnClickListener {
|
||||
SP.edit().putString(Constants.PREF_WEATHER_TEMP_UNIT, if (SP.getString(Constants.PREF_WEATHER_TEMP_UNIT, "F").equals("F")) "C" else "F").commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_WEATHER_UPDATE))
|
||||
updateSettings()
|
||||
}
|
||||
|
||||
all_day_label.text = if (SP.getBoolean(Constants.PREF_CALENDAR_ALL_DAY, false)) getString(R.string.settings_all_day_subtitle_visible) else getString(R.string.settings_all_day_subtitle_gone)
|
||||
action_show_all_day.setOnClickListener {
|
||||
SP.edit().putBoolean(Constants.PREF_CALENDAR_ALL_DAY, !SP.getBoolean(Constants.PREF_CALENDAR_ALL_DAY, false)).commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_CALENDAR_UPDATE))
|
||||
updateSettings()
|
||||
}
|
||||
|
||||
show_multiple_events_label.text = if (SP.getBoolean(Constants.PREF_SHOW_NEXT_EVENT, true)) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
|
||||
action_show_multiple_events.setOnClickListener {
|
||||
SP.edit().putBoolean(Constants.PREF_SHOW_NEXT_EVENT, !SP.getBoolean(Constants.PREF_SHOW_NEXT_EVENT, true)).commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE))
|
||||
updateSettings()
|
||||
}
|
||||
|
||||
show_diff_time_label.text = if (SP.getBoolean(Constants.PREF_SHOW_DIFF_TIME, true)) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
|
||||
action_show_diff_time.setOnClickListener {
|
||||
SP.edit().putBoolean(Constants.PREF_SHOW_DIFF_TIME, !SP.getBoolean(Constants.PREF_SHOW_DIFF_TIME, true)).commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE))
|
||||
updateSettings()
|
||||
}
|
||||
|
||||
show_declined_events_label.text = if (SP.getBoolean(Constants.PREF_SHOW_DECLINED_EVENTS, true)) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
|
||||
action_show_declined_events.setOnClickListener {
|
||||
SP.edit().putBoolean(Constants.PREF_SHOW_DECLINED_EVENTS, !SP.getBoolean(Constants.PREF_SHOW_DECLINED_EVENTS, true)).commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_CALENDAR_UPDATE))
|
||||
updateSettings()
|
||||
}
|
||||
|
||||
hour_format_label.text = if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) getString(R.string.settings_hour_format_subtitle_12) else getString(R.string.settings_hour_format_subtitle_24)
|
||||
action_hour_format.setOnClickListener {
|
||||
SP.edit().putString(Constants.PREF_HOUR_FORMAT, if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) "24" else "12").commit()
|
||||
Util.updateWidget(this)
|
||||
updateSettings()
|
||||
updateAppWidget()
|
||||
}
|
||||
|
||||
second_row_info_label.text = getString(Util.getSecondRowInfoString(SP.getInt(Constants.PREF_SECOND_ROW_INFORMATION, 0)))
|
||||
action_second_row_info.setOnClickListener {
|
||||
SP.edit().putInt(Constants.PREF_SECOND_ROW_INFORMATION, when (SP.getInt(Constants.PREF_SECOND_ROW_INFORMATION, 0)) {
|
||||
0 -> 1
|
||||
1 -> 2
|
||||
2 -> 0
|
||||
else -> 0
|
||||
}).commit()
|
||||
updateSettings()
|
||||
sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE))
|
||||
}
|
||||
|
||||
main_text_size_label.text = String.format("%.0f%s", SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f), "sp")
|
||||
action_main_text_size.setOnClickListener {
|
||||
var fontSize = SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f) + 1
|
||||
if (fontSize > 36) {
|
||||
fontSize = 20f
|
||||
}
|
||||
SP.edit().putFloat(Constants.PREF_TEXT_MAIN_SIZE, fontSize).commit()
|
||||
Util.updateWidget(this)
|
||||
updateSettings()
|
||||
updateAppWidget()
|
||||
}
|
||||
|
||||
second_text_size_label.text = String.format("%.0f%s", SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f), "sp")
|
||||
action_second_text_size.setOnClickListener {
|
||||
var fontSize = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) + 1
|
||||
if (fontSize > 28) {
|
||||
fontSize = 12f
|
||||
}
|
||||
SP.edit().putFloat(Constants.PREF_TEXT_SECOND_SIZE, fontSize).commit()
|
||||
Util.updateWidget(this)
|
||||
updateSettings()
|
||||
}
|
||||
|
||||
clock_text_size_label.text = String.format("%.0f%s", SP.getFloat(Constants.PREF_TEXT_CLOCK_SIZE, 90f), "sp")
|
||||
action_clock_text_size.setOnClickListener {
|
||||
var fontSize = SP.getFloat(Constants.PREF_TEXT_CLOCK_SIZE, 90f) + 5
|
||||
if (fontSize > 110) {
|
||||
fontSize = 50f
|
||||
}
|
||||
SP.edit().putFloat(Constants.PREF_TEXT_CLOCK_SIZE, fontSize).commit()
|
||||
Util.updateWidget(this)
|
||||
updateSettings()
|
||||
}
|
||||
|
||||
val textColor = try {
|
||||
Color.parseColor(SP.getString(Constants.PREF_TEXT_COLOR, "#FFFFFF"))
|
||||
} catch (e: Exception) {
|
||||
SP.edit().remove(Constants.PREF_TEXT_COLOR).commit()
|
||||
Color.parseColor(SP.getString(Constants.PREF_TEXT_COLOR, "#FFFFFF"))
|
||||
}
|
||||
font_color_label.text = SP.getString(Constants.PREF_TEXT_COLOR, "#FFFFFF").toUpperCase()
|
||||
action_font_color.setOnClickListener {
|
||||
val cp: ColorPicker = ColorPicker(this@MainActivity, Color.red(textColor), Color.green(textColor), Color.blue(textColor))
|
||||
cp.setOnColorSelected { color ->
|
||||
SP.edit().putString(Constants.PREF_TEXT_COLOR, "#" + Integer.toHexString(color)).commit()
|
||||
Util.updateWidget(this)
|
||||
updateSettings()
|
||||
updateAppWidget()
|
||||
cp.dismiss()
|
||||
}
|
||||
cp.show()
|
||||
}
|
||||
|
||||
val now = Calendar.getInstance()
|
||||
var dateStringValue: String = String.format("%s%s", Constants.engDateFormat.format(now.time)[0].toUpperCase(), Constants.engDateFormat.format(now.time).substring(1))
|
||||
if (SP.getBoolean(Constants.PREF_ITA_FORMAT_DATE, false)) {
|
||||
dateStringValue = String.format("%s%s", Constants.itDateFormat.format(now.time)[0].toUpperCase(), Constants.itDateFormat.format(now.time).substring(1))
|
||||
}
|
||||
date_format_label.text = dateStringValue
|
||||
action_date_format.setOnClickListener {
|
||||
SP.edit().putBoolean(Constants.PREF_ITA_FORMAT_DATE, !SP.getBoolean(Constants.PREF_ITA_FORMAT_DATE, false)).commit()
|
||||
Util.updateWidget(this)
|
||||
updateAppWidget()
|
||||
updateSettings()
|
||||
}
|
||||
|
||||
label_weather_refresh_period.text = getString(Util.getRefreshPeriodString(SP.getInt(Constants.PREF_WEATHER_REFRESH_PERIOD, 1)))
|
||||
action_weather_refresh_period.setOnClickListener {
|
||||
SP.edit().putInt(Constants.PREF_WEATHER_REFRESH_PERIOD, when (SP.getInt(Constants.PREF_WEATHER_REFRESH_PERIOD, 1)) {
|
||||
0 -> 1
|
||||
1 -> 2
|
||||
2 -> 3
|
||||
3 -> 4
|
||||
4 -> 5
|
||||
5 -> 0
|
||||
else -> 1
|
||||
}).commit()
|
||||
updateSettings()
|
||||
WeatherReceiver().setUpdates(this@MainActivity)
|
||||
}
|
||||
|
||||
show_until_label.text = getString(Util.getShowUntilString(SP.getInt(Constants.PREF_SHOW_UNTIL, 1)))
|
||||
action_show_until.setOnClickListener {
|
||||
SP.edit().putInt(Constants.PREF_SHOW_UNTIL, when (SP.getInt(Constants.PREF_SHOW_UNTIL, 1)) {
|
||||
0 -> 1
|
||||
1 -> 2
|
||||
2 -> 3
|
||||
3 -> 4
|
||||
4 -> 5
|
||||
5 -> 6
|
||||
6 -> 7
|
||||
7 -> 0
|
||||
else -> 1
|
||||
}).commit()
|
||||
updateSettings()
|
||||
sendBroadcast(Intent(Constants.ACTION_CALENDAR_UPDATE))
|
||||
}
|
||||
|
||||
text_shadow_label.text = getString(Util.getTextShadowString(SP.getInt(Constants.PREF_TEXT_SHADOW, 1)))
|
||||
action_text_shadow.setOnClickListener {
|
||||
SP.edit().putInt(Constants.PREF_TEXT_SHADOW, when (SP.getInt(Constants.PREF_TEXT_SHADOW, 1)) {
|
||||
0 -> 1
|
||||
1 -> 2
|
||||
2 -> 0
|
||||
else -> 1
|
||||
}).commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE))
|
||||
updateSettings()
|
||||
updateAppWidget()
|
||||
}
|
||||
|
||||
custom_font_label.text = getString(Util.getCustomFontLabel(SP.getInt(Constants.PREF_CUSTOM_FONT, Constants.CUSTOM_FONT_PRODUCT_SANS)))
|
||||
action_custom_font.setOnClickListener {
|
||||
|
||||
SP.edit().putInt(Constants.PREF_CUSTOM_FONT, when (SP.getInt(Constants.PREF_CUSTOM_FONT, Constants.CUSTOM_FONT_PRODUCT_SANS)) {
|
||||
0 -> Constants.CUSTOM_FONT_PRODUCT_SANS
|
||||
Constants.CUSTOM_FONT_PRODUCT_SANS -> 0
|
||||
else -> Constants.CUSTOM_FONT_PRODUCT_SANS
|
||||
}).commit()
|
||||
/*
|
||||
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||
intent.type = "* / *" TO FIX WITHOUT SPACE
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
|
||||
try {
|
||||
startActivityForResult(Intent.createChooser(intent, "Select a File to Upload"), Constants.CUSTOM_FONT_CHOOSER_REQUEST_CODE)
|
||||
} catch (ex: android.content.ActivityNotFoundException) {
|
||||
Toast.makeText(this, "Please install a File Manager.", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
*/
|
||||
|
||||
sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE))
|
||||
updateSettings()
|
||||
updateAppWidget()
|
||||
}
|
||||
|
||||
if (SP.getInt(Constants.PREF_WEATHER_PROVIDER, Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS) == Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS) {
|
||||
action_custom_location.visibility = View.GONE
|
||||
} else {
|
||||
label_custom_location.text = SP.getString(Constants.PREF_CUSTOM_LOCATION_ADD, getString(R.string.custom_location_gps))
|
||||
action_custom_location.setOnClickListener {
|
||||
startActivityForResult(Intent(this, CustomLocationActivity::class.java), Constants.RESULT_CODE_CUSTOM_LOCATION)
|
||||
}
|
||||
action_custom_location.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
if (SP.getInt(Constants.PREF_WEATHER_PROVIDER, Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS) == Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS) {
|
||||
label_weather_provider_api_key.text = getString(R.string.provider_google_awareness)
|
||||
alert_icon.visibility = View.GONE
|
||||
} else {
|
||||
if (WeatherUtil.getWeatherProviderKey(this, SP) == ("")) {
|
||||
label_weather_provider_api_key.text = getString(R.string.settings_weather_provider_api_key_subtitle_not_set)
|
||||
alert_icon.visibility = View.VISIBLE
|
||||
} else {
|
||||
label_weather_provider_api_key.text = getString(when (SP.getInt(Constants.PREF_WEATHER_PROVIDER, Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS)) {
|
||||
Constants.WEATHER_PROVIDER_OPEN_WEATHER -> R.string.provider_open_weather
|
||||
else -> R.string.settings_weather_provider_api_key_subtitle_all_set
|
||||
})
|
||||
alert_icon.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
action_weather_provider_api_key.setOnClickListener {
|
||||
startActivityForResult(Intent(this, WeatherProviderActivity::class.java), Constants.WEATHER_PROVIDER_REQUEST_CODE)
|
||||
}
|
||||
|
||||
calendar_app_label.text = SP.getString(Constants.PREF_CALENDAR_APP_NAME, getString(R.string.default_calendar_app))
|
||||
action_calendar_app.setOnClickListener {
|
||||
val i = Intent(this, ChooseApplicationActivity::class.java)
|
||||
i.putExtra("requestCode", Constants.CALENDAR_APP_REQUEST_CODE)
|
||||
startActivityForResult(i, Constants.CALENDAR_APP_REQUEST_CODE)
|
||||
}
|
||||
|
||||
weather_app_label.text = SP.getString(Constants.PREF_WEATHER_APP_NAME, getString(R.string.default_weather_app))
|
||||
action_weather_app.setOnClickListener {
|
||||
startActivityForResult(Intent(this, ChooseApplicationActivity::class.java), Constants.WEATHER_APP_REQUEST_CODE)
|
||||
}
|
||||
|
||||
clock_app_label.text = SP.getString(Constants.PREF_CLOCK_APP_NAME, getString(R.string.default_clock_app))
|
||||
action_clock_app.setOnClickListener {
|
||||
startActivityForResult(Intent(this, ChooseApplicationActivity::class.java), Constants.CLOCK_APP_REQUEST_CODE)
|
||||
}
|
||||
|
||||
event_app_label.text = SP.getString(Constants.PREF_EVENT_APP_NAME, getString(R.string.default_event_app))
|
||||
action_event_app.setOnClickListener {
|
||||
startActivityForResult(Intent(this, ChooseApplicationActivity::class.java), Constants.EVENT_APP_REQUEST_CODE)
|
||||
}
|
||||
|
||||
action_filter_calendar.setOnClickListener {
|
||||
val calendarSelectorList: List<CalendarSelector> = CalendarUtil.getCalendarList(this).map { CalendarSelector(it.id.toInt(), it.displayName, it.accountName) }
|
||||
var calFiltered = SP.getString(Constants.PREF_CALENDAR_FILTER, "")
|
||||
|
||||
if (!calendarSelectorList.isEmpty()) {
|
||||
val calNames = calendarSelectorList.map { if (it.name.equals(it.account_name)) String.format("%s: %s", getString(R.string.main_calendar), it.name) else it.name }.toTypedArray()
|
||||
val calSelected = calendarSelectorList.map { !calFiltered.contains(" " + Integer.toString(it.id) + ",") }.toBooleanArray()
|
||||
|
||||
AlertDialog.Builder(this).setTitle(getString(R.string.settings_filter_calendar_subtitle))
|
||||
.setMultiChoiceItems(calNames, calSelected,
|
||||
DialogInterface.OnMultiChoiceClickListener { dialog, item, isChecked ->
|
||||
val dialogItem: String = String.format(" %s%s", calendarSelectorList.get(item).id, ",")
|
||||
calFiltered = calFiltered.replace(dialogItem, "");
|
||||
if (!isChecked) {
|
||||
calFiltered += dialogItem
|
||||
}
|
||||
})
|
||||
.setPositiveButton(android.R.string.ok, { dialog: DialogInterface, _: Int ->
|
||||
SP.edit().putString(Constants.PREF_CALENDAR_FILTER, calFiltered).commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_CALENDAR_UPDATE))
|
||||
updateSettings()
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
} else {
|
||||
Toast.makeText(this, R.string.calendar_settings_list_error, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.activity
|
||||
|
||||
import android.content.Intent
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import com.anjlab.android.iab.v3.BillingProcessor
|
||||
import com.anjlab.android.iab.v3.TransactionDetails
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.util.Util
|
||||
import kotlinx.android.synthetic.main.activity_support_dev.*
|
||||
|
||||
class SupportDevActivity : AppCompatActivity(), BillingProcessor.IBillingHandler {
|
||||
internal lateinit var bp: BillingProcessor
|
||||
|
||||
internal val BILLING_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAox5CcxuoLJ6CmNS7s6lVQzJ253njKKGF8MoQ/gQ5gEw2Fr03fBvtHpiVMpnjhNLw5NMeIpzRvkVqeQ7BfkC7c0BLCJUqf/fFA11ArQe8na6QKt5O4d+v4sbHtP7mm3GQNPOBaqRzcpFZaiAbfk6mnalo+tzM47GXrQFt5bNSrMctCs7bbChqJfH2cyMW0F8DHWEEeO5xElBmH3lh4FVpwIUTPYJIV3n0yhE3qqRA0WXkDej66g/uAt/rebmMZLmwNwIive5cObU4o41YyKRv2wSAicrv3W40LftzXAOOordIbmzDFN8ksh3VrnESqwCDGG97nZVbPG/+3LD0xHWiRwIDAQAB"
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_support_dev)
|
||||
bp = BillingProcessor(this, BILLING_KEY, this)
|
||||
|
||||
action_website.setOnClickListener {
|
||||
Util.openURI(this, "http://tommasoberlose.com/")
|
||||
}
|
||||
|
||||
action_translate.setOnClickListener {
|
||||
Util.openURI(this, "https://github.com/tommasoberlose/another-widget/blob/master/app/src/main/res/values/strings.xml")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBillingInitialized() {
|
||||
loader.visibility = View.GONE
|
||||
try {
|
||||
val isAvailable = BillingProcessor.isIabServiceAvailable(this)
|
||||
val isOneTimePurchaseSupported = bp.isOneTimePurchaseSupported
|
||||
if (isAvailable && isOneTimePurchaseSupported) {
|
||||
val coffee = bp.getPurchaseListingDetails("donation_coffee")
|
||||
val donuts = bp.getPurchaseListingDetails("donation_donuts")
|
||||
val breakfast = bp.getPurchaseListingDetails("donation_breakfast")
|
||||
val lunch = bp.getPurchaseListingDetails("donation_lunch")
|
||||
val dinner = bp.getPurchaseListingDetails("donation_dinner")
|
||||
|
||||
if (coffee != null) {
|
||||
import_donation_coffee.text = coffee.priceText
|
||||
action_donation_coffee.setOnClickListener {
|
||||
bp.purchase(this, "donation_coffee")
|
||||
}
|
||||
} else {
|
||||
action_donation_coffee.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (donuts != null) {
|
||||
import_donation_donuts.text = donuts.priceText
|
||||
action_donation_donuts.setOnClickListener {
|
||||
bp.purchase(this, "donation_donuts")
|
||||
}
|
||||
} else {
|
||||
action_donation_donuts.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (breakfast != null) {
|
||||
import_donation_breakfast.text = breakfast.priceText
|
||||
action_donation_breakfast.setOnClickListener {
|
||||
bp.purchase(this, "donation_breakfast")
|
||||
}
|
||||
} else {
|
||||
action_donation_breakfast.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (lunch != null) {
|
||||
import_donation_lunch.text = lunch.priceText
|
||||
action_donation_lunch.setOnClickListener {
|
||||
bp.purchase(this, "donation_lunch")
|
||||
}
|
||||
} else {
|
||||
action_donation_lunch.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (dinner != null) {
|
||||
import_donation_dinner.text = dinner.priceText
|
||||
action_donation_dinner.setOnClickListener {
|
||||
bp.purchase(this, "donation_dinner")
|
||||
}
|
||||
} else {
|
||||
action_donation_dinner.visibility = View.GONE
|
||||
}
|
||||
|
||||
products_list.visibility = View.VISIBLE
|
||||
} else {
|
||||
products_card.visibility = View.GONE
|
||||
}
|
||||
} catch (ignored: Exception) {
|
||||
products_card.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPurchaseHistoryRestored() {
|
||||
}
|
||||
|
||||
override fun onProductPurchased(productId: String, details: TransactionDetails?) {
|
||||
Toast.makeText(this, R.string.thanks, Toast.LENGTH_SHORT).show()
|
||||
bp.consumePurchase(productId)
|
||||
}
|
||||
|
||||
override fun onBillingError(errorCode: Int, error: Throwable?) {
|
||||
Toast.makeText(this, R.string.error, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (!bp.handleActivityResult(requestCode, resultCode, data)) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
}
|
||||
|
||||
public override fun onDestroy() {
|
||||
bp.release()
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Build
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
import android.support.design.widget.BottomSheetDialog
|
||||
import android.text.Editable
|
||||
import android.text.Html
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.`object`.Constants
|
||||
import com.tommasoberlose.anotherwidget.util.CalendarUtil
|
||||
import com.tommasoberlose.anotherwidget.util.Util
|
||||
import com.tommasoberlose.anotherwidget.util.WeatherUtil
|
||||
import kotlinx.android.synthetic.main.activity_weather_provider.*
|
||||
import kotlinx.android.synthetic.main.key_time_wait_layout.view.*
|
||||
import kotlinx.android.synthetic.main.main_menu_layout.view.*
|
||||
import kotlinx.android.synthetic.main.provider_info_layout.view.*
|
||||
|
||||
class WeatherProviderActivity : AppCompatActivity() {
|
||||
|
||||
lateinit var SP: SharedPreferences
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_weather_provider)
|
||||
|
||||
SP = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
|
||||
updateUI()
|
||||
|
||||
action_save.setOnClickListener {
|
||||
SP.edit()
|
||||
.putString(WeatherUtil.getWeatherProviderKeyConstant(this, SP), api_key.text.toString())
|
||||
.commit()
|
||||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
|
||||
api_key.addTextChangedListener(object: TextWatcher {
|
||||
override fun afterTextChanged(text: Editable?) {
|
||||
if (text.toString().equals("") || text.toString().equals(
|
||||
WeatherUtil.getWeatherProviderKey(this@WeatherProviderActivity, SP))) {
|
||||
Util.collapse(button_container)
|
||||
} else {
|
||||
Util.expand(button_container)
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
|
||||
}
|
||||
})
|
||||
|
||||
action_open_provider.setOnClickListener {
|
||||
Util.openURI(this, "https://home.openweathermap.org/users/sign_up")
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
private fun updateUI() {
|
||||
val currentProvider = SP.getInt(Constants.PREF_WEATHER_PROVIDER, Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS)
|
||||
if (currentProvider == Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS) {
|
||||
api_key_container.visibility = View.GONE
|
||||
content_info.visibility = View.GONE
|
||||
} else {
|
||||
api_key_container.visibility = View.VISIBLE
|
||||
content_info.visibility = View.VISIBLE
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
last_info.text = Html.fromHtml(getString(R.string.api_key_info_all_set), Html.FROM_HTML_MODE_LEGACY)
|
||||
} else {
|
||||
last_info.text = Html.fromHtml(getString(R.string.api_key_info_all_set))
|
||||
}
|
||||
}
|
||||
label_weather_provider.text = when (currentProvider) {
|
||||
Constants.WEATHER_PROVIDER_OPEN_WEATHER -> getString(R.string.provider_open_weather)
|
||||
else -> getString(R.string.provider_google_awareness)
|
||||
}
|
||||
action_change_provider.setOnClickListener {
|
||||
SP.edit()
|
||||
.putInt(Constants.PREF_WEATHER_PROVIDER, when (currentProvider) {
|
||||
Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS -> Constants.WEATHER_PROVIDER_OPEN_WEATHER
|
||||
else -> Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS
|
||||
}).commit()
|
||||
updateUI()
|
||||
}
|
||||
|
||||
Util.collapse(button_container)
|
||||
api_key.setText(WeatherUtil.getWeatherProviderKey(this, SP))
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
val SP = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
if (!SP.getInt(Constants.PREF_WEATHER_PROVIDER, Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS).equals(Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS) && (api_key.text.toString().equals("") || !api_key.text.toString().equals(WeatherUtil.getWeatherProviderKey(this, SP)))) {
|
||||
AlertDialog.Builder(this)
|
||||
.setMessage(getString(R.string.error_weather_api_key))
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(android.R.string.yes, DialogInterface.OnClickListener { _,_ ->
|
||||
super.onBackPressed()
|
||||
})
|
||||
.show()
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.util.EventLog
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.`object`.AppInfoSavedEvent
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Created by tommaso on 15/10/17.
|
||||
*/
|
||||
class ApplicationInfoAdapter (private val context: Context, private var mDataset: ArrayList<ApplicationInfo>) : RecyclerView.Adapter<ApplicationInfoAdapter.ViewHolder>() {
|
||||
|
||||
class ViewHolder(var view: View, var text: TextView, var icon: ImageView) : RecyclerView.ViewHolder(view)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val v = LayoutInflater.from(parent.context).inflate(R.layout.application_info_layout, parent, false)
|
||||
return ViewHolder(v, v.findViewById(R.id.text), v.findViewById(R.id.icon))
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val pm = context.packageManager
|
||||
val app = mDataset[position]
|
||||
holder.text.text = pm.getApplicationLabel(app).toString()
|
||||
try {
|
||||
holder.icon.setImageDrawable(app.loadIcon(pm))
|
||||
} catch (ignore: Exception) {
|
||||
}
|
||||
|
||||
holder.view.setOnClickListener {
|
||||
EventBus.getDefault().post(AppInfoSavedEvent(app))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return mDataset.size
|
||||
}
|
||||
|
||||
fun changeData(newData: ArrayList<ApplicationInfo>) {
|
||||
mDataset = newData
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.adapters
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import com.tommasoberlose.anotherwidget.ui.fragments.*
|
||||
|
||||
class ViewPagerAdapter(fragmentActivity: FragmentActivity) :
|
||||
FragmentStateAdapter(fragmentActivity) {
|
||||
|
||||
override fun getItemCount(): Int = 5
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return when (position) {
|
||||
1 -> CalendarSettingsFragment.newInstance()
|
||||
2 -> WeatherSettingsFragment.newInstance()
|
||||
3 -> ClockSettingsFragment.newInstance()
|
||||
4 -> AdvancedSettingsFragment.newInstance()
|
||||
else -> GeneralSettingsFragment.newInstance()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,175 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.fragments
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.karumi.dexter.Dexter
|
||||
import com.karumi.dexter.MultiplePermissionsReport
|
||||
import com.karumi.dexter.PermissionToken
|
||||
import com.karumi.dexter.listener.PermissionRequest
|
||||
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
|
||||
import com.tommasoberlose.anotherwidget.databinding.FragmentAdvancedSettingsBinding
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
||||
import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver
|
||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
||||
import com.tommasoberlose.anotherwidget.ui.activities.SupportDevActivity
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||
import com.tommasoberlose.anotherwidget.utils.CalendarUtil
|
||||
import com.tommasoberlose.anotherwidget.utils.Util
|
||||
import com.tommasoberlose.anotherwidget.utils.openURI
|
||||
import kotlinx.android.synthetic.main.fragment_advanced_settings.*
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
class AdvancedSettingsFragment : Fragment() {
|
||||
|
||||
companion object {
|
||||
fun newInstance() = AdvancedSettingsFragment()
|
||||
}
|
||||
|
||||
private lateinit var viewModel: MainViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
|
||||
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
|
||||
val binding = DataBindingUtil.inflate<FragmentAdvancedSettingsBinding>(inflater, R.layout.fragment_advanced_settings, container, false)
|
||||
|
||||
subscribeUi(binding, viewModel)
|
||||
|
||||
binding.lifecycleOwner = this
|
||||
binding.viewModel = viewModel
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
setupListener()
|
||||
}
|
||||
|
||||
private fun subscribeUi(
|
||||
binding: FragmentAdvancedSettingsBinding,
|
||||
viewModel: MainViewModel
|
||||
) {
|
||||
viewModel.darkThemePreference.observe(viewLifecycleOwner, Observer {
|
||||
AppCompatDelegate.setDefaultNightMode(it)
|
||||
theme.text = when (it) {
|
||||
AppCompatDelegate.MODE_NIGHT_NO -> getString(R.string.settings_subtitle_dark_theme_light)
|
||||
AppCompatDelegate.MODE_NIGHT_YES -> getString(R.string.settings_subtitle_dark_theme_dark)
|
||||
AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY -> getString(R.string.settings_subtitle_dark_theme_by_battery_saver)
|
||||
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM -> getString(R.string.settings_subtitle_dark_theme_follow_system)
|
||||
else -> ""
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.showWallpaper.observe(viewLifecycleOwner, Observer {
|
||||
show_wallpaper_label.text = if (it && requireActivity().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
|
||||
})
|
||||
}
|
||||
|
||||
private fun setupListener() {
|
||||
action_change_theme.setOnClickListener {
|
||||
maintainScrollPosition {
|
||||
BottomSheetMenu<Int>(requireContext())
|
||||
.selectResource(Preferences.darkThemePreference)
|
||||
.addItem(
|
||||
getString(R.string.settings_subtitle_dark_theme_light),
|
||||
AppCompatDelegate.MODE_NIGHT_NO
|
||||
)
|
||||
.addItem(
|
||||
getString(R.string.settings_subtitle_dark_theme_dark),
|
||||
AppCompatDelegate.MODE_NIGHT_YES
|
||||
)
|
||||
.addItem(
|
||||
getString(R.string.settings_subtitle_dark_theme_default),
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM else AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY
|
||||
)
|
||||
.addOnSelectItemListener { value ->
|
||||
Preferences.darkThemePreference = value
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
|
||||
action_show_wallpaper.setOnClickListener {
|
||||
maintainScrollPosition {
|
||||
if (Preferences.showWallpaper) {
|
||||
Preferences.showWallpaper = false
|
||||
} else {
|
||||
requirePermission()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
action_translate.setOnClickListener {
|
||||
activity?.openURI("https://github.com/tommasoberlose/another-widget/blob/master/app/src/main/res/values/strings.xml")
|
||||
}
|
||||
|
||||
action_website.setOnClickListener {
|
||||
activity?.openURI("http://tommasoberlose.com/")
|
||||
}
|
||||
|
||||
action_help_dev.setOnClickListener {
|
||||
startActivity(Intent(requireContext(), SupportDevActivity::class.java))
|
||||
}
|
||||
|
||||
action_refresh_widget.setOnClickListener {
|
||||
Util.updateWidget(requireContext())
|
||||
CalendarUtil.updateEventList(requireContext())
|
||||
}
|
||||
}
|
||||
|
||||
private fun maintainScrollPosition(callback: () -> Unit) {
|
||||
val scrollPosition = scrollView.scrollY
|
||||
callback.invoke()
|
||||
lifecycleScope.launch {
|
||||
delay(200)
|
||||
scrollView.smoothScrollTo(0, scrollPosition)
|
||||
}
|
||||
}
|
||||
|
||||
private fun requirePermission() {
|
||||
Dexter.withContext(requireContext())
|
||||
.withPermissions(
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
).withListener(object: MultiplePermissionsListener {
|
||||
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
||||
report?.let {
|
||||
Preferences.showWallpaper = report.areAllPermissionsGranted()
|
||||
}
|
||||
}
|
||||
override fun onPermissionRationaleShouldBeShown(
|
||||
permissions: MutableList<PermissionRequest>?,
|
||||
token: PermissionToken?
|
||||
) {
|
||||
// Remember to invoke this method when the custom rationale is closed
|
||||
// or just by default if you don't want to use any custom rationale.
|
||||
token?.continuePermissionRequest()
|
||||
}
|
||||
})
|
||||
.check()
|
||||
}
|
||||
}
|
@ -0,0 +1,330 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.fragments
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.SimpleAdapter
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.chibatching.kotpref.bulk
|
||||
import com.karumi.dexter.Dexter
|
||||
import com.karumi.dexter.MultiplePermissionsReport
|
||||
import com.karumi.dexter.PermissionToken
|
||||
import com.karumi.dexter.listener.PermissionRequest
|
||||
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
|
||||
import com.tommasoberlose.anotherwidget.components.CalendarSelector
|
||||
import com.tommasoberlose.anotherwidget.databinding.FragmentCalendarSettingsBinding
|
||||
import com.tommasoberlose.anotherwidget.global.Constants
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.global.RequestCode
|
||||
import com.tommasoberlose.anotherwidget.ui.activities.ChooseApplicationActivity
|
||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||
import com.tommasoberlose.anotherwidget.utils.CalendarUtil
|
||||
import com.tommasoberlose.anotherwidget.utils.Util
|
||||
import com.tommasoberlose.anotherwidget.utils.toast
|
||||
import kotlinx.android.synthetic.main.fragment_calendar_settings.*
|
||||
import kotlinx.android.synthetic.main.fragment_calendar_settings.scrollView
|
||||
import kotlinx.android.synthetic.main.fragment_weather_settings.*
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class CalendarSettingsFragment : Fragment() {
|
||||
|
||||
companion object {
|
||||
fun newInstance() = CalendarSettingsFragment()
|
||||
}
|
||||
|
||||
private lateinit var viewModel: MainViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
|
||||
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
|
||||
val binding = DataBindingUtil.inflate<FragmentCalendarSettingsBinding>(inflater, R.layout.fragment_calendar_settings, container, false)
|
||||
|
||||
subscribeUi(binding, viewModel)
|
||||
|
||||
binding.lifecycleOwner = this
|
||||
binding.viewModel = viewModel
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
setupListener()
|
||||
}
|
||||
|
||||
private fun subscribeUi(
|
||||
binding: FragmentCalendarSettingsBinding,
|
||||
viewModel: MainViewModel
|
||||
) {
|
||||
viewModel.showEvents.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
binding.isCalendarEnabled = it
|
||||
}
|
||||
checkReadEventsPermission()
|
||||
})
|
||||
|
||||
viewModel.calendarAllDay.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
all_day_label.text =
|
||||
if (it) getString(R.string.settings_all_day_subtitle_visible) else getString(R.string.settings_all_day_subtitle_gone)
|
||||
}
|
||||
checkReadEventsPermission()
|
||||
})
|
||||
|
||||
viewModel.showDeclinedEvents.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
show_declined_events_label.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
|
||||
}
|
||||
checkReadEventsPermission()
|
||||
})
|
||||
|
||||
viewModel.secondRowInformation.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
second_row_info_label.text = getString(Util.getSecondRowInfoString(it))
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.showDiffTime.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
show_diff_time_label.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.showUntil.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
show_until_label.text = getString(Util.getShowUntilString(it))
|
||||
}
|
||||
checkReadEventsPermission()
|
||||
})
|
||||
|
||||
viewModel.showNextEvent.observe(viewLifecycleOwner, Observer {
|
||||
show_multiple_events_label.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
|
||||
})
|
||||
|
||||
viewModel.dateFormat.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
val now = Calendar.getInstance()
|
||||
var dateStringValue: String = String.format("%s%s", SimpleDateFormat(Constants.engDateFormat, Locale.getDefault()).format(now.time)[0].toUpperCase(), SimpleDateFormat(Constants.engDateFormat, Locale.getDefault()).format(now.time).substring(1))
|
||||
if (it) {
|
||||
dateStringValue = String.format("%s%s", SimpleDateFormat(Constants.itDateFormat, Locale.getDefault()).format(now.time)[0].toUpperCase(), SimpleDateFormat(Constants.itDateFormat, Locale.getDefault()).format(now.time).substring(1))
|
||||
}
|
||||
date_format_label.text = dateStringValue
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.calendarAppName.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
calendar_app_label.text = if (it != "") it else getString(R.string.default_calendar_app)
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.eventAppName.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
event_app_label.text = if (it != "") it else getString(R.string.default_calendar_app)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
private fun setupListener() {
|
||||
|
||||
action_show_events.setOnClickListener {
|
||||
Preferences.showEvents = !Preferences.showEvents
|
||||
}
|
||||
|
||||
action_filter_calendar.setOnClickListener {
|
||||
val calendarSelectorList: List<CalendarSelector> = CalendarUtil.getCalendarList(requireContext()).map { CalendarSelector(it.id.toInt(), it.displayName, it.accountName) }
|
||||
var calFiltered = Preferences.calendarFilter
|
||||
|
||||
if (calendarSelectorList.isNotEmpty()) {
|
||||
val calNames = calendarSelectorList.map { if (it.name == it.account_name) String.format("%s: %s", getString(R.string.main_calendar), it.name) else it.name }.toTypedArray()
|
||||
val calSelected = calendarSelectorList.map { !calFiltered.contains(" " + it.id.toString() + ",") }.toBooleanArray()
|
||||
|
||||
AlertDialog.Builder(requireContext()).setTitle(getString(R.string.settings_filter_calendar_subtitle))
|
||||
.setMultiChoiceItems(calNames, calSelected) { _, item, isChecked ->
|
||||
val dialogItem: String = String.format(" %s%s", calendarSelectorList.get(item).id, ",")
|
||||
calFiltered = calFiltered.replace(dialogItem, "");
|
||||
if (!isChecked) {
|
||||
calFiltered += dialogItem
|
||||
}
|
||||
}
|
||||
.setPositiveButton(android.R.string.ok) { _: DialogInterface, _: Int ->
|
||||
Preferences.calendarFilter = calFiltered
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
} else {
|
||||
requireActivity().toast(getString(R.string.calendar_settings_list_error))
|
||||
}
|
||||
}
|
||||
|
||||
action_show_all_day.setOnClickListener {
|
||||
if (Preferences.showEvents) {
|
||||
BottomSheetMenu<Boolean>(requireContext()).selectResource(Preferences.calendarAllDay)
|
||||
.addItem(getString(R.string.settings_all_day_subtitle_visible), true)
|
||||
.addItem(getString(R.string.settings_all_day_subtitle_gone), false)
|
||||
.addOnSelectItemListener { value ->
|
||||
Preferences.calendarAllDay = value
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
|
||||
action_show_declined_events.setOnClickListener {
|
||||
if (Preferences.showEvents) {
|
||||
BottomSheetMenu<Boolean>(requireContext()).selectResource(Preferences.showDeclinedEvents)
|
||||
.addItem(getString(R.string.settings_visible), true)
|
||||
.addItem(getString(R.string.settings_not_visible), false)
|
||||
.addOnSelectItemListener { value ->
|
||||
Preferences.showDeclinedEvents = value
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
|
||||
action_show_multiple_events.setOnClickListener {
|
||||
if (Preferences.showEvents) {
|
||||
BottomSheetMenu<Boolean>(requireContext()).selectResource(Preferences.showNextEvent)
|
||||
.addItem(getString(R.string.settings_visible), true)
|
||||
.addItem(getString(R.string.settings_not_visible), false)
|
||||
.addOnSelectItemListener { value ->
|
||||
Preferences.showNextEvent = value
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
|
||||
action_show_diff_time.setOnClickListener {
|
||||
if (Preferences.showEvents) {
|
||||
BottomSheetMenu<Boolean>(requireContext()).selectResource(Preferences.showDiffTime)
|
||||
.addItem(getString(R.string.settings_visible), true)
|
||||
.addItem(getString(R.string.settings_not_visible), false)
|
||||
.addOnSelectItemListener { value ->
|
||||
Preferences.showDiffTime = value
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
|
||||
action_second_row_info.setOnClickListener {
|
||||
if (Preferences.showEvents) {
|
||||
val dialog = BottomSheetMenu<Int>(requireContext()).selectResource(Preferences.secondRowInformation)
|
||||
(0 .. 1).forEach {
|
||||
dialog.addItem(getString(Util.getSecondRowInfoString(it)), it)
|
||||
}
|
||||
dialog.addOnSelectItemListener { value ->
|
||||
Preferences.secondRowInformation = value
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
|
||||
action_show_until.setOnClickListener {
|
||||
if (Preferences.showEvents) {
|
||||
val dialog = BottomSheetMenu<Int>(requireContext()).selectResource(Preferences.showUntil)
|
||||
intArrayOf(6,7,0,1,2,3,4,5).forEach {
|
||||
dialog.addItem(getString(Util.getShowUntilString(it)), it)
|
||||
}
|
||||
dialog.addOnSelectItemListener { value ->
|
||||
Preferences.showUntil = value
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
|
||||
action_event_app.setOnClickListener {
|
||||
startActivityForResult(Intent(requireContext(), ChooseApplicationActivity::class.java), RequestCode.EVENT_APP_REQUEST_CODE.code)
|
||||
}
|
||||
|
||||
action_calendar_app.setOnClickListener {
|
||||
startActivityForResult(Intent(requireContext(), ChooseApplicationActivity::class.java), RequestCode.CALENDAR_APP_REQUEST_CODE.code)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkReadEventsPermission(showEvents: Boolean = Preferences.showEvents) {
|
||||
if (requireActivity().checkCallingOrSelfPermission(Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED) {
|
||||
show_events_label.text = if (showEvents) getString(R.string.show_events_visible) else getString(R.string.show_events_not_visible)
|
||||
read_calendar_permission_alert_icon.isVisible = false
|
||||
CalendarUtil.updateEventList(requireContext())
|
||||
} else {
|
||||
show_events_label.text = if (showEvents) getString(R.string.description_permission_calendar) else getString(R.string.show_events_not_visible)
|
||||
read_calendar_permission_alert_icon.isVisible = showEvents
|
||||
read_calendar_permission_alert_icon.setOnClickListener {
|
||||
requirePermission()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun requirePermission() {
|
||||
Dexter.withContext(requireActivity())
|
||||
.withPermissions(
|
||||
Manifest.permission.READ_CALENDAR
|
||||
).withListener(object: MultiplePermissionsListener {
|
||||
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
||||
report?.let {
|
||||
if (report.areAllPermissionsGranted()){
|
||||
checkReadEventsPermission()
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun onPermissionRationaleShouldBeShown(
|
||||
permissions: MutableList<PermissionRequest>?,
|
||||
token: PermissionToken?
|
||||
) {
|
||||
// Remember to invoke this method when the custom rationale is closed
|
||||
// or just by default if you don't want to use any custom rationale.
|
||||
token?.continuePermissionRequest()
|
||||
}
|
||||
})
|
||||
.check()
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
when (requestCode) {
|
||||
RequestCode.CALENDAR_APP_REQUEST_CODE.code -> {
|
||||
Preferences.bulk {
|
||||
calendarAppName = data?.getStringExtra(Constants.RESULT_APP_NAME) ?: getString(R.string.default_calendar_app)
|
||||
calendarAppPackage = data?.getStringExtra(Constants.RESULT_APP_PACKAGE) ?: ""
|
||||
}
|
||||
}
|
||||
RequestCode.EVENT_APP_REQUEST_CODE.code -> {
|
||||
Preferences.bulk {
|
||||
eventAppName = data?.getStringExtra(Constants.RESULT_APP_NAME) ?: getString(R.string.default_event_app)
|
||||
eventAppPackage = data?.getStringExtra(Constants.RESULT_APP_PACKAGE) ?: ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
private fun maintainScrollPosition(callback: () -> Unit) {
|
||||
val scrollPosition = scrollView.scrollY
|
||||
callback.invoke()
|
||||
lifecycleScope.launch {
|
||||
delay(200)
|
||||
scrollView.smoothScrollTo(0, scrollPosition)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.fragments
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.chibatching.kotpref.bulk
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
|
||||
import com.tommasoberlose.anotherwidget.databinding.FragmentCalendarSettingsBinding
|
||||
import com.tommasoberlose.anotherwidget.databinding.FragmentClockSettingsBinding
|
||||
import com.tommasoberlose.anotherwidget.global.Constants
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.global.RequestCode
|
||||
import com.tommasoberlose.anotherwidget.ui.activities.ChooseApplicationActivity
|
||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||
import com.tommasoberlose.anotherwidget.utils.Util
|
||||
import com.tommasoberlose.anotherwidget.utils.toast
|
||||
import kotlinx.android.synthetic.main.fragment_clock_settings.*
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class ClockSettingsFragment : Fragment() {
|
||||
|
||||
companion object {
|
||||
fun newInstance() = ClockSettingsFragment()
|
||||
}
|
||||
|
||||
private lateinit var viewModel: MainViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
|
||||
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
|
||||
val binding = DataBindingUtil.inflate<FragmentClockSettingsBinding>(inflater, R.layout.fragment_clock_settings, container, false)
|
||||
|
||||
subscribeUi(binding, viewModel)
|
||||
|
||||
binding.lifecycleOwner = this
|
||||
binding.viewModel = viewModel
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
setupListener()
|
||||
}
|
||||
|
||||
private fun subscribeUi(
|
||||
binding: FragmentClockSettingsBinding,
|
||||
viewModel: MainViewModel
|
||||
) {
|
||||
viewModel.showClock.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
show_clock_label.text =
|
||||
if (it) getString(R.string.show_clock_visible) else getString(R.string.show_clock_not_visible)
|
||||
binding.isClockVisible = it
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.clockTextSize.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
clock_text_size_label.text = String.format("%.0fsp", it)
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.showNextAlarm.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
show_next_alarm_label.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.clockAppName.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
clock_app_label.text =
|
||||
if (Preferences.clockAppName != "") Preferences.clockAppName else getString(R.string.default_clock_app)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun setupListener() {
|
||||
action_show_clock.setOnClickListener {
|
||||
Preferences.showClock = !Preferences.showClock
|
||||
}
|
||||
|
||||
action_clock_text_size.setOnClickListener {
|
||||
val dialog = BottomSheetMenu<Float>(requireContext()).selectResource(Preferences.clockTextSize)
|
||||
(46 downTo 28).filter { it % 2 == 0 }.forEach {
|
||||
dialog.addItem("${it}sp", it.toFloat())
|
||||
}
|
||||
dialog.addOnSelectItemListener { value ->
|
||||
Preferences.clockTextSize = value
|
||||
}.show()
|
||||
}
|
||||
|
||||
action_show_next_alarm.setOnClickListener {
|
||||
BottomSheetMenu<Boolean>(requireContext()).selectResource(Preferences.showNextAlarm)
|
||||
.addItem(getString(R.string.settings_visible), true)
|
||||
.addItem(getString(R.string.settings_not_visible), false)
|
||||
.addOnSelectItemListener { value ->
|
||||
Preferences.showNextAlarm = value
|
||||
}.show()
|
||||
}
|
||||
|
||||
action_clock_app.setOnClickListener {
|
||||
if (Preferences.showClock) {
|
||||
startActivityForResult(Intent(requireActivity(), ChooseApplicationActivity::class.java),
|
||||
RequestCode.CLOCK_APP_REQUEST_CODE.code
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (resultCode == Activity.RESULT_OK && requestCode == RequestCode.CLOCK_APP_REQUEST_CODE.code) {
|
||||
Preferences.bulk {
|
||||
clockAppName = data?.getStringExtra(Constants.RESULT_APP_NAME) ?: getString(R.string.default_clock_app)
|
||||
clockAppPackage = data?.getStringExtra(Constants.RESULT_APP_PACKAGE) ?: ""
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
private fun maintainScrollPosition(callback: () -> Unit) {
|
||||
val scrollPosition = scrollView.scrollY
|
||||
callback.invoke()
|
||||
lifecycleScope.launch {
|
||||
delay(200)
|
||||
scrollView.smoothScrollTo(0, scrollPosition)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,208 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.fragments
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
|
||||
import com.tommasoberlose.anotherwidget.databinding.FragmentGeneralSettingsBinding
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.global.RequestCode
|
||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||
import com.tommasoberlose.anotherwidget.utils.Util
|
||||
import com.tommasoberlose.anotherwidget.utils.toPixel
|
||||
import com.tommasoberlose.anotherwidget.utils.toast
|
||||
import dev.sasikanth.colorsheet.ColorSheet
|
||||
import kotlinx.android.synthetic.main.fragment_general_settings.*
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
|
||||
|
||||
class GeneralSettingsFragment : Fragment() {
|
||||
|
||||
companion object {
|
||||
fun newInstance() = GeneralSettingsFragment()
|
||||
}
|
||||
|
||||
private lateinit var viewModel: MainViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
|
||||
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
|
||||
val binding = DataBindingUtil.inflate<FragmentGeneralSettingsBinding>(inflater, R.layout.fragment_general_settings, container, false)
|
||||
|
||||
subscribeUi(binding, viewModel)
|
||||
|
||||
binding.lifecycleOwner = this
|
||||
binding.viewModel = viewModel
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
setupListener()
|
||||
}
|
||||
|
||||
|
||||
private fun subscribeUi(
|
||||
binding: FragmentGeneralSettingsBinding,
|
||||
viewModel: MainViewModel
|
||||
) {
|
||||
|
||||
viewModel.textMainSize.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
main_text_size_label.text = String.format("%.0fsp", it)
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.textSecondSize.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
second_text_size_label.text = String.format("%.0fsp", it)
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.textGlobalColor.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
try {
|
||||
Color.parseColor(it)
|
||||
} catch (e: Exception) {
|
||||
Preferences.textGlobalColor = "#FFFFFF"
|
||||
}
|
||||
font_color_label.text = it.toUpperCase()
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.textShadow.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
text_shadow_label.text = getString(Util.getTextShadowString(it))
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.customFont.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
custom_font_label.text = getString(Util.getCustomFontLabel(it))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun maintainScrollPosition(callback: () -> Unit) {
|
||||
val scrollPosition = scrollView.scrollY
|
||||
callback.invoke()
|
||||
lifecycleScope.launch {
|
||||
delay(200)
|
||||
scrollView.smoothScrollTo(0, scrollPosition)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupListener() {
|
||||
action_main_text_size.setOnClickListener {
|
||||
val dialog = BottomSheetMenu<Float>(requireContext()).selectResource(Preferences.textMainSize)
|
||||
(32 downTo 20).filter { it % 2 == 0 }.forEach {
|
||||
dialog.addItem("${it}sp", it.toFloat())
|
||||
}
|
||||
dialog.addOnSelectItemListener { value ->
|
||||
Preferences.textMainSize = value
|
||||
}.show()
|
||||
}
|
||||
|
||||
action_second_text_size.setOnClickListener {
|
||||
val dialog = BottomSheetMenu<Float>(requireContext()).selectResource(Preferences.textSecondSize)
|
||||
(24 downTo 12).filter { it % 2 == 0 }.forEach {
|
||||
dialog.addItem("${it}sp", it.toFloat())
|
||||
}
|
||||
dialog.addOnSelectItemListener { value ->
|
||||
Preferences.textSecondSize = value
|
||||
}.show()
|
||||
}
|
||||
|
||||
action_font_color.setOnClickListener {
|
||||
val textColor = try {
|
||||
Color.parseColor(Preferences.textGlobalColor)
|
||||
} catch (e: Exception) {
|
||||
Preferences.textGlobalColor = "#FFFFFF"
|
||||
Color.parseColor(Preferences.textGlobalColor)
|
||||
}
|
||||
ColorSheet()
|
||||
.cornerRadius(16.toPixel(requireContext()))
|
||||
.colorPicker(
|
||||
colors = requireActivity().resources.getIntArray(R.array.grey),
|
||||
selectedColor = textColor,
|
||||
listener = { color ->
|
||||
Preferences.textGlobalColor = "#" + Integer.toHexString(color)
|
||||
})
|
||||
.show(requireActivity().supportFragmentManager)
|
||||
}
|
||||
|
||||
action_text_shadow.setOnClickListener {
|
||||
val dialog = BottomSheetMenu<Int>(requireContext()).selectResource(Preferences.textShadow)
|
||||
(2 downTo 0).forEach {
|
||||
dialog.addItem(getString(Util.getTextShadowString(it)), it)
|
||||
}
|
||||
dialog.addOnSelectItemListener { value ->
|
||||
Preferences.textShadow = value
|
||||
}.show()
|
||||
}
|
||||
|
||||
action_custom_font.setOnClickListener {
|
||||
val dialog = BottomSheetMenu<Int>(requireContext()).selectResource(Preferences.customFont)
|
||||
(0..1).forEach {
|
||||
dialog.addItem(getString(Util.getCustomFontLabel(it)), it)
|
||||
}
|
||||
dialog.addOnSelectItemListener { value ->
|
||||
Preferences.customFont = value
|
||||
}.show()
|
||||
|
||||
/*
|
||||
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||
intent.type = "* / *" TO FIX WITHOUT SPACE
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
|
||||
try {
|
||||
startActivityForResult(Intent.createChooser(intent, "Select a File to Upload"), Constants.CUSTOM_FONT_CHOOSER_REQUEST_CODE)
|
||||
} catch (ex: android.content.ActivityNotFoundException) {
|
||||
Toast.makeText(this, "Please install a File Manager.", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
when (requestCode) {
|
||||
RequestCode.CUSTOM_FONT_CHOOSER_REQUEST_CODE.code -> {
|
||||
/*val uri = data.data
|
||||
Log.d("AW", "File Uri: " + uri.toString())
|
||||
val path = Util.getPath(this, uri)
|
||||
Log.d("AW", "File Path: " + path)
|
||||
SP.edit()
|
||||
.putString(Constants.PREF_CUSTOM_FONT_FILE, path)
|
||||
.commit()
|
||||
sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE))
|
||||
updateSettings()*/
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
}
|
@ -0,0 +1,253 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.fragments
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.chibatching.kotpref.bulk
|
||||
import com.karumi.dexter.Dexter
|
||||
import com.karumi.dexter.MultiplePermissionsReport
|
||||
import com.karumi.dexter.PermissionToken
|
||||
import com.karumi.dexter.listener.PermissionRequest
|
||||
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
|
||||
import com.tommasoberlose.anotherwidget.databinding.FragmentWeatherSettingsBinding
|
||||
import com.tommasoberlose.anotherwidget.global.Constants
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.global.RequestCode
|
||||
import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver
|
||||
import com.tommasoberlose.anotherwidget.ui.activities.ChooseApplicationActivity
|
||||
import com.tommasoberlose.anotherwidget.ui.activities.CustomLocationActivity
|
||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
||||
import com.tommasoberlose.anotherwidget.ui.activities.WeatherProviderActivity
|
||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||
import com.tommasoberlose.anotherwidget.utils.Util
|
||||
import kotlinx.android.synthetic.main.fragment_weather_settings.*
|
||||
import kotlinx.android.synthetic.main.fragment_weather_settings.scrollView
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class WeatherSettingsFragment : Fragment() {
|
||||
|
||||
companion object {
|
||||
fun newInstance() = WeatherSettingsFragment()
|
||||
}
|
||||
|
||||
private lateinit var viewModel: MainViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
|
||||
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
|
||||
val binding = DataBindingUtil.inflate<FragmentWeatherSettingsBinding>(inflater, R.layout.fragment_weather_settings, container, false)
|
||||
|
||||
subscribeUi(binding, viewModel)
|
||||
|
||||
binding.lifecycleOwner = this
|
||||
binding.viewModel = viewModel
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
setupListener()
|
||||
}
|
||||
|
||||
private fun subscribeUi(
|
||||
binding: FragmentWeatherSettingsBinding,
|
||||
viewModel: MainViewModel
|
||||
) {
|
||||
viewModel.showWeather.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
show_weather_label.text =
|
||||
if (it) getString(R.string.show_weather_visible) else getString(R.string.show_weather_not_visible)
|
||||
binding.isWeatherVisible = it
|
||||
}
|
||||
checkLocationPermission()
|
||||
})
|
||||
|
||||
viewModel.weatherProviderApi.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
label_weather_provider_api_key.text =
|
||||
if (it == "") getString(R.string.settings_weather_provider_api_key_subtitle_not_set) else getString(
|
||||
R.string.settings_weather_provider_api_key_subtitle_all_set
|
||||
)
|
||||
api_key_alert_icon.isVisible = it == ""
|
||||
}
|
||||
checkLocationPermission()
|
||||
})
|
||||
|
||||
viewModel.customLocationAdd.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
label_custom_location.text =
|
||||
if (it == "") getString(R.string.custom_location_gps) else it
|
||||
}
|
||||
checkLocationPermission()
|
||||
})
|
||||
|
||||
viewModel.weatherTempUnit.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
temp_unit.text =
|
||||
if (it == "F") getString(R.string.fahrenheit) else getString(R.string.celsius)
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.weatherRefreshPeriod.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
label_weather_refresh_period.text = getString(Util.getRefreshPeriodString(it))
|
||||
}
|
||||
checkLocationPermission()
|
||||
})
|
||||
|
||||
viewModel.weatherAppName.observe(viewLifecycleOwner, Observer {
|
||||
maintainScrollPosition {
|
||||
weather_app_label.text =
|
||||
if (it != "") it else getString(R.string.default_weather_app)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun checkLocationPermission() {
|
||||
if (requireActivity().checkCallingOrSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
|
||||
location_permission_alert_icon.isVisible = false
|
||||
WeatherReceiver.setUpdates(requireContext())
|
||||
} else if (Preferences.showWeather && Preferences.customLocationAdd == "") {
|
||||
location_permission_alert_icon.isVisible = true
|
||||
location_permission_alert_icon.setOnClickListener {
|
||||
requirePermission()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupListener() {
|
||||
|
||||
action_show_weather.setOnClickListener {
|
||||
Preferences.showWeather = !Preferences.showWeather
|
||||
}
|
||||
|
||||
action_weather_provider_api_key.setOnClickListener {
|
||||
if (Preferences.showWeather) {
|
||||
startActivityForResult(
|
||||
Intent(requireContext(), WeatherProviderActivity::class.java),
|
||||
RequestCode.WEATHER_PROVIDER_REQUEST_CODE.code
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
action_custom_location.setOnClickListener {
|
||||
if (Preferences.showWeather) {
|
||||
startActivityForResult(
|
||||
Intent(requireContext(), CustomLocationActivity::class.java),
|
||||
Constants.RESULT_CODE_CUSTOM_LOCATION
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
action_change_unit.setOnClickListener {
|
||||
if (Preferences.showWeather) {
|
||||
BottomSheetMenu<String>(requireContext()).selectResource(Preferences.weatherTempUnit)
|
||||
.addItem(getString(R.string.fahrenheit), "F")
|
||||
.addItem(getString(R.string.celsius), "C")
|
||||
.addOnSelectItemListener { value ->
|
||||
Preferences.weatherTempUnit = value
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
|
||||
action_weather_refresh_period.setOnClickListener {
|
||||
if (Preferences.showWeather) {
|
||||
val dialog =
|
||||
BottomSheetMenu<Int>(requireContext()).selectResource(Preferences.weatherRefreshPeriod)
|
||||
(5 downTo 0).forEach {
|
||||
dialog.addItem(getString(Util.getRefreshPeriodString(it)), it)
|
||||
}
|
||||
dialog
|
||||
.addOnSelectItemListener { value ->
|
||||
Preferences.weatherRefreshPeriod = value
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
|
||||
action_weather_app.setOnClickListener {
|
||||
if (Preferences.showWeather) {
|
||||
startActivityForResult(
|
||||
Intent(requireContext(), ChooseApplicationActivity::class.java),
|
||||
RequestCode.WEATHER_APP_REQUEST_CODE.code
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
when (requestCode) {
|
||||
Constants.RESULT_CODE_CUSTOM_LOCATION -> {
|
||||
WeatherReceiver.setUpdates(requireContext())
|
||||
}
|
||||
RequestCode.WEATHER_APP_REQUEST_CODE.code -> {
|
||||
Preferences.bulk {
|
||||
weatherAppName = data?.getStringExtra(Constants.RESULT_APP_NAME) ?: getString(R.string.default_weather_app)
|
||||
weatherAppPackage = data?.getStringExtra(Constants.RESULT_APP_PACKAGE) ?: ""
|
||||
}
|
||||
Util.updateWidget(requireContext())
|
||||
}
|
||||
RequestCode.WEATHER_PROVIDER_REQUEST_CODE.code -> {
|
||||
WeatherReceiver.setOneTimeUpdate(requireContext())
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
private fun requirePermission() {
|
||||
Dexter.withContext(requireActivity())
|
||||
.withPermissions(
|
||||
Manifest.permission.ACCESS_FINE_LOCATION
|
||||
).withListener(object: MultiplePermissionsListener {
|
||||
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
||||
report?.let {
|
||||
if (report.areAllPermissionsGranted()){
|
||||
checkLocationPermission()
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun onPermissionRationaleShouldBeShown(
|
||||
permissions: MutableList<PermissionRequest>?,
|
||||
token: PermissionToken?
|
||||
) {
|
||||
// Remember to invoke this method when the custom rationale is closed
|
||||
// or just by default if you don't want to use any custom rationale.
|
||||
token?.continuePermissionRequest()
|
||||
}
|
||||
})
|
||||
.check()
|
||||
}
|
||||
|
||||
private fun maintainScrollPosition(callback: () -> Unit) {
|
||||
val scrollPosition = scrollView.scrollY
|
||||
callback.invoke()
|
||||
lifecycleScope.launch {
|
||||
delay(200)
|
||||
scrollView.smoothScrollTo(0, scrollPosition)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.view
|
||||
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Typeface
|
||||
import android.text.TextPaint
|
||||
import android.text.style.TypefaceSpan
|
||||
|
||||
class CustomTypefaceSpan(family: String, private val newType: Typeface) : TypefaceSpan(family) {
|
||||
|
||||
override fun updateDrawState(ds: TextPaint) {
|
||||
applyCustomTypeFace(ds, newType)
|
||||
}
|
||||
|
||||
override fun updateMeasureState(paint: TextPaint) {
|
||||
applyCustomTypeFace(paint, newType)
|
||||
}
|
||||
|
||||
private fun applyCustomTypeFace(paint: Paint, tf: Typeface) {
|
||||
val oldStyle: Int
|
||||
val old = paint.typeface
|
||||
if (old == null) {
|
||||
oldStyle = 0
|
||||
} else {
|
||||
oldStyle = old.style
|
||||
}
|
||||
|
||||
val fake = oldStyle and tf.style.inv()
|
||||
if (fake and Typeface.BOLD != 0) {
|
||||
paint.isFakeBoldText = true
|
||||
}
|
||||
|
||||
if (fake and Typeface.ITALIC != 0) {
|
||||
paint.textSkewX = -0.25f
|
||||
}
|
||||
|
||||
paint.typeface = tf
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.view
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface
|
||||
import android.content.res.TypedArray
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.widget.TextView
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
|
||||
|
||||
/**
|
||||
* Created by tommaso on 12/10/17.
|
||||
*/
|
||||
class TitleTextView : TextView {
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
|
||||
init(context, attrs)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
init(context, attrs)
|
||||
}
|
||||
|
||||
constructor(context: Context) : super(context) {}
|
||||
|
||||
fun init(context: Context, attrs: AttributeSet) {
|
||||
try {
|
||||
val ta = context.obtainStyledAttributes(attrs, R.styleable.FontText)
|
||||
|
||||
if (ta != null) {
|
||||
val fontAsset = ta.getString(R.styleable.FontText_typefaceAsset)
|
||||
|
||||
if (fontAsset != null && !fontAsset.isEmpty()) {
|
||||
val tf = Typeface.createFromAsset(getContext().assets, fontAsset)
|
||||
|
||||
if (tf != null)
|
||||
typeface = tf
|
||||
else
|
||||
Log.i("FontText", String.format("Could not create a font from asset: %s", fontAsset))
|
||||
}
|
||||
ta.recycle()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.i("FontText", "Could not create a font from asset")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.viewmodels
|
||||
|
||||
import android.app.Application
|
||||
import android.content.pm.ApplicationInfo
|
||||
import androidx.databinding.ObservableField
|
||||
import androidx.lifecycle.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class ChooseApplicationViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
val appList: LiveData<List<ApplicationInfo>> = liveData {
|
||||
val app = application.packageManager.getInstalledApplications(0)
|
||||
emit(app)
|
||||
}
|
||||
val searchInput: MutableLiveData<String> = MutableLiveData("")
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.viewmodels
|
||||
|
||||
import android.app.Application
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.location.Address
|
||||
import android.location.Geocoder
|
||||
import androidx.lifecycle.*
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
class CustomLocationViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
val addresses: MutableLiveData<List<Address>> = MutableLiveData(emptyList())
|
||||
val locationInput: MutableLiveData<String> = MutableLiveData(Preferences.customLocationAdd)
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.viewmodels
|
||||
|
||||
import androidx.lifecycle.*
|
||||
import com.chibatching.kotpref.livedata.asLiveData
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
|
||||
class MainViewModel : ViewModel() {
|
||||
|
||||
// General Settings
|
||||
val textGlobalColor = Preferences.asLiveData(Preferences::textGlobalColor)
|
||||
val textMainSize = Preferences.asLiveData(Preferences::textMainSize)
|
||||
val textSecondSize = Preferences.asLiveData(Preferences::textSecondSize)
|
||||
val textShadow = Preferences.asLiveData(Preferences::textShadow)
|
||||
val customFont = Preferences.asLiveData(Preferences::customFont)
|
||||
val secondRowInformation = Preferences.asLiveData(Preferences::secondRowInformation)
|
||||
|
||||
// Calendar Settings
|
||||
val showEvents = Preferences.asLiveData(Preferences::showEvents)
|
||||
val calendarAllDay = Preferences.asLiveData(Preferences::calendarAllDay)
|
||||
val showUntil = Preferences.asLiveData(Preferences::showUntil)
|
||||
val showDiffTime = Preferences.asLiveData(Preferences::showDiffTime)
|
||||
val showDeclinedEvents = Preferences.asLiveData(Preferences::showDeclinedEvents)
|
||||
val showNextEvent = Preferences.asLiveData(Preferences::showNextEvent)
|
||||
|
||||
val calendarAppName = Preferences.asLiveData(Preferences::calendarAppName)
|
||||
|
||||
val eventAppName = Preferences.asLiveData(Preferences::eventAppName)
|
||||
|
||||
|
||||
// Clock Settings
|
||||
val showClock = Preferences.asLiveData(Preferences::showClock)
|
||||
val clockTextSize = Preferences.asLiveData(Preferences::clockTextSize)
|
||||
|
||||
val clockAppName = Preferences.asLiveData(Preferences::clockAppName)
|
||||
val showNextAlarm = Preferences.asLiveData(Preferences::showNextAlarm)
|
||||
val dateFormat = Preferences.asLiveData(Preferences::dateFormat)
|
||||
|
||||
// Weather Settings
|
||||
val showWeather = Preferences.asLiveData(Preferences::showWeather)
|
||||
val weatherTempUnit = Preferences.asLiveData(Preferences::weatherTempUnit)
|
||||
val weatherRefreshPeriod = Preferences.asLiveData(Preferences::weatherRefreshPeriod)
|
||||
|
||||
val weatherAppName = Preferences.asLiveData(Preferences::weatherAppName)
|
||||
val weatherProviderApi = Preferences.asLiveData(Preferences::weatherProviderApi)
|
||||
|
||||
val customLocationAdd = Preferences.asLiveData(Preferences::customLocationAdd)
|
||||
|
||||
// Advanced Settings
|
||||
val darkThemePreference = Preferences.asLiveData(Preferences::darkThemePreference)
|
||||
val showWallpaper = Preferences.asLiveData(Preferences::showWallpaper)
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.viewmodels
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.android.billingclient.api.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class SupportDevViewModel : ViewModel() {
|
||||
|
||||
lateinit var billingClient: BillingClient
|
||||
val products: MutableLiveData<List<SkuDetails>> = MutableLiveData(emptyList())
|
||||
|
||||
fun openConnection() {
|
||||
|
||||
billingClient.startConnection(object : BillingClientStateListener {
|
||||
override fun onBillingSetupFinished(billingResult: BillingResult) {
|
||||
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
|
||||
val params = SkuDetailsParams.newBuilder()
|
||||
params.setSkusList(listOf("donation_coffee", "donation_donuts", "donation_breakfast", "donation_lunch", "donation_dinner")).setType(BillingClient.SkuType.INAPP)
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val skuDetailsList = billingClient.querySkuDetails(params.build()).skuDetailsList
|
||||
withContext(Dispatchers.Main) {
|
||||
products.value = skuDetailsList
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun onBillingServiceDisconnected() {
|
||||
// Try to restart the connection on the next request to
|
||||
// Google Play by calling the startConnection() method.
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun purchase(activity: Activity, product: SkuDetails) {
|
||||
val flowParams = BillingFlowParams.newBuilder()
|
||||
.setSkuDetails(product)
|
||||
.build()
|
||||
billingClient.launchBillingFlow(activity, flowParams)
|
||||
}
|
||||
|
||||
fun handlePurchase(purchase: Purchase) {
|
||||
if (!purchase.isAcknowledged) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
|
||||
.setPurchaseToken(purchase.purchaseToken)
|
||||
billingClient.acknowledgePurchase(acknowledgePurchaseParams.build())
|
||||
|
||||
val consumeParams =
|
||||
ConsumeParams.newBuilder()
|
||||
.setPurchaseToken(purchase.purchaseToken)
|
||||
.build()
|
||||
billingClient.consumePurchase(consumeParams)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun closeConnection() {
|
||||
billingClient.endConnection()
|
||||
}
|
||||
}
|
@ -1,543 +0,0 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.widget
|
||||
|
||||
import android.Manifest
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetProvider
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.preference.PreferenceManager
|
||||
import android.view.View
|
||||
import android.widget.RemoteViews
|
||||
|
||||
import com.tommasoberlose.anotherwidget.`object`.Constants
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.receiver.UpdatesReceiver
|
||||
import com.tommasoberlose.anotherwidget.util.Util
|
||||
import com.tommasoberlose.anotherwidget.receiver.WeatherReceiver
|
||||
|
||||
import java.util.Calendar
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit
|
||||
import android.app.PendingIntent
|
||||
import android.provider.CalendarContract
|
||||
import android.content.ContentUris
|
||||
import android.util.Log
|
||||
import com.tommasoberlose.anotherwidget.util.CalendarUtil
|
||||
import com.tommasoberlose.anotherwidget.util.WeatherUtil
|
||||
import android.graphics.Typeface
|
||||
import android.net.Uri
|
||||
import android.widget.TextClock
|
||||
import android.widget.TextView
|
||||
import android.content.ComponentName
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.os.Bundle
|
||||
import android.support.v4.content.ContextCompat.startActivity
|
||||
import android.provider.CalendarContract.Events
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.style.RelativeSizeSpan
|
||||
import android.text.style.StyleSpan
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.TypedValue
|
||||
import android.widget.LinearLayout
|
||||
import com.tommasoberlose.anotherwidget.receiver.OpenWeatherIntentReceiver
|
||||
import com.tommasoberlose.anotherwidget.ui.view.CustomTypefaceSpan
|
||||
import kotlinx.android.synthetic.main.the_widget.*
|
||||
import kotlinx.android.synthetic.main.the_widget.view.*
|
||||
import kotlinx.android.synthetic.main.the_widget_sans.view.*
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of App Widget functionality.
|
||||
*/
|
||||
class TheWidget : AppWidgetProvider() {
|
||||
|
||||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
||||
Util.updateSettingsByDefault(context)
|
||||
|
||||
for (appWidgetId in appWidgetIds) {
|
||||
updateAppWidget(context, appWidgetManager, appWidgetId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAppWidgetOptionsChanged(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int, newOptions: Bundle?) {
|
||||
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions)
|
||||
updateAppWidget(context, appWidgetManager, appWidgetId)
|
||||
}
|
||||
|
||||
override fun onEnabled(context: Context) {
|
||||
UpdatesReceiver().setUpdates(context)
|
||||
WeatherReceiver().setUpdates(context)
|
||||
}
|
||||
|
||||
override fun onDisabled(context: Context) {
|
||||
UpdatesReceiver().removeUpdates(context)
|
||||
WeatherReceiver().removeUpdates(context)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
internal fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager,
|
||||
appWidgetId: Int) {
|
||||
val SP = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val displayMetrics = Resources.getSystem().displayMetrics
|
||||
var height = Util.convertDpToPixel(110f, context).toInt()
|
||||
val width = displayMetrics.widthPixels
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_CLOCK, false)) {
|
||||
height += Util.convertSpToPixels(SP.getFloat(Constants.PREF_TEXT_CLOCK_SIZE, 90f), context).toInt() + Util.convertDpToPixel(16f, context).toInt()
|
||||
}
|
||||
if (SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f) > 30 && SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) > 22) {
|
||||
height += Util.convertDpToPixel(24f, context).toInt()
|
||||
}
|
||||
|
||||
generateWidgetView(context, appWidgetId, appWidgetManager, width - Util.convertDpToPixel(16f, context).toInt(), height)
|
||||
}
|
||||
|
||||
fun generateWidgetView(context: Context, appWidgetId: Int, appWidgetManager: AppWidgetManager, w: Int, h: Int) {
|
||||
var views = RemoteViews(context.packageName, R.layout.the_widget_sans)
|
||||
var v = View.inflate(context, R.layout.the_widget, null)
|
||||
|
||||
val SP = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
views.setTextColor(R.id.empty_date, Util.getFontColor(SP))
|
||||
views.setTextColor(R.id.divider1, Util.getFontColor(PreferenceManager.getDefaultSharedPreferences(context)))
|
||||
views.setTextColor(R.id.temp, Util.getFontColor(PreferenceManager.getDefaultSharedPreferences(context)))
|
||||
views.setTextColor(R.id.next_event, Util.getFontColor(PreferenceManager.getDefaultSharedPreferences(context)))
|
||||
views.setTextColor(R.id.next_event_difference_time, Util.getFontColor(PreferenceManager.getDefaultSharedPreferences(context)))
|
||||
views.setTextColor(R.id.next_event_date, Util.getFontColor(PreferenceManager.getDefaultSharedPreferences(context)))
|
||||
views.setTextColor(R.id.divider2, Util.getFontColor(PreferenceManager.getDefaultSharedPreferences(context)))
|
||||
views.setTextColor(R.id.calendar_temp, Util.getFontColor(PreferenceManager.getDefaultSharedPreferences(context)))
|
||||
//views.setTextColor(R.id.time, Util.getFontColor(PreferenceManager.getDefaultSharedPreferences(context)))
|
||||
|
||||
views.setTextViewTextSize(R.id.empty_date, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f))
|
||||
views.setTextViewTextSize(R.id.divider1, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f))
|
||||
views.setTextViewTextSize(R.id.temp, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f))
|
||||
views.setTextViewTextSize(R.id.next_event, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f))
|
||||
views.setTextViewTextSize(R.id.next_event_difference_time, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f))
|
||||
views.setTextViewTextSize(R.id.next_event_date, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f))
|
||||
views.setTextViewTextSize(R.id.divider2, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f))
|
||||
views.setTextViewTextSize(R.id.calendar_temp, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f))
|
||||
//views.setTextViewTextSize(R.id.time, TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_CLOCK_SIZE, 90f))
|
||||
|
||||
v = updateCalendarViewByLayout(context, v)
|
||||
v = updateLocationViewByLayout(context, v)
|
||||
v = updateClockViewByLayout(context, v)
|
||||
views.setImageViewBitmap(R.id.bitmap_container, Util.getBitmapFromView(v, w, h))
|
||||
|
||||
views = updateCalendarView(context, views, appWidgetId)
|
||||
views = updateLocationView(context, views, appWidgetId)
|
||||
views = updateClockView(context, views, appWidgetId)
|
||||
|
||||
views = fixViewsMargin(context, views)
|
||||
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views)
|
||||
}
|
||||
|
||||
fun updateCalendarView(context: Context, views: RemoteViews, widgetID: Int): RemoteViews {
|
||||
val SP = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val now = Calendar.getInstance()
|
||||
val calendarLayout = SP.getBoolean(Constants.PREF_SHOW_EVENTS, true) && Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)
|
||||
|
||||
views.setViewVisibility(R.id.empty_layout, View.VISIBLE)
|
||||
views.setViewVisibility(R.id.calendar_layout, View.GONE)
|
||||
var dateStringValue: String = Util.getCapWordString(Constants.engDateFormat.format(now.time))
|
||||
if (SP.getBoolean(Constants.PREF_ITA_FORMAT_DATE, false)) {
|
||||
dateStringValue = Util.getCapWordString(Constants.itDateFormat.format(now.time))
|
||||
}
|
||||
views.setTextViewText(R.id.empty_date, dateStringValue)
|
||||
|
||||
|
||||
val calPIntent = PendingIntent.getActivity(context, widgetID, Util.getCalendarIntent(context), 0)
|
||||
views.setOnClickPendingIntent(R.id.empty_date, calPIntent)
|
||||
|
||||
|
||||
if (calendarLayout) {
|
||||
val e = CalendarUtil.getNextEvent(context)
|
||||
|
||||
if (e.id != 0.toLong()) {
|
||||
views.setTextViewText(R.id.next_event, e.title)
|
||||
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_NEXT_EVENT, false) && CalendarUtil.getEventsCount(context) > 1) {
|
||||
val multipleIntent = PendingIntent.getBroadcast(context, widgetID, Intent(Constants.ACTION_GO_TO_NEXT_EVENT), 0)
|
||||
views.setViewVisibility(R.id.multiple_events, View.VISIBLE)
|
||||
views.setOnClickPendingIntent(R.id.multiple_events, multipleIntent)
|
||||
} else {
|
||||
views.setViewVisibility(R.id.multiple_events, View.GONE)
|
||||
}
|
||||
|
||||
val pIntent = PendingIntent.getActivity(context, widgetID, Util.getEventIntent(context, e), 0)
|
||||
views.setOnClickPendingIntent(R.id.next_event, pIntent)
|
||||
views.setOnClickPendingIntent(R.id.next_event_difference_time, pIntent)
|
||||
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_DIFF_TIME, true)) {
|
||||
views.setTextViewText(R.id.next_event_difference_time, Util.getDifferenceText(context, now.timeInMillis, e.startDate))
|
||||
views.setViewVisibility(R.id.next_event_difference_time, View.VISIBLE)
|
||||
} else {
|
||||
views.setViewVisibility(R.id.next_event_difference_time, View.GONE)
|
||||
}
|
||||
|
||||
if (SP.getInt(Constants.PREF_SECOND_ROW_INFORMATION, 0) == 2 && Util.getNextAlarm(context) != null) {
|
||||
val source = BitmapFactory.decodeResource(context.resources, R.drawable.ic_action_alarm);
|
||||
val result = Util.changeBitmapColor(source, Util.getFontColor(SP))
|
||||
views.setImageViewBitmap(R.id.second_row_icon, result)
|
||||
|
||||
views.setTextViewText(R.id.next_event_date, Util.getNextAlarm(context))
|
||||
|
||||
val clockIntent = PendingIntent.getActivity(context, widgetID, Util.getClockIntent(context), 0)
|
||||
views.setOnClickPendingIntent(R.id.next_event_date, clockIntent)
|
||||
} else if (e.address != "" && SP.getInt(Constants.PREF_SECOND_ROW_INFORMATION, 0) == 1) {
|
||||
|
||||
val source = BitmapFactory.decodeResource(context.resources, R.drawable.ic_action_location);
|
||||
val result = Util.changeBitmapColor(source, Util.getFontColor(SP))
|
||||
views.setImageViewBitmap(R.id.second_row_icon, result)
|
||||
|
||||
views.setTextViewText(R.id.next_event_date, e.address)
|
||||
|
||||
val mapIntent = PendingIntent.getActivity(context, widgetID, Util.getGoogleMapsIntentFromAddress(context, e.address), 0)
|
||||
views.setOnClickPendingIntent(R.id.next_event_date, mapIntent)
|
||||
} else {
|
||||
val source = BitmapFactory.decodeResource(context.resources, R.drawable.ic_action_calendar);
|
||||
val result = Util.changeBitmapColor(source, Util.getFontColor(SP))
|
||||
views.setImageViewBitmap(R.id.second_row_icon, result)
|
||||
|
||||
if (!e.allDay) {
|
||||
var startHour = Constants.goodHourFormat.format(e.startDate)
|
||||
var endHour = Constants.goodHourFormat.format(e.endDate)
|
||||
if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) {
|
||||
startHour = Constants.badHourFormat.format(e.startDate)
|
||||
endHour = Constants.badHourFormat.format(e.endDate)
|
||||
}
|
||||
var dayDiff = TimeUnit.MILLISECONDS.toDays(e.endDate - e.startDate)
|
||||
|
||||
val startCal = Calendar.getInstance()
|
||||
startCal.timeInMillis = e.startDate
|
||||
|
||||
val endCal = Calendar.getInstance()
|
||||
endCal.timeInMillis = e.endDate
|
||||
|
||||
if (startCal.get(Calendar.HOUR_OF_DAY) > endCal.get(Calendar.HOUR_OF_DAY)) {
|
||||
dayDiff++
|
||||
} else if (startCal.get(Calendar.HOUR_OF_DAY) == endCal.get(Calendar.HOUR_OF_DAY) && startCal.get(Calendar.MINUTE) >= endCal.get(Calendar.MINUTE)) {
|
||||
dayDiff++
|
||||
}
|
||||
|
||||
var multipleDay = ""
|
||||
if (dayDiff > 0) {
|
||||
multipleDay = String.format(" (+%s%s)", dayDiff, context.getString(R.string.day_char))
|
||||
}
|
||||
|
||||
views.setTextViewText(R.id.next_event_date, String.format("%s - %s%s", startHour, endHour, multipleDay))
|
||||
} else {
|
||||
views.setTextViewText(R.id.next_event_date, dateStringValue)
|
||||
}
|
||||
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_NEXT_EVENT, false) && CalendarUtil.getEventsCount(context) > 1) {
|
||||
val multipleIntent = PendingIntent.getBroadcast(context, widgetID, Intent(Constants.ACTION_GO_TO_NEXT_EVENT), 0)
|
||||
views.setOnClickPendingIntent(R.id.next_event_date, multipleIntent)
|
||||
} else {
|
||||
views.setOnClickPendingIntent(R.id.next_event_date, pIntent)
|
||||
}
|
||||
}
|
||||
|
||||
views.setViewVisibility(R.id.empty_layout, View.GONE)
|
||||
views.setViewVisibility(R.id.calendar_layout, View.VISIBLE)
|
||||
}
|
||||
}
|
||||
|
||||
return views
|
||||
}
|
||||
|
||||
fun updateLocationView(context: Context, views: RemoteViews, widgetID: Int): RemoteViews {
|
||||
val SP = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val locationLayout = SP.getBoolean(Constants.PREF_SHOW_WEATHER, true)
|
||||
|
||||
if (locationLayout && SP.contains(Constants.PREF_WEATHER_TEMP) && SP.contains(Constants.PREF_WEATHER_ICON)) {
|
||||
views.setViewVisibility(R.id.weather, View.VISIBLE)
|
||||
views.setViewVisibility(R.id.calendar_weather, View.VISIBLE)
|
||||
val temp = String.format(Locale.getDefault(), "%.0f °%s", SP.getFloat(Constants.PREF_WEATHER_TEMP, 0f), SP.getString(Constants.PREF_WEATHER_REAL_TEMP_UNIT, "F"))
|
||||
|
||||
|
||||
views.setViewVisibility(R.id.weather_icon, View.VISIBLE)
|
||||
views.setViewVisibility(R.id.empty_weather_icon, View.VISIBLE)
|
||||
val icon: String = SP.getString(Constants.PREF_WEATHER_ICON, "")
|
||||
if (icon.equals("")) {
|
||||
views.setViewVisibility(R.id.weather_icon, View.GONE)
|
||||
views.setViewVisibility(R.id.empty_weather_icon, View.GONE)
|
||||
} else {
|
||||
views.setImageViewResource(R.id.weather_icon, WeatherUtil.getWeatherIconResource(icon))
|
||||
views.setImageViewResource(R.id.empty_weather_icon, WeatherUtil.getWeatherIconResource(icon))
|
||||
}
|
||||
|
||||
views.setTextViewText(R.id.temp, temp)
|
||||
views.setTextViewText(R.id.calendar_temp, temp)
|
||||
|
||||
val i = Intent(context, OpenWeatherIntentReceiver::class.java)
|
||||
i.action = Constants.ACTION_OPEN_WEATHER_INTENT
|
||||
val weatherPIntent = PendingIntent.getBroadcast(context, widgetID, i, 0)
|
||||
|
||||
views.setOnClickPendingIntent(R.id.weather, weatherPIntent)
|
||||
views.setOnClickPendingIntent(R.id.calendar_weather, weatherPIntent)
|
||||
} else {
|
||||
views.setViewVisibility(R.id.weather, View.GONE)
|
||||
views.setViewVisibility(R.id.calendar_weather, View.GONE)
|
||||
}
|
||||
return views
|
||||
}
|
||||
|
||||
fun updateClockView(context: Context, views: RemoteViews, widgetID: Int): RemoteViews {
|
||||
val SP = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
if (!SP.getBoolean(Constants.PREF_SHOW_CLOCK, false)) {
|
||||
views.setViewVisibility(R.id.time, View.GONE)
|
||||
} else {
|
||||
// val now = Calendar.getInstance()
|
||||
// if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) {
|
||||
// val textBadHour = SpannableString(Constants.badHourFormat.format(now.timeInMillis).replace(" ", ""))
|
||||
// textBadHour.setSpan(RelativeSizeSpan(0.4f), textBadHour.length - 2,
|
||||
// textBadHour.length, Spannable.SPAN_INCLUSIVE_INCLUSIVE)
|
||||
//
|
||||
// views.setTextViewText(R.id.time, textBadHour)
|
||||
// } else {
|
||||
// views.setTextViewText(R.id.time, Constants.goodHourFormat.format(now.timeInMillis))
|
||||
// }
|
||||
|
||||
val clockPIntent = PendingIntent.getActivity(context, widgetID, Util.getClockIntent(context), 0)
|
||||
views.setOnClickPendingIntent(R.id.time, clockPIntent)
|
||||
views.setViewVisibility(R.id.time, View.VISIBLE)
|
||||
}
|
||||
|
||||
return views
|
||||
}
|
||||
|
||||
fun fixViewsMargin(context: Context, views: RemoteViews): RemoteViews {
|
||||
val SP = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
views.setViewVisibility(R.id.bottom_divider_24, View.GONE)
|
||||
views.setViewVisibility(R.id.bottom_divider_16, View.GONE)
|
||||
views.setViewVisibility(R.id.bottom_divider_8, View.GONE)
|
||||
val eVisible = SP.getBoolean(Constants.PREF_SHOW_EVENTS, true) && Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_CLOCK, false)) {
|
||||
if (eVisible) {
|
||||
views.setViewVisibility(R.id.bottom_divider_8, View.VISIBLE)
|
||||
} else {
|
||||
views.setViewVisibility(R.id.bottom_divider_24, View.VISIBLE)
|
||||
}
|
||||
} else {
|
||||
if (eVisible) {
|
||||
views.setViewVisibility(R.id.bottom_divider_8, View.VISIBLE)
|
||||
}
|
||||
}
|
||||
return views
|
||||
}
|
||||
|
||||
fun updateCalendarViewByLayout(context: Context, v: View): View {
|
||||
val SP = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val now = Calendar.getInstance()
|
||||
val calendarLayout = SP.getBoolean(Constants.PREF_SHOW_EVENTS, true) && Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)
|
||||
|
||||
v.empty_layout.visibility = View.VISIBLE
|
||||
v.calendar_layout.visibility = View.GONE
|
||||
var dateStringValue: String = Util.getCapWordString(Constants.engDateFormat.format(now.time))
|
||||
if (SP.getBoolean(Constants.PREF_ITA_FORMAT_DATE, false)) {
|
||||
dateStringValue = Util.getCapWordString(Constants.itDateFormat.format(now.time))
|
||||
}
|
||||
|
||||
v.empty_date.text = dateStringValue
|
||||
|
||||
if (calendarLayout) {
|
||||
val e = CalendarUtil.getNextEvent(context)
|
||||
|
||||
if (e.id != 0.toLong()) {
|
||||
v.next_event.text = e.title
|
||||
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_NEXT_EVENT, false) && CalendarUtil.getEventsCount(context) > 1) {
|
||||
v.multiple_events.visibility = View.VISIBLE
|
||||
} else {
|
||||
v.multiple_events.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (SP.getBoolean(Constants.PREF_SHOW_DIFF_TIME, true)) {
|
||||
v.next_event_difference_time.text = Util.getDifferenceText(context, now.timeInMillis, e.startDate)
|
||||
v.next_event_difference_time.visibility = View.VISIBLE
|
||||
} else {
|
||||
v.next_event_difference_time.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (SP.getInt(Constants.PREF_SECOND_ROW_INFORMATION, 0) == 2 && Util.getNextAlarm(context) != null) {
|
||||
v.second_row_icon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_action_alarm))
|
||||
v.next_event_date.text = Util.getNextAlarm(context)
|
||||
} else if (!e.address.equals("") && SP.getInt(Constants.PREF_SECOND_ROW_INFORMATION, 0) == 1) {
|
||||
v.second_row_icon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_action_location))
|
||||
v.next_event_date.text = e.address
|
||||
} else {
|
||||
v.second_row_icon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_action_calendar))
|
||||
if (!e.allDay) {
|
||||
var startHour = Constants.goodHourFormat.format(e.startDate)
|
||||
var endHour = Constants.goodHourFormat.format(e.endDate)
|
||||
if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) {
|
||||
startHour = Constants.badHourFormat.format(e.startDate)
|
||||
endHour = Constants.badHourFormat.format(e.endDate)
|
||||
}
|
||||
var dayDiff = TimeUnit.MILLISECONDS.toDays(e.endDate - e.startDate)
|
||||
|
||||
val startCal = Calendar.getInstance()
|
||||
startCal.timeInMillis = e.startDate
|
||||
|
||||
val endCal = Calendar.getInstance()
|
||||
endCal.timeInMillis = e.endDate
|
||||
|
||||
if (startCal.get(Calendar.HOUR_OF_DAY) > endCal.get(Calendar.HOUR_OF_DAY)) {
|
||||
dayDiff++
|
||||
} else if (startCal.get(Calendar.HOUR_OF_DAY) == endCal.get(Calendar.HOUR_OF_DAY) && startCal.get(Calendar.MINUTE) >= endCal.get(Calendar.MINUTE)) {
|
||||
dayDiff++
|
||||
}
|
||||
var multipleDay: String = ""
|
||||
if (dayDiff > 0) {
|
||||
multipleDay = String.format(" (+%s%s)", dayDiff, context.getString(R.string.day_char))
|
||||
}
|
||||
v.next_event_date.text = String.format("%s - %s%s", startHour, endHour, multipleDay)
|
||||
|
||||
} else {
|
||||
v.next_event_date.text = dateStringValue
|
||||
}
|
||||
}
|
||||
|
||||
v.empty_layout.visibility = View.GONE
|
||||
v.calendar_layout.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
v.empty_date.setTextColor(Util.getFontColor(SP))
|
||||
v.divider1.setTextColor(Util.getFontColor(SP))
|
||||
v.temp.setTextColor(Util.getFontColor(SP))
|
||||
v.next_event.setTextColor(Util.getFontColor(SP))
|
||||
v.next_event_difference_time.setTextColor(Util.getFontColor(SP))
|
||||
v.next_event_date.setTextColor(Util.getFontColor(SP))
|
||||
v.divider2.setTextColor(Util.getFontColor(SP))
|
||||
v.calendar_temp.setTextColor(Util.getFontColor(SP))
|
||||
v.second_row_icon.setColorFilter(Util.getFontColor(SP))
|
||||
v.time.setTextColor(Util.getFontColor(SP))
|
||||
v.multiple_events.setColorFilter(Util.getFontColor(SP))
|
||||
|
||||
|
||||
v.empty_date.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f))
|
||||
v.divider1.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f))
|
||||
v.temp.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f))
|
||||
v.next_event.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f))
|
||||
v.next_event_difference_time.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f))
|
||||
v.next_event_date.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f))
|
||||
v.divider2.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f))
|
||||
v.calendar_temp.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f))
|
||||
v.time.setTextSize(TypedValue.COMPLEX_UNIT_SP, SP.getFloat(Constants.PREF_TEXT_CLOCK_SIZE, 90f))
|
||||
|
||||
v.second_row_icon.scaleX = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 18f
|
||||
v.second_row_icon.scaleY = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 18f
|
||||
|
||||
v.weather_icon.scaleX = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 18f
|
||||
v.weather_icon.scaleY = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 18f
|
||||
|
||||
v.empty_weather_icon.scaleX = SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f) / 24f
|
||||
v.empty_weather_icon.scaleY = SP.getFloat(Constants.PREF_TEXT_MAIN_SIZE, 24f) / 24f
|
||||
|
||||
v.multiple_events.scaleX = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 16f
|
||||
v.multiple_events.scaleY = SP.getFloat(Constants.PREF_TEXT_SECOND_SIZE, 16f) / 16f
|
||||
|
||||
val shadowRadius = when (SP.getInt(Constants.PREF_TEXT_SHADOW, 1)) {
|
||||
0 -> 0f
|
||||
1 -> 5f
|
||||
2 -> 5f
|
||||
else -> 5f
|
||||
}
|
||||
val shadowColor = when (SP.getInt(Constants.PREF_TEXT_SHADOW, 1)) {
|
||||
0 -> Color.TRANSPARENT
|
||||
1 -> R.color.black_50
|
||||
2 -> Color.BLACK
|
||||
else -> R.color.black_50
|
||||
}
|
||||
val shadowDy = when (SP.getInt(Constants.PREF_TEXT_SHADOW, 1)) {
|
||||
0 -> 0f
|
||||
1 -> 0f
|
||||
2 -> 1f
|
||||
else -> 0f
|
||||
}
|
||||
v.empty_date.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
v.divider1.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
v.temp.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
v.next_event.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
v.next_event_difference_time.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
v.next_event_date.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
v.divider2.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
v.calendar_temp.setShadowLayer(shadowRadius, 0f, 0f, shadowColor)
|
||||
v.time.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
|
||||
if (SP.getInt(Constants.PREF_CUSTOM_FONT, Constants.CUSTOM_FONT_PRODUCT_SANS) == Constants.CUSTOM_FONT_PRODUCT_SANS) {
|
||||
val product_sans: Typeface = Typeface.createFromAsset(context.assets, "fonts/product_sans_regular.ttf")
|
||||
val product_sans_light: Typeface = Typeface.createFromAsset(context.assets, "fonts/product_sans_light.ttf")
|
||||
v.empty_date.typeface = product_sans
|
||||
v.divider1.typeface = product_sans
|
||||
v.temp.typeface = product_sans
|
||||
v.next_event.typeface = product_sans
|
||||
v.next_event_difference_time.typeface = product_sans
|
||||
v.next_event_date.typeface = product_sans
|
||||
v.divider2.typeface = product_sans
|
||||
v.calendar_temp.typeface = product_sans
|
||||
v.time.typeface = product_sans_light
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
fun updateLocationViewByLayout(context: Context, v: View): View {
|
||||
val SP = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val locationLayout = SP.getBoolean(Constants.PREF_SHOW_WEATHER, true)
|
||||
|
||||
if (locationLayout && SP.contains(Constants.PREF_WEATHER_TEMP) && SP.contains(Constants.PREF_WEATHER_ICON)) {
|
||||
v.weather.visibility = View.VISIBLE
|
||||
v.calendar_weather.visibility = View.VISIBLE
|
||||
val currentTemp = String.format(Locale.getDefault(), "%.0f °%s", SP.getFloat(Constants.PREF_WEATHER_TEMP, 0f), SP.getString(Constants.PREF_WEATHER_REAL_TEMP_UNIT, "F"))
|
||||
|
||||
|
||||
v.weather_icon.visibility = View.VISIBLE
|
||||
v.empty_weather_icon.visibility = View.VISIBLE
|
||||
val icon: String = SP.getString(Constants.PREF_WEATHER_ICON, "")
|
||||
if (icon.equals("")) {
|
||||
v.weather_icon.visibility = View.GONE
|
||||
v.empty_weather_icon.visibility = View.GONE
|
||||
} else {
|
||||
v.weather_icon.setImageResource(WeatherUtil.getWeatherIconResource(icon))
|
||||
v.empty_weather_icon.setImageResource(WeatherUtil.getWeatherIconResource(icon))
|
||||
}
|
||||
|
||||
v.temp.text = currentTemp
|
||||
v.calendar_temp.text = currentTemp
|
||||
} else {
|
||||
v.weather.visibility = View.GONE
|
||||
v.calendar_weather.visibility = View.GONE
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
fun updateClockViewByLayout(context: Context, v: View): View {
|
||||
val SP = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
if (!SP.getBoolean(Constants.PREF_SHOW_CLOCK, false)) {
|
||||
v.time.visibility = View.GONE
|
||||
} else {
|
||||
// val now = Calendar.getInstance()
|
||||
// if (SP.getString(Constants.PREF_HOUR_FORMAT, "12").equals("12")) {
|
||||
// val textBadHour = SpannableString(Constants.badHourFormat.format(now.timeInMillis).replace(" ", ""))
|
||||
// textBadHour.setSpan(RelativeSizeSpan(0.4f), textBadHour.length - 2,
|
||||
// textBadHour.length, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
|
||||
//
|
||||
// v.time.text = textBadHour
|
||||
// } else {
|
||||
// v.time.text = Constants.goodHourFormat.format(now.timeInMillis)
|
||||
// }
|
||||
v.time.visibility = View.VISIBLE
|
||||
}
|
||||
return v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,397 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.widgets
|
||||
|
||||
import android.Manifest
|
||||
import android.app.PendingIntent
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetProvider
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.res.Resources
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.text.format.DateUtils
|
||||
import android.util.Log
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.RemoteViews
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.global.Actions
|
||||
import com.tommasoberlose.anotherwidget.global.Constants
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.receivers.NewCalendarEventReceiver
|
||||
import com.tommasoberlose.anotherwidget.receivers.WidgetClickListenerReceiver
|
||||
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
||||
import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver
|
||||
import com.tommasoberlose.anotherwidget.utils.CalendarUtil
|
||||
import com.tommasoberlose.anotherwidget.utils.Util
|
||||
import com.tommasoberlose.anotherwidget.utils.WeatherUtil
|
||||
import com.tommasoberlose.anotherwidget.utils.toPixel
|
||||
import kotlinx.android.synthetic.main.the_widget.view.*
|
||||
import java.text.DateFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
class TheWidget : AppWidgetProvider() {
|
||||
|
||||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
||||
for (appWidgetId in appWidgetIds) {
|
||||
updateAppWidget(context, appWidgetManager, appWidgetId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAppWidgetOptionsChanged(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int, newOptions: Bundle?) {
|
||||
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions)
|
||||
updateAppWidget(context, appWidgetManager, appWidgetId)
|
||||
}
|
||||
|
||||
override fun onEnabled(context: Context) {
|
||||
CalendarUtil.updateEventList(context)
|
||||
WeatherReceiver.setUpdates(context)
|
||||
}
|
||||
|
||||
override fun onDisabled(context: Context) {
|
||||
UpdatesReceiver.removeUpdates(context)
|
||||
WeatherReceiver.removeUpdates(context)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
internal fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager,
|
||||
appWidgetId: Int) {
|
||||
val displayMetrics = Resources.getSystem().displayMetrics
|
||||
var height = 110.toPixel(context)
|
||||
val width = displayMetrics.widthPixels
|
||||
if (Preferences.showClock) {
|
||||
height += Util.convertSpToPixels(Preferences.clockTextSize, context).toInt() + 16.toPixel(context)
|
||||
}
|
||||
if (Preferences.textMainSize > 30 && Preferences.textSecondSize > 22) {
|
||||
height += 24.toPixel(context)
|
||||
}
|
||||
|
||||
generateWidgetView(context, appWidgetId, appWidgetManager, width - 16.toPixel(context), height)
|
||||
}
|
||||
|
||||
private fun generateWidgetView(context: Context, appWidgetId: Int, appWidgetManager: AppWidgetManager, w: Int, h: Int) {
|
||||
var views = RemoteViews(context.packageName, R.layout.the_widget_sans)
|
||||
|
||||
val generatedView = generateWidgetView(context, w)
|
||||
generatedView.measure(0, 0)
|
||||
views.setImageViewBitmap(R.id.bitmap_container, Util.getBitmapFromView(generatedView, w, generatedView.measuredHeight))
|
||||
|
||||
// Clock
|
||||
views = updateClockView(context, views, appWidgetId)
|
||||
|
||||
// Setup listener
|
||||
views = updateCalendarView(context, generatedView, views, appWidgetId)
|
||||
views = updateWeatherView(context, generatedView, views, appWidgetId)
|
||||
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views)
|
||||
}
|
||||
|
||||
private fun updateCalendarView(context: Context, v: View, views: RemoteViews, widgetID: Int): RemoteViews {
|
||||
|
||||
v.empty_date.measure(0, 0)
|
||||
views.setImageViewBitmap(R.id.empty_date_rect, Util.getBitmapFromView(v.empty_date))
|
||||
|
||||
views.setViewVisibility(R.id.empty_layout_rect, View.VISIBLE)
|
||||
views.setViewVisibility(R.id.calendar_layout_rect, View.GONE)
|
||||
views.setViewVisibility(R.id.second_row_rect, View.GONE)
|
||||
|
||||
val calPIntent = PendingIntent.getActivity(context, widgetID, Util.getCalendarIntent(context), 0)
|
||||
views.setOnClickPendingIntent(R.id.empty_date_rect, calPIntent)
|
||||
|
||||
val nextEvent = CalendarUtil.getNextEvent()
|
||||
val nextAlarm = Util.getNextAlarm(context)
|
||||
|
||||
if (Preferences.showEvents && Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
||||
if (Preferences.showNextEvent && CalendarUtil.getEventsCount() > 1) {
|
||||
v.action_next.measure(0, 0)
|
||||
views.setImageViewBitmap(R.id.action_next_rect, Util.getBitmapFromView(v.action_next))
|
||||
views.setViewVisibility(R.id.action_next_rect, View.VISIBLE)
|
||||
views.setOnClickPendingIntent(R.id.action_next_rect, PendingIntent.getBroadcast(context, widgetID, Intent(context, NewCalendarEventReceiver::class.java).apply { action = Actions.ACTION_GO_TO_NEXT_EVENT }, 0))
|
||||
|
||||
v.action_previous.measure(0, 0)
|
||||
views.setImageViewBitmap(R.id.action_previous_rect, Util.getBitmapFromView(v.action_previous))
|
||||
views.setViewVisibility(R.id.action_previous_rect, View.VISIBLE)
|
||||
views.setOnClickPendingIntent(R.id.action_previous_rect, PendingIntent.getBroadcast(context, widgetID, Intent(context, NewCalendarEventReceiver::class.java).apply { action = Actions.ACTION_GO_TO_PREVIOUS_EVENT }, 0))
|
||||
} else {
|
||||
views.setViewVisibility(R.id.action_next_rect, View.GONE)
|
||||
views.setViewVisibility(R.id.action_previous_rect, View.GONE)
|
||||
}
|
||||
|
||||
val pIntent = PendingIntent.getActivity(context, widgetID, Util.getEventIntent(context, nextEvent), 0)
|
||||
views.setOnClickPendingIntent(R.id.next_event_rect, pIntent)
|
||||
views.setOnClickPendingIntent(R.id.next_event_difference_time_rect, pIntent)
|
||||
|
||||
if (Preferences.showDiffTime && Calendar.getInstance().timeInMillis < nextEvent.startDate) {
|
||||
v.next_event_difference_time.measure(0, 0)
|
||||
views.setImageViewBitmap(R.id.next_event_difference_time_rect, Util.getBitmapFromView(v.next_event_difference_time))
|
||||
views.setViewVisibility(R.id.next_event_difference_time_rect, View.VISIBLE)
|
||||
} else {
|
||||
views.setViewVisibility(R.id.next_event_difference_time_rect, View.GONE)
|
||||
}
|
||||
|
||||
if (nextEvent.address != "" && Preferences.secondRowInformation == 1) {
|
||||
val mapIntent = PendingIntent.getActivity(context, widgetID, Util.getGoogleMapsIntentFromAddress(context, nextEvent.address), 0)
|
||||
views.setOnClickPendingIntent(R.id.second_row_rect, mapIntent)
|
||||
} else {
|
||||
views.setOnClickPendingIntent(R.id.next_event_rect, pIntent)
|
||||
}
|
||||
|
||||
v.next_event.measure(0, 0)
|
||||
views.setImageViewBitmap(R.id.next_event_rect, Util.getBitmapFromView(v.next_event))
|
||||
|
||||
|
||||
v.second_row.measure(0, 0)
|
||||
views.setImageViewBitmap(R.id.second_row_rect, Util.getBitmapFromView(v.second_row))
|
||||
views.setViewVisibility(R.id.second_row_rect, View.VISIBLE)
|
||||
|
||||
views.setViewVisibility(R.id.empty_layout_rect, View.GONE)
|
||||
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
|
||||
} else if (Preferences.secondRowInformation == 2 && nextAlarm != "") {
|
||||
val clockIntent = PendingIntent.getActivity(context, widgetID, Util.getClockIntent(context), 0)
|
||||
views.setOnClickPendingIntent(R.id.second_row_rect, clockIntent)
|
||||
|
||||
v.next_event.measure(0, 0)
|
||||
views.setImageViewBitmap(R.id.next_event_rect, Util.getBitmapFromView(v.next_event))
|
||||
|
||||
v.second_row.measure(0, 0)
|
||||
views.setImageViewBitmap(R.id.second_row_rect, Util.getBitmapFromView(v.second_row))
|
||||
views.setViewVisibility(R.id.second_row_rect, View.VISIBLE)
|
||||
|
||||
views.setViewVisibility(R.id.empty_layout_rect, View.GONE)
|
||||
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
|
||||
}
|
||||
|
||||
return views
|
||||
}
|
||||
|
||||
private fun updateWeatherView(context: Context, v: View, views: RemoteViews, widgetID: Int): RemoteViews {
|
||||
|
||||
if (Preferences.showWeather && Preferences.weatherIcon != "") {
|
||||
views.setViewVisibility(R.id.weather_rect, View.VISIBLE)
|
||||
views.setViewVisibility(R.id.calendar_weather_rect, View.VISIBLE)
|
||||
|
||||
val i = Intent(context, WidgetClickListenerReceiver::class.java)
|
||||
i.action = Actions.ACTION_OPEN_WEATHER_INTENT
|
||||
val weatherPIntent = PendingIntent.getBroadcast(context, widgetID, i, 0)
|
||||
|
||||
views.setOnClickPendingIntent(R.id.weather_rect, weatherPIntent)
|
||||
views.setOnClickPendingIntent(R.id.calendar_weather_rect, weatherPIntent)
|
||||
|
||||
v.weather.measure(0, 0)
|
||||
views.setImageViewBitmap(R.id.weather_rect, Util.getBitmapFromView(v.weather))
|
||||
|
||||
v.calendar_weather.measure(0, 0)
|
||||
views.setImageViewBitmap(R.id.calendar_weather_rect, Util.getBitmapFromView(v.calendar_weather))
|
||||
} else {
|
||||
views.setViewVisibility(R.id.weather_rect, View.GONE)
|
||||
views.setViewVisibility(R.id.calendar_weather_rect, View.GONE)
|
||||
}
|
||||
return views
|
||||
}
|
||||
|
||||
private fun updateClockView(context: Context, views: RemoteViews, widgetID: Int): RemoteViews {
|
||||
if (!Preferences.showClock) {
|
||||
views.setViewVisibility(R.id.time, View.GONE)
|
||||
} else {
|
||||
views.setTextColor(R.id.time, Util.getFontColor())
|
||||
views.setTextViewTextSize(R.id.time, TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(context))
|
||||
val clockPIntent = PendingIntent.getActivity(context, widgetID, Util.getClockIntent(context), 0)
|
||||
views.setOnClickPendingIntent(R.id.time, clockPIntent)
|
||||
views.setViewVisibility(R.id.time, View.VISIBLE)
|
||||
}
|
||||
|
||||
return views
|
||||
}
|
||||
|
||||
fun generateWidgetView(context: Context, maxWidth: Int): View {
|
||||
val v = View.inflate(context, R.layout.the_widget, null)
|
||||
|
||||
val now = Calendar.getInstance()
|
||||
|
||||
v.empty_layout.visibility = View.VISIBLE
|
||||
v.calendar_layout.visibility = View.GONE
|
||||
|
||||
val flags: Int = DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH
|
||||
v.empty_date.text = Util.getCapWordString("${SimpleDateFormat("EEEE", Locale.getDefault()).format(now.time)}, ${DateUtils.formatDateTime(context, now.timeInMillis, flags)}")
|
||||
|
||||
val nextEvent = CalendarUtil.getNextEvent()
|
||||
val nextAlarm = Util.getNextAlarm(context)
|
||||
|
||||
if (Preferences.showEvents && Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
||||
// Multiple counter
|
||||
v.action_next.isVisible = Preferences.showNextEvent && CalendarUtil.getEventsCount() > 1
|
||||
v.action_previous.isVisible = Preferences.showNextEvent && CalendarUtil.getEventsCount() > 1
|
||||
|
||||
v.next_event.text = nextEvent.title
|
||||
|
||||
if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) {
|
||||
v.next_event_difference_time.text = Util.getDifferenceText(context, now.timeInMillis, nextEvent.startDate).toLowerCase(Locale.getDefault())
|
||||
v.next_event_difference_time.visibility = View.VISIBLE
|
||||
} else {
|
||||
v.next_event_difference_time.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (nextEvent.address != "" && Preferences.secondRowInformation == 1) {
|
||||
v.second_row_icon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.round_place))
|
||||
v.next_event_date.text = nextEvent.address
|
||||
} else {
|
||||
v.second_row_icon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.round_today))
|
||||
if (!nextEvent.allDay) {
|
||||
val startHour = DateFormat.getTimeInstance(DateFormat.SHORT).format(nextEvent.startDate)
|
||||
val endHour = DateFormat.getTimeInstance(DateFormat.SHORT).format(nextEvent.endDate)
|
||||
|
||||
var dayDiff = TimeUnit.MILLISECONDS.toDays(nextEvent.endDate - nextEvent.startDate)
|
||||
|
||||
val startCal = Calendar.getInstance()
|
||||
startCal.timeInMillis = nextEvent.startDate
|
||||
|
||||
val endCal = Calendar.getInstance()
|
||||
endCal.timeInMillis = nextEvent.endDate
|
||||
|
||||
if (startCal.get(Calendar.HOUR_OF_DAY) > endCal.get(Calendar.HOUR_OF_DAY)) {
|
||||
dayDiff++
|
||||
} else if (startCal.get(Calendar.HOUR_OF_DAY) == endCal.get(Calendar.HOUR_OF_DAY) && startCal.get(Calendar.MINUTE) >= endCal.get(Calendar.MINUTE)) {
|
||||
dayDiff++
|
||||
}
|
||||
var multipleDay = ""
|
||||
if (dayDiff > 0) {
|
||||
multipleDay = String.format(" (+%s%s)", dayDiff, context.getString(R.string.day_char))
|
||||
}
|
||||
v.next_event_date.text = String.format("%s - %s%s", startHour, endHour, multipleDay)
|
||||
|
||||
} else {
|
||||
v.next_event_date.text = Util.getCapWordString(DateUtils.formatDateTime(context, now.timeInMillis, flags))
|
||||
}
|
||||
}
|
||||
|
||||
v.empty_layout.visibility = View.GONE
|
||||
v.calendar_layout.visibility = View.VISIBLE
|
||||
} else if (Preferences.secondRowInformation == 2 && nextAlarm != "") {
|
||||
v.second_row_icon.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.round_alarm
|
||||
)
|
||||
)
|
||||
v.next_event.text = Util.getCapWordString("${SimpleDateFormat("EEEE", Locale.getDefault()).format(now.time)}, ${DateUtils.formatDateTime(context, now.timeInMillis, flags)}")
|
||||
v.next_event_date.text = Util.getNextAlarm(context)
|
||||
v.empty_layout.visibility = View.GONE
|
||||
v.calendar_layout.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
|
||||
// Color
|
||||
listOf<TextView>(v.empty_date, v.divider1, v.temp, v.next_event, v.next_event_difference_time, v.next_event_date, v.divider2, v.calendar_temp).forEach {
|
||||
it.setTextColor(Util.getFontColor())
|
||||
}
|
||||
|
||||
listOf<ImageView>(v.second_row_icon, v.action_next, v.action_previous).forEach {
|
||||
it.setColorFilter(Util.getFontColor())
|
||||
}
|
||||
|
||||
// Text Size
|
||||
listOf<Pair<TextView, Float>>(
|
||||
v.empty_date to Preferences.textMainSize,
|
||||
v.divider1 to Preferences.textSecondSize,
|
||||
v.temp to Preferences.textMainSize,
|
||||
v.next_event to Preferences.textMainSize,
|
||||
v.next_event_difference_time to Preferences.textMainSize,
|
||||
v.next_event_date to Preferences.textSecondSize,
|
||||
v.divider2 to Preferences.textSecondSize,
|
||||
v.calendar_temp to Preferences.textSecondSize
|
||||
).forEach {
|
||||
it.first.setTextSize(TypedValue.COMPLEX_UNIT_SP, it.second)
|
||||
}
|
||||
|
||||
// Icons scale
|
||||
v.second_row_icon.scaleX = Preferences.textSecondSize / 18f
|
||||
v.second_row_icon.scaleY = Preferences.textSecondSize / 18f
|
||||
|
||||
v.weather_icon.scaleX = Preferences.textSecondSize / 18f
|
||||
v.weather_icon.scaleY = Preferences.textSecondSize / 18f
|
||||
|
||||
v.empty_weather_icon.scaleX = Preferences.textMainSize / 20f
|
||||
v.empty_weather_icon.scaleY = Preferences.textMainSize / 20f
|
||||
|
||||
v.action_next.scaleX = Preferences.textMainSize / 28f
|
||||
v.action_next.scaleY = Preferences.textMainSize / 28f
|
||||
|
||||
v.action_previous.scaleX = Preferences.textMainSize / 28f
|
||||
v.action_previous.scaleY = Preferences.textMainSize / 28f
|
||||
|
||||
|
||||
// Shadows
|
||||
val shadowRadius = when (Preferences.textShadow) {
|
||||
0 -> 0f
|
||||
1 -> 5f
|
||||
2 -> 5f
|
||||
else -> 5f
|
||||
}
|
||||
val shadowColor = when (Preferences.textShadow) {
|
||||
0 -> Color.TRANSPARENT
|
||||
1 -> R.color.black_50
|
||||
2 -> Color.BLACK
|
||||
else -> R.color.black_50
|
||||
}
|
||||
val shadowDy = when (Preferences.textShadow) {
|
||||
0 -> 0f
|
||||
1 -> 0f
|
||||
2 -> 1f
|
||||
else -> 0f
|
||||
}
|
||||
|
||||
listOf<TextView>(v.empty_date, v.divider1, v.temp, v.next_event, v.next_event_difference_time, v.next_event_date, v.divider2, v.calendar_temp).forEach {
|
||||
it.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||
}
|
||||
|
||||
// Custom Font
|
||||
if (Preferences.customFont == Constants.CUSTOM_FONT_PRODUCT_SANS) {
|
||||
val productSans: Typeface = Typeface.createFromAsset(context.assets, "fonts/product_sans_regular.ttf")
|
||||
listOf<TextView>(v.empty_date, v.divider1, v.temp, v.next_event, v.next_event_difference_time, v.next_event_date, v.divider2, v.calendar_temp).forEach {
|
||||
it.typeface = productSans
|
||||
}
|
||||
}
|
||||
|
||||
// Weather
|
||||
if (Preferences.showWeather && Preferences.weatherIcon != "") {
|
||||
v.weather.visibility = View.VISIBLE
|
||||
v.calendar_weather.visibility = View.VISIBLE
|
||||
val currentTemp = String.format(Locale.getDefault(), "%.0f °%s", Preferences.weatherTemp, Preferences.weatherRealTempUnit)
|
||||
|
||||
val icon: String = Preferences.weatherIcon
|
||||
if (icon == "") {
|
||||
v.weather_icon.visibility = View.GONE
|
||||
v.empty_weather_icon.visibility = View.GONE
|
||||
} else {
|
||||
v.weather_icon.setImageResource(WeatherUtil.getWeatherIconResource(icon))
|
||||
v.empty_weather_icon.setImageResource(WeatherUtil.getWeatherIconResource(icon))
|
||||
v.weather_icon.visibility = View.VISIBLE
|
||||
v.empty_weather_icon.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
v.temp.text = currentTemp
|
||||
v.calendar_temp.text = currentTemp
|
||||
} else {
|
||||
v.weather.visibility = View.GONE
|
||||
v.calendar_weather.visibility = View.GONE
|
||||
}
|
||||
|
||||
// Apply max width
|
||||
v.main_layout.layoutParams = RelativeLayout.LayoutParams(maxWidth, RelativeLayout.LayoutParams.WRAP_CONTENT)
|
||||
|
||||
return v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user