theedge 2010: android advanced techniques
DESCRIPTION
TheEdge 2010:The Android platform has matured rapidly during the last two years.We're going to bring you up to speed in the latest cutting edge Android development techniques including: New UI Patterns, supporting multiple screen resolutions, REST clients, Push applications and optimizing your applications.TRANSCRIPT
![Page 1: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/1.jpg)
Advanced Android TechniquesBy: Gilad Garon
![Page 2: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/2.jpg)
2
» This presentation is based onTheEdge 2010 Android Application: Download it from the Market Download the source code:
http://code.google.com/p/theedge2010/for all the examples in this presentation
Before we begin!
TheEdge 2010 Android App
![Page 3: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/3.jpg)
3
» UI Design Patterns» I/O Access» Optimizations
Agenda
![Page 4: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/4.jpg)
UI Design Patterns
![Page 5: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/5.jpg)
5
» Activity» Layouts» Intent
A little reminder about:
UI Design Patterns
![Page 6: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/6.jpg)
6
» Dashboard» Action Bar» Search Bar» Quick Actions» Flingable List Item
“Applications are ahead of the framework”
UI Design Patterns
![Page 7: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/7.jpg)
7
DashboardYou know what they say about First Impressions...
UI Design Patterns
Dashboard
![Page 8: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/8.jpg)
8
» Introduce your application» Reveal its functionality» Update the user» Just a layout, nothing fancy
Dashboard
UI Design Patterns
![Page 9: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/9.jpg)
9
Dashboard Components
UI Design Patterns
Action Bar
Updates Panel
Functionality Panel
![Page 10: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/10.jpg)
10
Implementation
UI Design Patterns
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/background">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="45dip" android:background="@color/action_bar_background"> <!-- Action Bar Code --> </LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"> <!-- Functionality Panel --> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/now_playing" android:layout_width="fill_parent" android:layout_height="90dip" android:orientation="horizontal"> <!-- Update Panel --> </LinearLayout></LinearLayout>
![Page 11: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/11.jpg)
11
Action Bar
UI Design Patterns
Action Bar
![Page 12: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/12.jpg)
12
» Improved Title Bar» Persistent across the application» Includes common actions» Navigation Control
Action Bar
UI Design Patterns
![Page 13: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/13.jpg)
13
Implementation
UI Design Patterns
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="45dip" android:background="@color/action_bar_background"> <ImageButton style="@style/action_bar_button" android:src="@drawable/home_btn_default" android:onClick="onHomeClick"/> <ImageView style="@style/action_bar_separator"/> <TextView style="@style/action_bar_text" android:text="Sessions"/> <ImageView style="@style/action_bar_separator"/> <ImageButton android:id="@+id/search_button" style="@style/action_bar_button" android:src="@drawable/search_button" android:onClick="onSearchClick"/></LinearLayout>
![Page 14: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/14.jpg)
14
Search Bar
UI Design Patterns
Search Bar
![Page 15: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/15.jpg)
15
» Implement search in your app» Persistent across the application» Can be used with the Action Bar» Multiple search modes» A clearer way to filter results
Search Bar
UI Design Patterns
![Page 16: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/16.jpg)
16
» Declare your application as searchable» Declare an activity that handles the search» Handle the search itself
Implementation
UI Design Patterns
![Page 17: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/17.jpg)
17
» Declare in /res/xml/searchable.xml
Searchable Configuration
UI Design Patterns
<?xml version="1.0" encoding="utf-8"?><searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_name" android:hint="Hint" ></searchable>
![Page 18: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/18.jpg)
18
» Declare as Searchable in the AndroidManifest.xml:Searchable Activity
UI Design Patterns
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.alphacsp.theedge" android:versionCode="4" android:versionName="1.03" android:installLocation="preferExternal"> <application android:label="TheEdge 2010" android:icon="@drawable/ic_launcher"> <activity android:name=".ui.activities.SearchActivity" android:label="Search" android:theme="@style/Theme.TheEdge"> <intent-filter> <action android:name="android.intent.action.SEARCH"/> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/> </activity> <activity android:name=".ui.activities.AboutActivity" android:label="About“ android:theme="@style/Theme.TheEdge"/> <meta-data android:name="android.app.default_searchable" android:value=".ui.activities.SearchActivity"/> </manifest>
![Page 19: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/19.jpg)
19
» Handle the Query:Searchable Activity
UI Design Patterns
public class SearchActivity extends TabActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.search_activity); Intent intent = getIntent(); String query = intent.getStringExtra(SearchManager.QUERY); final TabHost host = getTabHost(); Intent speakersIntent = new Intent(SearchActivity.this, SpeakersActivity.class); speakersIntent.putExtra(SearchManager.QUERY, query); host.addTab(host.newTabSpec("Speakers").setIndicator(buildIndicator("Speakers")).setContent(speakersIntent)); Intent sessionsIntent = new Intent(SearchActivity.this, SessionsActivity.class); sessionsIntent.putExtra(SearchManager.QUERY, query); host.addTab(host.newTabSpec("Sessions").setIndicator(buildIndicator("Sessions")).setContent(sessionsIntent)); }
![Page 20: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/20.jpg)
20
Quick ActionsQuick context menu
UI Design Patterns
![Page 21: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/21.jpg)
21
» Contextual actions driven popup menu» Natural flow to the screen context» Simple and effective» Wow effect
Quick Actions
UI Design Patterns
![Page 22: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/22.jpg)
22
» Not in the SDK» Custom Views» Implementation taken from: Lorenz’s Blog
http://www.londatiga.net/it/how-to-create-quickaction-dialog-in-android/
Implementation
UI Design Patterns
![Page 23: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/23.jpg)
23
Flingable List ItemFlingable context menu
UI Design Patterns
![Page 24: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/24.jpg)
24
» Contextual actions driven flinged menu» Natural flow to the screen context» Wow effect
Flingable List Item
UI Design Patterns
![Page 25: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/25.jpg)
25
» Major players: ViewFlipper Layout GestureDetector ListAdaptor ListActivity
Implementation
UI Design Patterns
![Page 26: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/26.jpg)
26
» Vertical scrollable view that allows multiple rows views (List Item)
» Uses ListAdapter to populate each List Item» Recycles Views (So don’t cache them!)» Supports different view types
A few words about ListView
UI Design Patterns
![Page 27: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/27.jpg)
27
» ListView should not hold N Views.» Use ConvertView in getView method:
ListView Recycler
UI Design Patterns
@Overridepublic View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = inflater.inflate(R.layout.speakers_list, parent, false); } //Get your components from the view final TextView speakerName = (TextView) convertView.findViewById(R.id.speaker_name); //Get your item Speaker speaker = getItem(position); return convertView; }
![Page 28: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/28.jpg)
28
ListView Recycler in action
UI Design Patterns
![Page 29: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/29.jpg)
29
ViewFlipper
UI Design Patterns
<ViewFlipper xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include android:id="@+id/first" layout="@layout/sessions_list"/>
<include android:id="@+id/second" layout="@layout/sessions_list_flinged"/>
</ViewFlipper>
» Allows transition between layouts» Supports animations
![Page 30: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/30.jpg)
30
GestureDetector
UI Design Patterns
GestureDetector gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { } @Override public boolean onDown(MotionEvent e) { } @Override public boolean onSingleTapUp(MotionEvent e) { } });
» Detects various gestures and events using the supplied MotionEvents
![Page 31: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/31.jpg)
31
ViewFlipp
er
• Handles layouts switches• Handles animations
ListAdapt
or
• Controls ViewFlipper• Handles gestures detection for the List Item• Handle Buttons presses from View Flipper
ListActivit
y
• Handles scrolling detection• Handles buttons presses
Implementation
UI Design Patterns
Read the Source Code…
![Page 32: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/32.jpg)
32
I/O Access
![Page 33: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/33.jpg)
33
» File System» Database» Network
Types of I/O:
I/O Access
![Page 34: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/34.jpg)
34
» Reading is fast» Writing is slow » Disk space affects performance» Make sure you support External Storage
(Both in installation and in caches/data)
Flash I/O
I/O Access
![Page 35: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/35.jpg)
35
» Virtual Table that allows Full Text Search» Produces results significantly faster than
LIKE» Comprehensive syntax
SQLite FTS
I/O Access
![Page 36: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/36.jpg)
36
» Similar to creating a regular table:Creating FTS table
I/O Access
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "TheEdge";
public static final String SPEAKERS_TABLE = "speakers";
@Language("SQLite")
private static final String CREATE_SPEAKERS_TABLE = "CREATE VIRTUAL TABLE " + SPEAKERS_TABLE + " USING fts3 (speaker_name TEXT , bio TEXT, company TEXT, image_uri TEXT)";
public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
Log.i(this.getClass().getSimpleName(), "Creating DB");
sqLiteDatabase.execSQL(CREATE_SPEAKERS_TABLE);
}
![Page 37: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/37.jpg)
37
» Use the MATCH keyword:Using:
I/O Access
public List<Session> searchSessions(String query) { final List<Session> sessionList = new ArrayList<Session>(); final SQLiteDatabase readableDatabase = getReadableDatabase(); final Cursor cursor = readableDatabase.rawQuery("select * from " + SESSIONS_TABLE + " where " + SESSIONS_TABLE + " match '" + query +
"'", null); if (cursor.moveToFirst()) { do { final Session session = new Session(); session.setTopic(cursor.getString(cursor.getColumnIndex("topic"))); session.setPresenter(cursor.getString(cursor.getColumnIndex("presenter"))); session.setSessionAbstract(cursor.getString(cursor.getColumnIndex("abstract"))); sessionList.add(session); } while (cursor.moveToNext()); } if (!cursor.isClosed()) { cursor.close(); } return sessionList;}
![Page 38: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/38.jpg)
38
» Use a Service» Use Apache HTTPClient not URLConnection» Don’t do it on the UI thread» Parsing can be costly, design your data
structure carefully
Network
I/O Access
![Page 39: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/39.jpg)
39
» Availability:Always check connectivity with ConnectivityManager.
» Performance:Don’t run on the UI Thread, use AsyncTask or Service.
» Bandwidth:Use as little as you can.
» Battery drain:Only use the network when you have to.
When using network, remember the following:
I/O Access
![Page 40: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/40.jpg)
40
I/O Access
Activity.onCreate UI Thread
Fetch data from Database / Files
UI Thread
Populate Activity with persistent data
New Thread
Check network for updates (MD5
hash / last modified header)
New Thread
Fetch new data from network and
persist itUI
ThreadUpdate UI Thread with updated data.
Activity with separate thread for Network
![Page 41: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/41.jpg)
41
Optimization
![Page 42: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/42.jpg)
42
» Allows you to execute a task without having to manage thread pools.» Defined by three generic types: Parameters, Progress and Result.» Has a lifecycle:
onPreExecute – Called before running the task. doInBackground – Actual work onProgressUpdate – Callback to update the UI on task progress onPostExecute – Called after task has ended, receives the
response object» Very smart and easy.
AsyncTask
Optimization
![Page 43: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/43.jpg)
43
» In order to implment lazy loading, we’ll need to do the following:1. Load the ListView an you would normally do.2. Create a task to fetch the data, use
AsyncTask or a Service.3. Change the data on the UI thread.4. Use notifyDataSetChanged() to let ListView
to update itself.
Lazy Loading your ListView
Optimization
![Page 44: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/44.jpg)
44
Example
Optimization
public class SpeakersActivity extends ListActivity implements ServiceListener { private void fetchImages() { for (Speaker speaker : speakers) { SpeakerImageFetcher speakerImageFetcher = new SpeakerImageFetcher(); speakerImageFetcher.execute(speaker); } } private class SpeakerImageFetcher extends AsyncTask<Speaker, Void, Void> { @Override protected Void doInBackground(Speaker... speakers) { final Speaker speaker = speakers[0]; final Bitmap bitmap = dataAccessor.fetchImage(speaker.getImageUrl()); speaker.setSpeakerImage(bitmap); return null; } @Override protected void onPostExecute(Void aVoid) { speakersAdapter.notifyDataSetChanged(); } }}
![Page 45: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/45.jpg)
45
» Runs in the background» Is not killed when the application ends» Running a service is easy» Getting callbacks is a bit awkward» Declare it in your AndroidManifest.xml
Services
Optimization
![Page 46: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/46.jpg)
46
Services oriented application:
Optimization
Activity
Service Helper
Service
Data Accessor
SQLite HttpClient
![Page 47: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/47.jpg)
47
Service Example:
Optimization
public class NetworkService extends IntentService { @Override protected void onHandleIntent(Intent intent) { final DataAccessor dataAccessor = DataAccessor.getSingleton(this); final ResultReceiver receiver = intent.getParcelableExtra(STATUS_LISTENER); final int requestAction = intent.getIntExtra(REFRESH_ACTION, -1); boolean result = false; if (requestAction == REFRESH_SPEAKERS) { result = dataAccessor.syncAllSpeakers(); } else if (requestAction == REFRESH_SESSIONS) { result = dataAccessor.syncAllSessions(); } else if (requestAction == REFRESH_SCHEDULE) { result = dataAccessor.syncAllEvents(); } else if (requestAction == REFRESH_ALL) { dataAccessor.syncAllSpeakers(); dataAccessor.syncAllSessions(); dataAccessor.syncAllEvents(); } if (result) { receiver.send(STATUS_REFRESHED, Bundle.EMPTY); } receiver.send(STATUS_NOT_REFRESHED, Bundle.EMPTY); }}
![Page 48: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/48.jpg)
48
» ResultReceiver: Implements Parcelable, so can be passed
in the Intent object Good for “Here and now” results per
intent
Getting a Callback from a Service:
Optimization
![Page 49: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/49.jpg)
49
» Accepts the Activity as the Listener using a custom interface
ResultReceiver Example
Optimization
public class NetworkServiceHelper extends ResultReceiver {
private final ServiceListener listener;
public NetworkServiceHelper(ServiceListener listener) { super(new Handler()); this.listener = listener; }
@Override protected void onReceiveResult(int resultCode, Bundle resultData) { if (listener != null) { listener.onReceiveResult(resultCode, resultData); } }}
![Page 50: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/50.jpg)
50
Optimization
public class ScheduleActivity extends Activity implements ServiceListener { private NetworkServiceHelper networkServiceHelper;
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.schedule_activity); dataAccessor = DataAccessor.getSingleton(this); initCalendar(); networkServiceHelper = new NetworkServiceHelper(this); final Intent serviceIntent = new Intent(Intent.ACTION_SYNC, null, this, NetworkService.class); serviceIntent.putExtra(NetworkService.STATUS_LISTENER, networkServiceHelper); serviceIntent.putExtra(NetworkService.REFRESH_ACTION, NetworkService.REFRESH_SCHEDULE); startService(serviceIntent); }
@Override public void onReceiveResult(int resultCode, Bundle resultData) { if (resultCode == NetworkService.STATUS_REFRESHED) { calendarLayout.removeAllViews(); initCalendar(); } }}
Using the service:
![Page 51: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/51.jpg)
51
Reference
![Page 52: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/52.jpg)
52
Reference
» http://developer.android.com/guide/index.html» http://www.londatiga.net/it/how-to-create-quickaction-dialog-i
n-android/
» http://code.google.com/p/theedge2010/» http://android-developers.blogspot.com/?hl=en» http://www.google.com/events/io/2010/sessions.html#Android» http://www.sqlite.org/fts3.html» http://www.sqlite.org/cvstrac/wiki/wiki?p=FtsUsage
![Page 53: TheEdge 2010: Android Advanced Techniques](https://reader037.vdocuments.us/reader037/viewer/2022110119/55583db3d8b42acb078b4d52/html5/thumbnails/53.jpg)
53
Thank You!We appreciate your feedback