1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.codelab.rssexample; 18 19 import android.app.Activity; 20 import android.content.ContentValues; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.database.Cursor; 24 import android.graphics.Typeface; 25 import android.net.Uri; 26 import android.os.Bundle; 27 import android.view.Menu; 28 import android.view.View; 29 import android.view.ViewGroup; 30 import android.webkit.WebView; 31 import android.widget.AdapterView; 32 import android.widget.ListView; 33 import android.widget.SimpleCursorAdapter; 34 import android.widget.TextView; 35 import android.widget.AdapterView.OnItemSelectedListener; 36 37 import java.util.logging.Logger; 38 39 public class MyRssReader5 extends Activity implements OnItemSelectedListener { 40 41 private ListView mRssList; 42 private Cursor mCur; 43 private RssCursorAdapter mAdap; 44 private WebView mWebView; 45 private static final int ADD_ELEMENT_REQUEST = 1; 46 private Logger mLogger = Logger.getLogger(this.getPackageName()); 47 48 @Override onCreate(Bundle savedInstanceState)49 public void onCreate(Bundle savedInstanceState) { 50 super.onCreate(savedInstanceState); 51 // 52 // Load screen layout. 53 setContentView(R.layout.main_screen2); 54 55 // Populate ArrayAdapter and bind it to ListView 56 mRssList = (ListView)findViewById(R.id.rssListView); 57 mRssList.setOnItemSelectedListener(this); 58 59 mWebView = (WebView)findViewById(R.id.rssWebView); 60 61 mCur = managedQuery(RssContentProvider.CONTENT_URI, // Query for all items. 62 null, 63 null, 64 RssContentProvider.DEFAULT_SORT_ORDER); 65 66 mAdap = new RssCursorAdapter( 67 this, 68 R.layout.list_element, // Our layout resource. 69 mCur, 70 new String[]{RssContentProvider.TITLE}, // Columns to retrieve. 71 new int[]{R.id.list_item}); // IDs of widgets to display 72 mRssList.setAdapter(mAdap); // the corresponding column. 73 74 // Set the last selected item. 75 // (icicle is only set if this is being restarted). 76 if(savedInstanceState != null && savedInstanceState.containsKey("lastIndexItem")){ 77 mRssList.setSelection(savedInstanceState.getInteger("lastIndexItem")); 78 } 79 } 80 81 //BEGIN_INCLUDE(5_4) 82 // Listener to listen for list selection changes, and send the new text to 83 // the web view. onItemSelected(AdapterView parent, View v, int position, long id)84 public void onItemSelected(AdapterView parent, View v, int position, long id){ 85 // Need to nest this in a try block because we get called sometimes 86 // with the index of a recently deleted item. 87 String content = ""; 88 try{ 89 content = mCur.getString(mCur.getColumnIndex(RssContentProvider.CONTENT)); 90 mLogger.info("MyRssReader5 content string:" + content); 91 } 92 catch (Exception e){ 93 // This method is sometimes called after a backing data item 94 // is deleted. In that case, we don't want to throw an error. 95 mLogger.warning("MyRssReader5.onItemSelected() couldn't get the content" + 96 "from the cursor " + e.getMessage()); 97 } 98 mWebView.loadData(content, "text/html", null); 99 } 100 //END_INCLUDE(5_4) 101 onNothingSelected(AdapterView parent)102 public void onNothingSelected(AdapterView parent){ 103 mWebView.loadData("<html><body><p>No selection chosen</p></body></html>", "text/html", null); 104 } 105 106 // Store our state before we are potentially bumped from memory. 107 // We'd like to store the current ListView selection. 108 @Override onSaveInstanceState(Bundle outState)109 protected void onSaveInstanceState(Bundle outState){ 110 int index = mRssList.getSelectedItemIndex(); 111 if(index > -1){ 112 outState.putInteger("lastIndexItem", index); 113 } 114 } 115 116 // Add our initial menu options. We will tweak this menu when it's loaded swap out 117 // "start service" or "stop service", depending on whether the service is currently running. 118 @Override onCreateOptionsMenu(Menu menu)119 public boolean onCreateOptionsMenu(Menu menu){ 120 // Always call the superclass implementation to 121 // provide standard items. 122 super.onCreateOptionsMenu(menu); 123 124 menu.add(0, 0, R.string.menu_option_start, null); 125 menu.add(0, 1, R.string.menu_option_stop, null); 126 menu.add(0, 2, R.string.menu_option_add, null); 127 menu.add(0, 3, R.string.menu_option_delete, null); 128 menu.add(0, 4, R.string.menu_option_update, null); 129 130 return true; 131 } 132 133 // Toggle out start service/stop service depending on whether the service is running. 134 @Override onPrepareOptionsMenu(Menu menu)135 public boolean onPrepareOptionsMenu(Menu menu){ 136 return true; 137 } 138 139 // Handle our menu clicks. 140 @Override onOptionsItemSelected(Menu.Item item)141 public boolean onOptionsItemSelected(Menu.Item item){ 142 super.onOptionsItemSelected(item); 143 144 switch (item.getId()){ 145 case 0: // Start service 146 Intent basicStartIntent = new Intent(RssService.class); 147 startService(basicStartIntent); 148 break; 149 case 1: // Stop service 150 Intent stopIntent = new Intent(RssService.class); 151 stopService(stopIntent); 152 break; 153 case 2: // Add Item 154 Intent addIntent = new Intent(AddRssItem.class); 155 // Use an ID so that if we create a "remove item" form we 156 // can tell which form is returning a value. 157 startActivityForResult(addIntent, ADD_ELEMENT_REQUEST); 158 break; 159 case 3: // Delete item. 160 if(mRssList.hasFocus()){ 161 int currentSelectionIndex = mRssList.getSelectedItemIndex(); 162 mLogger.info("MyRssReader5.onOptionsItemSelected(): Deleting list member:" + 163 mRssList.getSelectedItemIndex()); 164 // Create our content URI by adding the ID of the currently selected item using a 165 // convenience method. 166 Long itemID = mAdap.getItemId(currentSelectionIndex); 167 getContentResolver().delete(RssContentProvider.CONTENT_URI.addId(itemID), null); 168 } 169 break; 170 case 4: // Requery all 171 Bundle startupVals = new Bundle(1); 172 startupVals.putBoolean(RssService.REQUERY_KEY, true); 173 Intent requeryIntent = new Intent(RssService.class); 174 startService(requeryIntent, startupVals); 175 break; 176 default: 177 showAlert(null, "I have no idea what you clicked!", "ok", null, false, null); 178 break; 179 } 180 return true; 181 } 182 183 // Called by the "Add RSS Item" floating screen when it closes. 184 @Override onActivityResult(int requestCode, int resultCode, Intent data)185 protected void onActivityResult(int requestCode, int resultCode, Intent data){ 186 if(resultCode == RESULT_OK){ 187 switch (requestCode){ 188 case ADD_ELEMENT_REQUEST: 189 ContentValues vals = new ContentValues(5); 190 vals.put(RssContentProvider.TITLE, data.getStringExtra(RssContentProvider.TITLE)); 191 vals.put(RssContentProvider.URL, data.getStringExtra(RssContentProvider.URL)); 192 vals.put(RssContentProvider.CONTENT, data.getStringExtra(RssContentProvider.CONTENT)); 193 vals.put(RssContentProvider.LAST_UPDATED, data.getIntExtra(RssContentProvider.LAST_UPDATED, 0)); 194 Uri uri = getContentResolver().insert( 195 RssContentProvider.CONTENT_URI, 196 vals); 197 if(uri != null){ 198 // Tell the service to requery the service, then set 199 // it as the active selection. 200 Bundle startupVals = new Bundle(1); 201 startupVals.putString(RssService.RSS_URL, data.getStringExtra("URL")); 202 Intent startIntent = new Intent(RssService.class); 203 startIntent.putExtras(startupVals); 204 startService(startIntent); 205 mRssList.setSelection(mRssList.getCount() - 1); 206 } 207 break; 208 default: 209 break; 210 } 211 } 212 } 213 214 // Our private ArrayAdapter implementation that returns a bold TextView for 215 // RSS items that are unread, or a normal TextView for items that have been read. 216 private class RssCursorAdapter extends SimpleCursorAdapter { RssCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to)217 public RssCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { 218 super(context, layout, c, from, to); 219 } 220 221 // Here's our only important override--returning the list item. 222 @Override getView(int position, View convertView, ViewGroup parent)223 public View getView(int position, View convertView, ViewGroup parent){ 224 TextView view = (TextView)super.getView(position, convertView, parent); 225 226 if(view != null){ 227 228 // Now get the hasBeenRead value to determine the font. 229 int hasBeenReadColumnIndex = getCursor().getColumnIndex(RssContentProvider.HAS_BEEN_READ); 230 boolean hasBeenRead = (getCursor().getInt(hasBeenReadColumnIndex) == 1 ? true : false); 231 if(! hasBeenRead){ 232 Typeface type = view.getTypeface(); 233 view.setTypeface(Typeface.create(type, Typeface.BOLD_ITALIC)); 234 } 235 } 236 return view; 237 } 238 } 239 240 } 241 242