Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for Calendar events #310

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
587943c
Adding support for Calendar events
nmitsou Nov 14, 2015
7c8226f
Merge branch 'master' into calendar
nmitsou Nov 14, 2015
c52a5bb
Merge branch 'master' into calendar
nmitsou Nov 15, 2015
cc3307f
fixing conflict
nmitsou Nov 15, 2015
39aea75
Fixing ugly but on search of 'events'
nmitsou Nov 16, 2015
c0b39bf
Fixing ugly bug on search of 'events'
nmitsou Nov 16, 2015
18ff18b
Merge branch 'calendar' of https://github.com/nmitsou/KISS into calendar
nmitsou Nov 16, 2015
e9d13ba
Cleaning up code (comments from saveman71)
nmitsou Nov 22, 2015
62cd080
Merge remote-tracking branch 'upstream/master' into calendar
nmitsou Nov 22, 2015
2b56beb
Refresh calendar events when calendar data is updated.
nmitsou Nov 22, 2015
d05ea77
changing text on preferences
nmitsou Nov 22, 2015
6d35e27
ongoing. changed icon, today / week / month queries
nmitsou Nov 23, 2015
86817fa
Merge remote-tracking branch 'upstream/master' into calendar
nmitsou Nov 23, 2015
93da2ee
Merge remote-tracking branch 'upstream/master' into calendar
nmitsou Nov 26, 2015
d26746c
Merge remote-tracking branch 'upstream/master' into calendar
nmitsou Nov 26, 2015
0eb18f8
Hide calendar option on settings on older devices
nmitsou Nov 27, 2015
2590936
Cove case of older device (api<14)
nmitsou Nov 28, 2015
88d72d2
changing the special queries to !day, !week and !month
nmitsou Nov 28, 2015
51289de
Beautification of the result
nmitsou Nov 29, 2015
a2c9ec9
removing :
nmitsou Nov 29, 2015
550c201
Adding eventResult on RecordAdapter. Is this really needed?
nmitsou Dec 1, 2015
c912dd9
custom calendar icon on the fly (only once per EventResult)
nmitsou Dec 4, 2015
a6185c1
Fix on the icon display
nmitsou Dec 4, 2015
af847d9
creating non visible icons in a different thread. I am sceptical abou…
nmitsou Dec 4, 2015
7f22a1f
Switch to allow special queries on calendar but not normal search que…
nmitsou Dec 4, 2015
482ca31
Merge remote-tracking branch 'upstream/master' into calendar
nmitsou Dec 5, 2015
1c2d51a
fixing description on settings
nmitsou Dec 6, 2015
f3e8de1
adding enable-events-special-search-only on safe settings
nmitsou Dec 6, 2015
8dda044
adding enable-events-special-search-only on safe settings, test circl…
nmitsou Dec 6, 2015
37f857c
Merge branch 'calendar' of https://github.com/nmitsou/KISS into calendar
nmitsou Dec 9, 2015
9e84cae
Merge branch 'master' into calendar
nmitsou Dec 9, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/src/main/AndroidManifest.xml
Expand Up @@ -41,6 +41,8 @@
<!-- To autorotation toggle -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

<uses-permission android:name="android.permission.READ_CALENDAR"/>

<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
Expand Down Expand Up @@ -149,4 +151,4 @@
</receiver>
</application>

