Multiple changes and fixes

This commit is contained in:
Tommaso Berlose 2017-10-13 18:28:45 +02:00
parent f7e99184c9
commit 4d80c53b67
85 changed files with 903 additions and 347 deletions

View File

@ -6,6 +6,8 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'io.fabric'
android {
compileSdkVersion 26
buildToolsVersion "26.0.2"
@ -13,7 +15,7 @@ android {
applicationId "com.tommasoberlose.anotherwidget"
minSdkVersion 19
targetSdkVersion 26
versionCode 5
versionCode 11
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
@ -23,9 +25,6 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
}
dependencies {
@ -42,6 +41,11 @@ dependencies {
compile 'com.mcxiaoke.volley:library:1.0.6@aar'
compile 'com.android.support:customtabs:26.1.0'
compile 'com.android.support:cardview-v7:26.1.0'
compile 'com.heinrichreimersoftware:material-intro:1.6.2'
kapt 'com.android.databinding:compiler:2.3.3'
compile('com.crashlytics.sdk.android:crashlytics:2.7.0@aar') {
transitive = true;
}
compile 'com.android.support:design:26.1.0'
compile 'com.github.rubensousa:bottomsheetbuilder:1.6.0'
compile 'com.github.johnhiott:DarkSkyApi:v0.1.5'
}

3
app/fabric.properties Normal file
View File

@ -0,0 +1,3 @@
#Contains API Secret used to validate your application. Commit to internal source control; avoid making secret public.
#Wed Oct 11 22:01:24 CEST 2017
apiSecret=df2efbce5a4f9101ba6923b7dfa5725a5283ee08c3e748ccfafb01a5070bb532

View File

@ -1 +1 @@
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":5},"path":"app-release.apk","properties":{"packageId":"com.tommasoberlose.anotherwidget","split":"","minSdkVersion":"19"}}]
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":11},"path":"app-release.apk","properties":{"packageId":"com.tommasoberlose.anotherwidget","split":"","minSdkVersion":"19"}}]

View File

@ -4,7 +4,7 @@
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
@ -16,8 +16,8 @@
android:theme="@style/AppTheme">
<activity
android:name=".ui.activity.MainActivity"
android:launchMode="singleInstance"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleInstance"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -41,6 +41,7 @@
android:priority="1000">
<intent-filter>
<action android:name="android.intent.action.PROVIDER_CHANGED" />
<data android:scheme="content" />
<data android:host="com.android.calendar" />
</intent-filter>
@ -51,6 +52,9 @@
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="com.tommasoberlose.anotherwidget.action.ACTION_TIME_UPDATE" />
<action android:name="com.tommasoberlose.anotherwidget.action.ACTION_CALENDAR_UPDATE" />
</intent-filter>
</receiver>
<receiver
@ -59,13 +63,16 @@
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="com.tommasoberlose.anotherwidget.action.ACTION_WEATHER_UPDATE" />
</intent-filter>
</receiver>
<activity android:name=".ui.activity.SplashActivity"
android:theme="@style/Theme.Intro"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait" />
<meta-data
android:name="io.fabric.ApiKey"
android:value="5232fd734b08a20a984c2de02b37df19269608ef" />
<activity android:name=".ui.activity.CustomLocationActivity"></activity>
</application>
</manifest>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,6 @@
package com.tommasoberlose.anotherwidget.`object`
import android.annotation.SuppressLint
import java.text.SimpleDateFormat
import java.util.*
@ -7,10 +8,13 @@ import java.util.*
* Created by tommaso on 05/10/17.
*/
@SuppressLint("SimpleDateFormat")
object Constants {
val CALENDAR_REQUEST_CODE = 1
val LOCATION_REQUEST_CODE = 2
val RESULT_CODE_CUSTOM_LOCATION = 45
val PREF_FIRST_STEP = "PREF_FIRST_STEP"
val PREF_WEATHER_ICON = "PREF_WEATHER_ICON"
val PREF_WEATHER_TEMP = "PREF_WEATHER_TEMP"
@ -21,12 +25,22 @@ object Constants {
val PREF_NEXT_EVENT_ID = "PREF_NEXT_EVENT_ID"
val PREF_NEXT_EVENT_NAME = "PREF_NEXT_EVENT_NAME"
val PREF_NEXT_EVENT_START_DATE = "PREF_NEXT_EVENT_START_DATE"
val PREF_NEXT_EVENT_ALL_DAY = "PREF_NEXT_EVENT_ALL_DAY"
val PREF_NEXT_EVENT_END_DATE = "PREF_NEXT_EVENT_END_DATE"
val PREF_NEXT_EVENT_CALENDAR_ID = "PREF_NEXT_EVENT_CALENDAR_ID"
val PREF_CUSTOM_LOCATION_LAT = "PREF_CUSTOM_LOCATION_LAT"
val PREF_CUSTOM_LOCATION_LON = "PREF_CUSTOM_LOCATION_LON"
val PREF_CUSTOM_LOCATION_ADD = "PREF_CUSTOM_LOCATION_ADD"
val PREF_HOUR_FORMAT = "PREF_HOUR_FORMAT"
val PREF_ITA_FORMAT_DATE = "PREF_ITA_FORMAT_DATE"
val PREF_WEATHER_REFRESH_PERIOD = "PREF_WEATHER_REFRESH_PERIOD"
val dateFormat = SimpleDateFormat("EEEE, MMM d", Locale.getDefault())
val hourFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
val itDateFormat = SimpleDateFormat("EEEE, d MMM")
val engDateFormat = SimpleDateFormat("EEEE, MMM d")
val goodHourFormat = SimpleDateFormat("HH:mm")
val badHourFormat = SimpleDateFormat("KK:mm aa")
val ACTION_TIME_UPDATE = "com.tommasoberlose.anotherwidget.action.ACTION_TIME_UPDATE"
val ACTION_CALENDAR_UPDATE = "com.tommasoberlose.anotherwidget.action.ACTION_CALENDAR_UPDATE"
val ACTION_WEATHER_UPDATE = "com.tommasoberlose.anotherwidget.action.ACTION_WEATHER_UPDATE"
}

View File

@ -14,13 +14,15 @@ class Event {
var startDate: Long = 0
var endDate: Long = 0
var calendarID: Int = 0
var allDay: Boolean = false
constructor(id:Int, title:String, startDate:Long, endDate:Long, calendarID: Int) {
constructor(id:Int, title:String, startDate:Long, endDate:Long, calendarID: Int, allDay: Boolean) {
this.id = id
this.title = title
this.startDate = startDate
this.endDate = endDate
this.calendarID = calendarID
this.allDay = allDay
}
constructor(eventCursor: Cursor, instanceCursor: Cursor) {
@ -29,6 +31,7 @@ class Event {
endDate = instanceCursor.getLong(2)
title = eventCursor.getString(0)
allDay = !eventCursor.getString(1).equals("0")
calendarID = eventCursor.getInt(2)
}

View File

@ -6,31 +6,42 @@ import android.content.Context
import android.content.Intent
import android.app.AlarmManager
import android.app.PendingIntent
import android.icu.text.LocaleDisplayNames
import android.preference.PreferenceManager
import android.util.Log
import com.tommasoberlose.anotherwidget.`object`.Constants
import com.tommasoberlose.anotherwidget.`object`.Event
import com.tommasoberlose.anotherwidget.util.CalendarUtil
import com.tommasoberlose.anotherwidget.util.Util
import java.util.*
class UpdatesReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action.equals(Intent.ACTION_BOOT_COMPLETED) || intent.action.equals(Intent.ACTION_INSTALL_PACKAGE) || intent.action.equals(Constants.ACTION_TIME_UPDATE)) {
Util.updateWidget(context)
if (intent.action.equals(Intent.ACTION_BOOT_COMPLETED) || intent.action.equals(Intent.ACTION_MY_PACKAGE_REPLACED)) {
setUpdates(context)
} else if (intent.action.equals(Constants.ACTION_TIME_UPDATE)) {
val e: Event = CalendarUtil.getNextEvent(context)
if (e.id == 0 || e.endDate < Calendar.getInstance().timeInMillis) {
CalendarUtil.updateEventList(context)
} else {
Util.updateWidget(context)
}
} else if (intent.action.equals(Constants.ACTION_CALENDAR_UPDATE)) {
CalendarUtil.updateEventList(context)
}
}
fun setUpdates(context: Context) {
removeUpdates(context)
CalendarUtil.updateEventList(context)
if (Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)) {
CalendarUtil.updateEventList(context)
val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val i = Intent(context, UpdatesReceiver::class.java)
i.action = Constants.ACTION_TIME_UPDATE
val pi = PendingIntent.getBroadcast(context, 0, i, 0)
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), (1000 * 60).toLong(), pi)
}
val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val i = Intent(context, UpdatesReceiver::class.java)
i.action = Constants.ACTION_TIME_UPDATE
val pi = PendingIntent.getBroadcast(context, 0, i, 0)
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), (1000 * 60).toLong(), pi)
}
fun removeUpdates(context: Context) {

View File

@ -6,6 +6,9 @@ import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.preference.PreferenceManager
import android.util.Log
import com.tommasoberlose.anotherwidget.`object`.Constants
import com.tommasoberlose.anotherwidget.util.Util
import com.tommasoberlose.anotherwidget.util.WeatherUtil
@ -13,23 +16,32 @@ import com.tommasoberlose.anotherwidget.util.WeatherUtil
class WeatherReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action.equals(Intent.ACTION_BOOT_COMPLETED) || intent.action.equals(Intent.ACTION_INSTALL_PACKAGE) || intent.action.equals(Constants.ACTION_WEATHER_UPDATE)) {
WeatherUtil.getWeather(context)
if (intent.action.equals(Intent.ACTION_BOOT_COMPLETED) || intent.action.equals(Intent.ACTION_MY_PACKAGE_REPLACED)) {
setUpdates(context)
} else if (intent.action.equals(Constants.ACTION_WEATHER_UPDATE)) {
WeatherUtil.updateWeather(context)
}
}
fun setUpdates(context: Context) {
val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
removeUpdates(context)
WeatherUtil.updateWeather(context)
if (Util.checkGrantedPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)) {
WeatherUtil.getWeather(context)
val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val i = Intent(context, WeatherReceiver::class.java)
i.action = Constants.ACTION_WEATHER_UPDATE
val pi = PendingIntent.getBroadcast(context, 1, i, 0)
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), (1000 * 60 * 60 * 2).toLong(), pi) // 2 hour
val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val i = Intent(context, WeatherReceiver::class.java)
i.action = Constants.ACTION_WEATHER_UPDATE
val pi = PendingIntent.getBroadcast(context, 1, i, 0)
val refresh: Long = when (SP.getInt(Constants.PREF_WEATHER_REFRESH_PERIOD, 1)) {
0 -> 30
1 -> 60
2 -> 60 * 3
3 -> 60 * 6
4 -> 60 * 12
5 -> 60 * 24
else -> 60
}
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * refresh, pi)
}
fun removeUpdates(context: Context) {

View File

@ -0,0 +1,80 @@
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.Toast
import com.tommasoberlose.anotherwidget.`object`.Constants
import com.tommasoberlose.anotherwidget.util.WeatherUtil
import kotlinx.android.synthetic.main.activity_custom_location.*
class CustomLocationActivity : AppCompatActivity() {
@SuppressLint("ApplySharedPref")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_custom_location)
val SP = PreferenceManager.getDefaultSharedPreferences(this)
val list = ArrayList<String>()
val addressesList = ArrayList<Address>()
val thread: Thread = Thread()
var adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, list)
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()
}
location.addTextChangedListener(object: TextWatcher {
override fun afterTextChanged(text: Editable?) {
val coder = Geocoder(this@CustomLocationActivity)
try {
val addresses = coder.getFromLocationName(text.toString(), 10) as ArrayList<Address>
list.clear()
addressesList.clear()
addresses.mapTo(list) { it.getAddressLine(0) }
addresses.mapTo(addressesList) { it }
adapter = ArrayAdapter(this@CustomLocationActivity, R.layout.custom_location_item, list)
list_view.adapter = adapter
} catch (ignored: Exception) {
Toast.makeText(this@CustomLocationActivity, "Erroreeeee", Toast.LENGTH_SHORT).show()
}
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
})
}
}

