notecipher / app / src / info / guardianproject / notepadbot / NoteCipher.java @ 61b66389
History | View | Annotate | Download (16.4 KB)
| 1 |
/*
|
|---|---|
| 2 |
* Copyright (C) 2008 Google Inc.
|
| 3 |
*
|
| 4 |
* Licensed under the Apache License, Version 2.0 (the "License")savedInstanceState;
|
| 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 info.guardianproject.notepadbot; |
| 18 |
|
| 19 |
import android.app.AlertDialog; |
| 20 |
import android.content.ContentResolver; |
| 21 |
import android.content.Context; |
| 22 |
import android.content.DialogInterface; |
| 23 |
import android.content.Intent; |
| 24 |
import android.content.res.Configuration; |
| 25 |
import android.database.Cursor; |
| 26 |
import android.net.Uri; |
| 27 |
import android.os.Bundle; |
| 28 |
import android.support.v4.app.LoaderManager; |
| 29 |
import android.support.v4.content.CursorLoader; |
| 30 |
import android.support.v4.content.Loader; |
| 31 |
import android.support.v4.widget.SimpleCursorAdapter; |
| 32 |
import android.util.Log; |
| 33 |
import android.view.ContextMenu; |
| 34 |
import android.view.ContextMenu.ContextMenuInfo; |
| 35 |
import android.view.MotionEvent; |
| 36 |
import android.view.View; |
| 37 |
import android.view.View.OnTouchListener; |
| 38 |
import android.widget.AdapterView; |
| 39 |
import android.widget.AdapterView.AdapterContextMenuInfo; |
| 40 |
import android.widget.AdapterView.OnItemClickListener; |
| 41 |
import android.widget.ListView; |
| 42 |
import android.widget.TextView; |
| 43 |
import android.widget.Toast; |
| 44 |
|
| 45 |
import com.actionbarsherlock.app.SherlockFragmentActivity; |
| 46 |
import com.actionbarsherlock.view.Menu; |
| 47 |
import com.actionbarsherlock.view.MenuItem; |
| 48 |
|
| 49 |
import info.guardianproject.cacheword.CacheWordActivityHandler; |
| 50 |
import info.guardianproject.cacheword.ICacheWordSubscriber; |
| 51 |
|
| 52 |
import net.sqlcipher.database.SQLiteDatabase; |
| 53 |
|
| 54 |
import java.io.FileNotFoundException; |
| 55 |
import java.io.IOException; |
| 56 |
import java.io.InputStream; |
| 57 |
|
| 58 |
public class NoteCipher extends SherlockFragmentActivity implements ICacheWordSubscriber { |
| 59 |
|
| 60 |
private static final int ACTIVITY_CREATE = 0; |
| 61 |
private static final int ACTIVITY_EDIT = 1; |
| 62 |
|
| 63 |
private static final int INSERT_ID = Menu.FIRST; |
| 64 |
private static final int DELETE_ID = Menu.FIRST + 1; |
| 65 |
private static final int REKEY_ID = Menu.FIRST + 2; |
| 66 |
private static final int SHARE_ID = Menu.FIRST + 3; |
| 67 |
private static final int VIEW_ID = Menu.FIRST + 4; |
| 68 |
private static final int LOCK_ID = Menu.FIRST + 5; |
| 69 |
private static final int SETTINGS_ID = Menu.FIRST + 6; |
| 70 |
|
| 71 |
public static final String TAG = "notecipher"; |
| 72 |
|
| 73 |
private NotesDbAdapter mDbHelper;
|
| 74 |
|
| 75 |
private Uri dataStream;
|
| 76 |
|
| 77 |
private final static int MAX_SIZE = 1000000; |
| 78 |
|
| 79 |
private CacheWordActivityHandler mCacheWord;
|
| 80 |
|
| 81 |
private ListView notesListView; |
| 82 |
private SimpleCursorAdapter notesCursorAdapter;
|
| 83 |
|
| 84 |
/** Called when the activity is first created. */
|
| 85 |
@Override
|
| 86 |
public void onCreate(Bundle savedInstanceState) { |
| 87 |
super.onCreate(savedInstanceState);
|
| 88 |
|
| 89 |
if (getIntent() != null) { |
| 90 |
if (getIntent().hasExtra(Intent.EXTRA_STREAM)) {
|
| 91 |
dataStream = (Uri) getIntent().getExtras().get(Intent.EXTRA_STREAM); |
| 92 |
} else {
|
| 93 |
dataStream = getIntent().getData(); |
| 94 |
} |
| 95 |
} |
| 96 |
|
| 97 |
SQLiteDatabase.loadLibs(this);
|
| 98 |
setContentView(R.layout.notes_list); |
| 99 |
notesListView = (ListView) findViewById(R.id.notesListView);
|
| 100 |
notesListView.setOnItemClickListener(new OnItemClickListener() {
|
| 101 |
@Override
|
| 102 |
public void onItemClick(AdapterView<?> ad, View v, int position, |
| 103 |
long id) {
|
| 104 |
Intent i = new Intent(getApplication(), NoteEdit.class);
|
| 105 |
i.putExtra(NotesDbAdapter.KEY_ROWID, id); |
| 106 |
startActivityForResult(i, ACTIVITY_EDIT); |
| 107 |
} |
| 108 |
}); |
| 109 |
registerForContextMenu(notesListView); |
| 110 |
mCacheWord = new CacheWordActivityHandler(this, ((App)getApplication()).getCWSettings()); |
| 111 |
|
| 112 |
// Create an array to specify the fields we want to display in the list (only TITLE)
|
| 113 |
String[] from = new String[] { NotesDbAdapter.KEY_TITLE }; |
| 114 |
|
| 115 |
// and an array of the fields we want to bind those fields to (in this
|
| 116 |
// case just text1)
|
| 117 |
int[] to = new int[] { R.id.row_text }; |
| 118 |
|
| 119 |
// Now create an empty simple cursor adapter that later will display the notes
|
| 120 |
notesCursorAdapter = new SimpleCursorAdapter(this, R.layout.notes_row, null, from, to |
| 121 |
, SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); |
| 122 |
notesListView.setAdapter(notesCursorAdapter); |
| 123 |
} |
| 124 |
|
| 125 |
@Override
|
| 126 |
protected void onPause() { |
| 127 |
super.onPause();
|
| 128 |
mCacheWord.onPause(); |
| 129 |
} |
| 130 |
|
| 131 |
@Override
|
| 132 |
protected void onResume() { |
| 133 |
super.onResume();
|
| 134 |
mCacheWord.onResume(); |
| 135 |
} |
| 136 |
|
| 137 |
@Override
|
| 138 |
public void onAttachedToWindow() { |
| 139 |
super.onAttachedToWindow();
|
| 140 |
|
| 141 |
findViewById(R.id.listlayout).setOnTouchListener(new OnTouchListener() {
|
| 142 |
@Override
|
| 143 |
public boolean onTouch(View v, MotionEvent event) { |
| 144 |
|
| 145 |
if (mDbHelper != null && mDbHelper.isOpen()) |
| 146 |
createNote(); |
| 147 |
|
| 148 |
return false; |
| 149 |
} |
| 150 |
}); |
| 151 |
} |
| 152 |
|
| 153 |
private void closeDatabase() { |
| 154 |
if (mDbHelper != null) { |
| 155 |
mDbHelper.close(); |
| 156 |
mDbHelper = null;
|
| 157 |
} |
| 158 |
} |
| 159 |
|
| 160 |
private void unlockDatabase() { |
| 161 |
if (mCacheWord.isLocked())
|
| 162 |
return;
|
| 163 |
mDbHelper = new NotesDbAdapter(mCacheWord, this); |
| 164 |
try {
|
| 165 |
|
| 166 |
mDbHelper.open(); |
| 167 |
|
| 168 |
if (dataStream != null) |
| 169 |
importDataStream(); |
| 170 |
else
|
| 171 |
fillData(); |
| 172 |
|
| 173 |
} catch (Exception e) { |
| 174 |
e.printStackTrace(); |
| 175 |
Toast.makeText(this, getString(R.string.err_pass), Toast.LENGTH_LONG).show();
|
| 176 |
} |
| 177 |
} |
| 178 |
|
| 179 |
private void fillData() { |
| 180 |
if (mCacheWord.isLocked())
|
| 181 |
return;
|
| 182 |
|
| 183 |
getSupportLoaderManager().restartLoader(VIEW_ID, null, new LoaderManager.LoaderCallbacks<Cursor>() { |
| 184 |
|
| 185 |
@Override
|
| 186 |
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) { |
| 187 |
return new NotesLoader(NoteCipher.this, mDbHelper); |
| 188 |
} |
| 189 |
|
| 190 |
@Override
|
| 191 |
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { |
| 192 |
notesCursorAdapter.swapCursor(cursor); |
| 193 |
|
| 194 |
TextView emptyTV = (TextView) findViewById(R.id.emptytext); |
| 195 |
if (notesCursorAdapter.isEmpty()) {
|
| 196 |
Toast.makeText(NoteCipher.this, R.string.on_start, Toast.LENGTH_LONG).show(); |
| 197 |
emptyTV.setText(R.string.no_notes); |
| 198 |
} else {
|
| 199 |
emptyTV.setText("");
|
| 200 |
} |
| 201 |
} |
| 202 |
|
| 203 |
@Override
|
| 204 |
public void onLoaderReset(Loader<Cursor> loader) { } |
| 205 |
}); |
| 206 |
} |
| 207 |
|
| 208 |
@Override
|
| 209 |
public boolean onCreateOptionsMenu(Menu menu) { |
| 210 |
super.onCreateOptionsMenu(menu);
|
| 211 |
menu.add(0, INSERT_ID, 0, R.string.menu_insert) |
| 212 |
.setIcon(R.drawable.new_content) |
| 213 |
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
| 214 |
//menu.add(0, REKEY_ID, 0, R.string.menu_rekey)
|
| 215 |
// .setIcon(R.drawable.key_icon)
|
| 216 |
// .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
| 217 |
menu.add(0, LOCK_ID, 0, R.string.menu_lock) |
| 218 |
.setIcon(R.drawable.lock) |
| 219 |
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
| 220 |
menu.add(0, SETTINGS_ID, 0, R.string.settings) |
| 221 |
.setIcon(R.drawable.settings) |
| 222 |
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
| 223 |
return true; |
| 224 |
} |
| 225 |
|
| 226 |
@Override
|
| 227 |
public boolean onMenuItemSelected(int featureId, MenuItem item) { |
| 228 |
switch (item.getItemId()) {
|
| 229 |
case INSERT_ID:
|
| 230 |
createNote(); |
| 231 |
return true; |
| 232 |
case REKEY_ID:
|
| 233 |
return true; |
| 234 |
case LOCK_ID:
|
| 235 |
if (!mCacheWord.isLocked())
|
| 236 |
mCacheWord.manuallyLock(); |
| 237 |
return true; |
| 238 |
case SETTINGS_ID:
|
| 239 |
startActivity(new Intent(this, Settings.class)); |
| 240 |
return true; |
| 241 |
} |
| 242 |
|
| 243 |
return super.onMenuItemSelected(featureId, item); |
| 244 |
} |
| 245 |
|
| 246 |
@Override
|
| 247 |
public void onCreateContextMenu(ContextMenu menu, View v, |
| 248 |
ContextMenuInfo menuInfo) {
|
| 249 |
super.onCreateContextMenu(menu, v, menuInfo);
|
| 250 |
// menu.add(0, VIEW_ID, 0, R.string.menu_view);
|
| 251 |
menu.add(0, SHARE_ID, 0, R.string.menu_share); |
| 252 |
menu.add(0, DELETE_ID, 0, R.string.menu_delete); |
| 253 |
|
| 254 |
} |
| 255 |
|
| 256 |
@Override
|
| 257 |
public boolean onContextItemSelected(android.view.MenuItem item) { |
| 258 |
AdapterContextMenuInfo info; |
| 259 |
|
| 260 |
switch (item.getItemId()) {
|
| 261 |
case DELETE_ID:
|
| 262 |
info = (AdapterContextMenuInfo) item.getMenuInfo(); |
| 263 |
mDbHelper.deleteNote(info.id); |
| 264 |
fillData(); |
| 265 |
return true; |
| 266 |
case SHARE_ID:
|
| 267 |
info = (AdapterContextMenuInfo) item.getMenuInfo(); |
| 268 |
shareEntry(info.id); |
| 269 |
|
| 270 |
return true; |
| 271 |
case VIEW_ID:
|
| 272 |
info = (AdapterContextMenuInfo) item.getMenuInfo(); |
| 273 |
viewEntry(info.id); |
| 274 |
|
| 275 |
return true; |
| 276 |
} |
| 277 |
return super.onContextItemSelected(item); |
| 278 |
} |
| 279 |
|
| 280 |
private void shareEntry(final long id) { |
| 281 |
if (mCacheWord.isLocked())
|
| 282 |
return;
|
| 283 |
|
| 284 |
getSupportLoaderManager().restartLoader(SHARE_ID, null, new LoaderManager.LoaderCallbacks<Cursor>() { |
| 285 |
|
| 286 |
@Override
|
| 287 |
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) { |
| 288 |
return new NoteEdit.NoteContentLoader(NoteCipher.this, mDbHelper, id); |
| 289 |
} |
| 290 |
|
| 291 |
@Override
|
| 292 |
public void onLoadFinished(Loader<Cursor> loader, Cursor note) { |
| 293 |
byte[] blob = note.getBlob(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_DATA)); |
| 294 |
String title = note.getString(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE));
|
| 295 |
String mimeType = note.getString(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_TYPE));
|
| 296 |
|
| 297 |
if (mimeType == null) |
| 298 |
mimeType = "text/plain";
|
| 299 |
|
| 300 |
if (blob != null) { |
| 301 |
try {
|
| 302 |
NoteUtils.shareData(NoteCipher.this, title, mimeType, blob); |
| 303 |
} catch (IOException e) { |
| 304 |
Toast.makeText(NoteCipher.this, getString(R.string.err_export, e.getMessage()), Toast.LENGTH_LONG) |
| 305 |
.show(); |
| 306 |
} |
| 307 |
} else {
|
| 308 |
String body = note.getString( note.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY) );
|
| 309 |
NoteUtils.shareText(NoteCipher.this, body); |
| 310 |
} |
| 311 |
note.close(); |
| 312 |
} |
| 313 |
|
| 314 |
@Override
|
| 315 |
public void onLoaderReset(Loader<Cursor> loader) { } |
| 316 |
}); |
| 317 |
} |
| 318 |
|
| 319 |
private void viewEntry(final long id) { |
| 320 |
if (mCacheWord.isLocked())
|
| 321 |
return;
|
| 322 |
|
| 323 |
getSupportLoaderManager().restartLoader(VIEW_ID, null, new LoaderManager.LoaderCallbacks<Cursor>() { |
| 324 |
|
| 325 |
@Override
|
| 326 |
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) { |
| 327 |
return new NoteEdit.NoteContentLoader(NoteCipher.this, mDbHelper, id); |
| 328 |
} |
| 329 |
|
| 330 |
@Override
|
| 331 |
public void onLoadFinished(Loader<Cursor> loader, Cursor note) { |
| 332 |
byte[] blob = note.getBlob(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_DATA)); |
| 333 |
String mimeType = note.getString(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_TYPE));
|
| 334 |
|
| 335 |
if (mimeType == null) |
| 336 |
mimeType = "text/plain";
|
| 337 |
|
| 338 |
if (blob != null) { |
| 339 |
String title = note.getString(
|
| 340 |
note.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)); |
| 341 |
|
| 342 |
NoteUtils.savePublicFile(NoteCipher.this, title, mimeType, blob); |
| 343 |
|
| 344 |
} |
| 345 |
note.close(); |
| 346 |
} |
| 347 |
|
| 348 |
@Override
|
| 349 |
public void onLoaderReset(Loader<Cursor> loader) { } |
| 350 |
}); |
| 351 |
} |
| 352 |
|
| 353 |
private void createNote() { |
| 354 |
if (mCacheWord.isLocked())
|
| 355 |
return;
|
| 356 |
|
| 357 |
Intent i = new Intent(this, NoteEdit.class); |
| 358 |
startActivityForResult(i, ACTIVITY_CREATE); |
| 359 |
} |
| 360 |
|
| 361 |
/*
|
| 362 |
* Called after the return from creating a new note (non-Javadoc)
|
| 363 |
* @see android.app.Activity#onActivityResult(int, int,
|
| 364 |
* android.content.Intent)
|
| 365 |
*/
|
| 366 |
@Override
|
| 367 |
protected void onActivityResult(int requestCode, int resultCode, |
| 368 |
Intent intent) {
|
| 369 |
super.onActivityResult(requestCode, resultCode, intent);
|
| 370 |
|
| 371 |
mDbHelper = new NotesDbAdapter(mCacheWord, this); |
| 372 |
|
| 373 |
fillData(); |
| 374 |
} |
| 375 |
|
| 376 |
@Override
|
| 377 |
protected void onStop() { |
| 378 |
super.onStop();
|
| 379 |
} |
| 380 |
|
| 381 |
@Override
|
| 382 |
public void onConfigurationChanged(Configuration newConfig) { |
| 383 |
super.onConfigurationChanged(newConfig);
|
| 384 |
} |
| 385 |
|
| 386 |
@Override
|
| 387 |
protected void onSaveInstanceState(Bundle outState) { |
| 388 |
super.onSaveInstanceState(outState);
|
| 389 |
} |
| 390 |
|
| 391 |
@Override
|
| 392 |
protected void onDestroy() { |
| 393 |
super.onDestroy();
|
| 394 |
|
| 395 |
closeDatabase(); |
| 396 |
NoteUtils.cleanupTmp(this);
|
| 397 |
} |
| 398 |
|
| 399 |
private void importDataStream() { |
| 400 |
if (mCacheWord.isLocked())
|
| 401 |
return;
|
| 402 |
|
| 403 |
try {
|
| 404 |
ContentResolver cr = getContentResolver(); |
| 405 |
InputStream is = cr.openInputStream(dataStream);
|
| 406 |
|
| 407 |
String mimeType = cr.getType(dataStream);
|
| 408 |
|
| 409 |
byte[] data = NoteUtils.readBytesAndClose(is); |
| 410 |
|
| 411 |
if (data.length > MAX_SIZE){
|
| 412 |
Toast.makeText(this, R.string.err_size, Toast.LENGTH_LONG).show();
|
| 413 |
} else {
|
| 414 |
String title = dataStream.getLastPathSegment();
|
| 415 |
String body = dataStream.getPath();
|
| 416 |
|
| 417 |
new NotesDbAdapter(mCacheWord, this).createNote(title, body, data, mimeType); |
| 418 |
|
| 419 |
Toast.makeText(this, getString(R.string.on_import, title), Toast.LENGTH_LONG).show();
|
| 420 |
|
| 421 |
// handleDelete();
|
| 422 |
|
| 423 |
data = null;
|
| 424 |
dataStream = null;
|
| 425 |
title = null;
|
| 426 |
body = null;
|
| 427 |
|
| 428 |
System.gc();
|
| 429 |
|
| 430 |
fillData(); |
| 431 |
} |
| 432 |
|
| 433 |
} catch (FileNotFoundException e) { |
| 434 |
Log.e(TAG, e.getMessage(), e); |
| 435 |
|
| 436 |
} catch (IOException e) { |
| 437 |
Log.e(TAG, e.getMessage(), e); |
| 438 |
|
| 439 |
} catch (OutOfMemoryError e) { |
| 440 |
Toast.makeText(this, R.string.err_size, Toast.LENGTH_LONG).show();
|
| 441 |
|
| 442 |
} finally {
|
| 443 |
dataStream = null;
|
| 444 |
|
| 445 |
} |
| 446 |
} |
| 447 |
|
| 448 |
/*
|
| 449 |
* Call this to delete the original image, will ask the user
|
| 450 |
*/
|
| 451 |
private void handleDelete() { |
| 452 |
final AlertDialog.Builder b = new AlertDialog.Builder(this); |
| 453 |
b.setIcon(android.R.drawable.ic_dialog_alert); |
| 454 |
b.setTitle(R.string.app_name); |
| 455 |
b.setMessage(R.string.confirm_delete); |
| 456 |
b.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
| 457 |
@Override
|
| 458 |
public void onClick(DialogInterface dialog, int whichButton) { |
| 459 |
|
| 460 |
// User clicked OK so go ahead and delete
|
| 461 |
ContentResolver cr = getContentResolver(); |
| 462 |
|
| 463 |
if (cr != null) |
| 464 |
cr.delete(dataStream, null, null); |
| 465 |
else {
|
| 466 |
Toast.makeText(NoteCipher.this, R.string.unable_to_delete_original, Toast.LENGTH_SHORT).show(); |
| 467 |
} |
| 468 |
|
| 469 |
} |
| 470 |
}); |
| 471 |
b.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
|
| 472 |
@Override
|
| 473 |
public void onClick(DialogInterface dialog, int whichButton) { |
| 474 |
|
| 475 |
} |
| 476 |
}); |
| 477 |
b.show(); |
| 478 |
} |
| 479 |
|
| 480 |
void showLockScreen() {
|
| 481 |
Intent intent = new Intent(this, LockScreenActivity.class); |
| 482 |
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); |
| 483 |
intent.putExtra("originalIntent", getIntent());
|
| 484 |
startActivity(intent); |
| 485 |
finish(); |
| 486 |
} |
| 487 |
|
| 488 |
void clearViewsAndLock() {
|
| 489 |
closeDatabase(); |
| 490 |
notesListView.setAdapter(null);
|
| 491 |
System.gc();
|
| 492 |
showLockScreen(); |
| 493 |
} |
| 494 |
|
| 495 |
@Override
|
| 496 |
public void onCacheWordUninitialized() { |
| 497 |
Log.d(TAG, "onCacheWordUninitialized");
|
| 498 |
clearViewsAndLock(); |
| 499 |
} |
| 500 |
|
| 501 |
@Override
|
| 502 |
public void onCacheWordLocked() { |
| 503 |
Log.d(TAG, "onCacheWordLocked");
|
| 504 |
clearViewsAndLock(); |
| 505 |
} |
| 506 |
|
| 507 |
@Override
|
| 508 |
public void onCacheWordOpened() { |
| 509 |
Log.d(TAG, "onCacheWordOpened");
|
| 510 |
unlockDatabase(); |
| 511 |
|
| 512 |
if (mDbHelper.isOpen()) {
|
| 513 |
if (dataStream != null) |
| 514 |
importDataStream(); |
| 515 |
else
|
| 516 |
fillData(); |
| 517 |
} |
| 518 |
} |
| 519 |
|
| 520 |
public static class NotesLoader extends CursorLoader { |
| 521 |
NotesDbAdapter db; |
| 522 |
|
| 523 |
public NotesLoader(Context context) { |
| 524 |
super(context);
|
| 525 |
} |
| 526 |
|
| 527 |
public NotesLoader(Context context, NotesDbAdapter db) { |
| 528 |
super(context);
|
| 529 |
this.db = db;
|
| 530 |
} |
| 531 |
|
| 532 |
@Override
|
| 533 |
public Cursor loadInBackground() { |
| 534 |
if (db == null) |
| 535 |
return null; |
| 536 |
return db.fetchAllNotes();
|
| 537 |
} |
| 538 |
} |
| 539 |
} |