</manifest>
</manifest>
5 changes: 4 additions & 1 deletion app/src/main/java/fr/neamar/kiss/DataHandler.java
Expand Up @@ -13,6 +13,7 @@
import fr.neamar.kiss.dataprovider.AliasProvider;
import fr.neamar.kiss.dataprovider.AppProvider;
import fr.neamar.kiss.dataprovider.ContactProvider;
import fr.neamar.kiss.dataprovider.EventProvider;
import fr.neamar.kiss.dataprovider.PhoneProvider;
import fr.neamar.kiss.dataprovider.Provider;
import fr.neamar.kiss.dataprovider.SearchProvider;
Expand Down Expand Up @@ -73,7 +74,9 @@ public DataHandler(Context context) {
if (prefs.getBoolean("enable-alias", true)) {
providers.add(new AliasProvider(context, appProvider));
}

if (prefs.getBoolean("enable-events", true)) {
providers.add(new EventProvider(context));
}
if (prefs.getBoolean("enable-shortcuts", true)) {
shortcutProvider = new ShortcutProvider(context);
providers.add(shortcutProvider);
Expand Down
95 changes: 95 additions & 0 deletions app/src/main/java/fr/neamar/kiss/dataprovider/EventProvider.java
@@ -0,0 +1,95 @@
package fr.neamar.kiss.dataprovider;

import android.content.Context;

import java.util.ArrayList;
import java.util.regex.Pattern;

import fr.neamar.kiss.loader.LoadAppPojos;
import fr.neamar.kiss.loader.LoadEventPojos;
import fr.neamar.kiss.normalizer.StringNormalizer;
import fr.neamar.kiss.pojo.AliasPojo;
import fr.neamar.kiss.pojo.AppPojo;
import fr.neamar.kiss.pojo.EventPojo;
import fr.neamar.kiss.pojo.Pojo;
import fr.neamar.kiss.pojo.SettingPojo;

public class EventProvider extends Provider<EventPojo> {
private final String eventsName;

public EventProvider(Context context) {
super(new LoadEventPojos(context));
eventsName="Events: ".toLowerCase();
}

public ArrayList<Pojo> getResults(String query) {
query = StringNormalizer.normalize(query);
ArrayList<Pojo> results = new ArrayList<>();

int relevance;
String eventNameLowerCased;
for (EventPojo event : pojos) {
relevance = 0;
eventNameLowerCased = event.nameNormalized;
if (eventNameLowerCased.startsWith(query)) {
relevance = 10;
}
else if (eventNameLowerCased.contains(query)) {
relevance = 5;
}
else if (eventsName.startsWith(query)) {
// Also display for a search on "events" for instance
relevance = 4;
}

if (relevance>0)
{
event.displayName = event.name.replaceFirst(
"(?i)(" + Pattern.quote(query) + ")", "{$1}");

//event.setDisplayNameHighlightRegion(matchPositionStart, matchPositionEnd);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented code

event.relevance = relevance;
results.add(event);
}
}

return results;
}

/**
* Return a Pojo
*
* @param id we're looking for
* @param allowSideEffect do we allow this function to have potential side effect? Set to false to ensure none.
* @return an apppojo, or null
*/
public Pojo findById(String id, Boolean allowSideEffect) {
for (Pojo pojo : pojos) {
if (pojo.id.equals(id)) {
// Reset displayName to default value
if (allowSideEffect) {
pojo.displayName = pojo.name;
}
return pojo;
}

}

return null;
}

public Pojo findById(String id) {
return findById(id, true);
}

public ArrayList<Pojo> getAllEvents() {
ArrayList<Pojo> records = new ArrayList<>(pojos.size());
records.trimToSize();

for (Pojo pojo : pojos) {
pojo.displayName = pojo.name;
records.add(pojo);
}
return records;
}
}
85 changes: 85 additions & 0 deletions app/src/main/java/fr/neamar/kiss/loader/LoadEventPojos.java
@@ -0,0 +1,85 @@
package fr.neamar.kiss.loader;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CalendarContract;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import fr.neamar.kiss.normalizer.StringNormalizer;
import fr.neamar.kiss.pojo.EventPojo;

/**
* Created by nmitsou on 09.11.15.
*/
public class LoadEventPojos extends LoadPojos<EventPojo> {
public LoadEventPojos(Context context) {
super(context, "none://");
}

@Override
protected ArrayList<EventPojo> doInBackground(Void... params) {

ArrayList<EventPojo> events = new ArrayList<>();

String[] proj =
new String[]{
CalendarContract.Events._ID,
CalendarContract.Events.DTSTART,
CalendarContract.Events.DTEND,
CalendarContract.Events.TITLE,
CalendarContract.Events.DESCRIPTION};


String selectionClause = "(dtstart >= ? and dtend <=?)";
String[] selectionsArgs = new String[]{"" + new Date().getTime(), ""+ getDateInFuture(new Date()).getTime()};

Cursor cursor = context.getContentResolver()
.query(
Uri.parse("content://com.android.calendar/events"),
proj, selectionClause,
selectionsArgs, "dtstart");


cursor.moveToFirst();
// fetching calendars name
int eventsCount = cursor.getCount();

for (int i = 0; i < eventsCount; i++) {

EventPojo event = new EventPojo();
event.description = cursor.getString(4);
event.title = cursor.getString(3);
event.id = cursor.getString(0);
event.startDate = getDate(Long.parseLong(cursor.getString(1)));
event.stopDate = getDate(Long.parseLong(cursor.getString(2)));
event.setName(event.startDate+" "+event.title);
event.nameNormalized = StringNormalizer.normalize(event.name);
events.add(event);
cursor.moveToNext();

}
return events;

}
public static String getDate(long milliSeconds) {
SimpleDateFormat formatter = new SimpleDateFormat(
"dd/MM/yy hh:mm a");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(milliSeconds);
return formatter.format(calendar.getTime());
}

//method created for demonstration purposes
public Date getDateInFuture(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DATE, 30); //1 month
return calendar.getTime();
}

}
13 changes: 13 additions & 0 deletions app/src/main/java/fr/neamar/kiss/pojo/EventPojo.java
@@ -0,0 +1,13 @@
package fr.neamar.kiss.pojo;

/**
* Created by nmitsou on 09.11.15.
*/
public class EventPojo extends Pojo {

public String id;
public String startDate;
public String stopDate;
public String title;
public String description;
}
84 changes: 84 additions & 0 deletions app/src/main/java/fr/neamar/kiss/result/EventResult.java
@@ -0,0 +1,84 @@
package fr.neamar.kiss.result;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.provider.CalendarContract;
import android.provider.ContactsContract;
import android.view.MenuItem;
import android.view.View;
import android.widget.PopupMenu;
import android.widget.TextView;

import fr.neamar.kiss.R;
import fr.neamar.kiss.adapter.RecordAdapter;
import fr.neamar.kiss.pojo.EventPojo;
import fr.neamar.kiss.pojo.PhonePojo;

/**
* Created by nmitsou on 09.11.15.
*/
public class EventResult extends Result {
private final EventPojo eventPojo;

public EventResult(EventPojo eventPojo) {
super();
this.pojo = this.eventPojo = eventPojo;
}

@Override
public View display(Context context, int position, View v) {
if (v == null)
v = inflateFromId(context, R.layout.item_event);

TextView appName = (TextView) v.findViewById(R.id.item_event_text);
String text = context.getString(R.string.ui_item_event);
//appName.setText(eventPojo.startDate + " " + eventPojo.title);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here aswell

appName.setText(enrichText(eventPojo.displayName));

return v;
}



@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@Override
public void doLaunch(Context context, View v) {
Intent calendar = new Intent(Intent.ACTION_VIEW);
Uri.Builder uri = CalendarContract.Events.CONTENT_URI.buildUpon();
uri.appendPath(eventPojo.id);
calendar.setData(uri.build());
context.startActivity(calendar);
}

@Override
protected Boolean popupMenuClickHandler(Context context, RecordAdapter parent, MenuItem item) {
/*switch (item.getItemId()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too

case R.id.item_phone_createcontact:
// Create a new contact with this phone number
Intent createIntent = new Intent(Intent.ACTION_INSERT);
createIntent.setType(ContactsContract.Contacts.CONTENT_TYPE);
createIntent.putExtra(ContactsContract.Intents.Insert.PHONE, phonePojo.phone);
createIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(createIntent);
return true;
case R.id.item_phone_sendmessage:
String url = "sms:" + phonePojo.phone;
Intent messageIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse(url));
messageIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(messageIntent);
return true;
}*/

return super.popupMenuClickHandler(context, parent, item);
}


@Override
public Drawable getDrawable(Context context) {
return context.getResources().getDrawable(android.R.drawable.ic_menu_call);
}
}
4 changes: 3 additions & 1 deletion app/src/main/java/fr/neamar/kiss/result/Result.java
Expand Up @@ -18,6 +18,7 @@
import fr.neamar.kiss.db.DBHelper;
import fr.neamar.kiss.pojo.AppPojo;
import fr.neamar.kiss.pojo.ContactPojo;
import fr.neamar.kiss.pojo.EventPojo;
import fr.neamar.kiss.pojo.PhonePojo;
import fr.neamar.kiss.pojo.Pojo;
import fr.neamar.kiss.pojo.SearchPojo;
Expand Down Expand Up @@ -45,10 +46,11 @@ else if (pojo instanceof TogglePojo)
return new ToggleResult((TogglePojo) pojo);
else if (pojo instanceof PhonePojo)
return new PhoneResult((PhonePojo) pojo);
else if (pojo instanceof EventPojo)
return new EventResult((EventPojo) pojo);
else if (pojo instanceof ShortcutPojo)
return new ShortcutResult((ShortcutPojo) pojo);


throw new RuntimeException("Unable to create a result from POJO");
}