View File

@ -2,6 +2,7 @@ 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
@ -16,8 +17,6 @@ import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.util.Util
import com.tommasoberlose.anotherwidget.receiver.UpdatesReceiver
import com.tommasoberlose.anotherwidget.receiver.WeatherReceiver
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.the_widget.*
import java.util.*
import java.util.concurrent.TimeUnit
import android.content.Intent
@ -25,8 +24,18 @@ import android.content.BroadcastReceiver
import com.tommasoberlose.anotherwidget.util.CalendarUtil
import com.tommasoberlose.anotherwidget.util.WeatherUtil
import android.content.DialogInterface
import android.graphics.drawable.Drawable
import android.support.v4.content.ContextCompat
import android.util.Log
import android.view.MenuItem
import android.widget.Toast
import com.crashlytics.android.Crashlytics
import com.github.rubensousa.bottomsheetbuilder.BottomSheetBuilder
import com.github.rubensousa.bottomsheetbuilder.BottomSheetMenuDialog
import com.tommasoberlose.anotherwidget.`object`.CalendarSelector
import io.fabric.sdk.android.Fabric
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.the_widget.*
class MainActivity : AppCompatActivity() {
@ -41,9 +50,7 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
receiver
// TODO Util.showIntro(this)
Fabric.with(this, Crashlytics())
action_support.setOnClickListener(object: View.OnClickListener {
override fun onClick(p0: View?) {
@ -80,15 +87,11 @@ class MainActivity : AppCompatActivity() {
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) {
UpdatesReceiver().removeUpdates(this)
} else {
UpdatesReceiver().setUpdates(this)
Constants.CALENDAR_REQUEST_CODE -> if (!(permissions.size != 1 || grantResults.size != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED)) {
CalendarUtil.updateEventList(this)
}
Constants.LOCATION_REQUEST_CODE -> if (permissions.size != 1 || grantResults.size != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
WeatherReceiver().removeUpdates(this)
} else {
WeatherReceiver().setUpdates(this)
Constants.LOCATION_REQUEST_CODE -> if (!(permissions.size != 1 || grantResults.size != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED)) {
WeatherUtil.updateWeather(this)
}
}
}
@ -107,11 +110,11 @@ class MainActivity : AppCompatActivity() {
}
})
} else {
if (!Util.checkGrantedPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
if (!Util.checkGrantedPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
no_location_permission_container.visibility = View.VISIBLE
request_location.setOnClickListener(object: View.OnClickListener {
override fun onClick(view: View?) {
ActivityCompat.requestPermissions(this@MainActivity, arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), Constants.LOCATION_REQUEST_CODE)
ActivityCompat.requestPermissions(this@MainActivity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), Constants.LOCATION_REQUEST_CODE)
}
})
} else {
@ -123,18 +126,36 @@ class MainActivity : AppCompatActivity() {
internal fun updateAppWidget() {
widget_bg.setImageDrawable(Util.getCurrentWallpaper(this))
updateCalendarView()
updateLocationView()
val wallpaper: Drawable? = Util.getCurrentWallpaper(this)
if (wallpaper != null) {
widget_bg.setImageDrawable(wallpaper)
updateCalendarView()
updateLocationView()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == Constants.RESULT_CODE_CUSTOM_LOCATION) {
if (resultCode == Activity.RESULT_OK) {
updateSettings()
WeatherUtil.updateWeather(this)
}
}
}
fun updateCalendarView() {
val SP = PreferenceManager.getDefaultSharedPreferences(this)
val now = Calendar.getInstance()
val calendarLayout = Util.checkGrantedPermission(this, Manifest.permission.READ_CALENDAR)
empty_layout.visibility = View.VISIBLE
calendar_layout.visibility = View.GONE
empty_date.text = String.format("%s%s", Constants.dateFormat.format(now.time)[0].toUpperCase(), Constants.dateFormat.format(now.time).substring(1))
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))
}
empty_date.text = dateStringValue
//empty_date.setImageBitmap(Util.buildUpdate(this, String.format("%s%s", Constants.dateFormat.format(now.time)[0].toUpperCase(), Constants.dateFormat.format(now.time).substring(1)), "fonts/product_sans_regular.ttf"))
if (calendarLayout) {
val e = CalendarUtil.getNextEvent(this)
@ -148,18 +169,25 @@ class MainActivity : AppCompatActivity() {
var time = ""
val hour = TimeUnit.MILLISECONDS.toHours(difference)
if (hour > 0) {
time = hour.toString() + getString(R.string.h_code)
time = hour.toString() + getString(R.string.h_code) + " "
}
val minutes = TimeUnit.MILLISECONDS.toMinutes(difference - hour * 3600 * 1000)
if (minutes > 0) {
time += " " + minutes + getString(R.string.min_code)
time += "" + minutes + getString(R.string.min_code)
}
next_event.text = String.format("%s %s %s", e.title, getString(R.string.in_code), time)
} else {
next_event.text = String.format("%s", e.title)
}
next_event_date.text = String.format("%s - %s", Constants.hourFormat.format(e.startDate), Constants.hourFormat.format(e.endDate))
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)
next_event_date.text = String.format("%s - %s", startHour, endHour)
} else {
next_event_date.text = dateStringValue
}
empty_layout.visibility = View.GONE
calendar_layout.visibility = View.VISIBLE
@ -168,7 +196,7 @@ class MainActivity : AppCompatActivity() {
}
fun updateLocationView() {
val locationLayout = Util.checkGrantedPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
val locationLayout = Util.checkGrantedPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
val SP = PreferenceManager.getDefaultSharedPreferences(this)
if (locationLayout && SP.contains(Constants.PREF_WEATHER_TEMP) && SP.contains(Constants.PREF_WEATHER_ICON)) {
@ -202,40 +230,92 @@ class MainActivity : AppCompatActivity() {
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()
WeatherUtil.getWeather(this)
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()
updateUI()
CalendarUtil.updateEventList(this)
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()
sendBroadcast(Intent(Constants.ACTION_CALENDAR_UPDATE))
updateSettings()
}
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()
updateSettings()
Util.updateWidget(this)
}
label_weather_refresh_period.text = getString(Util.getRefreshPeriodString(SP.getInt(Constants.PREF_WEATHER_REFRESH_PERIOD, 1)))
action_weather_refresh_period.setOnClickListener {
val dialog: BottomSheetMenuDialog = BottomSheetBuilder(this, R.style.Theme_Design_Light_BottomSheetDialog)
.setMode(BottomSheetBuilder.MODE_LIST)
.setMenu(R.menu.weather_refresh_period_menu)
.setIconTintColor(ContextCompat.getColor(this, R.color.black_50))
.delayDismissOnItemClick(false)
.setItemClickListener({ item: MenuItem ->
SP.edit().putInt(Constants.PREF_WEATHER_REFRESH_PERIOD, when (item.itemId) {
R.id.refresh_1 -> 1
R.id.refresh_2 -> 2
R.id.refresh_3 -> 3
R.id.refresh_4 -> 4
R.id.refresh_5 -> 5
else -> 1
}).commit()
updateSettings()
WeatherReceiver().setUpdates(this@MainActivity)
})
.createDialog()
dialog.show()
}
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_filter_calendar.setOnClickListener {
val calendarSelectorList: List<CalendarSelector> = CalendarUtil.getCalendarList(this)
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()
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()
CalendarUtil.updateEventList(this)
})
.setNegativeButton(android.R.string.cancel, null)
.show()
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()
}
}
}

