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