aboutsummaryrefslogtreecommitdiffstats
path: root/cgeo-calendar/src/cgeo/calendar/CalendarActivity.java
blob: 15b587292f4947f8688066207a39c0750f003ea6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
package cgeo.calendar;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.text.Html;
import android.text.Spanned;
import android.text.style.ImageSpan;
import android.util.Log;
import android.util.SparseArray;
import android.view.Gravity;
import android.widget.Toast;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Date;

public final class CalendarActivity extends Activity {
    private static final String LOG_TAG = "cgeo.calendar";
    private String shortDesc;
    private String hiddenDate;
    private String url;
    private String personalNote;
    private String name;
    private String location;
    private String coords;
    private Uri uri;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try {
            uri = getIntent().getData();
            if (uri == null) {
                finish();
                return;
            }
            shortDesc = getParameter(ICalendar.PARAM_SHORT_DESC);
            hiddenDate = getParameter(ICalendar.PARAM_HIDDEN_DATE);
            url = getParameter(ICalendar.PARAM_URL);
            personalNote = getParameter(ICalendar.PARAM_NOTE);
            name = getParameter(ICalendar.PARAM_NAME);
            location = getParameter(ICalendar.PARAM_LOCATION);
            coords = getParameter(ICalendar.PARAM_COORDS);

            if (name.length() > 0 && hiddenDate.length() > 0) {
                if (Compatibility.isLevel14()) {
                    addToCalendarLevel14();
                    finish();
                } else {
                    selectCalendarForAdding();
                }
            }
        } catch (Exception e) {
            Log.e(LOG_TAG, e.getMessage(), e);
            finish();
        }
    }

    private String getParameter(final String paramKey) {
        try {
            final String param = uri.getQueryParameter(paramKey);
            if (param == null) {
                return "";
            }
            return URLDecoder.decode(param, "UTF-8").trim();
        } catch (UnsupportedEncodingException e) {
        }
        return "";
    }

    /**
     * Adds the cache to the Android-calendar if it is an event.
     */
    private void selectCalendarForAdding() {
        final String[] projection = new String[] { "_id", "displayName" };
        final Uri calendarProvider = Compatibility.getCalendarProviderURI();

        final Cursor cursor = managedQuery(calendarProvider, projection, "selected=1", null, null);

        if (cursor == null || cursor.getCount() <= 0) {
            showToast(getResources().getString(R.string.event_fail));
            finish();
            return;
        }

        final SparseArray<String> calendars = new SparseArray<String>();
        cursor.moveToFirst();

        final int indexId = cursor.getColumnIndex("_id");
        final int indexName = cursor.getColumnIndex("displayName");

        do {
            final String idString = cursor.getString(indexId);
            if (idString != null) {
                try {
                    int id = Integer.parseInt(idString);
                    final String calName = cursor.getString(indexName);

                    if (id > 0 && calName != null) {
                        calendars.put(id, calName);
                    }
                } catch (NumberFormatException e) {
                    Log.e(LOG_TAG, "CalendarActivity.selectCalendarForAdding", e);
                }
            }
        } while (cursor.moveToNext());

        if (calendars.size() == 0) {
            showToast(getResources().getString(R.string.event_fail));
            finish();
            return;
        }

        final String[] items = new String[calendars.size()];
        for (int i = 0; i < calendars.size(); i++) {
            items[i] = calendars.valueAt(i);
        }

        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.calendars);
        builder.setItems(items, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {
                final int calendarId = calendars.keyAt(item);
                addToCalendar(calendarId);
                finish();
            }
        });
        builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                finish();
            }
        });
        builder.create().show();
    }

    /**
     * @return <code>Date</code> based on hidden date. Time is set to 00:00:00.
     */
    private Date parseDate() {
        final Date eventDate = new Date(Long.parseLong(hiddenDate));
        eventDate.setHours(0);
        eventDate.setMinutes(0);
        eventDate.setSeconds(0);

        return eventDate;
    }

    /**
     * @return description string with images removed and personal note included
     */
    private String parseDescription() {
        final StringBuilder description = new StringBuilder();
        description.append(url);
        if (shortDesc.length() > 0) {
            // remove images in short description
            final Spanned spanned = Html.fromHtml(shortDesc, null, null);
            String text = spanned.toString();
            final ImageSpan[] spans = spanned.getSpans(0, spanned.length(), ImageSpan.class);
            for (int i = spans.length - 1; i >= 0; i--) {
                text = text.substring(0, spanned.getSpanStart(spans[i])) + text.substring(spanned.getSpanEnd(spans[i]));
            }
            if (text.length() > 0) {
                description.append("\n\n");
                description.append(text);
            }
        }

        if (personalNote.length() > 0) {
            description.append("\n\n").append(Html.fromHtml(personalNote).toString());
        }

        return description.toString();
    }

    /**
     * @return location string with coordinates and location
     */
    private String parseLocation() {
        final StringBuilder locBuffer = new StringBuilder();
        if (coords.length() > 0) {
            locBuffer.append(coords);
        }
        if (location.length() > 0) {
            boolean addParentheses = false;
            if (locBuffer.length() > 0) {
                addParentheses = true;
                locBuffer.append(" (");
            }

            locBuffer.append(Html.fromHtml(location).toString());
            if (addParentheses) {
                locBuffer.append(')');
            }
        }

        return locBuffer.toString();
    }

    /**
     * @param calendarId
     *            The selected calendar
     */
    private void addToCalendar(int calendarId) {
        try {
            final Uri calendarProvider = Compatibility.getCalendarEventsProviderURI();

            final Date eventDate = parseDate();
            final String description = parseDescription();
            final String eventLocation = parseLocation();

            // values
            final ContentValues event = new ContentValues();
            event.put("calendar_id", calendarId);
            event.put("dtstart", eventDate.getTime() + 43200000); // noon
            event.put("dtend", eventDate.getTime() + 43200000 + 3600000); // + one hour
            event.put("eventTimezone", "UTC");
            event.put("title", Html.fromHtml(name).toString());
            event.put("description", description);

            if (eventLocation.length() > 0) {
                event.put("eventLocation", eventLocation);
            }
            event.put("allDay", 1);
            event.put("hasAlarm", 0);

            getContentResolver().insert(calendarProvider, event);

            showToast(getResources().getString(R.string.event_success));
        } catch (Exception e) {
            showToast(getResources().getString(R.string.event_fail));

            Log.e(LOG_TAG, "CalendarActivity.addToCalendarFn", e);
        }
    }

    /**
     * Add cache to calendar in Android versions 4.0 and greater using <code>Intent</code>. This does not require
     * calendar permissions.
     * TODO Does this work with apps other than default calendar app?
     */
    private void addToCalendarLevel14() {
        try {
            final Date eventDate = parseDate();
            final String description = parseDescription();
            final String eventLocation = parseLocation();

            /*
             * TODO These strings are available as constants starting with API 14 and can be used when
             * targetSdkVersion changes to 14. For example CalendarContract.EXTRA_EVENT_BEGIN_TIME and
             * Events.TITLE
             */
            final Intent intent = new Intent(Intent.ACTION_INSERT)
                    .setData(Compatibility.getCalendarEventsProviderURI())
                    .putExtra("beginTime", eventDate.getTime() + 43200000)
                    .putExtra("allDay", true)
                    .putExtra("title", Html.fromHtml(name).toString())
                    .putExtra("description", description)
                    .putExtra("hasAlarm", false)
                    .putExtra("eventTimezone", "UTC")
                    .putExtra("eventLocation", eventLocation);
            startActivity(intent);
        } catch (Exception e) {
            showToast(getResources().getString(R.string.event_fail));

            Log.e(LOG_TAG, "CalendarActivity.addToCalendarLevel14: " + e.toString());
        }
    }

    public final void showToast(final String text) {
        final Toast toast = Toast.makeText(this, text, Toast.LENGTH_LONG);

        toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 100);
        toast.show();
    }

}