Added calendar filter

This commit is contained in:
Tommaso Berlose 2017-10-10 14:52:12 +02:00
parent f62f9dc3bd
commit f7e99184c9
15 changed files with 193 additions and 70 deletions

View File

@ -38,10 +38,9 @@
<receiver
android:name=".receiver.NewCalendarEventReceiver"
android:enabled="true"
android:exported="false">
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>

View File

@ -3,7 +3,7 @@ package com.tommasoberlose.anotherwidget.`object`
/**
* Created by tommaso on 08/10/17.
*/
class Calendar(id: Int, name: String, account_name: String) {
class CalendarSelector(id: Int, name: String, account_name: String) {
var id: Int = 0
var name: String = ""
var account_name: String = ""

View File

@ -18,6 +18,12 @@ object Constants {
val PREF_CALENDAR_ALL_DAY = "PREF_CALENDAR_ALL_DAY"
val PREF_CALENDAR_FILTER = "PREF_CALENDAR_FILTER"
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_END_DATE = "PREF_NEXT_EVENT_END_DATE"
val PREF_NEXT_EVENT_CALENDAR_ID = "PREF_NEXT_EVENT_CALENDAR_ID"
val dateFormat = SimpleDateFormat("EEEE, MMM d", Locale.getDefault())
val hourFormat = SimpleDateFormat("HH:mm", Locale.getDefault())

View File

@ -8,18 +8,28 @@ import java.util.Date
* Created by tommaso on 05/10/17.
*/
class Event(eventCursor: Cursor, instanceCursor: Cursor) {
class Event {
var id: Int = 0
var title: String? = null
var startDate: Long = 0
var endDate: Long = 0
var calendarID: Int = 0
init {
constructor(id:Int, title:String, startDate:Long, endDate:Long, calendarID: Int) {
this.id = id
this.title = title
this.startDate = startDate
this.endDate = endDate
this.calendarID = calendarID
}
constructor(eventCursor: Cursor, instanceCursor: Cursor) {
id = instanceCursor.getInt(0)
startDate = instanceCursor.getLong(1)
endDate = instanceCursor.getLong(2)
title = eventCursor.getString(0)
calendarID = eventCursor.getInt(2)
}
override fun toString(): String {

View File

@ -3,11 +3,15 @@ package com.tommasoberlose.anotherwidget.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
import com.tommasoberlose.anotherwidget.util.CalendarUtil
import com.tommasoberlose.anotherwidget.util.Util
class NewCalendarEventReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Util.updateWidget(context)
if (intent.action.equals(Intent.ACTION_PROVIDER_CHANGED)) {
CalendarUtil.updateEventList(context)
}
}
}

View File

@ -7,6 +7,7 @@ import android.content.Intent
import android.app.AlarmManager
import android.app.PendingIntent
import com.tommasoberlose.anotherwidget.`object`.Constants
import com.tommasoberlose.anotherwidget.util.CalendarUtil
import com.tommasoberlose.anotherwidget.util.Util
@ -22,7 +23,7 @@ class UpdatesReceiver : BroadcastReceiver() {
removeUpdates(context)
if (Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)) {
Util.updateWidget(context)
CalendarUtil.updateEventList(context)
val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val i = Intent(context, UpdatesReceiver::class.java)

View File

@ -2,6 +2,7 @@ package com.tommasoberlose.anotherwidget.ui.activity
import android.Manifest
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.pm.PackageManager
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
@ -23,6 +24,9 @@ import android.content.Intent
import android.content.BroadcastReceiver
import com.tommasoberlose.anotherwidget.util.CalendarUtil
import com.tommasoberlose.anotherwidget.util.WeatherUtil
import android.content.DialogInterface
import android.util.Log
import com.tommasoberlose.anotherwidget.`object`.CalendarSelector
class MainActivity : AppCompatActivity() {
@ -53,9 +57,9 @@ class MainActivity : AppCompatActivity() {
}
})
action_project.setOnClickListener(object: View.OnClickListener {
action_rate.setOnClickListener(object: View.OnClickListener {
override fun onClick(p0: View?) {
Util.openURI(this@MainActivity, "https://github.com/tommasoberlose/another-widget")
Util.openURI(this@MainActivity, "https://play.google.com/store/apps/details?id=com.tommasoberlose.anotherwidget")
}
})
}
@ -133,10 +137,12 @@ class MainActivity : AppCompatActivity() {
empty_date.text = String.format("%s%s", Constants.dateFormat.format(now.time)[0].toUpperCase(), Constants.dateFormat.format(now.time).substring(1))
if (calendarLayout) {
val eventList = CalendarUtil.getNextEvent(this)
val e = CalendarUtil.getNextEvent(this)
if (e.id != 0) {
val difference = e.startDate - now.timeInMillis
if (eventList.isNotEmpty()) {
val difference = eventList[0].startDate - now.timeInMillis
if (difference > 1000 * 60) {
var time = ""
@ -149,11 +155,11 @@ class MainActivity : AppCompatActivity() {
time += " " + minutes + getString(R.string.min_code)
}
next_event.text = String.format("%s %s %s", eventList[0].title, getString(R.string.in_code), time)
next_event.text = String.format("%s %s %s", e.title, getString(R.string.in_code), time)
} else {
next_event.text = String.format("%s", eventList[0].title)
next_event.text = String.format("%s", e.title)
}
next_event_date.text = String.format("%s - %s", Constants.hourFormat.format(eventList[0].startDate), Constants.hourFormat.format(eventList[0].endDate))
next_event_date.text = String.format("%s - %s", Constants.hourFormat.format(e.startDate), Constants.hourFormat.format(e.endDate))
empty_layout.visibility = View.GONE
calendar_layout.visibility = View.VISIBLE
@ -204,7 +210,32 @@ class MainActivity : AppCompatActivity() {
action_show_all_day.setOnClickListener {
SP.edit().putBoolean(Constants.PREF_CALENDAR_ALL_DAY, !SP.getBoolean(Constants.PREF_CALENDAR_ALL_DAY, false)).commit()
updateUI()
Util.updateWidget(this)
CalendarUtil.updateEventList(this)
}
action_filter_calendar.setOnClickListener {
val calendarSelectorList: List<CalendarSelector> = CalendarUtil.getCalendarList(this)
var calFiltered = SP.getString(Constants.PREF_CALENDAR_FILTER, "")
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()
}
}

View File

@ -77,10 +77,10 @@ class TheWidget : AppWidgetProvider() {
if (calendarLayout) {
val eventList = CalendarUtil.getNextEvent(context)
val e = CalendarUtil.getNextEvent(context)
if (eventList.isNotEmpty()) {
val difference = eventList[0].startDate - now.timeInMillis
if (e.id != 0) {
val difference = e.startDate - now.timeInMillis
if (difference > 1000 * 60) {
var time = ""
@ -93,18 +93,18 @@ class TheWidget : AppWidgetProvider() {
time += " " + minutes + context.getString(R.string.min_code)
}
views.setTextViewText(R.id.next_event, String.format("%s %s %s", eventList[0].title, context.getString(R.string.in_code), time))
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", eventList[0].title))
views.setTextViewText(R.id.next_event, String.format("%s", e.title))
}
views.setTextViewText(R.id.next_event_date, String.format("%s - %s", Constants.hourFormat.format(eventList[0].startDate), Constants.hourFormat.format(eventList[0].endDate)))
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, eventList[0].startDate)
ContentUris.appendId(builder, e.startDate)
val intent = Intent(Intent.ACTION_VIEW)
.setData(builder.build())
val pIntent = PendingIntent.getActivity(context, widgetID, intent, 0)

View File

@ -1,11 +1,14 @@
package com.tommasoberlose.anotherwidget.util
import android.Manifest
import android.annotation.SuppressLint
import android.content.ContentUris
import android.content.Context
import android.content.SharedPreferences
import android.preference.PreferenceManager
import android.provider.CalendarContract
import android.util.Log
import com.tommasoberlose.anotherwidget.`object`.CalendarSelector
import com.tommasoberlose.anotherwidget.`object`.Constants
import com.tommasoberlose.anotherwidget.`object`.Event
import java.util.*
@ -16,7 +19,7 @@ import java.util.*
object CalendarUtil {
fun getNextEvent(context: Context): List<Event> {
fun updateEventList(context: Context) {
val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
val eventList = ArrayList<Event>()
@ -29,24 +32,26 @@ object CalendarUtil {
ContentUris.appendId(builder, hourLimit.timeInMillis)
if (!Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)) {
return eventList
resetNextEventData(context)
}
val instanceCursor = context.contentResolver.query(builder.build(), arrayOf(CalendarContract.Instances.EVENT_ID, CalendarContract.Instances.BEGIN, CalendarContract.Instances.END), null, null, null) ?: return eventList
val instanceCursor = context.contentResolver.query(builder.build(), arrayOf(CalendarContract.Instances.EVENT_ID, CalendarContract.Instances.BEGIN, CalendarContract.Instances.END), null, null, null)
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),
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) ?: return eventList
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 (e.endDate - now.timeInMillis > 1000 * 60 * 30 && (SP.getBoolean(Constants.PREF_CALENDAR_ALL_DAY, false) || !allDay)) {
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.moveToNext()
@ -58,10 +63,17 @@ object CalendarUtil {
}
instanceCursor.close()
return eventList
if (eventList.isEmpty()) {
resetNextEventData(context)
} else {
saveNextEventData(context, eventList.get(0))
}
}
fun getCalendarList(context: Context): List<com.tommasoberlose.anotherwidget.`object`.Calendar> {
val calendarList = ArrayList<com.tommasoberlose.anotherwidget.`object`.Calendar>()
fun getCalendarList(context: Context): List<CalendarSelector> {
val calendarList = ArrayList<CalendarSelector>()
if (!Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)) {
return calendarList
@ -76,7 +88,7 @@ object CalendarUtil {
calendarCursor.moveToFirst()
for (j in 0 until calendarCursor.count) {
calendarList.add(com.tommasoberlose.anotherwidget.`object`.Calendar(calendarCursor.getInt(0), calendarCursor.getString(1), calendarCursor.getString(2)))
calendarList.add(CalendarSelector(calendarCursor.getInt(0), calendarCursor.getString(1), calendarCursor.getString(2)))
calendarCursor.moveToNext()
}
@ -84,4 +96,33 @@ object CalendarUtil {
return calendarList
}
fun resetNextEventData(context: Context) {
val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
SP.edit()
.remove(Constants.PREF_NEXT_EVENT_ID)
.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_CALENDAR_ID)
.apply()
}
@SuppressLint("ApplySharedPref")
fun saveNextEventData(context: Context, event: Event) {
val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
SP.edit()
.putInt(Constants.PREF_NEXT_EVENT_ID, event.id)
.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)
.putInt(Constants.PREF_NEXT_EVENT_CALENDAR_ID, event.calendarID)
.commit()
Util.updateWidget(context)
}
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))
}
}

View File

@ -3,7 +3,7 @@
<item>
<shape android:shape="rectangle">
<corners
android:radius="3dp" />
android:radius="2dp" />
<solid
android:color="@color/black_30"/>
</shape>

View File

@ -61,35 +61,17 @@
android:orientation="vertical"
android:paddingTop="20dp"
android:paddingBottom="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="@string/settings_calendar_title"
style="@style/AnotherWidget.Settings.Header"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
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_change_unit"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_unit_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/temp_unit"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:paddingLeft="32dp"
android:paddingRight="32dp"
android:clickable="true"
@ -97,7 +79,6 @@
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_filter_calendar"
android:visibility="gone"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
@ -113,8 +94,8 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:paddingLeft="32dp"
android:paddingRight="32dp"
android:clickable="true"
@ -134,6 +115,37 @@
android:id="@+id/all_day_label"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_weather_title"
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_change_unit"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_unit_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/temp_unit"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
@ -236,18 +248,18 @@
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:id="@+id/action_share"
android:id="@+id/action_rate"
android:orientation="vertical">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:padding="2dp"
android:layout_marginTop="8dp"
android:src="@drawable/ic_action_sms"/>
android:src="@drawable/ic_action_rate"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/action_share"
android:text="@string/action_rate"
style="@style/AnotherWidget.Main.Button.TabBar"
android:background="@android:color/transparent"/>
</LinearLayout>
@ -261,18 +273,18 @@
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:id="@+id/action_project"
android:id="@+id/action_share"
android:orientation="vertical">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:padding="2dp"
android:layout_marginTop="8dp"
android:src="@drawable/ic_action_code"/>
android:src="@drawable/ic_action_sms"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/action_project"
android:text="@string/action_share"
style="@style/AnotherWidget.Main.Button.TabBar"
android:background="@android:color/transparent"/>
</LinearLayout>

View File

@ -29,4 +29,8 @@
<string name="settings_all_day_title">Eventi Giornalieri</string>
<string name="settings_all_day_subtitle_visible">Visibili</string>
<string name="settings_all_day_subtitle_gone">Non Visibili</string>
<string name="main_calendar">Calendario Account</string>
<string name="settings_calendar_title">Impostazioni Calendario</string>
<string name="settings_weather_title">Impostazioni Meteo</string>
<string name="settings_general_title">Impostazioni Generali</string>
</resources>

View File

@ -3,7 +3,7 @@
<color name="colorPrimary">#0092ca</color>
<color name="colorPrimaryDark">#0083B5</color>
<color name="colorNightDark">#124E96</color>
<color name="colorAccent">#FF008E</color>
<color name="colorAccent">#124E96</color>
<color name="colorPrimaryLight">#DAEAF6</color>
<color name="black_50">#80000000</color>
<color name="black_30">#48000000</color>

View File

@ -30,4 +30,8 @@
<string name="settings_all_day_title">All Day Events</string>
<string name="settings_all_day_subtitle_visible">Visible</string>
<string name="settings_all_day_subtitle_gone">Not Visible</string>
<string name="main_calendar">Account Calendar</string>
<string name="settings_calendar_title">Calendar Settings</string>
<string name="settings_weather_title">Weather Settings</string>
<string name="settings_general_title">General Settings</string>
</resources>

View File

@ -57,6 +57,17 @@
<item name="android:textSize">12sp</item>
</style>
<style name="AnotherWidget.Settings.Header" parent="TextAppearance.AppCompat.Button">
<item name="android:textSize">10sp</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:layout_gravity">center_horizontal</item>
<item name="android:paddingRight">6dp</item>
<item name="android:paddingLeft">6dp</item>
<item name="android:paddingTop">4dp</item>
<item name="android:paddingBottom">4dp</item>
<item name="android:background">@drawable/dark_card_background</item>
</style>
<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>