View File

@ -1,41 +0,0 @@
package com.tommasoberlose.anotherwidget.ui.activity
import android.Manifest
import android.os.Bundle
import com.tommasoberlose.anotherwidget.R
import com.heinrichreimersoftware.materialintro.app.IntroActivity
import com.heinrichreimersoftware.materialintro.slide.SimpleSlide
class SplashActivity : IntroActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
isButtonNextVisible = true
isButtonBackVisible = false
isButtonCtaVisible = false
buttonCtaTintMode = BUTTON_CTA_TINT_MODE_TEXT
addSlide(SimpleSlide.Builder()
.title(R.string.app_name)
.background(R.color.colorPrimary)
.backgroundDark(R.color.colorPrimaryDark)
.build())
addSlide(SimpleSlide.Builder()
.title(R.string.title_permission_calendar)
.description(R.string.description_permission_calendar)
.background(R.color.colorPrimary)
.backgroundDark(R.color.colorPrimaryDark)
.permission(Manifest.permission.READ_CALENDAR)
.build())
addSlide(SimpleSlide.Builder()
.title(R.string.title_permission_location)
.description(R.string.description_permission_location)
.background(R.color.colorPrimary)
.backgroundDark(R.color.colorPrimaryDark)
.permission(Manifest.permission.ACCESS_COARSE_LOCATION)
.build())
}
}

