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