/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.notepad;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
/**
* This Activity allows the user to edit a note's title. It displays a floating window
* containing an EditText.
*
* NOTE: Notice that the provider operations in this Activity are taking place on the UI thread.
* This is not a good practice. It is only done here to make the code more readable. A real
* application should use the {@link android.content.AsyncQueryHandler}
* or {@link android.os.AsyncTask} object to perform operations asynchronously on a separate thread.
*/
public class TitleEditor extends Activity {
/**
* This is a special intent action that means "edit the title of a note".
*/
public static final String EDIT_TITLE_ACTION = "com.android.notepad.action.EDIT_TITLE";
// Creates a projection that returns the note ID and the note contents.
private static final String[] PROJECTION = new String[] {
NotePad.Notes._ID, // 0
NotePad.Notes.COLUMN_NAME_TITLE, // 1
};
// The position of the title column in a Cursor returned by the provider.
private static final int COLUMN_INDEX_TITLE = 1;
// An EditText object for preserving the edited title.
private EditText mText;
// A URI object for the note whose title is being edited.
private Uri mUri;
// The title that was last saved.
private String mSavedTitle;
/**
* This method is called by Android when the Activity is first started. From the incoming
* Intent, it determines what kind of editing is desired, and then does it.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the View for this Activity object's UI.
setContentView(R.layout.title_editor);
// Gets the View ID for the EditText box
mText = (EditText) this.findViewById(R.id.title);
// Get the Intent that activated this Activity, and from it get the URI of the note whose
// title we need to edit.
mUri = getIntent().getData();
/*
* Using the URI passed in with the triggering Intent, gets the note.
*
* Note: This is being done on the UI thread. It will block the thread until the query
* completes. In a sample app, going against a simple provider based on a local database,
* the block will be momentary, but in a real app you should use
* android.content.AsyncQueryHandler or android.os.AsyncTask.
*/
Cursor cursor = getContentResolver().query(
mUri, // The URI for the note that is to be retrieved.
PROJECTION, // The columns to retrieve
null, // No selection criteria are used, so no where columns are needed.
null, // No where columns are used, so no where values are needed.
null // No sort order is needed.
);
if (cursor != null) {
// The Cursor was just retrieved, so its index is set to one record *before* the first
// record retrieved. This moves it to the first record.
cursor.moveToFirst();
// Displays the current title text in the EditText object.
mText.setText(cursor.getString(COLUMN_INDEX_TITLE));
}
}
/**
* This method is called when the Activity is about to come to the foreground. This happens
* when the Activity comes to the top of the task stack, OR when it is first starting.
*
* Displays the current title for the selected note.
*/
@Override
protected void onResume() {
super.onResume();
}
/**
* This method is called when the Activity loses focus.
*
* While there is no need to override this method in this app, it is shown here to highlight
* that we are not saving any state in onPause, but have moved app state saving to onStop
* callback.
* In earlier versions of this app and popular literature it had been shown that onPause is good
* place to persist any unsaved work, however, this is not really a good practice because of how
* application and process lifecycle behave.
* As a general guideline apps should have a way of saving their business logic that does not
* solely rely on Activity (or other component) lifecyle state transitions.
* As a backstop you should save any app state, not saved during lifetime of the Activity, in
* onStop().
* For a more detailed explanation of this recommendation please read
*
* Processes and Application Life Cycle .
*
* Pausing and Resuming an Activity .
*/
@Override
protected void onPause() {
super.onPause();
}
/**
* This method is called when the Activity becomes invisible.
*
* For Activity objects that edit information, onStop() may be the one place where changes are
* saved.
* Updates the note with the text currently in the text box.
*/
@Override
protected void onStop() {
super.onStop();
saveTitle();
}
public void onClickOk(View v) {
saveTitle();
finish();
}
// Saves the title if required
private void saveTitle() {
if (!TextUtils.isEmpty(mText.getText())) {
String newTitle = mText.getText().toString();
if (!newTitle.equals(mSavedTitle)) {
// Creates a values map for updating the provider.
ContentValues values = new ContentValues();
// In the values map, sets the title to the current contents of the edit box.
values.put(NotePad.Notes.COLUMN_NAME_TITLE, newTitle);
/*
* Updates the provider with the note's new title.
*
* Note: This is being done on the UI thread. It will block the thread until the
* update completes. In a sample app, going against a simple provider based on a
* local database, the block will be momentary, but in a real app you should use
* android.content.AsyncQueryHandler or android.os.AsyncTask.
*/
getContentResolver().update(
mUri, // The URI for the note to update.
values,
// The values map containing the columns to update and the values to use.
null, // No selection criteria is used, so no "where" columns are needed.
null // No "where" columns are used, so no "where" values are needed.
);
mSavedTitle = newTitle;
}
} else {
Toast.makeText(this, R.string.title_blank, Toast.LENGTH_SHORT).show();
}
}
}