View File

@ -0,0 +1,49 @@
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")
}
}
}

View File

@ -24,6 +24,13 @@ 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
/**
@ -63,95 +70,109 @@ class TheWidget : AppWidgetProvider() {
}
fun updateCalendarView(context: Context, views: RemoteViews, widgetID: Int): RemoteViews {
val now = Calendar.getInstance()
val calendarLayout = Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)
val SP = PreferenceManager.getDefaultSharedPreferences(context)
val now = Calendar.getInstance()
val calendarLayout = Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)
views.setViewVisibility(R.id.empty_layout, View.VISIBLE)
views.setViewVisibility(R.id.calendar_layout, View.GONE)
views.setTextViewText(R.id.empty_date, Constants.dateFormat.format(now.time)[0].toUpperCase() + Constants.dateFormat.format(now.time).substring(1))
views.setViewVisibility(R.id.empty_layout, View.VISIBLE)
views.setViewVisibility(R.id.calendar_layout, View.GONE)
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))
}
views.setTextViewText(R.id.empty_date, dateStringValue)
//views.setImageViewBitmap(R.id.empty_date, Util.buildUpdate(context, Constants.dateFormat.format(now.time)[0].toUpperCase() + Constants.dateFormat.format(now.time).substring(1), "fonts/product_sans_regular.ttf"))
val calIntent = Intent(Intent.ACTION_MAIN)
calIntent.addCategory(Intent.CATEGORY_APP_CALENDAR)
val calPIntent = PendingIntent.getActivity(context, widgetID, calIntent, 0)
views.setOnClickPendingIntent(R.id.main_layout, calPIntent)
val calIntent = Intent(Intent.ACTION_MAIN)
calIntent.addCategory(Intent.CATEGORY_APP_CALENDAR)
val calPIntent = PendingIntent.getActivity(context, widgetID, calIntent, 0)
views.setOnClickPendingIntent(R.id.main_layout, calPIntent)
if (calendarLayout) {
val e = CalendarUtil.getNextEvent(context)
if (calendarLayout) {
val e = CalendarUtil.getNextEvent(context)
if (e.id != 0) {
val difference = e.startDate - now.timeInMillis
if (e.id != 0) {
val difference = e.startDate - now.timeInMillis
if (difference > 1000 * 60) {
var time = ""
val hour = TimeUnit.MILLISECONDS.toHours(difference)
if (hour > 0) {
time = hour.toString() + context.getString(R.string.h_code)
}
val minutes = TimeUnit.MILLISECONDS.toMinutes(difference - hour * 3600 * 1000)
if (minutes > 0) {
time += " " + minutes + context.getString(R.string.min_code)
}
views.setTextViewText(R.id.next_event, String.format("%s %s %s", e.title, context.getString(R.string.in_code), time))
} else {
views.setTextViewText(R.id.next_event, String.format("%s", e.title))
if (difference > 1000 * 60) {
var time = ""
val hour = TimeUnit.MILLISECONDS.toHours(difference)
if (hour > 0) {
time = hour.toString() + context.getString(R.string.h_code) + " "
}
val minutes = TimeUnit.MILLISECONDS.toMinutes(difference - hour * 3600 * 1000)
if (minutes > 0) {
time += "" + minutes + context.getString(R.string.min_code)
}
views.setTextViewText(R.id.next_event_date, String.format("%s - %s", Constants.hourFormat.format(e.startDate), Constants.hourFormat.format(e.endDate)))
views.setViewVisibility(R.id.empty_layout, View.GONE)
views.setViewVisibility(R.id.calendar_layout, View.VISIBLE)
val builder = CalendarContract.CONTENT_URI.buildUpon()
builder.appendPath("time")
ContentUris.appendId(builder, e.startDate)
val intent = Intent(Intent.ACTION_VIEW)
.setData(builder.build())
val pIntent = PendingIntent.getActivity(context, widgetID, intent, 0)
views.setOnClickPendingIntent(R.id.main_layout, pIntent)
views.setTextViewText(R.id.next_event, String.format("%s %s %s", e.title, context.getString(R.string.in_code), time))
} else {
views.setTextViewText(R.id.next_event, String.format("%s", e.title))
}
}
return views
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)
views.setTextViewText(R.id.next_event_date, String.format("%s - %s", startHour, endHour))
} else {
views.setTextViewText(R.id.next_event_date, dateStringValue)
}
views.setViewVisibility(R.id.empty_layout, View.GONE)
views.setViewVisibility(R.id.calendar_layout, View.VISIBLE)
val builder = CalendarContract.CONTENT_URI.buildUpon()
builder.appendPath("time")
ContentUris.appendId(builder, e.startDate)
val intent = Intent(Intent.ACTION_VIEW)
.setData(builder.build())
val pIntent = PendingIntent.getActivity(context, widgetID, intent, 0)
views.setOnClickPendingIntent(R.id.main_layout, pIntent)
}
}
fun updateLocationView(context: Context, views: RemoteViews, widgetID: Int): RemoteViews {
val locationLayout = Util.checkGrantedPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
return views
}
val SP = PreferenceManager.getDefaultSharedPreferences(context)
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_TEMP_UNIT, "F"))
fun updateLocationView(context: Context, views: RemoteViews, widgetID: Int): RemoteViews {
val locationLayout = Util.checkGrantedPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
val SP = PreferenceManager.getDefaultSharedPreferences(context)
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_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 weatherIntent = Intent("com.google.android.googlequicksearchbox.GOOGLE_SEARCH")
weatherIntent.addCategory(Intent.CATEGORY_DEFAULT)
weatherIntent.putExtra("type", "string")
weatherIntent.putExtra("query", "weather")
val weatherPIntent = PendingIntent.getActivity(context, widgetID, weatherIntent, 0)
views.setOnClickPendingIntent(R.id.weather, weatherPIntent)
views.setOnClickPendingIntent(R.id.calendar_weather, weatherPIntent)
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.setViewVisibility(R.id.weather, View.GONE)
views.setViewVisibility(R.id.calendar_weather, View.GONE)
views.setImageViewResource(R.id.weather_icon, WeatherUtil.getWeatherIconResource(icon))
views.setImageViewResource(R.id.empty_weather_icon, WeatherUtil.getWeatherIconResource(icon))
}
return views
views.setTextViewText(R.id.temp, temp)
views.setTextViewText(R.id.calendar_temp, temp)
val weatherIntent: Intent = Intent(Intent.ACTION_VIEW)
weatherIntent.addCategory(Intent.CATEGORY_DEFAULT)
weatherIntent.data = Uri.parse("dynact://velour/weather/ProxyActivity")
weatherIntent.component = ComponentName("com.google.android.googlequicksearchbox", "com.google.android.apps.gsa.velour.DynamicActivityTrampoline")
val weatherPIntent = PendingIntent.getActivity(context, widgetID, weatherIntent, 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
}
}
}

View File

@ -5,6 +5,7 @@ import android.annotation.SuppressLint
import android.content.ContentUris
import android.content.Context
import android.content.SharedPreferences
import android.net.Uri
import android.preference.PreferenceManager
import android.provider.CalendarContract
import android.util.Log
@ -25,7 +26,7 @@ object CalendarUtil {
val now = Calendar.getInstance()
val hourLimit = Calendar.getInstance()
hourLimit.add(Calendar.HOUR, 6)
hourLimit.add(Calendar.HOUR, 8)
val builder = CalendarContract.Instances.CONTENT_URI.buildUpon()
ContentUris.appendId(builder, now.timeInMillis)
@ -33,41 +34,53 @@ object CalendarUtil {
if (!Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)) {
resetNextEventData(context)
}
} else {
val instanceCursor = context.contentResolver.query(builder.build(), arrayOf(CalendarContract.Instances.EVENT_ID, CalendarContract.Instances.BEGIN, CalendarContract.Instances.END), null, null, null)
instanceCursor.moveToFirst()
val instanceCursor = context.contentResolver.query(builder.build(), arrayOf(CalendarContract.Instances.EVENT_ID, CalendarContract.Instances.BEGIN, CalendarContract.Instances.END), null, null, null)
if (instanceCursor != null && instanceCursor.count > 0) {
instanceCursor.moveToFirst()
for (i in 0 until instanceCursor.count) {
val ID = instanceCursor.getInt(0)
val eventCursor = context.contentResolver.query(CalendarContract.Events.CONTENT_URI, arrayOf(CalendarContract.Events.TITLE, CalendarContract.Events.ALL_DAY, CalendarContract.Events.CALENDAR_ID),
CalendarContract.Events._ID + " is ?",
arrayOf(Integer.toString(ID)), null)
for (i in 0 until instanceCursor.count) {
val ID = instanceCursor.getInt(0)
if (eventCursor != null && eventCursor.count > 0) {
eventCursor.moveToFirst()
val eventCursor = context.contentResolver.query(CalendarContract.Events.CONTENT_URI, arrayOf(CalendarContract.Events.TITLE, CalendarContract.Events.ALL_DAY, CalendarContract.Events.CALENDAR_ID),
CalendarContract.Events._ID + " is ?",
arrayOf(Integer.toString(ID)), null)
eventCursor.moveToFirst()
for (j in 0 until eventCursor.count) {
val e = Event(eventCursor, instanceCursor)
val allDay: Boolean = !eventCursor.getString(1).equals("0")
if ((SP.getBoolean(Constants.PREF_CALENDAR_ALL_DAY, false) || !allDay) && !(SP.getString(Constants.PREF_CALENDAR_FILTER, "").contains(" " + e.calendarID + ","))) {
eventList.add(e)
}
eventCursor.moveToNext()
}
}
for (j in 0 until eventCursor.count) {
val e = Event(eventCursor, instanceCursor)
val allDay: Boolean = !eventCursor.getString(1).equals("0")
if (e.endDate - now.timeInMillis > 1000 * 60 * 30 && (SP.getBoolean(Constants.PREF_CALENDAR_ALL_DAY, false) || !allDay) && !(SP.getString(Constants.PREF_CALENDAR_FILTER, "").contains(" " + e.calendarID + ","))) {
eventList.add(e)
eventCursor.close()
instanceCursor.moveToNext()
}
eventCursor.moveToNext()
}
eventCursor.close()
instanceCursor.close()
instanceCursor.moveToNext()
}
instanceCursor.close()
if (eventList.isEmpty()) {
resetNextEventData(context)
} else {
saveNextEventData(context, eventList.get(0))
if (eventList.isEmpty()) {
resetNextEventData(context)
} else {
Collections.sort(eventList, { event: Event, event1: Event ->
if (event.startDate > event1.startDate) {
return@sort 1
} else if (event.startDate < event1.startDate) {
return@sort -1
}
return@sort 0
})
saveNextEventData(context, eventList.get(0))
}
}
}
@ -79,24 +92,54 @@ object CalendarUtil {
return calendarList
}
val calendarCursor = context.contentResolver.query(CalendarContract.Calendars.CONTENT_URI,
arrayOf(CalendarContract.Calendars._ID, CalendarContract.Calendars.NAME, CalendarContract.Calendars.ACCOUNT_NAME),
null,
null,
null) ?: return calendarList
try {
val calendarCursor = context.contentResolver.query(Uri.parse("content://com.android.calendar/calendars"),
arrayOf(CalendarContract.Calendars._ID, CalendarContract.Calendars.NAME, CalendarContract.Calendars.ACCOUNT_NAME),
null,
null,
null)
calendarCursor.moveToFirst()
if (calendarCursor != null && calendarCursor.count > 0) {
for (j in 0 until calendarCursor.count) {
calendarList.add(CalendarSelector(calendarCursor.getInt(0), calendarCursor.getString(1), calendarCursor.getString(2)))
calendarCursor.moveToNext()
calendarCursor.moveToFirst()
for (j in 0 until calendarCursor.count) {
calendarList.add(CalendarSelector(calendarCursor.getInt(0), calendarCursor.getString(1), calendarCursor.getString(2)))
calendarCursor.moveToNext()
}
}
calendarCursor.close()
} catch (ignored: Exception) {
try {
val calendarCursor = context.contentResolver.query(CalendarContract.Calendars.CONTENT_URI,
arrayOf(CalendarContract.Calendars._ID, CalendarContract.Calendars.NAME, CalendarContract.Calendars.ACCOUNT_NAME),
null,
null,
null)
if (calendarCursor != null && calendarCursor.count > 0) {
calendarCursor.moveToFirst()
for (j in 0 until calendarCursor.count) {
calendarList.add(CalendarSelector(calendarCursor.getInt(0), calendarCursor.getString(1), calendarCursor.getString(2)))
calendarCursor.moveToNext()
}
}
calendarCursor.close()
} catch (ignore: Exception) {
} finally {
return calendarList
}
} finally {
return calendarList
}
calendarCursor.close()
return calendarList
}
@SuppressLint("ApplySharedPref")
fun resetNextEventData(context: Context) {
val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
SP.edit()
@ -104,8 +147,10 @@ object CalendarUtil {
.remove(Constants.PREF_NEXT_EVENT_NAME)
.remove(Constants.PREF_NEXT_EVENT_START_DATE)
.remove(Constants.PREF_NEXT_EVENT_END_DATE)
.remove(Constants.PREF_NEXT_EVENT_ALL_DAY)
.remove(Constants.PREF_NEXT_EVENT_CALENDAR_ID)
.apply()
.commit()
Util.updateWidget(context)
}
@SuppressLint("ApplySharedPref")
@ -116,6 +161,7 @@ object CalendarUtil {
.putString(Constants.PREF_NEXT_EVENT_NAME, event.title)
.putLong(Constants.PREF_NEXT_EVENT_START_DATE, event.startDate)
.putLong(Constants.PREF_NEXT_EVENT_END_DATE, event.endDate)
.putBoolean(Constants.PREF_NEXT_EVENT_ALL_DAY, event.allDay)
.putInt(Constants.PREF_NEXT_EVENT_CALENDAR_ID, event.calendarID)
.commit()
Util.updateWidget(context)
@ -123,6 +169,6 @@ object CalendarUtil {
fun getNextEvent(context: Context): Event {
val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
return Event(SP.getInt(Constants.PREF_NEXT_EVENT_ID, 0), SP.getString(Constants.PREF_NEXT_EVENT_NAME, ""), SP.getLong(Constants.PREF_NEXT_EVENT_START_DATE, 0), SP.getLong(Constants.PREF_NEXT_EVENT_END_DATE, 0), SP.getInt(Constants.PREF_NEXT_EVENT_CALENDAR_ID, 0))
return Event(SP.getInt(Constants.PREF_NEXT_EVENT_ID, 0), SP.getString(Constants.PREF_NEXT_EVENT_NAME, ""), SP.getLong(Constants.PREF_NEXT_EVENT_START_DATE, 0), SP.getLong(Constants.PREF_NEXT_EVENT_END_DATE, 0), SP.getInt(Constants.PREF_NEXT_EVENT_CALENDAR_ID, 0), SP.getBoolean(Constants.PREF_NEXT_EVENT_ALL_DAY, false))
}
}

View File

@ -1,7 +1,6 @@
package com.tommasoberlose.anotherwidget.util
import android.Manifest
import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationManager
import android.app.PendingIntent
@ -9,35 +8,25 @@ import android.app.WallpaperManager
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.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.net.Uri
import android.os.Bundle
import android.preference.PreferenceManager
import android.provider.CalendarContract
import android.support.annotation.DrawableRes
import android.support.customtabs.CustomTabsIntent
import android.support.v4.app.NotificationCompat
import android.support.v4.content.ContextCompat
import android.util.Log
import com.survivingwithandroid.weather.lib.WeatherClient
import com.survivingwithandroid.weather.lib.WeatherConfig
import com.survivingwithandroid.weather.lib.exception.WeatherLibException
import com.survivingwithandroid.weather.lib.model.CurrentWeather
import com.survivingwithandroid.weather.lib.provider.openweathermap.OpenweathermapProviderType
import com.survivingwithandroid.weather.lib.request.WeatherRequest
import android.util.DisplayMetrics
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.`object`.Constants
import com.tommasoberlose.anotherwidget.`object`.Event
import com.tommasoberlose.anotherwidget.ui.activity.MainActivity
import com.tommasoberlose.anotherwidget.ui.activity.SplashActivity
import com.tommasoberlose.anotherwidget.ui.widget.TheWidget
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.support.annotation.StringRes
import android.util.TypedValue
import java.util.ArrayList
import java.util.Calendar
/**
* Created by tommaso on 05/10/17.
@ -102,16 +91,70 @@ object Util {
context.startActivity(Intent.createChooser(sendIntent, context.getString(R.string.action_share)));
}
fun showIntro(context: Context) {
val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
val firstTime: Boolean = SP.getBoolean(Constants.PREF_FIRST_STEP, true)
// TODO SP.edit().putBoolean(Constants.PREF_FIRST_STEP, false).apply()
if (firstTime) {
context.startActivity(Intent(context, SplashActivity::class.java))
fun getCurrentWallpaper(context: Context): Drawable? {
var wallpaper: Drawable? = null
try {
wallpaper = WallpaperManager.getInstance(context).drawable
} catch (e: Exception) {
wallpaper = BitmapDrawable(context.resources, getResizedBitmap(BitmapFactory.decodeResource(context.resources, R.drawable.pixel_2_wallpaper), 800))
} finally {
return wallpaper
}
}
fun getCurrentWallpaper(context: Context): Drawable {
return WallpaperManager.getInstance(context).getDrawable();
fun buildUpdate(context: Context, time: String, fontPath: String): Bitmap {
val myBitmap:Bitmap = Bitmap.createBitmap(convertDpToPixel(300f, context).toInt(), convertDpToPixel(40f, context).toInt(), Bitmap.Config.ARGB_8888)
val myCanvas: Canvas = Canvas(myBitmap)
val paint: Paint = Paint()
val clock: Typeface = Typeface.createFromAsset(context.assets, fontPath)
paint.isAntiAlias = true
paint.isSubpixelText = true
paint.typeface = clock
paint.style = Paint.Style.FILL
paint.color = Color.WHITE
paint.textSize = convertSpToPixels(14f, context)
paint.textAlign = Paint.Align.CENTER
paint.setShadowLayer(5f,0f, 0f, R.color.black_50)
myCanvas.drawText("Ultra Pixel Meeting Ciao Ciao", convertDpToPixel(150f, context), convertDpToPixel(20f, context), paint)
return myBitmap;
}
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
}
}
}

View File

@ -4,9 +4,7 @@ import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.location.*
import android.os.Bundle
import android.preference.PreferenceManager
import com.survivingwithandroid.weather.lib.WeatherClient
@ -18,83 +16,108 @@ import com.survivingwithandroid.weather.lib.request.WeatherRequest
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.`object`.Constants
/**
* Created by tommaso on 08/10/17.
*/
object WeatherUtil {
val API_KEY_1 = "43e744ad8ff91b09ea62dbc7d0e7c1dd"
val API_KEY_2 = "61cde158f4bcc2e5cd18de7b9d000702"
fun getWeather(context: Context) {
if (!Util.checkGrantedPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)) {
return
}
fun updateWeather(context: Context) {
val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
if (SP.getString(Constants.PREF_CUSTOM_LOCATION_ADD, "").equals("") || SP.getString(Constants.PREF_CUSTOM_LOCATION_LAT, "").equals("") || SP.getString(Constants.PREF_CUSTOM_LOCATION_LON, "").equals("")) {
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
getCurrentWeather(context, locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER))
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0f, object: LocationListener {
override fun onLocationChanged(location: Location) {
locationManager.removeUpdates(this)
getCurrentWeather(context, location)
if (!Util.checkGrantedPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)) {
return
}
@SuppressLint("ApplySharedPref")
override fun onProviderDisabled(p0: String?) {
}
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
getCurrentWeather(context, locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER))
getCurrentWeather(context, locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER))
@SuppressLint("ApplySharedPref")
override fun onProviderEnabled(p0: String?) {
}
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0f, object : LocationListener {
override fun onLocationChanged(location: Location) {
locationManager.removeUpdates(this)
getCurrentWeather(context, location)
}
override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) {
}
})
@SuppressLint("ApplySharedPref")
override fun onProviderDisabled(p0: String?) {
}
@SuppressLint("ApplySharedPref")
override fun onProviderEnabled(p0: String?) {
}
override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) {
}
})
} else {
weatherNetworkRequest(context, SP.getString(Constants.PREF_CUSTOM_LOCATION_LAT, "").toDouble(), SP.getString(Constants.PREF_CUSTOM_LOCATION_LON, "").toDouble())
}
}
@SuppressLint("ApplySharedPref")
fun getCurrentWeather(context: Context, location: Location?) {
if (location != null) {
val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
try {
val config = WeatherConfig()
config.unitSystem = if (SP.getString(Constants.PREF_WEATHER_TEMP_UNIT, "F").equals("C")) WeatherConfig.UNIT_SYSTEM.M else WeatherConfig.UNIT_SYSTEM.I
config.lang = "en" // If you want to use english
config.maxResult = 1 // Max number of cities retrieved
config.numDays = 1 // Max num of days in the forecast
config.ApiKey = "43e744ad8ff91b09ea62dbc7d0e7c1dd";
val client = WeatherClient.ClientBuilder().attach(context)
.httpClient(com.survivingwithandroid.weather.lib.client.volley.WeatherClientDefault::class.java)
.provider(OpenweathermapProviderType())
.config(config)
.build()
client.getCurrentCondition(WeatherRequest(location.longitude, location.latitude), object : WeatherClient.WeatherEventListener {
@SuppressLint("ApplySharedPref")
override fun onWeatherRetrieved(currentWeather: CurrentWeather) {
SP.edit()
.putFloat(Constants.PREF_WEATHER_TEMP, currentWeather.weather.temperature.temp)
.putString(Constants.PREF_WEATHER_ICON, currentWeather.weather.currentCondition.icon)
.commit()
Util.updateWidget(context)
}
@SuppressLint("ApplySharedPref")
override fun onWeatherError(e: WeatherLibException?) {
}
@SuppressLint("ApplySharedPref")
override fun onConnectionError(throwable: Throwable?) {
}
})
} catch (t: Exception) {
}
weatherNetworkRequest(context, location.latitude, location.longitude)
}
}
fun weatherNetworkRequest(context: Context, latitude: Double, longitude: Double) {
val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
try {
val config = WeatherConfig()
config.unitSystem = if (SP.getString(Constants.PREF_WEATHER_TEMP_UNIT, "F").equals("C")) WeatherConfig.UNIT_SYSTEM.M else WeatherConfig.UNIT_SYSTEM.I
config.lang = "en" // If you want to use english
config.maxResult = 1 // Max number of cities retrieved
config.numDays = 1 // Max num of days in the forecast
config.ApiKey = API_KEY_2
val client = WeatherClient.ClientBuilder().attach(context)
.httpClient(com.survivingwithandroid.weather.lib.client.volley.WeatherClientDefault::class.java)
.provider(OpenweathermapProviderType())
.config(config)
.build()
client.getCurrentCondition(WeatherRequest(longitude, latitude), object : WeatherClient.WeatherEventListener {
@SuppressLint("ApplySharedPref")
override fun onWeatherRetrieved(currentWeather: CurrentWeather) {
SP.edit()
.putFloat(Constants.PREF_WEATHER_TEMP, currentWeather.weather.temperature.temp)
.putString(Constants.PREF_WEATHER_ICON, currentWeather.weather.currentCondition.icon)
.commit()
Util.updateWidget(context)
}
@SuppressLint("ApplySharedPref")
override fun onWeatherError(e: WeatherLibException?) {
removeWeather(context, SP)
}
@SuppressLint("ApplySharedPref")
override fun onConnectionError(throwable: Throwable?) {
removeWeather(context, SP)
}
})
} catch (t: Exception) {
removeWeather(context, SP)
}
}
@SuppressLint("ApplySharedPref")
fun removeWeather(context: Context, SP: SharedPreferences) {
SP.edit().
remove(Constants.PREF_WEATHER_TEMP)
.remove(Constants.PREF_WEATHER_ICON)
.commit()
Util.updateWidget(context)
}
fun getWeatherIconResource(icon: String): Int {
when (icon) {
"01d" -> {

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1019 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1011 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 863 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_background"
tools:context="com.tommasoberlose.anotherwidget.ui.activity.CustomLocationActivity">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:padding="8dp"
app:cardCornerRadius="0dp"
android:id="@+id/toolbar"
android:background="@android:color/white">
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:padding="16dp"
android:inputType="textCapWords"
android:id="@+id/location"
android:gravity="center_vertical"
android:hint="@string/settings_custom_location_title"/>
</android.support.v7.widget.CardView>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/list_view"
android:layout_below="@+id/toolbar" />
</RelativeLayout>

View File

@ -59,14 +59,63 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="20dp"
android:paddingBottom="20dp">
android:paddingTop="8dp"
android:paddingBottom="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="@string/settings_calendar_title"
android:visibility="gone"
style="@style/AnotherWidget.Settings.Header"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:paddingLeft="32dp"
android:paddingRight="32dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_date_format"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_date_format_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/date_format_label"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:paddingLeft="32dp"
android:paddingRight="32dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_hour_format"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_hour_format_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/hour_format_label"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -115,13 +164,46 @@
android:id="@+id/all_day_label"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="@color/black_10"
android:alpha="0.5"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_weather_title"
android:visibility="gone"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
style="@style/AnotherWidget.Settings.Header"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:paddingLeft="32dp"
android:paddingRight="32dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_custom_location"
android:visibility="gone"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_custom_location_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/label_custom_location"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -146,6 +228,30 @@
android:id="@+id/temp_unit"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:paddingLeft="32dp"
android:paddingRight="32dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_weather_refresh_period"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_weather_refresh_period_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/label_weather_refresh_period"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:gravity="center_vertical"
android:padding="16dp"
style="@style/AnotherWidget.Settings.Title"/>

View File

@ -1,6 +1,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_layout">
<LinearLayout
android:layout_width="match_parent"
@ -13,6 +14,8 @@
android:id="@+id/empty_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lines="1"
android:maxLines="1"
style="@style/AnotherWidget.Title" />
<LinearLayout
android:orientation="horizontal"
@ -20,6 +23,7 @@
android:layout_height="match_parent"
android:gravity="center"
android:id="@+id/weather"
android:minWidth="110dp"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
@ -29,8 +33,8 @@
android:text="@string/divider"
style="@style/AnotherWidget.Subtitle"/>
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_width="20dp"
android:layout_height="20dp"
android:id="@+id/empty_weather_icon"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"/>
@ -83,6 +87,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="2dp"
android:text="@string/divider"
style="@style/AnotherWidget.Subtitle"/>
<ImageView

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:title="@string/settings_weather_refresh_period_subtitle_1"
android:icon="@drawable/ic_action_refresh_0"
android:id="@+id/refresh_1" />
<item
android:title="@string/settings_weather_refresh_period_subtitle_2"
android:icon="@drawable/ic_action_refresh_1"
android:id="@+id/refresh_2" />
<item
android:title="@string/settings_weather_refresh_period_subtitle_3"
android:icon="@drawable/ic_action_refresh_2"
android:id="@+id/refresh_3" />
<item
android:title="@string/settings_weather_refresh_period_subtitle_4"
android:icon="@drawable/ic_action_refresh_3"
android:id="@+id/refresh_4" />
<item
android:title="@string/settings_weather_refresh_period_subtitle_5"
android:icon="@drawable/ic_action_refresh_5"
android:id="@+id/refresh_5" />
</menu>

View File

@ -6,8 +6,8 @@
<string name="button_request_permission">Concedi Accesso</string>
<string name="all_set_btn">Rimani Aggiornato</string>
<string name="all_set_title">Molto bene!</string>
<string name="action_support">Supporta</string>
<string name="action_rate">Valuta</string>
<string name="action_support">Supportami</string>
<string name="action_rate">Valuta App</string>
<string name="action_share">Condividi</string>
<string name="divider">|</string>
<string name="notification_title">Ottieni di più dal tuo widget</string>
@ -18,8 +18,8 @@
<string name="description_permission_location">Concedi l\'accesso alla tua posizione per vedere il meteo.</string>
<string name="all_set_subtitle">Hai completato la configurazione! Rimani aggiornato.</string>
<string name="action_about">Info</string>
<string name="h_code">ore</string>
<string name="min_code">min</string>
<string name="h_code">" ore"</string>
<string name="min_code">" min"</string>
<string name="in_code">tra</string>
<string name="action_project">Progetto</string>
<string name="settings_unit_title">Unità di Misura</string>
@ -33,4 +33,19 @@
<string name="settings_calendar_title">Impostazioni Calendario</string>
<string name="settings_weather_title">Impostazioni Meteo</string>
<string name="settings_general_title">Impostazioni Generali</string>
<string name="calendar_settings_list_error">Errore nel caricamento della lista dei calendari</string>
<string name="settings_hour_format_title">Formato Ora</string>
<string name="settings_hour_format_subtitle_12">12 ore AM/PM</string>
<string name="settings_hour_format_subtitle_24">24 ore</string>
<string name="all_day">Tutto il giorno</string>
<string name="settings_date_format_title">Formato Data</string>
<string name="settings_weather_refresh_period_title">Intervallo Aggiornamento</string>
<string name="settings_weather_refresh_period_subtitle_0">30 Minuti</string>
<string name="settings_weather_refresh_period_subtitle_1">1 Ora</string>
<string name="settings_weather_refresh_period_subtitle_2">3 Ore</string>
<string name="settings_weather_refresh_period_subtitle_3">6 Ore</string>
<string name="settings_weather_refresh_period_subtitle_4">12 Ore</string>
<string name="settings_weather_refresh_period_subtitle_5">24 Ore</string>
<string name="settings_custom_location_title">Località Meteo</string>
<string name="custom_location_gps">Geolocalizzazione</string>
</resources>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="FontText">
<attr name="typefaceAsset" format="string"/>
</declare-styleable>
</resources>

View File

@ -11,14 +11,14 @@
<string name="notification_subtitle">View your events and the weather in another widget.</string>
<string name="divider">|</string>
<string name="action_share">Share</string>
<string name="action_rate">Rate</string>
<string name="action_support">Support</string>
<string name="action_rate">Rate App</string>
<string name="action_support">Support Me</string>
<string name="all_set_title">Good Job!</string>
<string name="all_set_subtitle">You have completed the configuration.\nWatch out for updates.</string>
<string name="all_set_btn">Stay up to date</string>
<string name="action_about">About</string>
<string name="h_code">h</string>
<string name="min_code">min</string>
<string name="min_code">" min"</string>
<string name="in_code">in</string>
<string name="action_project">Project</string>
<string name="settings_unit_title">Unit of Measure</string>
@ -34,4 +34,19 @@
<string name="settings_calendar_title">Calendar Settings</string>
<string name="settings_weather_title">Weather Settings</string>
<string name="settings_general_title">General Settings</string>
<string name="calendar_settings_list_error">Error loading the calendar list</string>
<string name="settings_hour_format_title">Hour Format</string>
<string name="settings_hour_format_subtitle_12">12 Hour AM/PM</string>
<string name="settings_hour_format_subtitle_24">24 Hour</string>
<string name="all_day">All Day Event</string>
<string name="settings_date_format_title">Date Format</string>
<string name="settings_weather_refresh_period_title">Refresh Period</string>
<string name="settings_weather_refresh_period_subtitle_0">30 Minutes</string>
<string name="settings_weather_refresh_period_subtitle_1">1 Hour</string>
<string name="settings_weather_refresh_period_subtitle_2">3 Hours</string>
<string name="settings_weather_refresh_period_subtitle_3">6 Hours</string>
<string name="settings_weather_refresh_period_subtitle_4">12 Hours</string>
<string name="settings_weather_refresh_period_subtitle_5">24 Hours</string>
<string name="settings_custom_location_title">Custom Location</string>
<string name="custom_location_gps">Geolocation</string>
</resources>

View File

@ -9,7 +9,6 @@
<style name="AnotherWidget.Main.Title" parent="TextAppearance.AppCompat.Medium">
<item name="android:textColor">@android:color/white</item>
<item name="android:textSize">28sp</item>
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:gravity">center</item>
<item name="android:textStyle">bold</item>
</style>
@ -17,7 +16,6 @@
<style name="AnotherWidget.Main.Subtitle" parent="TextAppearance.AppCompat.Small">
<item name="android:textColor">@android:color/white</item>
<item name="android:textSize">20sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:gravity">center</item>
</style>
@ -25,7 +23,6 @@
<item name="android:textColor">@android:color/white</item>
<item name="android:textSize">18sp</item>
<item name="android:gravity">center</item>
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:alpha">0.6</item>
</style>
@ -70,7 +67,6 @@
<style name="AnotherWidget.Settings.Title" parent="TextAppearance.AppCompat.Medium">
<item name="android:textColor">@android:color/white</item>
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:textSize">16sp</item>
<item name="android:textStyle">bold</item>
</style>
@ -83,12 +79,10 @@
<style name="AnotherWidget.Title" parent="TextAppearance.AppCompat.Medium">
<item name="android:textColor">@android:color/white</item>
<item name="android:padding">4dp</item>
<item name="android:textSize">26sp</item>
<item name="android:textSize">24sp</item>
<item name="android:shadowColor">@color/black_50</item>
<item name="android:shadowRadius">5</item>
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:gravity">center</item>
<item name="android:textStyle">bold</item>
</style>
<style name="AnotherWidget.Subtitle" parent="TextAppearance.AppCompat.Small">
@ -96,19 +90,14 @@
<item name="android:textSize">16sp</item>
<item name="android:shadowColor">@color/black_50</item>
<item name="android:shadowRadius">5</item>
<item name="android:gravity">center</item>
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:gravity">center_horizontal</item>
</style>
<style name="AnotherWidget.Date" parent="AnotherWidget.Subtitle">
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:textStyle">bold</item>
</style>
<style name="AnotherWidget.Date.Big" parent="AnotherWidget.Title">
<item name="android:textSize">24sp</item>
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">22sp</item>
</style>
</resources>

View File

@ -5,10 +5,12 @@ buildscript {
repositories {
google()
jcenter()
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-beta7'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'io.fabric.tools:gradle:1.+'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@ -20,6 +22,7 @@ allprojects {
google()
jcenter()
maven { url 'https://jitpack.io' }
maven { url 'https://maven.fabric.io/public' }
}
}