Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
halo
packages_apps_Calendar
Commits
fec5bff4
Commit
fec5bff4
authored
12 years ago
by
Chris Wren
Browse files
Options
Download
Email Patches
Plain Diff
add global dismiss to calendar, open source part
Change-Id: If179adc814a1da977712c9dc804e81a2cc726bce
parent
268fe32f
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
483 additions
and
4 deletions
+483
-4
AndroidManifest.xml
AndroidManifest.xml
+3
-0
res/values/strings.xml
res/values/strings.xml
+2
-0
src/com/android/calendar/CloudNotificationBackplane.java
src/com/android/calendar/CloudNotificationBackplane.java
+31
-0
src/com/android/calendar/ExtensionsFactory.java
src/com/android/calendar/ExtensionsFactory.java
+40
-0
src/com/android/calendar/alerts/AlertReceiver.java
src/com/android/calendar/alerts/AlertReceiver.java
+1
-3
src/com/android/calendar/alerts/AlertService.java
src/com/android/calendar/alerts/AlertService.java
+2
-0
src/com/android/calendar/alerts/AlertUtils.java
src/com/android/calendar/alerts/AlertUtils.java
+1
-0
src/com/android/calendar/alerts/DismissAlarmsService.java
src/com/android/calendar/alerts/DismissAlarmsService.java
+15
-1
src/com/android/calendar/alerts/GlobalDismissManager.java
src/com/android/calendar/alerts/GlobalDismissManager.java
+388
-0
No files found.
AndroidManifest.xml
View file @
fec5bff4
...
...
@@ -185,6 +185,9 @@
</intent-filter>
</receiver>
<receiver
android:name=
".alerts.GlobalDismissManager"
android:exported=
"false"
/>
<service
android:name=
".alerts.AlertService"
/>
<service
android:name=
".alerts.DismissAlarmsService"
/>
...
...
This diff is collapsed.
Click to expand it.
res/values/strings.xml
View file @
fec5bff4
...
...
@@ -710,4 +710,6 @@
<!-- Description of the selected marker for accessibility support [CHAR LIMIT = NONE]-->
<string
name=
"acessibility_recurrence_choose_end_date_description"
>
change end date
</string>
<!-- Do Not Translate. Sender identity for global notification synchronization. -->
<string
name=
"notification_sender_id"
></string>
</resources>
This diff is collapsed.
Click to expand it.
src/com/android/calendar/CloudNotificationBackplane.java
0 → 100644
View file @
fec5bff4
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package
com.android.calendar
;
import
java.io.IOException
;
import
android.content.Context
;
import
android.os.Bundle
;
public
interface
CloudNotificationBackplane
{
public
boolean
open
(
Context
context
);
public
boolean
subscribeToGroup
(
String
senderId
,
String
account
,
String
groupId
)
throws
IOException
;
public
void
send
(
String
to
,
String
msgId
,
String
collapseKey
,
long
timeToLive
,
Bundle
data
)
throws
IOException
;
public
void
close
();
}
This diff is collapsed.
Click to expand it.
src/com/android/calendar/ExtensionsFactory.java
View file @
fec5bff4
...
...
@@ -18,6 +18,7 @@ package com.android.calendar;
import
android.content.Context
;
import
android.content.res.AssetManager
;
import
android.os.Bundle
;
import
android.util.Log
;
import
android.view.Menu
;
import
android.view.MenuItem
;
...
...
@@ -27,10 +28,12 @@ import java.io.IOException;
import
java.io.InputStream
;
import
java.util.Properties
;
/*
* Skeleton for additional options in the AllInOne menu.
*/
public
class
ExtensionsFactory
{
private
static
String
TAG
=
"ExtensionsFactory"
;
// Config filename for mappings of various class names to their custom
...
...
@@ -38,6 +41,7 @@ public class ExtensionsFactory {
private
static
String
EXTENSIONS_PROPERTIES
=
"calendar_extensions.properties"
;
private
static
String
ALL_IN_ONE_MENU_KEY
=
"AllInOneMenuExtensions"
;
private
static
String
CLOUD_NOTIFICATION_KEY
=
"CloudNotificationChannel"
;
private
static
Properties
sProperties
=
new
Properties
();
private
static
AllInOneMenuExtensionsInterface
sAllInOneMenuExtensions
=
null
;
...
...
@@ -95,4 +99,40 @@ public class ExtensionsFactory {
return
sAllInOneMenuExtensions
;
}
public
static
CloudNotificationBackplane
getCloudNotificationBackplane
()
{
CloudNotificationBackplane
cnb
=
null
;
String
className
=
sProperties
.
getProperty
(
CLOUD_NOTIFICATION_KEY
);
if
(
className
!=
null
)
{
cnb
=
createInstance
(
className
);
}
else
{
Log
.
d
(
TAG
,
CLOUD_NOTIFICATION_KEY
+
" not found in properties file."
);
}
if
(
cnb
==
null
)
{
cnb
=
new
CloudNotificationBackplane
()
{
@Override
public
boolean
open
(
Context
context
)
{
return
true
;
}
@Override
public
boolean
subscribeToGroup
(
String
senderId
,
String
account
,
String
groupId
)
throws
IOException
{
return
true
;}
@Override
public
void
send
(
String
to
,
String
msgId
,
String
collapseKey
,
long
timeToLive
,
Bundle
data
)
{
}
@Override
public
void
close
()
{
}
};
}
return
cnb
;
}
}
This diff is collapsed.
Click to expand it.
src/com/android/calendar/alerts/AlertReceiver.java
View file @
fec5bff4
...
...
@@ -105,9 +105,7 @@ public class AlertReceiver extends BroadcastReceiver {
}
if
(
DELETE_ALL_ACTION
.
equals
(
intent
.
getAction
()))
{
/* The user has clicked the "Clear All Notifications"
* buttons so dismiss all Calendar alerts.
*/
// The user has dismissed a digest notification.
// TODO Grab a wake lock here?
Intent
serviceIntent
=
new
Intent
(
context
,
DismissAlarmsService
.
class
);
context
.
startService
(
serviceIntent
);
...
...
This diff is collapsed.
Click to expand it.
src/com/android/calendar/alerts/AlertService.java
View file @
fec5bff4
...
...
@@ -814,6 +814,8 @@ public class AlertService extends Service {
lowPriorityEvents
.
add
(
newInfo
);
}
}
// TODO(cwren) add beginTime/startTime
GlobalDismissManager
.
processEventIds
(
context
,
eventIds
.
keySet
());
}
finally
{
if
(
alertCursor
!=
null
)
{
alertCursor
.
close
();
...
...
This diff is collapsed.
Click to expand it.
src/com/android/calendar/alerts/AlertUtils.java
View file @
fec5bff4
...
...
@@ -56,6 +56,7 @@ public class AlertUtils {
public
static
final
String
EVENT_END_KEY
=
"eventend"
;
public
static
final
String
NOTIFICATION_ID_KEY
=
"notificationid"
;
public
static
final
String
EVENT_IDS_KEY
=
"eventids"
;
public
static
final
String
EVENT_STARTS_KEY
=
"starts"
;
// A flag for using local storage to save alert state instead of the alerts DB table.
// This allows the unbundled app to run alongside other calendar apps without eating
...
...
This diff is collapsed.
Click to expand it.
src/com/android/calendar/alerts/DismissAlarmsService.java
View file @
fec5bff4
...
...
@@ -28,6 +28,10 @@ import android.provider.CalendarContract.CalendarAlerts;
import
android.support.v4.app.TaskStackBuilder
;
import
com.android.calendar.EventInfoActivity
;
import
com.android.calendar.alerts.GlobalDismissManager.AlarmId
;
import
java.util.LinkedList
;
import
java.util.List
;
/**
* Service for asynchronously marking fired alarms as dismissed.
...
...
@@ -55,21 +59,31 @@ public class DismissAlarmsService extends IntentService {
long
eventEnd
=
intent
.
getLongExtra
(
AlertUtils
.
EVENT_END_KEY
,
-
1
);
boolean
showEvent
=
intent
.
getBooleanExtra
(
AlertUtils
.
SHOW_EVENT_KEY
,
false
);
long
[]
eventIds
=
intent
.
getLongArrayExtra
(
AlertUtils
.
EVENT_IDS_KEY
);
long
[]
eventStarts
=
intent
.
getLongArrayExtra
(
AlertUtils
.
EVENT_STARTS_KEY
);
int
notificationId
=
intent
.
getIntExtra
(
AlertUtils
.
NOTIFICATION_ID_KEY
,
-
1
);
List
<
AlarmId
>
alarmIds
=
new
LinkedList
<
AlarmId
>();
Uri
uri
=
CalendarAlerts
.
CONTENT_URI
;
String
selection
;
// Dismiss a specific fired alarm if id is present, otherwise, dismiss all alarms
if
(
eventId
!=
-
1
)
{
alarmIds
.
add
(
new
AlarmId
(
eventId
,
eventStart
));
selection
=
CalendarAlerts
.
STATE
+
"="
+
CalendarAlerts
.
STATE_FIRED
+
" AND "
+
CalendarAlerts
.
EVENT_ID
+
"="
+
eventId
;
}
else
if
(
eventIds
!=
null
&&
eventIds
.
length
>
0
)
{
}
else
if
(
eventIds
!=
null
&&
eventIds
.
length
>
0
&&
eventStarts
!=
null
&&
eventIds
.
length
==
eventStarts
.
length
)
{
selection
=
buildMultipleEventsQuery
(
eventIds
);
for
(
int
i
=
1
;
i
<
eventIds
.
length
;
i
++)
{
alarmIds
.
add
(
new
AlarmId
(
eventIds
[
i
],
eventStarts
[
i
]));
}
}
else
{
// NOTE: I don't believe that this ever happens.
selection
=
CalendarAlerts
.
STATE
+
"="
+
CalendarAlerts
.
STATE_FIRED
;
}
GlobalDismissManager
.
dismissGlobally
(
getApplicationContext
(),
alarmIds
);
ContentResolver
resolver
=
getContentResolver
();
ContentValues
values
=
new
ContentValues
();
values
.
put
(
PROJECTION
[
COLUMN_INDEX_STATE
],
CalendarAlerts
.
STATE_DISMISSED
);
...
...
This diff is collapsed.
Click to expand it.
src/com/android/calendar/alerts/GlobalDismissManager.java
0 → 100644
View file @
fec5bff4
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package
com.android.calendar.alerts
;
import
android.content.BroadcastReceiver
;
import
android.content.ContentResolver
;
import
android.content.ContentValues
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.SharedPreferences
;
import
android.database.Cursor
;
import
android.net.Uri
;
import
android.os.AsyncTask
;
import
android.os.Bundle
;
import
android.provider.CalendarContract.CalendarAlerts
;
import
android.provider.CalendarContract.Calendars
;
import
android.provider.CalendarContract.Events
;
import
android.util.Log
;
import
android.util.Pair
;
import
com.android.calendar.CloudNotificationBackplane
;
import
com.android.calendar.ExtensionsFactory
;
import
com.android.calendar.R
;
import
java.io.IOException
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
/**
* Utilities for managing notification dismissal across devices.
*/
public
class
GlobalDismissManager
extends
BroadcastReceiver
{
private
static
final
String
TAG
=
"GlobalDismissManager"
;
private
static
final
String
GOOGLE_ACCOUNT_TYPE
=
"com.google"
;
private
static
final
String
GLOBAL_DISMISS_MANAGER_PREFS
=
"com.android.calendar.alerts.GDM"
;
private
static
final
String
ACCOUNT_KEY
=
"known_accounts"
;
protected
static
final
long
FOUR_WEEKS
=
60
*
60
*
24
*
7
*
4
;
static
final
String
[]
EVENT_PROJECTION
=
new
String
[]
{
Events
.
_ID
,
Events
.
CALENDAR_ID
};
static
final
String
[]
EVENT_SYNC_PROJECTION
=
new
String
[]
{
Events
.
_ID
,
Events
.
_SYNC_ID
};
static
final
String
[]
CALENDARS_PROJECTION
=
new
String
[]
{
Calendars
.
_ID
,
Calendars
.
ACCOUNT_NAME
,
Calendars
.
ACCOUNT_TYPE
};
public
static
final
String
SYNC_ID
=
"sync_id"
;
public
static
final
String
START_TIME
=
"start_time"
;
public
static
final
String
ACCOUNT_NAME
=
"account_name"
;
// redundant?
public
static
final
String
DISMISS_INTENT
=
"com.android.calendar.alerts.DISMISS"
;
public
static
class
AlarmId
{
public
long
mEventId
;
public
long
mStart
;
public
AlarmId
(
long
id
,
long
start
)
{
mEventId
=
id
;
mStart
=
start
;
}
}
/**
* Look for unknown accounts in a set of events and associate with them.
* Returns immediately, processing happens in the background.
*
* @param context application context
* @param eventIds IDs for events that have posted notifications that may be
* dismissed.
*/
public
static
void
processEventIds
(
final
Context
context
,
final
Set
<
Long
>
eventIds
)
{
final
String
senderId
=
context
.
getResources
().
getString
(
R
.
string
.
notification_sender_id
);
if
(
senderId
==
null
||
senderId
.
isEmpty
())
{
Log
.
i
(
TAG
,
"no sender configured"
);
return
;
}
new
AsyncTask
<
Void
,
Void
,
Void
>()
{
@Override
protected
Void
doInBackground
(
Void
...
params
)
{
Map
<
Long
,
Long
>
eventsToCalendars
=
lookupEventToCalendarMap
(
context
,
eventIds
);
Set
<
Long
>
calendars
=
new
LinkedHashSet
<
Long
>();
calendars
.
addAll
(
eventsToCalendars
.
values
());
if
(
calendars
.
isEmpty
())
{
Log
.
d
(
TAG
,
"foudn no calendars for events"
);
return
null
;
}
Map
<
Long
,
Pair
<
String
,
String
>>
calendarsToAccounts
=
lookupCalendarToAccountMap
(
context
,
calendars
);
if
(
calendarsToAccounts
.
isEmpty
())
{
Log
.
d
(
TAG
,
"found no accounts for calendars"
);
return
null
;
}
// filter out non-google accounts (necessary?)
Set
<
String
>
accounts
=
new
LinkedHashSet
<
String
>();
for
(
Pair
<
String
,
String
>
accountPair
:
calendarsToAccounts
.
values
())
{
if
(
GOOGLE_ACCOUNT_TYPE
.
equals
(
accountPair
.
first
))
{
accounts
.
add
(
accountPair
.
second
);
}
}
// filter out accounts we already know about
SharedPreferences
prefs
=
context
.
getSharedPreferences
(
GLOBAL_DISMISS_MANAGER_PREFS
,
Context
.
MODE_PRIVATE
);
Set
<
String
>
existingAccounts
=
prefs
.
getStringSet
(
ACCOUNT_KEY
,
new
HashSet
<
String
>());
accounts
.
removeAll
(
existingAccounts
);
if
(
accounts
.
isEmpty
())
{
return
null
;
}
// subscribe to remaining accounts
CloudNotificationBackplane
cnb
=
ExtensionsFactory
.
getCloudNotificationBackplane
();
if
(
cnb
.
open
(
context
))
{
for
(
String
account
:
accounts
)
{
try
{
cnb
.
subscribeToGroup
(
senderId
,
account
,
account
);
accounts
.
add
(
account
);
}
catch
(
IOException
e
)
{
// Try again, next time the account triggers and alert.
}
}
cnb
.
close
();
prefs
.
edit
()
.
putStringSet
(
ACCOUNT_KEY
,
accounts
)
.
commit
();
}
return
null
;
}
}.
execute
();
}
/**
* Globally dismiss notifications that are backed by the same events.
*
* @param context application context
* @param alarmIds Unique identifiers for events that have been dismissed by the user.
* @return true if notification_sender_id is available
*/
public
static
void
dismissGlobally
(
final
Context
context
,
final
List
<
AlarmId
>
alarmIds
)
{
final
String
senderId
=
context
.
getResources
().
getString
(
R
.
string
.
notification_sender_id
);
if
(
""
.
equals
(
senderId
))
{
Log
.
i
(
TAG
,
"no sender configured"
);
return
;
}
new
AsyncTask
<
Void
,
Void
,
Void
>()
{
@Override
protected
Void
doInBackground
(
Void
...
params
)
{
Set
<
Long
>
eventIds
=
new
HashSet
<
Long
>(
alarmIds
.
size
());
for
(
AlarmId
alarmId:
alarmIds
)
{
eventIds
.
add
(
alarmId
.
mEventId
);
}
// find the mapping between calendars and events
Map
<
Long
,
Long
>
eventsToCalendars
=
lookupEventToCalendarMap
(
context
,
eventIds
);
if
(
eventsToCalendars
.
isEmpty
())
{
Log
.
d
(
TAG
,
"found no calendars for events"
);
return
null
;
}
Set
<
Long
>
calendars
=
new
LinkedHashSet
<
Long
>();
calendars
.
addAll
(
eventsToCalendars
.
values
());
// find the accounts associated with those calendars
Map
<
Long
,
Pair
<
String
,
String
>>
calendarsToAccounts
=
lookupCalendarToAccountMap
(
context
,
calendars
);
if
(
calendarsToAccounts
.
isEmpty
())
{
Log
.
d
(
TAG
,
"found no accounts for calendars"
);
return
null
;
}
// TODO group by account to reduce queries
Map
<
String
,
String
>
syncIdToAccount
=
new
HashMap
<
String
,
String
>();
Map
<
Long
,
String
>
eventIdToSyncId
=
new
HashMap
<
Long
,
String
>();
ContentResolver
resolver
=
context
.
getContentResolver
();
for
(
Long
eventId
:
eventsToCalendars
.
keySet
())
{
Long
calendar
=
eventsToCalendars
.
get
(
eventId
);
Pair
<
String
,
String
>
account
=
calendarsToAccounts
.
get
(
calendar
);
if
(
GOOGLE_ACCOUNT_TYPE
.
equals
(
account
.
first
))
{
Uri
uri
=
asSync
(
Events
.
CONTENT_URI
,
account
.
first
,
account
.
second
);
Cursor
cursor
=
resolver
.
query
(
uri
,
EVENT_SYNC_PROJECTION
,
Events
.
_ID
+
" = "
+
eventId
,
null
,
null
);
try
{
cursor
.
moveToPosition
(-
1
);
int
sync_id_idx
=
cursor
.
getColumnIndex
(
Events
.
_SYNC_ID
);
if
(
sync_id_idx
!=
-
1
)
{
while
(
cursor
.
moveToNext
())
{
String
syncId
=
cursor
.
getString
(
sync_id_idx
);
syncIdToAccount
.
put
(
syncId
,
account
.
second
);
eventIdToSyncId
.
put
(
eventId
,
syncId
);
}
}
}
finally
{
cursor
.
close
();
}
}
}
if
(
syncIdToAccount
.
isEmpty
())
{
Log
.
d
(
TAG
,
"found no syncIds for events"
);
return
null
;
}
// TODO group by account to reduce packets
CloudNotificationBackplane
cnb
=
ExtensionsFactory
.
getCloudNotificationBackplane
();
if
(
cnb
.
open
(
context
))
{
for
(
AlarmId
alarmId:
alarmIds
)
{
String
syncId
=
eventIdToSyncId
.
get
(
alarmId
.
mEventId
);
String
account
=
syncIdToAccount
.
get
(
syncId
);
Bundle
data
=
new
Bundle
();
data
.
putString
(
SYNC_ID
,
syncId
);
data
.
putLong
(
START_TIME
,
alarmId
.
mStart
);
data
.
putString
(
ACCOUNT_NAME
,
account
);
try
{
cnb
.
send
(
account
,
syncId
+
":"
+
alarmId
.
mStart
,
syncId
,
FOUR_WEEKS
,
data
);
}
catch
(
IOException
e
)
{
// TODO save a note to try again later
}
}
cnb
.
close
();
}
return
null
;
}
}.
execute
();
}
private
static
Uri
asSync
(
Uri
uri
,
String
accountType
,
String
account
)
{
return
uri
.
buildUpon
()
.
appendQueryParameter
(
android
.
provider
.
CalendarContract
.
CALLER_IS_SYNCADAPTER
,
"true"
)
.
appendQueryParameter
(
Calendars
.
ACCOUNT_NAME
,
account
)
.
appendQueryParameter
(
Calendars
.
ACCOUNT_TYPE
,
accountType
).
build
();
}
/**
* build a selection over a set of row IDs
*
* @param ids row IDs to select
* @param key row name for the table
* @return a selection string suitable for a resolver query.
*/
private
static
String
buildMultipleIdQuery
(
Set
<
Long
>
ids
,
String
key
)
{
StringBuilder
selection
=
new
StringBuilder
();
boolean
first
=
true
;
for
(
Long
id
:
ids
)
{
if
(
first
)
{
first
=
false
;
}
else
{
selection
.
append
(
" OR "
);
}
selection
.
append
(
key
);
selection
.
append
(
"="
);
selection
.
append
(
id
);
}
return
selection
.
toString
();
}
/**
* @param context application context
* @param eventIds Event row IDs to query.
* @return a map from event to calendar
*/
private
static
Map
<
Long
,
Long
>
lookupEventToCalendarMap
(
final
Context
context
,
final
Set
<
Long
>
eventIds
)
{
Map
<
Long
,
Long
>
eventsToCalendars
=
new
HashMap
<
Long
,
Long
>();
ContentResolver
resolver
=
context
.
getContentResolver
();
String
eventSelection
=
buildMultipleIdQuery
(
eventIds
,
Events
.
_ID
);
Cursor
eventCursor
=
resolver
.
query
(
Events
.
CONTENT_URI
,
EVENT_PROJECTION
,
eventSelection
,
null
,
null
);
try
{
eventCursor
.
moveToPosition
(-
1
);
int
calendar_id_idx
=
eventCursor
.
getColumnIndex
(
Events
.
CALENDAR_ID
);
int
event_id_idx
=
eventCursor
.
getColumnIndex
(
Events
.
_ID
);
if
(
calendar_id_idx
!=
-
1
&&
event_id_idx
!=
-
1
)
{
while
(
eventCursor
.
moveToNext
())
{
eventsToCalendars
.
put
(
eventCursor
.
getLong
(
event_id_idx
),
eventCursor
.
getLong
(
calendar_id_idx
));
}
}
}
finally
{
eventCursor
.
close
();
}
return
eventsToCalendars
;
}
/**
* @param context application context
* @param calendars Calendar row IDs to query.
* @return a map from Calendar to a pair (account type, account name)
*/
private
static
Map
<
Long
,
Pair
<
String
,
String
>>
lookupCalendarToAccountMap
(
final
Context
context
,
Set
<
Long
>
calendars
)
{
Map
<
Long
,
Pair
<
String
,
String
>>
calendarsToAccounts
=
new
HashMap
<
Long
,
Pair
<
String
,
String
>>();
;
ContentResolver
resolver
=
context
.
getContentResolver
();
String
calendarSelection
=
buildMultipleIdQuery
(
calendars
,
Calendars
.
_ID
);
Cursor
calendarCursor
=
resolver
.
query
(
Calendars
.
CONTENT_URI
,
CALENDARS_PROJECTION
,
calendarSelection
,
null
,
null
);
try
{
calendarCursor
.
moveToPosition
(-
1
);
int
calendar_id_idx
=
calendarCursor
.
getColumnIndex
(
Calendars
.
_ID
);
int
account_name_idx
=
calendarCursor
.
getColumnIndex
(
Calendars
.
ACCOUNT_NAME
);
int
account_type_idx
=
calendarCursor
.
getColumnIndex
(
Calendars
.
ACCOUNT_TYPE
);
if
(
calendar_id_idx
!=
-
1
&&
account_name_idx
!=
-
1
&&
account_type_idx
!=
-
1
)
{
while
(
calendarCursor
.
moveToNext
())
{
Long
id
=
calendarCursor
.
getLong
(
calendar_id_idx
);
String
name
=
calendarCursor
.
getString
(
account_name_idx
);
String
type
=
calendarCursor
.
getString
(
account_type_idx
);
calendarsToAccounts
.
put
(
id
,
new
Pair
<
String
,
String
>(
type
,
name
));
}
}
}
finally
{
calendarCursor
.
close
();
}
return
calendarsToAccounts
;
}
@Override
public
void
onReceive
(
Context
context
,
Intent
intent
)
{
boolean
updated
=
false
;
if
(
intent
.
hasExtra
(
SYNC_ID
)
&&
intent
.
hasExtra
(
ACCOUNT_NAME
))
{
String
syncId
=
intent
.
getStringExtra
(
SYNC_ID
);
long
startTime
=
intent
.
getLongExtra
(
START_TIME
,
0L
);
ContentResolver
resolver
=
context
.
getContentResolver
();
Uri
uri
=
asSync
(
Events
.
CONTENT_URI
,
GOOGLE_ACCOUNT_TYPE
,
intent
.
getStringExtra
(
ACCOUNT_NAME
));
Cursor
cursor
=
resolver
.
query
(
uri
,
EVENT_SYNC_PROJECTION
,
Events
.
_SYNC_ID
+
" = '"
+
syncId
+
"'"
,
null
,
null
);
try
{
int
event_id_idx
=
cursor
.
getColumnIndex
(
Events
.
_ID
);
cursor
.
moveToFirst
();
if
(
event_id_idx
!=
-
1
&&
!
cursor
.
isAfterLast
())
{
long
eventId
=
cursor
.
getLong
(
event_id_idx
);
ContentValues
values
=
new
ContentValues
();
String
selection
=
CalendarAlerts
.
STATE
+
"="
+
CalendarAlerts
.
STATE_FIRED
+
" AND "
+
CalendarAlerts
.
EVENT_ID
+
"="
+
eventId
+
" AND "
+
CalendarAlerts
.
BEGIN
+
"="
+
startTime
;
values
.
put
(
CalendarAlerts
.
STATE
,
CalendarAlerts
.
STATE_DISMISSED
);
if
(
resolver
.
update
(
CalendarAlerts
.
CONTENT_URI
,
values
,
selection
,
null
)
>
0
)
{
updated
|=
true
;
}
}
}
finally
{
cursor
.
close
();
}
}
if
(
updated
)
{
Log
.
d
(
TAG
,
"updating alarm state"
);
AlertService
.
updateAlertNotification
(
context
);
}
}
}
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment