diff options
author | Andy Doan <andy.doan@linaro.org> | 2011-10-25 11:30:55 -0500 |
---|---|---|
committer | Andy Doan <andy.doan@linaro.org> | 2011-10-25 11:30:55 -0500 |
commit | a753db33fbac98355ff7696c48a305f0a4fe7374 (patch) | |
tree | db00cec18186c596c1029ccefcadf0f6dfa75318 | |
parent | 47b8ed2a481aca9fc0d6b60c4c9d9a22ab4add9e (diff) | |
download | LinaroConnect-a753db33fbac98355ff7696c48a305f0a4fe7374.tar.gz |
add a new activity for displaying ical schedules
-rw-r--r-- | AndroidManifest.xml | 8 | ||||
-rw-r--r-- | res/layout/schedule_item.xml | 29 | ||||
-rw-r--r-- | src/org/linaro/connect/ScheduleActivity.java | 141 | ||||
-rw-r--r-- | src/org/linaro/connect/sched/ScheduleItem.java | 171 |
4 files changed, 349 insertions, 0 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 80484f7..eb5b651 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -38,6 +38,14 @@ <data android:scheme="http"/> </intent-filter> </activity> + <activity android:name=".ScheduleActivity" + android:label="@string/app_name"> + <intent-filter> + <action android:name="org.linaro.connect.SCHEDULE" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:scheme="http"/> + </intent-filter> + </activity> </application> </manifest>
\ No newline at end of file diff --git a/res/layout/schedule_item.xml b/res/layout/schedule_item.xml new file mode 100644 index 0000000..288bb19 --- /dev/null +++ b/res/layout/schedule_item.xml @@ -0,0 +1,29 @@ +<?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="wrap_content" + android:orientation="vertical" + android:background="@drawable/list_selector"> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:background="@drawable/rounded"> + + <TextView android:id="@+id/schedule_summary" + android:layout_height="wrap_content" + android:layout_width="match_parent" + android:paddingLeft = "6px" + android:textColor="@color/linaro_green" + android:textSize="12sp" + /> + <TextView android:id="@+id/schedule_time" + android:layout_height="wrap_content" + android:layout_width="match_parent" + android:paddingLeft = "12px" + android:textSize="10sp" + android:textColor="@color/light_text" + /> +</LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/src/org/linaro/connect/ScheduleActivity.java b/src/org/linaro/connect/ScheduleActivity.java new file mode 100644 index 0000000..0e13f3c --- /dev/null +++ b/src/org/linaro/connect/ScheduleActivity.java @@ -0,0 +1,141 @@ +package org.linaro.connect; + +import java.io.InputStream; + +import org.linaro.connect.sched.ScheduleItem; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ListView; +import android.widget.TextView; + +public class ScheduleActivity extends Activity { + + private static final int REFRESH_ID = Menu.FIRST + 1; + + private ScheduleAdapter mAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); + super.onCreate(savedInstanceState); + + setContentView(R.layout.main); + + Intent i = getIntent(); + String label = i.getStringExtra(JSONLayoutItem.INTENT_LABEL); + String title = getTitle() + " - " + label; + setTitle(title); + + ListView lv = (ListView) findViewById(R.id.connect_items); + mAdapter = new ScheduleAdapter(); + lv.setAdapter(mAdapter); + lv.setOnItemClickListener(mClickListener); + } + + @Override + protected void onResume() { + super.onResume(); + mAdapter.refresh(false); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + boolean result = super.onCreateOptionsMenu(menu); + + MenuItem item = menu.add(0, REFRESH_ID, 0, R.string.posting_refresh); + item.setIcon(R.drawable.ic_menu_refresh); + + return result; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == REFRESH_ID) { + mAdapter.refresh(true); + return true; + } + return super.onOptionsItemSelected(item); + } + + private class ScheduleAdapter extends CachedLayoutAdapter<ScheduleItem, ScheduleItem[]> { + + private final static long INTERVAL = 1000*60*10; //check every 10 minutes + + private final ScheduleItem.Filter mFilter; + + ScheduleAdapter() { + super(getApplicationContext(), R.layout.schedule_item, R.id.schedule_summary); + setRefreshInterval(INTERVAL); + + Uri uri = getIntent().getData(); + + String day = uri.getQueryParameter("day"); + String track = uri.getQueryParameter("track"); + mFilter = new ScheduleItem.Filter(day, track); + + String url = getIntent().getDataString(); + int idx = url.indexOf('?'); + if(idx > 0) + url = url.substring(0, idx); + + setUrl(url); + } + + @Override + protected void updateLayout(ScheduleItem items[]) { + clear(); + if(items == null) + return; + + for(ScheduleItem si: items) + add(si); + } + + @Override + protected ScheduleItem[] getItems() { + InputStream is = getInputStream(); + return ScheduleItem.fromInputStream(is, mFilter); + }; + + private void setTextView(View v, int id, String s) { + TextView tv = (TextView)v.findViewById(id); + tv.setText(s); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View v = super.getView(position, convertView, parent); + ScheduleItem si = getItem(position); + setTextView(v, R.id.schedule_time, si.getStartTime()); + return v; + } + + @Override + protected void onBusy(boolean busy) { + setProgressBarIndeterminateVisibility(busy); + } + } + + private final OnItemClickListener mClickListener = new OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> parent, View v, int pos, long id) + { + ScheduleItem si = mAdapter.getItem(pos); + if( si != null ) { + Intent i = si.getIntent(getApplicationContext()); + if( i != null) + startActivityForResult(i, 0); + } + } + }; +} diff --git a/src/org/linaro/connect/sched/ScheduleItem.java b/src/org/linaro/connect/sched/ScheduleItem.java new file mode 100644 index 0000000..debf206 --- /dev/null +++ b/src/org/linaro/connect/sched/ScheduleItem.java @@ -0,0 +1,171 @@ +package org.linaro.connect.sched; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; + +import org.linaro.connect.LinaroConnect; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.text.format.Time; +import android.util.Log; + +public class ScheduleItem implements Serializable { + + private final HashMap<String, String> mFields; + + private ScheduleItem() { + mFields = new HashMap<String, String>(); + } + + private void addField(String key, String val) { + mFields.put(key, val); + } + + public String getSummary() { + return mFields.get("SUMMARY"); + } + + public String getDescription() { + return mFields.get("DESCRIPTION"); + } + + public String getLocation() { + return mFields.get("LOCATION"); + } + + public String getCategory() { + return mFields.get("CATEGORIES"); + } + + public String getUrl() { + return mFields.get("URL"); + } + + public Uri getUri() { + return Uri.parse(getUrl()); + } + + private Date getDate(String field) { + String s = mFields.get(field); + Time t = new Time(); + t.parse(s); + return new Date(t.toMillis(false)); + } + + public String getStartTime() { + return getDate("DTSTART").toLocaleString(); + } + + @Override + public String toString() { + return getSummary(); + } + + private boolean matches(Filter f) { + if( f == null ) + return true; + + boolean matches = true; + + if(matches && f.dayOfWeek != -1) { + Date d = getDate("DTSTART"); + Calendar c = Calendar.getInstance(); + c.setTime(d); + matches = (c.get(Calendar.DAY_OF_WEEK) == f.dayOfWeek); + } + + if( matches && f.track != null ) + matches = f.track.equals(getCategory()); + + return matches; + } + + public Intent getIntent(Context ctx) { + return null; + } + + private static ScheduleItem parseLine(String line, ScheduleItem cur, + List<ScheduleItem> items, + Filter f) { + if( "BEGIN:VEVENT".equals(line) ) { + cur = new ScheduleItem(); + } + else if( "END:VEVENT".equals(line) ) { + if(cur != null && cur.matches(f)) + items.add(cur); + cur = null; + } + else if( cur != null ) { + String parts[] = line.split(":", 2); + if( parts.length > 1 ) + cur.addField(parts[0], parts[1]); + } + return cur; + } + + private static int getDayOfWeek(String day) { + if( "monday".equalsIgnoreCase(day)) + return Calendar.MONDAY; + else if( "tuesday".equalsIgnoreCase(day)) + return Calendar.TUESDAY; + else if( "wednesday".equalsIgnoreCase(day)) + return Calendar.WEDNESDAY; + else if( "thursday".equalsIgnoreCase(day)) + return Calendar.THURSDAY; + else if( "friday".equalsIgnoreCase(day)) + return Calendar.FRIDAY; + else if( "saturday".equalsIgnoreCase(day)) + return Calendar.SATURDAY; + else if( "sunday".equalsIgnoreCase(day)) + return Calendar.SUNDAY; + return -1; + } + + public static class Filter { + int dayOfWeek = -1; + String track = null; + + public Filter(String day, String track) { + dayOfWeek = getDayOfWeek(day); + this.track = track; + } + } + + /** + * Takes an iCal input stream and returns corresponding objects. If a filter + * is provided it will narrow down results based on it + */ + public static ScheduleItem[] fromInputStream(InputStream is, Filter f) { + ArrayList<ScheduleItem> items = new ArrayList<ScheduleItem>(); + + if (is == null) + return new ScheduleItem[0]; + + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + try { + String line; + ScheduleItem cur = null; + while( (line=br.readLine()) != null ) + cur = parseLine(line, cur, items, f); + } + catch(IOException e) { + Log.e(LinaroConnect.TAG, "Error reading schedule input stream", e); + } + + try { + br.close(); + } catch (IOException e) {} + + return items.toArray(new ScheduleItem[items.size()]); + } +} |