小米開源便籤Notes-原始碼研究(1)-匯出功能整體思路

小雷FansUnion發表於2015-11-10

NotesListActivity是入口Activity。


響應選單事件,我的手機是“左鍵選單”。
如果選單項的ID是“R.id.menu_export_text”,就執行匯出,儲存到/mnt/sdcard/MIUI/notes目錄下。
@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_new_folder: {
			showCreateOrModifyFolderDialog(true);
			break;
		}
		case R.id.menu_export_text: {
			exportNoteToText();
			break;
		}
		case R.id.menu_sync: {
			if (isSyncMode()) {
				if (TextUtils.equals(item.getTitle(),
						getString(R.string.menu_sync))) {
					GTaskSyncService.startSync(this);
				} else {
					GTaskSyncService.cancelSync(this);
				}
			} else {
				startPreferenceActivity();
			}
			break;
		}
		case R.id.menu_setting: {
			startPreferenceActivity();
			break;
		}
		case R.id.menu_new_note: {
			createNewNote();
			break;
		}
		case R.id.menu_search:
			onSearchRequested();
			break;
		default:
			break;
		}
		return true;
	}



NotesListActivity中的匯出方法。
傳入上下文,獲得備份工具類BackupUtils的一個例項(單例)。
然後,新建一個非同步任務AsyncTask,執行具體的備份功能。
後臺方法執行在doInBackground,呼叫BackupUtils的exportToText方法。
onPostExecute給出使用者反饋,3種情況:
a.SDCard沒有掛在,警告對話方塊AlertDialog提示出錯。
b.STATE_SYSTEM_ERROR,執行時錯誤。
c.成功,(*^__^*) 。
private void exportNoteToText() {
		final BackupUtils backup = BackupUtils
				.getInstance(NotesListActivity.this);
		new AsyncTask<Void, Void, Integer>() {


			@Override
			protected Integer doInBackground(Void... unused) {
				return backup.exportToText();
			}


			@Override
			protected void onPostExecute(Integer result) {
				if (result == BackupUtils.STATE_SD_CARD_UNMOUONTED) {
					AlertDialog.Builder builder = new AlertDialog.Builder(
							NotesListActivity.this);
					builder.setTitle(NotesListActivity.this
							.getString(R.string.failed_sdcard_export));
					builder.setMessage(NotesListActivity.this
							.getString(R.string.error_sdcard_unmounted));
					builder.setPositiveButton(android.R.string.ok, null);
					builder.show();
				} else if (result == BackupUtils.STATE_SUCCESS) {
					AlertDialog.Builder builder = new AlertDialog.Builder(
							NotesListActivity.this);
					builder.setTitle(NotesListActivity.this
							.getString(R.string.success_sdcard_export));
					builder.setMessage(NotesListActivity.this.getString(
							R.string.format_exported_file_location,
							backup.getExportedTextFileName(),
							backup.getExportedTextFileDir()));
					builder.setPositiveButton(android.R.string.ok, null);
					builder.show();
				} else if (result == BackupUtils.STATE_SYSTEM_ERROR) {
					AlertDialog.Builder builder = new AlertDialog.Builder(
							NotesListActivity.this);
					builder.setTitle(NotesListActivity.this
							.getString(R.string.failed_sdcard_export));
					builder.setMessage(NotesListActivity.this
							.getString(R.string.error_sdcard_export));
					builder.setPositiveButton(android.R.string.ok, null);
					builder.show();
				}
			}


		}.execute();
	}



接下來深入看
BackupUtils的匯出方法。
public int exportToText() {
		return mTextExport.exportToText();
	}


mTextExport是一個靜態內部類。

具體的匯出邏輯如下:
1.從內容提供器ContentProvider中查詢,根目錄下的資料夾,
  備份資料夾和資料夾下的便籤notes。

2.從內容提供器ContentProvider中查詢,根目錄下便籤notes,
  備份便籤。
  
  查詢語句,類似
Cursor folderCursor = mContext.getContentResolver().query(
					Notes.CONTENT_NOTE_URI,
					NOTE_PROJECTION,
					"(" + NoteColumns.TYPE + "=" + Notes.TYPE_FOLDER + " AND "
							+ NoteColumns.PARENT_ID + "<>"
							+ Notes.ID_TRASH_FOLER + ") OR " + NoteColumns.ID
							+ "=" + Notes.ID_CALL_RECORD_FOLDER, null, null);



在整個匯出功能中,最難的是內容提供器的查詢。


AndroidManifest.xml中有配置NotesProvider,繼承自ContentProvider。
 
 <provider
            android:name="net.micode.notes.data.NotesProvider"
            android:authorities="micode_notes"
            android:multiprocess="true" />



public class NotesProvider extends ContentProvider {


本篇就先介紹到這,整體的匯出思路已經比較清楚了,今後在單獨詳細介紹ContentProvider的實現。

相關文章