Restore tag records when re-starting MyTag activity.
[android/platform/packages/apps/Tag.git] / src / com / android / apps / tag / TagList.java
1 /*
2  * Copyright (C) 2010 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.android.apps.tag;
18
19 import com.android.apps.tag.provider.TagContract.NdefMessages;
20
21 import android.app.Activity;
22 import android.app.ListActivity;
23 import android.content.ContentUris;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.database.CharArrayBuffer;
27 import android.database.Cursor;
28 import android.net.Uri;
29 import android.os.AsyncTask;
30 import android.os.Bundle;
31 import android.provider.Browser;
32 import android.text.Html;
33 import android.text.format.DateUtils;
34 import android.view.LayoutInflater;
35 import android.view.View;
36 import android.view.View.OnClickListener;
37 import android.view.ViewGroup;
38 import android.widget.CursorAdapter;
39 import android.widget.ListView;
40 import android.widget.TextView;
41
42 import java.util.Locale;
43
44 /**
45  * An {@link Activity} that displays a flat list of tags that can be "opened".
46  */
47 public class TagList extends ListActivity implements OnClickListener {
48     static final String TAG = "TagList";
49
50     static final String EXTRA_SHOW_STARRED_ONLY = "show_starred_only";
51
52     TagAdapter mAdapter;
53     boolean mShowStarredOnly;
54
55     @Override
56     public void onCreate(Bundle savedInstanceState) {
57         super.onCreate(savedInstanceState);
58
59         setContentView(R.layout.tag_list);
60         findViewById(R.id.more_info).setVisibility(View.GONE);
61
62         mShowStarredOnly = getIntent().getBooleanExtra(EXTRA_SHOW_STARRED_ONLY, false);
63
64         new TagLoaderTask().execute((Void[]) null);
65         mAdapter = new TagAdapter(this);
66         setListAdapter(mAdapter);
67         registerForContextMenu(getListView());
68     }
69
70     @Override
71     protected void onDestroy() {
72         if (mAdapter != null) {
73             mAdapter.changeCursor(null);
74         }
75         super.onDestroy();
76     }
77
78     @Override
79     protected void onListItemClick(ListView l, View v, int position, long id) {
80         Intent intent = new Intent(Intent.ACTION_VIEW,
81                 ContentUris.withAppendedId(NdefMessages.CONTENT_URI, id));
82         startActivity(intent);
83     }
84
85     public void setEmptyView() {
86         TextView empty = (TextView) findViewById(R.id.text);
87         View button = findViewById(R.id.more_info);
88
89         if (mShowStarredOnly) {
90             empty.setText(R.string.empty_list_starred);
91             button.setVisibility(View.GONE);
92         } else {
93             empty.setText(Html.fromHtml(getString(R.string.empty_list)));
94             button.setVisibility(View.VISIBLE);
95             button.setOnClickListener(this);
96         }
97     }
98
99     private static String replaceLocale(String str) {
100         // Substitute locale if present in string
101         if (str.contains("%locale%")) {
102             Locale locale = Locale.getDefault();
103             str = str.replace("%locale%", locale.getLanguage());
104         }
105         return str;
106     }
107
108     @Override
109     public void onClick(View view) {
110         Uri uri = Uri.parse(replaceLocale(getString(R.string.more_info_url)));
111         Intent intent = new Intent(Intent.ACTION_VIEW, uri);
112         intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
113         startActivity(intent);
114     }
115
116     interface TagQuery {
117         static final String[] PROJECTION = new String[] {
118                 NdefMessages._ID, // 0
119                 NdefMessages.DATE, // 1
120                 NdefMessages.TITLE, // 2
121                 NdefMessages.STARRED, // 3
122         };
123
124         static final int COLUMN_ID = 0;
125         static final int COLUMN_DATE = 1;
126         static final int COLUMN_TITLE = 2;
127         static final int COLUMN_STARRED = 3;
128     }
129
130     /**
131      * Asynchronously loads the tag info from the database.
132      */
133     final class TagLoaderTask extends AsyncTask<Void, Void, Cursor> {
134         @Override
135         public Cursor doInBackground(Void... args) {
136             String selection = mShowStarredOnly ? NdefMessages.STARRED + "=1" : null;
137             Cursor cursor = getContentResolver().query(
138                     NdefMessages.CONTENT_URI,
139                     TagQuery.PROJECTION,
140                     selection,
141                     null, NdefMessages.DATE + " DESC");
142
143             // Ensure the cursor executes and fills its window
144             if (cursor != null) cursor.getCount();
145             return cursor;
146         }
147
148         @Override
149         protected void onPostExecute(Cursor cursor) {
150             if (cursor == null || cursor.getCount() == 0) {
151                 // Don't setup the empty view until after the first load
152                 // so the empty text doesn't flash when first loading the
153                 // activity.
154                 setEmptyView();
155             }
156             mAdapter.changeCursor(cursor);
157         }
158     }
159
160     /**
161      * Struct to hold pointers to views in the list items to save time at view binding time.
162      */
163     static final class ViewHolder {
164         public CharArrayBuffer titleBuffer;
165         public TextView mainLine;
166         public TextView dateLine;
167     }
168
169     /**
170      * Adapter to display the tag entries.
171      */
172     public class TagAdapter extends CursorAdapter {
173         private final LayoutInflater mInflater;
174
175         public TagAdapter(Context context) {
176             super(context, null, false);
177             mInflater = LayoutInflater.from(context);
178         }
179
180         @Override
181         public void bindView(View view, Context context, Cursor cursor) {
182             ViewHolder holder = (ViewHolder) view.getTag();
183
184             CharArrayBuffer buf = holder.titleBuffer;
185             cursor.copyStringToBuffer(TagQuery.COLUMN_TITLE, buf);
186             holder.mainLine.setText(buf.data, 0, buf.sizeCopied);
187
188             holder.dateLine.setText(DateUtils.getRelativeTimeSpanString(
189                     context, cursor.getLong(TagQuery.COLUMN_DATE)));
190         }
191
192         @Override
193         public View newView(Context context, Cursor cursor, ViewGroup parent) {
194             View view = mInflater.inflate(R.layout.tag_list_item, null);
195
196             // Cache items for the view
197             ViewHolder holder = new ViewHolder();
198             holder.titleBuffer = new CharArrayBuffer(64);
199             holder.mainLine = (TextView) view.findViewById(R.id.title);
200             holder.dateLine = (TextView) view.findViewById(R.id.date);
201             view.setTag(holder);
202
203             return view;
204         }
205
206         @Override
207         public void onContentChanged() {
208             // Kick off an async query to refresh the list
209             new TagLoaderTask().execute((Void[]) null);
210         }
211     }
212 }