Release v2.0.1
This commit is contained in:
@ -1,186 +0,0 @@
|
||||
package com.tommasoberlose.anotherwidget.utils
|
||||
|
||||
import android.Manifest
|
||||
import android.content.ContentUris
|
||||
import android.content.Context
|
||||
import android.provider.CalendarContract
|
||||
import android.util.Log
|
||||
import com.chibatching.kotpref.blockingBulk
|
||||
import com.chibatching.kotpref.bulk
|
||||
import com.tommasoberlose.anotherwidget.components.events.Event
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmResults
|
||||
import me.everything.providers.android.calendar.CalendarProvider
|
||||
import java.util.*
|
||||
import kotlin.Comparator
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
/**
|
||||
* Created by tommaso on 08/10/17.
|
||||
*/
|
||||
|
||||
object CalendarUtil {
|
||||
|
||||
fun updateEventList(context: Context) {
|
||||
if (Preferences.showEvents) {
|
||||
val eventList = ArrayList<Event>()
|
||||
|
||||
val now = Calendar.getInstance()
|
||||
val limit = Calendar.getInstance()
|
||||
when (Preferences.showUntil) {
|
||||
0 -> limit.add(Calendar.HOUR, 3)
|
||||
1 -> limit.add(Calendar.HOUR, 6)
|
||||
2 -> limit.add(Calendar.HOUR, 12)
|
||||
3 -> limit.add(Calendar.DAY_OF_MONTH, 1)
|
||||
4 -> limit.add(Calendar.DAY_OF_MONTH, 3)
|
||||
5 -> limit.add(Calendar.DAY_OF_MONTH, 7)
|
||||
6 -> limit.add(Calendar.MINUTE, 30)
|
||||
7 -> limit.add(Calendar.HOUR, 1)
|
||||
else -> limit.add(Calendar.HOUR, 6)
|
||||
}
|
||||
|
||||
val builder = CalendarContract.Instances.CONTENT_URI.buildUpon()
|
||||
ContentUris.appendId(builder, now.timeInMillis)
|
||||
ContentUris.appendId(builder, limit.timeInMillis)
|
||||
|
||||
if (!Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)) {
|
||||
resetNextEventData(context)
|
||||
} else {
|
||||
val provider = CalendarProvider(context)
|
||||
val data = provider.getInstances(now.timeInMillis, limit.timeInMillis)
|
||||
if (data != null) {
|
||||
val instances = data.list
|
||||
for (instance in instances) {
|
||||
try {
|
||||
val e = provider.getEvent(instance.eventId)
|
||||
if (e != null && instance.begin <= limit.timeInMillis && (Preferences.calendarAllDay || !e.allDay) && !(Preferences.calendarFilter.contains(" " + e.calendarId + ",")) && (Preferences.showDeclinedEvents || e.selfAttendeeStatus.toInt() != CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED)) {
|
||||
if (e.allDay) {
|
||||
val start = Calendar.getInstance()
|
||||
start.timeInMillis = instance.begin
|
||||
val end = Calendar.getInstance()
|
||||
end.timeInMillis = instance.end
|
||||
instance.begin = start.timeInMillis - start.timeZone.getOffset(start.timeInMillis)
|
||||
instance.end = end.timeInMillis - end.timeZone.getOffset(end.timeInMillis)
|
||||
}
|
||||
eventList.add(Event(instance.id, e.id, e.title ?: "", instance.begin, instance.end, e.calendarId.toInt(), e.allDay, e.eventLocation ?: ""))
|
||||
}
|
||||
} catch (ignored: Exception) {}
|
||||
}
|
||||
}
|
||||
|
||||
if (eventList.isEmpty()) {
|
||||
resetNextEventData(context)
|
||||
} else {
|
||||
eventList.sortWith(Comparator { event: Event, event1: Event ->
|
||||
if (event.allDay && event1.allDay) {
|
||||
event.startDate.compareTo(event1.startDate)
|
||||
} else if (event.allDay) {
|
||||
1
|
||||
} else if (event1.allDay) {
|
||||
-1
|
||||
} else {
|
||||
event1.startDate.compareTo(event.startDate)
|
||||
}
|
||||
})
|
||||
eventList.reverse()
|
||||
saveEvents(eventList)
|
||||
saveNextEventData(context, eventList[0])
|
||||
}
|
||||
}
|
||||
} else {
|
||||
resetNextEventData(context)
|
||||
}
|
||||
|
||||
UpdatesReceiver.setUpdates(context)
|
||||
Util.updateWidget(context)
|
||||
}
|
||||
|
||||
fun getCalendarList(context: Context): List<me.everything.providers.android.calendar.Calendar> {
|
||||
val calendarList = ArrayList<me.everything.providers.android.calendar.Calendar>()
|
||||
|
||||
if (!Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)) {
|
||||
return calendarList
|
||||
}
|
||||
val provider = CalendarProvider(context)
|
||||
val data = provider.calendars
|
||||
return if (data != null) {
|
||||
data.list
|
||||
} else {
|
||||
calendarList
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveEvents(eventList: ArrayList<Event>) {
|
||||
Realm.getDefaultInstance().executeTransactionAsync { realm ->
|
||||
realm.where(Event::class.java).findAll().deleteAllFromRealm()
|
||||
realm.copyToRealm(eventList)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetNextEventData(context: Context) {
|
||||
Realm.getDefaultInstance().executeTransactionAsync {
|
||||
it.where(Event::class.java).findAll().deleteAllFromRealm()
|
||||
}
|
||||
|
||||
Preferences.bulk {
|
||||
remove(Preferences::nextEventId)
|
||||
remove(Preferences::nextEventName)
|
||||
remove(Preferences::nextEventStartDate)
|
||||
remove(Preferences::nextEventAllDay)
|
||||
remove(Preferences::nextEventLocation)
|
||||
remove(Preferences::nextEventEndDate)
|
||||
remove(Preferences::nextEventCalendarId)
|
||||
}
|
||||
|
||||
Util.updateWidget(context)
|
||||
}
|
||||
|
||||
private fun saveNextEventData(context: Context, event: Event) {
|
||||
Preferences.nextEventId = event.id
|
||||
Util.updateWidget(context)
|
||||
}
|
||||
|
||||
fun getNextEvent(): Event? {
|
||||
val realm = Realm.getDefaultInstance()
|
||||
return realm.where(Event::class.java).equalTo("id", Preferences.nextEventId).findFirst() ?: realm.where(Event::class.java).findFirst()
|
||||
}
|
||||
|
||||
fun goToNextEvent(context: Context) {
|
||||
val eventList = Realm.getDefaultInstance().where(Event::class.java).findAll()
|
||||
|
||||
if (eventList.isNotEmpty()) {
|
||||
val index = eventList.indexOfFirst { it.id == Preferences.nextEventId }
|
||||
if (index > -1 && index < eventList.size - 1) {
|
||||
Preferences.nextEventId = eventList[index + 1]!!.id
|
||||
} else {
|
||||
Preferences.nextEventId = eventList.first()!!.id
|
||||
}
|
||||
} else {
|
||||
resetNextEventData(context)
|
||||
}
|
||||
UpdatesReceiver.setUpdates(context)
|
||||
Util.updateWidget(context)
|
||||
}
|
||||
|
||||
fun goToPreviousEvent(context: Context) {
|
||||
val eventList = Realm.getDefaultInstance().where(Event::class.java).findAll()
|
||||
|
||||
if (eventList.isNotEmpty()) {
|
||||
val index = eventList.indexOfFirst { it.id == Preferences.nextEventId }
|
||||
if (index > 0) {
|
||||
Preferences.nextEventId = eventList[index - 1]!!.id
|
||||
} else {
|
||||
Preferences.nextEventId = eventList.last()!!.id
|
||||
}
|
||||
} else {
|
||||
resetNextEventData(context)
|
||||
}
|
||||
UpdatesReceiver.setUpdates(context)
|
||||
Util.updateWidget(context)
|
||||
}
|
||||
|
||||
fun getEvents(): RealmResults<Event> = Realm.getDefaultInstance().where(Event::class.java).findAll()
|
||||
fun getEventsCount(): Int = Realm.getDefaultInstance().where(Event::class.java).findAll().size
|
||||
}
|
@ -8,6 +8,7 @@ import android.widget.Toast
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.app.Activity
|
||||
import android.app.WallpaperManager
|
||||
import android.content.*
|
||||
import android.net.Uri
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
@ -18,8 +19,15 @@ import android.util.Patterns
|
||||
import java.security.NoSuchAlgorithmException
|
||||
import kotlin.math.max
|
||||
import android.content.Intent
|
||||
import android.content.res.Resources
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.TypedValue
|
||||
import android.view.animation.Animation
|
||||
import android.view.animation.Transformation
|
||||
import android.widget.LinearLayout
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import java.util.*
|
||||
|
||||
|
||||
fun PackageManager.missingSystemFeature(name: String): Boolean = !hasSystemFeature(name)
|
||||
@ -33,10 +41,11 @@ fun Context.toast(message: String) {
|
||||
fun Int.toPixel(context: Context): Int = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), context.resources.displayMetrics).toInt()
|
||||
fun Float.toPixel(context: Context): Float = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, context.resources.displayMetrics)
|
||||
|
||||
fun View.reveal(initialX: Int, initialY: Int) {
|
||||
fun View.reveal(initialX: Int? = null, initialY: Int? = null) {
|
||||
|
||||
when (visibility) {
|
||||
View.VISIBLE -> {
|
||||
val anim = ViewAnimationUtils.createCircularReveal(this, initialX, initialY, max(width.toFloat(), height.toFloat()), 0f)
|
||||
val anim = ViewAnimationUtils.createCircularReveal(this, initialX ?: this.measuredWidth / 2, initialY ?: this.measuredHeight / 2, max(width.toFloat(), height.toFloat()), 0f)
|
||||
.apply {
|
||||
duration = 200
|
||||
}
|
||||
@ -48,7 +57,7 @@ fun View.reveal(initialX: Int, initialY: Int) {
|
||||
})
|
||||
anim.start()
|
||||
} else -> {
|
||||
val anim = ViewAnimationUtils.createCircularReveal(this, initialX, initialY, 0f, max(width.toFloat(), height.toFloat()))
|
||||
val anim = ViewAnimationUtils.createCircularReveal(this, initialX ?: this.measuredWidth / 2, initialY ?: this.measuredHeight / 2, 0f, max(width.toFloat(), height.toFloat()))
|
||||
.apply {
|
||||
duration = 200
|
||||
}
|
||||
@ -58,6 +67,58 @@ fun View.reveal(initialX: Int, initialY: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun View.expand() {
|
||||
if (visibility != View.VISIBLE) {
|
||||
measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
val targetHeight = measuredHeight
|
||||
|
||||
layoutParams.height = 0
|
||||
visibility = View.VISIBLE
|
||||
val a = object : Animation() {
|
||||
protected override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
|
||||
layoutParams.height = if (interpolatedTime == 1f)
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
else
|
||||
(targetHeight * interpolatedTime).toInt()
|
||||
translationY = 0f
|
||||
requestLayout()
|
||||
}
|
||||
|
||||
override fun willChangeBounds(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
a.duration = 500L
|
||||
startAnimation(a)
|
||||
}
|
||||
}
|
||||
|
||||
fun View.collapse() {
|
||||
if (visibility != View.GONE) {
|
||||
val initialHeight = measuredHeight
|
||||
|
||||
val a = object : Animation() {
|
||||
protected override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
|
||||
if (interpolatedTime == 1f) {
|
||||
visibility = View.GONE
|
||||
} else {
|
||||
layoutParams.height = initialHeight - (initialHeight * interpolatedTime).toInt()
|
||||
requestLayout()
|
||||
}
|
||||
}
|
||||
|
||||
override fun willChangeBounds(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
a.duration = 500L //(initialHeight / v.context.resources.displayMetrics.density).toLong()
|
||||
startAnimation(a)
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.openURI(url: String) {
|
||||
try {
|
||||
val builder: CustomTabsIntent.Builder = CustomTabsIntent.Builder()
|
||||
@ -117,14 +178,38 @@ fun Activity.isDarkTheme(): Boolean {
|
||||
|
||||
fun Activity.isNotificationAccessGranted(): Boolean = Settings.Secure.getString(this.contentResolver,"enabled_notification_listeners").contains(this.packageName)
|
||||
|
||||
//fun Activity.sendEmailTo(email: String) {
|
||||
// val i = Intent(Intent.ACTION_VIEW).apply {
|
||||
// data = Uri.parse("mailto:$email")
|
||||
// }
|
||||
// try {
|
||||
// startActivity(Intent.createChooser(i, getString(R.string.settings_title_feedback)))
|
||||
// } catch (ex: java.lang.Exception) {
|
||||
// toast(getString(R.string.generic_error))
|
||||
// }
|
||||
//
|
||||
//}
|
||||
fun Float.convertDpToPixel(context: Context): Float {
|
||||
val resources: Resources = context.resources
|
||||
val metrics: DisplayMetrics = resources.displayMetrics
|
||||
val px: Float = this * (metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)
|
||||
return px
|
||||
}
|
||||
|
||||
fun Float.convertSpToPixels(context: Context): Float {
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, this, context.resources.displayMetrics)
|
||||
}
|
||||
|
||||
fun Context.checkGrantedPermission(permission: String): Boolean {
|
||||
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
|
||||
fun Context.getCurrentWallpaper(): Drawable? = try {
|
||||
WallpaperManager.getInstance(this).drawable
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
fun String.getCapWordString(): String {
|
||||
return try {
|
||||
val ar = this.split(" ")
|
||||
var newText = ""
|
||||
for (t: String in ar) {
|
||||
newText += " "
|
||||
newText += t.substring(0, 1).toUpperCase(Locale.getDefault())
|
||||
newText += t.substring(1)
|
||||
}
|
||||
newText.substring(1)
|
||||
} catch (e: Exception) {
|
||||
this
|
||||
}
|
||||
}
|
@ -1,521 +0,0 @@
|
||||
package com.tommasoberlose.anotherwidget.utils
|
||||
|
||||
import android.app.*
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.*
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Resources
|
||||
import android.graphics.*
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.util.DisplayMetrics
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.util.TypedValue
|
||||
import android.content.Intent
|
||||
import android.content.ComponentName
|
||||
import android.provider.AlarmClock
|
||||
import android.provider.CalendarContract
|
||||
import android.text.format.DateFormat
|
||||
import android.text.format.DateUtils
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.animation.Animation
|
||||
import android.view.animation.Transformation
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import com.tommasoberlose.anotherwidget.components.events.Event
|
||||
import com.tommasoberlose.anotherwidget.global.Actions
|
||||
import com.tommasoberlose.anotherwidget.global.Constants
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.ui.widgets.TheWidget
|
||||
import org.joda.time.DateTime
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
/**
|
||||
* Created by tommaso on 05/10/17.
|
||||
*/
|
||||
|
||||
object Util {
|
||||
|
||||
fun checkGrantedPermission(context: Context, permission: String): Boolean {
|
||||
return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
|
||||
fun updateWidget(context: Context) {
|
||||
val widgetManager = AppWidgetManager.getInstance(context)
|
||||
val widgetComponent = ComponentName(context, TheWidget::class.java)
|
||||
val widgetIds = widgetManager.getAppWidgetIds(widgetComponent)
|
||||
val update = Intent(context, TheWidget::class.java)
|
||||
update.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds)
|
||||
update.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
context.sendBroadcast(update)
|
||||
}
|
||||
|
||||
fun showWeatherErrorNotification(context: Context) {
|
||||
TODO("weather notification")
|
||||
// val mNotificationManager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
// val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
// val SP = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
//
|
||||
// if (SP.getBoolean(Constants.PREF_SHOW_GPS_NOTIFICATION, true) && !locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) && SP.getInt(Constants.PREF_WEATHER_PROVIDER, Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS) == Constants.WEATHER_PROVIDER_GOOGLE_AWARENESS) {
|
||||
// val settingsIntent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
|
||||
// val pi: PendingIntent = PendingIntent.getActivity(context, 50, settingsIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
//
|
||||
// val providerIntent2 = Intent(context, MainActivity::class.java)
|
||||
// providerIntent2.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
// providerIntent2.putExtra(Constants.ACTION_EXTRA_OPEN_WEATHER_PROVIDER, true)
|
||||
// val pi2: PendingIntent = PendingIntent.getActivity(context, 51, providerIntent2, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
//
|
||||
// val providerIntentDisable = Intent(context, MainActivity::class.java)
|
||||
// providerIntentDisable.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
// providerIntentDisable.putExtra(Constants.ACTION_EXTRA_DISABLE_GPS_NOTIFICATION, true)
|
||||
// val piDisable: PendingIntent = PendingIntent.getActivity(context, 52, providerIntentDisable, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
//
|
||||
// val mBuilder: NotificationCompat.Builder = NotificationCompat.Builder(context, "Error")
|
||||
// .setSmallIcon(R.drawable.ic_stat_name)
|
||||
// .setColor(ContextCompat.getColor(context, R.color.colorPrimary))
|
||||
// .setContentTitle(context.getString(R.string.notification_gps_title))
|
||||
// .setContentText(context.getString(R.string.notification_gps_subtitle))
|
||||
// .addAction(R.drawable.ic_action_sync, context.getString(R.string.change_provider), pi2)
|
||||
// .addAction(R.drawable.ic_action_settings, context.getString(R.string.disable_notification), piDisable)
|
||||
// .setContentIntent(pi)
|
||||
//
|
||||
// mNotificationManager.notify(10, mBuilder.build());
|
||||
// } else {
|
||||
// mNotificationManager.cancel(10)
|
||||
// }
|
||||
}
|
||||
|
||||
fun getGoogleMapsIntentFromAddress(context: Context, address:String): Intent {
|
||||
val gmmIntentUri: Uri = Uri.parse("geo:0,0?q=$address")
|
||||
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
||||
mapIntent.`package` = "com.google.android.apps.maps"
|
||||
|
||||
return if (mapIntent.resolveActivity(context.packageManager) != null) {
|
||||
mapIntent
|
||||
} else {
|
||||
val map = "http://maps.google.co.in/maps?q=$address"
|
||||
val i = Intent(Intent.ACTION_VIEW, Uri.parse(map));
|
||||
i
|
||||
}
|
||||
}
|
||||
|
||||
fun getCurrentWallpaper(context: Context): Drawable? = try {
|
||||
WallpaperManager.getInstance(context).drawable
|
||||
} catch (e: Exception) {
|
||||
// BitmapDrawable(context.resources, getResizedBitmap(BitmapFactory.decodeResource(context.resources, R.drawable.pixel_2_wallpaper), 800))
|
||||
null
|
||||
}
|
||||
|
||||
fun getBitmapFromView(view: View): Bitmap {
|
||||
//Define a bitmap with the same size as the view
|
||||
val measuredWidth = View.MeasureSpec.makeMeasureSpec(view.width, View.MeasureSpec.UNSPECIFIED)
|
||||
val measuredHeight = View.MeasureSpec.makeMeasureSpec(view.height, View.MeasureSpec.UNSPECIFIED)
|
||||
view.measure(measuredWidth, measuredHeight)
|
||||
view.layout(0,0, measuredWidth, measuredHeight)
|
||||
val returnedBitmap = Bitmap.createBitmap(view.measuredWidth, view.measuredHeight, Bitmap.Config.ARGB_8888)
|
||||
//Bind a canvas to it
|
||||
val canvas = Canvas(returnedBitmap)
|
||||
// draw the view on the canvas
|
||||
view.draw(canvas)
|
||||
//return the bitmap
|
||||
return returnedBitmap
|
||||
}
|
||||
|
||||
fun getBitmapFromView(view: View, w: Int, h: Int): Bitmap {
|
||||
//Define a bitmap with the same size as the view
|
||||
val measuredWidth = View.MeasureSpec.makeMeasureSpec(w, View.MeasureSpec.EXACTLY)
|
||||
val measuredHeight = View.MeasureSpec.makeMeasureSpec(h, View.MeasureSpec.EXACTLY)
|
||||
view.measure(measuredWidth, measuredHeight)
|
||||
view.layout(0,0, measuredWidth, measuredHeight)
|
||||
val returnedBitmap = Bitmap.createBitmap(view.measuredWidth, view.measuredHeight, Bitmap.Config.ARGB_8888)
|
||||
//Bind a canvas to it
|
||||
val canvas = Canvas(returnedBitmap)
|
||||
// draw the view on the canvas
|
||||
view.draw(canvas)
|
||||
//return the bitmap
|
||||
return returnedBitmap
|
||||
}
|
||||
|
||||
fun convertDpToPixel(dp: Float, context: Context): Float {
|
||||
val resources: Resources = context.resources
|
||||
val metrics: DisplayMetrics = resources.displayMetrics
|
||||
val px: Float = dp * (metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)
|
||||
return px
|
||||
}
|
||||
|
||||
fun convertSpToPixels(sp: Float, context: Context): Float {
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, context.resources.displayMetrics)
|
||||
}
|
||||
|
||||
fun getResizedBitmap(image: Bitmap, maxSize: Int): Bitmap {
|
||||
var width = image.width
|
||||
var height = image.height
|
||||
|
||||
val bitmapRatio = width.toFloat() / height.toFloat()
|
||||
if (bitmapRatio > 1) {
|
||||
width = maxSize
|
||||
height = (width / bitmapRatio).toInt()
|
||||
} else {
|
||||
height = maxSize
|
||||
width = (height * bitmapRatio).toInt()
|
||||
}
|
||||
|
||||
return Bitmap.createScaledBitmap(image, width, height, true)
|
||||
}
|
||||
|
||||
fun getRefreshPeriodString(period: Int): Int {
|
||||
return when (period) {
|
||||
0 -> R.string.settings_weather_refresh_period_subtitle_0
|
||||
1 -> R.string.settings_weather_refresh_period_subtitle_1
|
||||
2 -> R.string.settings_weather_refresh_period_subtitle_2
|
||||
3 -> R.string.settings_weather_refresh_period_subtitle_3
|
||||
4 -> R.string.settings_weather_refresh_period_subtitle_4
|
||||
5 -> R.string.settings_weather_refresh_period_subtitle_5
|
||||
else -> R.string.settings_weather_refresh_period_subtitle_0
|
||||
}
|
||||
}
|
||||
|
||||
fun getShowUntilString(period: Int): Int {
|
||||
return when (period) {
|
||||
0 -> R.string.settings_show_until_subtitle_0
|
||||
1 -> R.string.settings_show_until_subtitle_1
|
||||
2 -> R.string.settings_show_until_subtitle_2
|
||||
3 -> R.string.settings_show_until_subtitle_3
|
||||
4 -> R.string.settings_show_until_subtitle_4
|
||||
5 -> R.string.settings_show_until_subtitle_5
|
||||
6 -> R.string.settings_show_until_subtitle_6
|
||||
7 -> R.string.settings_show_until_subtitle_7
|
||||
else -> R.string.settings_show_until_subtitle_1
|
||||
}
|
||||
}
|
||||
|
||||
fun getSecondRowInfoString(info: Int): Int {
|
||||
return when (info) {
|
||||
0 -> R.string.settings_second_row_info_subtitle_0
|
||||
1 -> R.string.settings_second_row_info_subtitle_1
|
||||
2 -> R.string.settings_second_row_info_subtitle_2
|
||||
else -> R.string.settings_second_row_info_subtitle_0
|
||||
}
|
||||
}
|
||||
|
||||
fun getTextShadowString(shadow: Int): Int {
|
||||
return when (shadow) {
|
||||
0 -> R.string.settings_text_shadow_subtitle_none
|
||||
1 -> R.string.settings_text_shadow_subtitle_low
|
||||
2 -> R.string.settings_text_shadow_subtitle_high
|
||||
else -> R.string.settings_text_shadow_subtitle_low
|
||||
}
|
||||
}
|
||||
|
||||
fun getCustomFontLabel(shadow: Int): Int {
|
||||
return when (shadow) {
|
||||
0 -> R.string.custom_font_subtitle_0
|
||||
1 -> R.string.custom_font_subtitle_1
|
||||
else -> R.string.custom_font_subtitle_1
|
||||
}
|
||||
}
|
||||
|
||||
fun getCalendarIntent(context: Context): Intent {
|
||||
return when (Preferences.calendarAppPackage) {
|
||||
"" -> {
|
||||
Intent(Intent.ACTION_MAIN).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
addCategory(Intent.CATEGORY_APP_CALENDAR)
|
||||
}
|
||||
}
|
||||
"_" -> {
|
||||
Intent()
|
||||
}
|
||||
else -> {
|
||||
val pm: PackageManager = context.packageManager
|
||||
try {
|
||||
pm.getLaunchIntentForPackage(Preferences.calendarAppPackage)!!.apply {
|
||||
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Intent(Intent.ACTION_MAIN).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
addCategory(Intent.CATEGORY_APP_CALENDAR)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getWeatherIntent(context: Context): Intent {
|
||||
return when (Preferences.weatherAppPackage) {
|
||||
"" -> {
|
||||
Intent(Intent.ACTION_VIEW).apply {
|
||||
addCategory(Intent.CATEGORY_DEFAULT)
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
data = Uri.parse("dynact://velour/weather/ProxyActivity")
|
||||
component = ComponentName("com.google.android.googlequicksearchbox", "com.google.android.apps.gsa.velour.DynamicActivityTrampoline")
|
||||
}
|
||||
}
|
||||
"_" -> {
|
||||
Intent()
|
||||
}
|
||||
else -> {
|
||||
val pm: PackageManager = context.packageManager
|
||||
try {
|
||||
pm.getLaunchIntentForPackage(Preferences.weatherAppPackage)!!.apply {
|
||||
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Intent(Intent.ACTION_VIEW).apply {
|
||||
addCategory(Intent.CATEGORY_DEFAULT)
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
data = Uri.parse("dynact://velour/weather/ProxyActivity")
|
||||
component = ComponentName("com.google.android.googlequicksearchbox", "com.google.android.apps.gsa.velour.DynamicActivityTrampoline")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getEventIntent(context: Context, e: Event): Intent {
|
||||
return when (Preferences.eventAppPackage) {
|
||||
"" -> {
|
||||
val uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, e.eventID)
|
||||
Intent(Intent.ACTION_VIEW).apply {
|
||||
data = uri
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
putExtra("beginTime", e.startDate)
|
||||
putExtra("endTime", e.endDate)
|
||||
}
|
||||
}
|
||||
"_" -> {
|
||||
Intent()
|
||||
}
|
||||
else -> {
|
||||
val pm: PackageManager = context.packageManager
|
||||
try {
|
||||
pm.getLaunchIntentForPackage(Preferences.eventAppPackage)!!.apply {
|
||||
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
val uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, e.id)
|
||||
Intent(Intent.ACTION_VIEW).apply {
|
||||
data = uri
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
putExtra("beginTime", e.startDate)
|
||||
putExtra("endTime", e.endDate)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getClockIntent(context: Context): Intent {
|
||||
return when (Preferences.clockAppPackage) {
|
||||
"" -> {
|
||||
Intent(AlarmClock.ACTION_SHOW_ALARMS).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
}
|
||||
}
|
||||
"_" -> {
|
||||
Intent()
|
||||
}
|
||||
else -> {
|
||||
val pm: PackageManager = context.packageManager
|
||||
try {
|
||||
pm.getLaunchIntentForPackage(Preferences.clockAppPackage)!!.apply {
|
||||
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Intent(AlarmClock.ACTION_SHOW_ALARMS).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getCapWordString(text: String): String {
|
||||
return try {
|
||||
val ar = text.split(" ")
|
||||
var newText = ""
|
||||
for (t: String in ar) {
|
||||
newText += " "
|
||||
newText += t.substring(0, 1).toUpperCase(Locale.getDefault())
|
||||
newText += t.substring(1)
|
||||
}
|
||||
newText.substring(1)
|
||||
} catch (e: Exception) {
|
||||
text
|
||||
}
|
||||
}
|
||||
|
||||
fun showLocationNotification(context: Context, show: Boolean) {
|
||||
TODO("Show location notification")
|
||||
// val mNotificationManager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager;
|
||||
//
|
||||
// if (show) {
|
||||
// val mBuilder: NotificationCompat.Builder = NotificationCompat.Builder(context, "Config")
|
||||
// .setSmallIcon(R.drawable.ic_stat_name)
|
||||
// .setPriority(Notification.PRIORITY_MIN)
|
||||
// .setColor(ContextCompat.getColor(context, R.color.colorPrimary))
|
||||
// .setContentTitle(context.getString(R.string.notification_gps_title))
|
||||
// .setContentText(context.getString(R.string.notification_gps_subtitle))
|
||||
// .setAutoCancel(true);
|
||||
//
|
||||
// val intent: Intent = Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
||||
// val pi: PendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
// mBuilder.setContentIntent(pi);
|
||||
// mNotificationManager.notify(1, mBuilder.build());
|
||||
// } else {
|
||||
// mNotificationManager.cancel(1);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
fun showWeatherNotification(context: Context, show: Boolean) {
|
||||
TODO("Show location notification")
|
||||
// val mNotificationManager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager;
|
||||
//
|
||||
// if (show) {
|
||||
// val mBuilder: NotificationCompat.Builder = NotificationCompat.Builder(context, "Config")
|
||||
// .setSmallIcon(R.drawable.ic_stat_name)
|
||||
// .setColor(ContextCompat.getColor(context, R.color.colorPrimary))
|
||||
// .setContentTitle(context.getString(R.string.settings_weather_provider_api_key_title))
|
||||
// .setContentText(context.getString(R.string.settings_weather_provider_api_key_subtitle_not_set))
|
||||
// .setAutoCancel(true);
|
||||
//
|
||||
// val intent: Intent = Intent(context, MainActivity::class.java);
|
||||
// intent.putExtra(Constants.ACTION_EXTRA_OPEN_WEATHER_PROVIDER, true)
|
||||
// val pi: PendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
// mBuilder.setContentIntent(pi);
|
||||
// mNotificationManager.notify(2, mBuilder.build());
|
||||
// } else {
|
||||
// mNotificationManager.cancel(2);
|
||||
// }
|
||||
}
|
||||
|
||||
fun expand(v: View) {
|
||||
if (v.visibility != View.VISIBLE) {
|
||||
v.measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
val targetHeight = v.measuredHeight
|
||||
|
||||
v.layoutParams.height = 0
|
||||
v.visibility = View.VISIBLE
|
||||
val a = object : Animation() {
|
||||
protected override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
|
||||
v.layoutParams.height = if (interpolatedTime == 1f)
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
else
|
||||
(targetHeight * interpolatedTime).toInt()
|
||||
v.translationY = 0f
|
||||
v.requestLayout()
|
||||
}
|
||||
|
||||
override fun willChangeBounds(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
a.duration = 500L
|
||||
v.startAnimation(a)
|
||||
}
|
||||
}
|
||||
|
||||
fun collapse(v: View) {
|
||||
if (v.visibility != View.GONE) {
|
||||
val initialHeight = v.measuredHeight
|
||||
|
||||
val a = object : Animation() {
|
||||
protected override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
|
||||
if (interpolatedTime == 1f) {
|
||||
v.visibility = View.GONE
|
||||
} else {
|
||||
v.layoutParams.height = initialHeight - (initialHeight * interpolatedTime).toInt()
|
||||
v.requestLayout()
|
||||
}
|
||||
}
|
||||
|
||||
override fun willChangeBounds(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
a.duration = 500L //(initialHeight / v.context.resources.displayMetrics.density).toLong()
|
||||
v.startAnimation(a)
|
||||
}
|
||||
}
|
||||
|
||||
fun getEmojiByUnicode(unicode: Int): String {
|
||||
return String(Character.toChars(unicode))
|
||||
}
|
||||
|
||||
fun getDifferenceText(context: Context, now: Long, start: Long): String {
|
||||
val nowDate = DateTime(now)
|
||||
val eventDate = DateTime(start)
|
||||
|
||||
var difference = start - now
|
||||
difference += 60 * 1000 - (difference % (60 * 1000))
|
||||
|
||||
when {
|
||||
difference <= 0 || TimeUnit.MILLISECONDS.toHours(difference) < 1 -> {
|
||||
return ""
|
||||
}
|
||||
TimeUnit.MILLISECONDS.toHours(difference) < 12 -> {
|
||||
return DateUtils.getRelativeTimeSpanString(start, now, DateUtils.HOUR_IN_MILLIS).toString()
|
||||
}
|
||||
eventDate.dayOfYear == nowDate.plusDays(1).dayOfYear -> {
|
||||
return String.format("%s", context.getString(R.string.tomorrow))
|
||||
}
|
||||
eventDate.dayOfYear == nowDate.dayOfYear -> {
|
||||
return String.format("%s", context.getString(R.string.today))
|
||||
}
|
||||
else -> {
|
||||
return DateUtils.getRelativeTimeSpanString(start, now, DateUtils.DAY_IN_MILLIS).toString()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun getFontColor(): Int {
|
||||
return try {
|
||||
Color.parseColor(Preferences.textGlobalColor)
|
||||
} catch (e: Exception) {
|
||||
Color.parseColor("#FFFFFF")
|
||||
}
|
||||
}
|
||||
|
||||
fun getTintedDrawable(context: Context, inputDrawable: Int, color: Int): Drawable? = ContextCompat.getDrawable(context, inputDrawable)?.apply {
|
||||
DrawableCompat.setTint(this, color)
|
||||
DrawableCompat.setTintMode(this, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
fun changeBitmapColor(sourceBitmap: Bitmap, color: Int): Bitmap {
|
||||
val resultBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0,
|
||||
sourceBitmap.width - 1, sourceBitmap.height - 1)
|
||||
val p = Paint()
|
||||
val filter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
|
||||
p.colorFilter = filter
|
||||
|
||||
val canvas = Canvas(resultBitmap)
|
||||
canvas.drawBitmap(resultBitmap, 0f, 0f, p)
|
||||
|
||||
return resultBitmap
|
||||
}
|
||||
|
||||
fun getNextAlarm(context: Context): String = with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
||||
return if (nextAlarmClock != null && nextAlarmClock.triggerTime - Calendar.getInstance().timeInMillis > 5 * 60 * 1000) {
|
||||
DateFormat.getTimeFormat(context).format(Date(nextAlarmClock.triggerTime))
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
@ -1,145 +0,0 @@
|
||||
package com.tommasoberlose.anotherwidget.utils
|
||||
|
||||
import android.content.Context
|
||||
import com.google.android.gms.location.LocationServices
|
||||
import com.kwabenaberko.openweathermaplib.constants.Units
|
||||
import com.kwabenaberko.openweathermaplib.implementation.OpenWeatherMapHelper
|
||||
import com.kwabenaberko.openweathermaplib.implementation.callbacks.CurrentWeatherCallback
|
||||
import com.kwabenaberko.openweathermaplib.models.currentweather.CurrentWeather
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
|
||||
|
||||
/**
|
||||
* Created by tommaso on 08/10/17.
|
||||
*/
|
||||
|
||||
object WeatherUtil {
|
||||
|
||||
fun updateWeather(context: Context) {
|
||||
if (Preferences.customLocationAdd != "") {
|
||||
weatherNetworkRequest(
|
||||
context
|
||||
)
|
||||
} else {
|
||||
LocationServices.getFusedLocationProviderClient(context).lastLocation.addOnSuccessListener {
|
||||
Preferences.customLocationLat = it.latitude.toString()
|
||||
Preferences.customLocationLon = it.longitude.toString()
|
||||
|
||||
weatherNetworkRequest(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun weatherNetworkRequest(context: Context) {
|
||||
if (Preferences.showWeather && Preferences.weatherProviderApi != "" && Preferences.customLocationLat != "" && Preferences.customLocationLon != "") {
|
||||
val helper = OpenWeatherMapHelper(Preferences.weatherProviderApi)
|
||||
helper.setUnits(if (Preferences.weatherTempUnit == "F") Units.IMPERIAL else Units.METRIC)
|
||||
helper.getCurrentWeatherByGeoCoordinates(Preferences.customLocationLat.toDouble(), Preferences.customLocationLon.toDouble(), object : CurrentWeatherCallback {
|
||||
override fun onSuccess(currentWeather: CurrentWeather?) {
|
||||
currentWeather?.let {
|
||||
Preferences.weatherTemp = currentWeather.main.temp.toFloat()
|
||||
Preferences.weatherIcon = currentWeather.weather[0].icon
|
||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||
Util.updateWidget(context)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(throwable: Throwable?) {
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
removeWeather(context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeWeather(context: Context) {
|
||||
Preferences.remove(Preferences::weatherTemp)
|
||||
Preferences.remove(Preferences::weatherTempUnit)
|
||||
Util.updateWidget(context)
|
||||
}
|
||||
|
||||
fun getWeatherIconResource(icon: String): Int {
|
||||
when (icon) {
|
||||
"01d" -> {
|
||||
return R.drawable.clear_day
|
||||
}
|
||||
"02d" -> {
|
||||
return R.drawable.partly_cloudy
|
||||
}
|
||||
"03d" -> {
|
||||
return R.drawable.mostly_cloudy
|
||||
}
|
||||
"04d" -> {
|
||||
return R.drawable.cloudy_weather
|
||||
}
|
||||
"09d" -> {
|
||||
return R.drawable.storm_weather_day
|
||||
}
|
||||
"10d" -> {
|
||||
return R.drawable.rainy_day
|
||||
}
|
||||
"11d" -> {
|
||||
return R.drawable.thunder_day
|
||||
}
|
||||
"13d" -> {
|
||||
return R.drawable.snow_day
|
||||
}
|
||||
"50d" -> {
|
||||
return R.drawable.haze_day
|
||||
}
|
||||
"80d" -> {
|
||||
return R.drawable.windy_day
|
||||
}
|
||||
"81d" -> {
|
||||
return R.drawable.rain_snow_day
|
||||
}
|
||||
"82d" -> {
|
||||
return R.drawable.haze_weather
|
||||
}
|
||||
|
||||
|
||||
|
||||
"01n" -> {
|
||||
return R.drawable.clear_night
|
||||
}
|
||||
"02n" -> {
|
||||
return R.drawable.partly_cloudy_night
|
||||
}
|
||||
"03n" -> {
|
||||
return R.drawable.mostly_cloudy_night
|
||||
}
|
||||
"04n" -> {
|
||||
return R.drawable.cloudy_weather
|
||||
}
|
||||
"09n" -> {
|
||||
return R.drawable.storm_weather_night
|
||||
}
|
||||
"10n" -> {
|
||||
return R.drawable.rainy_night
|
||||
}
|
||||
"11n" -> {
|
||||
return R.drawable.thunder_night
|
||||
}
|
||||
"13n" -> {
|
||||
return R.drawable.snow_night
|
||||
}
|
||||
"50n" -> {
|
||||
return R.drawable.haze_night
|
||||
}
|
||||
"80n" -> {
|
||||
return R.drawable.windy_night
|
||||
}
|
||||
"81n" -> {
|
||||
return R.drawable.rain_snow_night
|
||||
}
|
||||
"82n" -> {
|
||||
return R.drawable.haze_weather
|
||||
}
|
||||
else -> {
|
||||
return R.drawable.unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user