Expand Down
Expand Up @@ -18,6 +18,7 @@ public NullSearcher(MainActivity activity) {

@Override
protected List<Pojo> doInBackground(Void... voids) {
// Ask for records
return new ArrayList<Pojo>();
}
}
Binary file added app/src/main/res/drawable-hdpi/ic_event.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions app/src/main/res/layout/item_event.xml
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="@dimen/result_margin_bottom"
android:paddingLeft="@dimen/result_margin_left"
android:paddingRight="@dimen/result_margin_right"
android:paddingTop="@dimen/result_margin_top">

<ImageView
android:id="@+id/item_event_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginBottom="@dimen/icon_margin_bottom"
android:layout_marginLeft="@dimen/icon_margin_left"
android:layout_marginRight="@dimen/icon_margin_right"
android:layout_marginTop="@dimen/icon_margin_top"
android:contentDescription="@null"
android:src="@drawable/ic_event"/>

<TextView
android:id="@+id/item_event_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ui_item_event"
android:textColor="?attr/resultColor"
android:textSize="@dimen/result_title_size"/>

</LinearLayout>
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Expand Up @@ -5,6 +5,7 @@
<string name="activity_setting">KISS settings</string>
<string name="ui_search_hint">Search apps, contacts, …</string>
<string name="ui_item_search">Search for “%s”</string>
<string name="ui_item_event">Event: “%s”</string>
<string name="ui_item_phone">Call “%s”</string>
<string name="ui_item_contact_hint_message">Message</string>
<string name="ui_item_contact_hint_call">Call</string>
Expand All @@ -30,6 +31,9 @@
<string name="aliases_desc">Enable aliases (convenience shortcuts)</string>
<string name="aliases_name">Aliases</string>

<string name="events_desc">Enable calendar events</string>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe "Search in my calendar events" is better? (i.e. same as "Search in my contacts")

<string name="events_name">Calendar</string>

<string name="contacts_desc">Search in my contacts</string>
<string name="contacts_name">Contacts</string>

Expand Down