Merge branch 'gingerbread' into gingerbread-release
@@ -223,18 +223,34 @@ typedef void ANativeActivity_createFunc(ANativeActivity* activity,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the function that NativeInstance looks for when launching its
|
* The name of the function that NativeInstance looks for when launching its
|
||||||
* native code.
|
* native code. This is the default function that is used, you can specify
|
||||||
|
* "android.app.func_name" string meta-data in your manifest to use a different
|
||||||
|
* function.
|
||||||
*/
|
*/
|
||||||
extern ANativeActivity_createFunc ANativeActivity_onCreate;
|
extern ANativeActivity_createFunc ANativeActivity_onCreate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finish the given activity. Its finish() method will be called, causing it
|
* Finish the given activity. Its finish() method will be called, causing it
|
||||||
* to be stopped and destroyed.
|
* to be stopped and destroyed. Note that this method can be called from
|
||||||
|
* *any* thread; it will send a message to the main thread of the process
|
||||||
|
* where the Java finish call will take place.
|
||||||
*/
|
*/
|
||||||
void ANativeActivity_finish(ANativeActivity* activity);
|
void ANativeActivity_finish(ANativeActivity* activity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the window format of the given activity. Calls getWindow().setFormat()
|
||||||
|
* of the given activity. Note that this method can be called from
|
||||||
|
* *any* thread; it will send a message to the main thread of the process
|
||||||
|
* where the Java finish call will take place.
|
||||||
|
*/
|
||||||
void ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format);
|
void ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the window flags of the given activity. Calls getWindow().setFlags()
|
||||||
|
* of the given activity. Note that this method can be called from
|
||||||
|
* *any* thread; it will send a message to the main thread of the process
|
||||||
|
* where the Java finish call will take place. See window.h for flag constants.
|
||||||
|
*/
|
||||||
void ANativeActivity_setWindowFlags(ANativeActivity* activity,
|
void ANativeActivity_setWindowFlags(ANativeActivity* activity,
|
||||||
uint32_t addFlags, uint32_t removeFlags);
|
uint32_t addFlags, uint32_t removeFlags);
|
||||||
|
|
||||||
@@ -247,6 +263,12 @@ enum {
|
|||||||
ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED = 0x0002,
|
ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED = 0x0002,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the IME while in the given activity. Calls InputMethodManager.showSoftInput()
|
||||||
|
* for the given activity. Note that this method can be called from
|
||||||
|
* *any* thread; it will send a message to the main thread of the process
|
||||||
|
* where the Java finish call will take place.
|
||||||
|
*/
|
||||||
void ANativeActivity_showSoftInput(ANativeActivity* activity, uint32_t flags);
|
void ANativeActivity_showSoftInput(ANativeActivity* activity, uint32_t flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -258,6 +280,12 @@ enum {
|
|||||||
ANATIVEACTIVITY_HIDE_SOFT_INPUT_NOT_ALWAYS = 0x0002,
|
ANATIVEACTIVITY_HIDE_SOFT_INPUT_NOT_ALWAYS = 0x0002,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide the IME while in the given activity. Calls InputMethodManager.hideSoftInput()
|
||||||
|
* for the given activity. Note that this method can be called from
|
||||||
|
* *any* thread; it will send a message to the main thread of the process
|
||||||
|
* where the Java finish call will take place.
|
||||||
|
*/
|
||||||
void ANativeActivity_hideSoftInput(ANativeActivity* activity, uint32_t flags);
|
void ANativeActivity_hideSoftInput(ANativeActivity* activity, uint32_t flags);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
70
ndk/platforms/android-9/samples/native-activity/Android.mk
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# Copyright (C) 2010 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.
|
||||||
|
|
||||||
|
LOCAL_PATH:= $(call my-dir)
|
||||||
|
|
||||||
|
##################################################################
|
||||||
|
#
|
||||||
|
# NOTE: This is a helper to build this sample code using the
|
||||||
|
# Android platform build system, inside of its source tree. This
|
||||||
|
# is NOT part of the NDK and is not for use with the NDK build
|
||||||
|
# system.
|
||||||
|
#
|
||||||
|
##################################################################
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
# Native code.
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE_TAGS := samples
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES += \
|
||||||
|
$(TOPDIR)frameworks/base/native/include \
|
||||||
|
$(TOPDIR)frameworks/base/opengl/include \
|
||||||
|
$(TOPDIR)development/ndk/sources/android/native_app_glue
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := \
|
||||||
|
jni/main.c jni/glutils.c \
|
||||||
|
../../../../sources/android/native_app_glue/android_native_app_glue.c
|
||||||
|
|
||||||
|
LOCAL_NDK_VERSION := 4
|
||||||
|
LOCAL_SDK_VERSION := 8
|
||||||
|
|
||||||
|
LOCAL_SHARED_LIBRARIES := liblog libandroid libEGL libGLESv1_CM
|
||||||
|
|
||||||
|
LOCAL_PRELINK_MODULE := false
|
||||||
|
|
||||||
|
LOCAL_MODULE := libnative-activity
|
||||||
|
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
# Packaging .ap (and Java code if there was some)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE_TAGS := samples
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||||
|
|
||||||
|
LOCAL_PACKAGE_NAME := NativeActivity
|
||||||
|
|
||||||
|
LOCAL_CERTIFICATE := shared
|
||||||
|
|
||||||
|
LOCAL_JNI_SHARED_LIBRARIES := libnative-activity
|
||||||
|
|
||||||
|
LOCAL_SDK_VERSION := current
|
||||||
|
|
||||||
|
include $(BUILD_PACKAGE)
|
||||||
@@ -59,7 +59,7 @@ struct engine {
|
|||||||
static int engine_init_display(struct engine* engine) {
|
static int engine_init_display(struct engine* engine) {
|
||||||
// initialize opengl and egl
|
// initialize opengl and egl
|
||||||
const EGLint attribs[] = {
|
const EGLint attribs[] = {
|
||||||
EGL_DEPTH_SIZE, 16,
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
EGLint w, h, dummy;
|
EGLint w, h, dummy;
|
||||||
@@ -72,6 +72,7 @@ static int engine_init_display(struct engine* engine) {
|
|||||||
|
|
||||||
eglInitialize(display, 0, 0);
|
eglInitialize(display, 0, 0);
|
||||||
selectConfigForNativeWindow(display, attribs, engine->app->window, &config);
|
selectConfigForNativeWindow(display, attribs, engine->app->window, &config);
|
||||||
|
|
||||||
surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
|
surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
|
||||||
context = eglCreateContext(display, config, NULL, NULL);
|
context = eglCreateContext(display, config, NULL, NULL);
|
||||||
|
|
||||||
@@ -94,7 +95,7 @@ static int engine_init_display(struct engine* engine) {
|
|||||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glShadeModel(GL_SMOOTH);
|
glShadeModel(GL_SMOOTH);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -111,7 +112,7 @@ static void engine_draw_frame(struct engine* engine) {
|
|||||||
// Just fill the screen with a color.
|
// Just fill the screen with a color.
|
||||||
glClearColor(((float)engine->state.x)/engine->width, engine->state.angle,
|
glClearColor(((float)engine->state.x)/engine->width, engine->state.angle,
|
||||||
((float)engine->state.y)/engine->height, 1);
|
((float)engine->state.y)/engine->height, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
eglSwapBuffers(engine->display, engine->surface);
|
eglSwapBuffers(engine->display, engine->surface);
|
||||||
}
|
}
|
||||||
@@ -119,7 +120,7 @@ static void engine_draw_frame(struct engine* engine) {
|
|||||||
/**
|
/**
|
||||||
* Tear down the EGL context currently associated with the display.
|
* Tear down the EGL context currently associated with the display.
|
||||||
*/
|
*/
|
||||||
static int engine_term_display(struct engine* engine) {
|
static void engine_term_display(struct engine* engine) {
|
||||||
if (engine->display != EGL_NO_DISPLAY) {
|
if (engine->display != EGL_NO_DISPLAY) {
|
||||||
eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
if (engine->context != EGL_NO_CONTEXT) {
|
if (engine->context != EGL_NO_CONTEXT) {
|
||||||
|
|||||||
@@ -21,9 +21,13 @@ import android.content.Context;
|
|||||||
import android.hardware.Camera;
|
import android.hardware.Camera;
|
||||||
import android.hardware.Camera.Size;
|
import android.hardware.Camera.Size;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -32,6 +36,7 @@ import java.util.List;
|
|||||||
|
|
||||||
public class CameraPreview extends Activity {
|
public class CameraPreview extends Activity {
|
||||||
private Preview mPreview;
|
private Preview mPreview;
|
||||||
|
Camera mCamera;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -39,55 +44,137 @@ public class CameraPreview extends Activity {
|
|||||||
|
|
||||||
// Hide the window title.
|
// Hide the window title.
|
||||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
|
||||||
// Create our Preview view and set it as the content of our activity.
|
// Create a RelativeLayout container that will hold a SurfaceView,
|
||||||
|
// and set it as the content of our activity.
|
||||||
mPreview = new Preview(this);
|
mPreview = new Preview(this);
|
||||||
setContentView(mPreview);
|
setContentView(mPreview);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
mCamera = Camera.open();
|
||||||
|
mPreview.setCamera(mCamera);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
|
||||||
|
// Because the Camera object is a shared resource, it's very
|
||||||
|
// important to release it when the activity is paused.
|
||||||
|
if (mCamera != null) {
|
||||||
|
mPreview.setCamera(null);
|
||||||
|
mCamera.release();
|
||||||
|
mCamera = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
class Preview extends SurfaceView implements SurfaceHolder.Callback {
|
/**
|
||||||
|
* A simple wrapper around a Camera and a SurfaceView that renders a centered preview of the Camera
|
||||||
|
* to the surface. We need to center the SurfaceView because not all devices have cameras that
|
||||||
|
* support preview sizes at the same aspect ratio as the device's display.
|
||||||
|
*/
|
||||||
|
class Preview extends ViewGroup implements SurfaceHolder.Callback {
|
||||||
|
private final String TAG = "Preview";
|
||||||
|
|
||||||
|
SurfaceView mSurfaceView;
|
||||||
SurfaceHolder mHolder;
|
SurfaceHolder mHolder;
|
||||||
|
Size mPreviewSize;
|
||||||
|
List<Size> mSupportedPreviewSizes;
|
||||||
Camera mCamera;
|
Camera mCamera;
|
||||||
|
|
||||||
Preview(Context context) {
|
Preview(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
|
mSurfaceView = new SurfaceView(context);
|
||||||
|
addView(mSurfaceView);
|
||||||
|
|
||||||
// Install a SurfaceHolder.Callback so we get notified when the
|
// Install a SurfaceHolder.Callback so we get notified when the
|
||||||
// underlying surface is created and destroyed.
|
// underlying surface is created and destroyed.
|
||||||
mHolder = getHolder();
|
mHolder = mSurfaceView.getHolder();
|
||||||
mHolder.addCallback(this);
|
mHolder.addCallback(this);
|
||||||
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCamera(Camera camera) {
|
||||||
|
mCamera = camera;
|
||||||
|
if (mCamera != null) {
|
||||||
|
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
|
||||||
|
requestLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
// We purposely disregard child measurements because act as a
|
||||||
|
// wrapper to a SurfaceView that centers the camera preview instead
|
||||||
|
// of stretching it.
|
||||||
|
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
|
||||||
|
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
|
||||||
|
setMeasuredDimension(width, height);
|
||||||
|
|
||||||
|
if (mSupportedPreviewSizes != null) {
|
||||||
|
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||||
|
if (changed && getChildCount() > 0) {
|
||||||
|
final View child = getChildAt(0);
|
||||||
|
|
||||||
|
final int width = r - l;
|
||||||
|
final int height = b - t;
|
||||||
|
|
||||||
|
int previewWidth = width;
|
||||||
|
int previewHeight = height;
|
||||||
|
if (mPreviewSize != null) {
|
||||||
|
previewWidth = mPreviewSize.width;
|
||||||
|
previewHeight = mPreviewSize.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Center the child SurfaceView within the parent.
|
||||||
|
if (width * previewHeight > height * previewWidth) {
|
||||||
|
final int scaledChildWidth = previewWidth * height / previewHeight;
|
||||||
|
child.layout((width - scaledChildWidth) / 2, 0,
|
||||||
|
(width + scaledChildWidth) / 2, height);
|
||||||
|
} else {
|
||||||
|
final int scaledChildHeight = previewHeight * width / previewWidth;
|
||||||
|
child.layout(0, (height - scaledChildHeight) / 2,
|
||||||
|
width, (height + scaledChildHeight) / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void surfaceCreated(SurfaceHolder holder) {
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
// The Surface has been created, acquire the camera and tell it where
|
// The Surface has been created, acquire the camera and tell it where
|
||||||
// to draw.
|
// to draw.
|
||||||
mCamera = Camera.open();
|
|
||||||
try {
|
try {
|
||||||
|
if (mCamera != null) {
|
||||||
mCamera.setPreviewDisplay(holder);
|
mCamera.setPreviewDisplay(holder);
|
||||||
|
}
|
||||||
} catch (IOException exception) {
|
} catch (IOException exception) {
|
||||||
mCamera.release();
|
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
|
||||||
mCamera = null;
|
|
||||||
// TODO: add more exception handling logic here
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
// Surface will be destroyed when we return, so stop the preview.
|
// Surface will be destroyed when we return, so stop the preview.
|
||||||
// Because the CameraDevice object is not a shared resource, it's very
|
if (mCamera != null) {
|
||||||
// important to release it when the activity is paused.
|
|
||||||
mCamera.stopPreview();
|
mCamera.stopPreview();
|
||||||
mCamera.release();
|
}
|
||||||
mCamera = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
|
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
|
||||||
final double ASPECT_TOLERANCE = 0.05;
|
final double ASPECT_TOLERANCE = 0.1;
|
||||||
double targetRatio = (double) w / h;
|
double targetRatio = (double) w / h;
|
||||||
if (sizes == null) return null;
|
if (sizes == null) return null;
|
||||||
|
|
||||||
@@ -123,10 +210,8 @@ class Preview extends SurfaceView implements SurfaceHolder.Callback {
|
|||||||
// Now that the size is known, set up the camera parameters and begin
|
// Now that the size is known, set up the camera parameters and begin
|
||||||
// the preview.
|
// the preview.
|
||||||
Camera.Parameters parameters = mCamera.getParameters();
|
Camera.Parameters parameters = mCamera.getParameters();
|
||||||
|
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
|
||||||
List<Size> sizes = parameters.getSupportedPreviewSizes();
|
requestLayout();
|
||||||
Size optimalSize = getOptimalPreviewSize(sizes, w, h);
|
|
||||||
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
|
|
||||||
|
|
||||||
mCamera.setParameters(parameters);
|
mCamera.setParameters(parameters);
|
||||||
mCamera.startPreview();
|
mCamera.startPreview();
|
||||||
|
|||||||
@@ -20,16 +20,15 @@
|
|||||||
own application, the package name must be changed from "com.example.*"
|
own application, the package name must be changed from "com.example.*"
|
||||||
to come from a domain that you own or have control over. -->
|
to come from a domain that you own or have control over. -->
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.android.notepad"
|
package="com.example.android.notepad" >
|
||||||
>
|
|
||||||
<application android:icon="@drawable/app_notes"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
>
|
|
||||||
<provider android:name="NotePadProvider"
|
|
||||||
android:authorities="com.google.provider.NotePad"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<activity android:name="NotesList" android:label="@string/title_notes_list">
|
<application android:icon="@drawable/app_notes"
|
||||||
|
android:label="@string/app_name" >
|
||||||
|
<provider android:name="NotePadProvider"
|
||||||
|
android:authorities="com.example.notepad.provider.NotePad" />
|
||||||
|
|
||||||
|
<activity android:name="NotesList"
|
||||||
|
android:label="@string/title_notes_list">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
@@ -50,16 +49,13 @@
|
|||||||
|
|
||||||
<activity android:name="NoteEditor"
|
<activity android:name="NoteEditor"
|
||||||
android:theme="@android:style/Theme.Light"
|
android:theme="@android:style/Theme.Light"
|
||||||
android:label="@string/title_note"
|
android:configChanges="keyboardHidden|orientation">
|
||||||
android:screenOrientation="sensor"
|
|
||||||
android:configChanges="keyboardHidden|orientation"
|
|
||||||
>
|
|
||||||
<!-- This filter says that we can view or edit the data of
|
<!-- This filter says that we can view or edit the data of
|
||||||
a single note -->
|
a single note -->
|
||||||
<intent-filter android:label="@string/resolve_edit">
|
<intent-filter android:label="@string/resolve_edit">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<action android:name="android.intent.action.EDIT" />
|
<action android:name="android.intent.action.EDIT" />
|
||||||
<action android:name="com.android.notepad.action.EDIT_NOTE" />
|
<action android:name="com.android.notes.action.EDIT_NOTE" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
|
<data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
@@ -77,6 +73,7 @@
|
|||||||
<activity android:name="TitleEditor"
|
<activity android:name="TitleEditor"
|
||||||
android:label="@string/title_edit_title"
|
android:label="@string/title_edit_title"
|
||||||
android:theme="@android:style/Theme.Dialog"
|
android:theme="@android:style/Theme.Dialog"
|
||||||
|
android:icon="@drawable/ic_menu_edit"
|
||||||
android:windowSoftInputMode="stateVisible">
|
android:windowSoftInputMode="stateVisible">
|
||||||
<!-- This activity implements an alternative action that can be
|
<!-- This activity implements an alternative action that can be
|
||||||
performed on notes: editing their title. It can be used as
|
performed on notes: editing their title. It can be used as
|
||||||
@@ -110,6 +107,6 @@
|
|||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<uses-sdk android:targetSdkVersion="4" android:minSdkVersion="3"/>
|
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4"/>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.8 KiB |
BIN
samples/NotePad/res/drawable-hdpi/app_notes.png
Executable file → Normal file
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 3.8 KiB |
BIN
samples/NotePad/res/drawable-hdpi/ic_menu_compose.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
samples/NotePad/res/drawable-hdpi/ic_menu_delete.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
samples/NotePad/res/drawable-hdpi/ic_menu_discard.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
samples/NotePad/res/drawable-hdpi/ic_menu_edit.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
samples/NotePad/res/drawable-hdpi/ic_menu_revert.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
samples/NotePad/res/drawable-hdpi/ic_menu_save.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
samples/NotePad/res/drawable/ic_menu_compose.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
samples/NotePad/res/drawable/ic_menu_delete.png
Executable file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
samples/NotePad/res/drawable/ic_menu_discard.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
samples/NotePad/res/drawable/ic_menu_edit.png
Executable file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
samples/NotePad/res/drawable/ic_menu_revert.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
samples/NotePad/res/drawable/ic_menu_save.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
@@ -13,17 +13,15 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<view xmlns:android="http://schemas.android.com/apk/res/android"
|
<view xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
class="com.example.android.notepad.NoteEditor$LinedEditText"
|
class="com.example.android.notepad.NoteEditor$LinedEditText"
|
||||||
android:id="@+id/note"
|
android:id="@+id/note"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="fill_parent"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:padding="5dip"
|
android:padding="5dp"
|
||||||
android:scrollbars="vertical"
|
android:scrollbars="vertical"
|
||||||
android:fadingEdge="vertical"
|
android:fadingEdge="vertical"
|
||||||
android:gravity="top"
|
android:gravity="top"
|
||||||
android:textSize="22sp"
|
android:textSize="22sp"
|
||||||
android:capitalize="sentences"
|
android:capitalize="sentences" />
|
||||||
/>
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@android:id/text1"
|
android:id="@android:id/text1"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="?android:attr/listPreferredItemHeight"
|
android:layout_height="?android:attr/listPreferredItemHeight"
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
|
|||||||
20
samples/NotePad/res/menu/editor_options_menu.xml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:id="@+id/menu_save"
|
||||||
|
android:icon="@drawable/ic_menu_save"
|
||||||
|
android:alphabeticShortcut='s'
|
||||||
|
android:title="@string/menu_save" />
|
||||||
|
<group android:id="@+id/menu_group_edit">
|
||||||
|
<item android:id="@+id/menu_revert"
|
||||||
|
android:icon="@drawable/ic_menu_revert"
|
||||||
|
android:title="@string/menu_revert" />
|
||||||
|
<item android:id="@+id/menu_delete"
|
||||||
|
android:icon="@drawable/ic_menu_delete"
|
||||||
|
android:title="@string/menu_delete" />
|
||||||
|
</group>
|
||||||
|
<group android:id="@+id/menu_group_insert">
|
||||||
|
<item android:id="@+id/menu_discard"
|
||||||
|
android:icon="@drawable/ic_menu_discard"
|
||||||
|
android:title="@string/menu_discard" />
|
||||||
|
</group>
|
||||||
|
</menu>
|
||||||
7
samples/NotePad/res/menu/list_context_menu.xml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:id="@+id/context_open"
|
||||||
|
android:title="@string/menu_open" />
|
||||||
|
<item android:id="@+id/context_delete"
|
||||||
|
android:title="@string/menu_delete" />
|
||||||
|
</menu>
|
||||||
8
samples/NotePad/res/menu/list_options_menu.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<!-- This is our one standard application action (creating a new note). -->
|
||||||
|
<item android:id="@+id/menu_add"
|
||||||
|
android:icon="@drawable/ic_menu_compose"
|
||||||
|
android:alphabeticShortcut='a'
|
||||||
|
android:title="@string/menu_add" />
|
||||||
|
</menu>
|
||||||
@@ -15,25 +15,28 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
|
<string name="app_name">NotePad</string>
|
||||||
|
<string name="live_folder_name">Notes</string>
|
||||||
|
|
||||||
|
<string name="title_edit_title">Note title:</string>
|
||||||
|
<string name="title_create">Create note</string>
|
||||||
|
<string name="title_edit">Edit: \"%1$s\"</string>
|
||||||
|
<string name="title_notes_list">Notes</string>
|
||||||
|
|
||||||
|
<string name="menu_add">Add note</string>
|
||||||
|
<string name="menu_save">Save</string>
|
||||||
<string name="menu_delete">Delete</string>
|
<string name="menu_delete">Delete</string>
|
||||||
<string name="menu_insert">Add note</string>
|
<string name="menu_open">Open</string>
|
||||||
<string name="menu_revert">Revert</string>
|
<string name="menu_revert">Revert changes</string>
|
||||||
<string name="menu_discard">Discard</string>
|
<string name="menu_discard">Discard</string>
|
||||||
|
|
||||||
|
<string name="button_ok">OK</string>
|
||||||
|
<string name="text_title">Title:</string>
|
||||||
|
|
||||||
<string name="resolve_edit">Edit note</string>
|
<string name="resolve_edit">Edit note</string>
|
||||||
<string name="resolve_title">Edit title</string>
|
<string name="resolve_title">Edit title</string>
|
||||||
|
|
||||||
<string name="title_create">Create note</string>
|
|
||||||
<string name="title_edit">Edit note</string>
|
|
||||||
<string name="title_notes_list">Note pad</string>
|
|
||||||
<string name="title_note">Note</string>
|
|
||||||
<string name="title_edit_title">Note title:</string>
|
|
||||||
|
|
||||||
<string name="app_name">Note Pad</string>
|
|
||||||
<string name="live_folder_name">Notes</string>
|
|
||||||
|
|
||||||
<string name="button_ok">OK</string>
|
|
||||||
|
|
||||||
<string name="error_title">Error</string>
|
<string name="error_title">Error</string>
|
||||||
<string name="error_message">Error loading note</string>
|
<string name="error_message">Error loading note</string>
|
||||||
|
<string name="nothing_to_save">There is nothing to save</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -16,13 +16,12 @@
|
|||||||
|
|
||||||
package com.example.android.notepad;
|
package com.example.android.notepad;
|
||||||
|
|
||||||
import com.example.android.notepad.NotePad.Notes;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
@@ -32,8 +31,12 @@ import android.os.Bundle;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.example.android.notepad.NotePad.NoteColumns;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic activity for editing a note in a database. This can be used
|
* A generic activity for editing a note in a database. This can be used
|
||||||
@@ -41,32 +44,29 @@ import android.widget.EditText;
|
|||||||
* {@link Intent#ACTION_EDIT}, or create a new note {@link Intent#ACTION_INSERT}.
|
* {@link Intent#ACTION_EDIT}, or create a new note {@link Intent#ACTION_INSERT}.
|
||||||
*/
|
*/
|
||||||
public class NoteEditor extends Activity {
|
public class NoteEditor extends Activity {
|
||||||
private static final String TAG = "Notes";
|
private static final String TAG = "NoteEditor";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard projection for the interesting columns of a normal note.
|
* Standard projection for the interesting columns of a normal note.
|
||||||
*/
|
*/
|
||||||
private static final String[] PROJECTION = new String[] {
|
private static final String[] PROJECTION = new String[] {
|
||||||
Notes._ID, // 0
|
NoteColumns._ID, // 0
|
||||||
Notes.NOTE, // 1
|
NoteColumns.NOTE, // 1
|
||||||
|
NoteColumns.TITLE, // 2
|
||||||
};
|
};
|
||||||
/** The index of the note column */
|
/** The index of the note column */
|
||||||
private static final int COLUMN_INDEX_NOTE = 1;
|
private static final int COLUMN_INDEX_NOTE = 1;
|
||||||
|
/** The index of the title column */
|
||||||
|
private static final int COLUMN_INDEX_TITLE = 2;
|
||||||
|
|
||||||
// This is our state data that is stored when freezing.
|
// This is our state data that is stored when freezing.
|
||||||
private static final String ORIGINAL_CONTENT = "origContent";
|
private static final String ORIGINAL_CONTENT = "origContent";
|
||||||
|
|
||||||
// Identifiers for our menu items.
|
|
||||||
private static final int REVERT_ID = Menu.FIRST;
|
|
||||||
private static final int DISCARD_ID = Menu.FIRST + 1;
|
|
||||||
private static final int DELETE_ID = Menu.FIRST + 2;
|
|
||||||
|
|
||||||
// The different distinct states the activity can be run in.
|
// The different distinct states the activity can be run in.
|
||||||
private static final int STATE_EDIT = 0;
|
private static final int STATE_EDIT = 0;
|
||||||
private static final int STATE_INSERT = 1;
|
private static final int STATE_INSERT = 1;
|
||||||
|
|
||||||
private int mState;
|
private int mState;
|
||||||
private boolean mNoteOnly = false;
|
|
||||||
private Uri mUri;
|
private Uri mUri;
|
||||||
private Cursor mCursor;
|
private Cursor mCursor;
|
||||||
private EditText mText;
|
private EditText mText;
|
||||||
@@ -112,7 +112,6 @@ public class NoteEditor extends Activity {
|
|||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
|
|
||||||
// Do some setup based on the action being performed.
|
// Do some setup based on the action being performed.
|
||||||
|
|
||||||
final String action = intent.getAction();
|
final String action = intent.getAction();
|
||||||
if (Intent.ACTION_EDIT.equals(action)) {
|
if (Intent.ACTION_EDIT.equals(action)) {
|
||||||
// Requested to edit: set that state, and the data being edited.
|
// Requested to edit: set that state, and the data being edited.
|
||||||
@@ -163,16 +162,21 @@ public class NoteEditor extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
// If we didn't have any trouble retrieving the data, it is now
|
// If we didn't have any trouble retrieving the data, it is now
|
||||||
// time to get at the stuff.
|
// time to get at the stuff.
|
||||||
if (mCursor != null) {
|
if (mCursor != null) {
|
||||||
|
// Requery in case something changed while paused (such as the title)
|
||||||
|
mCursor.requery();
|
||||||
// Make sure we are at the one and only row in the cursor.
|
// Make sure we are at the one and only row in the cursor.
|
||||||
mCursor.moveToFirst();
|
mCursor.moveToFirst();
|
||||||
|
|
||||||
// Modify our overall title depending on the mode we are running in.
|
// Modify our overall title depending on the mode we are running in.
|
||||||
if (mState == STATE_EDIT) {
|
if (mState == STATE_EDIT) {
|
||||||
setTitle(getText(R.string.title_edit));
|
// Set the title of the Activity to include the note title
|
||||||
|
String title = mCursor.getString(COLUMN_INDEX_TITLE);
|
||||||
|
Resources res = getResources();
|
||||||
|
String text = String.format(res.getString(R.string.title_edit), title);
|
||||||
|
setTitle(text);
|
||||||
} else if (mState == STATE_INSERT) {
|
} else if (mState == STATE_INSERT) {
|
||||||
setTitle(getText(R.string.title_create));
|
setTitle(getText(R.string.title_create));
|
||||||
}
|
}
|
||||||
@@ -206,34 +210,106 @@ public class NoteEditor extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
// The user is going somewhere, so make sure changes are saved
|
||||||
|
|
||||||
// The user is going somewhere else, so make sure their current
|
|
||||||
// changes are safely saved away in the provider. We don't need
|
|
||||||
// to do this if only editing.
|
|
||||||
if (mCursor != null) {
|
|
||||||
String text = mText.getText().toString();
|
String text = mText.getText().toString();
|
||||||
int length = text.length();
|
int length = text.length();
|
||||||
|
|
||||||
// If this activity is finished, and there is no text, then we
|
// If this activity is finished, and there is no text, then we
|
||||||
// do something a little special: simply delete the note entry.
|
// simply delete the note entry.
|
||||||
// Note that we do this both for editing and inserting... it
|
// Note that we do this both for editing and inserting... it
|
||||||
// would be reasonable to only do it when inserting.
|
// would be reasonable to only do it when inserting.
|
||||||
if (isFinishing() && (length == 0) && !mNoteOnly) {
|
if (isFinishing() && (length == 0) && mCursor != null) {
|
||||||
setResult(RESULT_CANCELED);
|
setResult(RESULT_CANCELED);
|
||||||
deleteNote();
|
deleteNote();
|
||||||
|
|
||||||
// Get out updates into the provider.
|
|
||||||
} else {
|
} else {
|
||||||
|
saveNote();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
// Inflate menu from XML resource
|
||||||
|
MenuInflater inflater = getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.editor_options_menu, menu);
|
||||||
|
|
||||||
|
// Append to the
|
||||||
|
// menu items for any other activities that can do stuff with it
|
||||||
|
// as well. This does a query on the system for any activities that
|
||||||
|
// implement the ALTERNATIVE_ACTION for our data, adding a menu item
|
||||||
|
// for each one that is found.
|
||||||
|
Intent intent = new Intent(null, getIntent().getData());
|
||||||
|
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
|
||||||
|
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
|
||||||
|
new ComponentName(this, NoteEditor.class), null, intent, 0, null);
|
||||||
|
|
||||||
|
return super.onCreateOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||||
|
if (mState == STATE_EDIT) {
|
||||||
|
menu.setGroupVisible(R.id.menu_group_edit, true);
|
||||||
|
menu.setGroupVisible(R.id.menu_group_insert, false);
|
||||||
|
|
||||||
|
// Check if note has changed and enable/disable the revert option
|
||||||
|
String savedNote = mCursor.getString(COLUMN_INDEX_NOTE);
|
||||||
|
String currentNote = mText.getText().toString();
|
||||||
|
if (savedNote.equals(currentNote)) {
|
||||||
|
menu.findItem(R.id.menu_revert).setEnabled(false);
|
||||||
|
} else {
|
||||||
|
menu.findItem(R.id.menu_revert).setEnabled(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
menu.setGroupVisible(R.id.menu_group_edit, false);
|
||||||
|
menu.setGroupVisible(R.id.menu_group_insert, true);
|
||||||
|
}
|
||||||
|
return super.onPrepareOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
// Handle all of the possible menu actions.
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.menu_save:
|
||||||
|
saveNote();
|
||||||
|
finish();
|
||||||
|
break;
|
||||||
|
case R.id.menu_delete:
|
||||||
|
deleteNote();
|
||||||
|
finish();
|
||||||
|
break;
|
||||||
|
case R.id.menu_revert:
|
||||||
|
case R.id.menu_discard:
|
||||||
|
cancelNote();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void saveNote() {
|
||||||
|
// Make sure their current
|
||||||
|
// changes are safely saved away in the provider. We don't need
|
||||||
|
// to do this if only editing.
|
||||||
|
if (mCursor != null) {
|
||||||
|
// Get out updates into the provider.
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
|
|
||||||
// This stuff is only done when working with a full-fledged note.
|
|
||||||
if (!mNoteOnly) {
|
|
||||||
// Bump the modification time to now.
|
// Bump the modification time to now.
|
||||||
values.put(Notes.MODIFIED_DATE, System.currentTimeMillis());
|
values.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
|
||||||
|
|
||||||
|
String text = mText.getText().toString();
|
||||||
|
int length = text.length();
|
||||||
// If we are creating a new note, then we want to also create
|
// If we are creating a new note, then we want to also create
|
||||||
// an initial title for it.
|
// an initial title for it.
|
||||||
if (mState == STATE_INSERT) {
|
if (mState == STATE_INSERT) {
|
||||||
|
if (length == 0) {
|
||||||
|
Toast.makeText(this, R.string.nothing_to_save, Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
String title = text.substring(0, Math.min(30, length));
|
String title = text.substring(0, Math.min(30, length));
|
||||||
if (length > 30) {
|
if (length > 30) {
|
||||||
int lastSpace = title.lastIndexOf(' ');
|
int lastSpace = title.lastIndexOf(' ');
|
||||||
@@ -241,74 +317,22 @@ public class NoteEditor extends Activity {
|
|||||||
title = title.substring(0, lastSpace);
|
title = title.substring(0, lastSpace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
values.put(Notes.TITLE, title);
|
values.put(NoteColumns.TITLE, title);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write our text back into the provider.
|
// Write our text back into the provider.
|
||||||
values.put(Notes.NOTE, text);
|
values.put(NoteColumns.NOTE, text);
|
||||||
|
|
||||||
// Commit all of our changes to persistent storage. When the update completes
|
// Commit all of our changes to persistent storage. When the update completes
|
||||||
// the content provider will notify the cursor of the change, which will
|
// the content provider will notify the cursor of the change, which will
|
||||||
// cause the UI to be updated.
|
// cause the UI to be updated.
|
||||||
|
try {
|
||||||
getContentResolver().update(mUri, values, null, null);
|
getContentResolver().update(mUri, values, null, null);
|
||||||
}
|
} catch (NullPointerException e) {
|
||||||
}
|
Log.e(TAG, e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
super.onCreateOptionsMenu(menu);
|
|
||||||
|
|
||||||
// Build the menus that are shown when editing.
|
|
||||||
if (mState == STATE_EDIT) {
|
|
||||||
menu.add(0, REVERT_ID, 0, R.string.menu_revert)
|
|
||||||
.setShortcut('0', 'r')
|
|
||||||
.setIcon(android.R.drawable.ic_menu_revert);
|
|
||||||
if (!mNoteOnly) {
|
|
||||||
menu.add(0, DELETE_ID, 0, R.string.menu_delete)
|
|
||||||
.setShortcut('1', 'd')
|
|
||||||
.setIcon(android.R.drawable.ic_menu_delete);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the menus that are shown when inserting.
|
|
||||||
} else {
|
|
||||||
menu.add(0, DISCARD_ID, 0, R.string.menu_discard)
|
|
||||||
.setShortcut('0', 'd')
|
|
||||||
.setIcon(android.R.drawable.ic_menu_delete);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we are working on a full note, then append to the
|
|
||||||
// menu items for any other activities that can do stuff with it
|
|
||||||
// as well. This does a query on the system for any activities that
|
|
||||||
// implement the ALTERNATIVE_ACTION for our data, adding a menu item
|
|
||||||
// for each one that is found.
|
|
||||||
if (!mNoteOnly) {
|
|
||||||
Intent intent = new Intent(null, getIntent().getData());
|
|
||||||
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
|
|
||||||
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
|
|
||||||
new ComponentName(this, NoteEditor.class), null, intent, 0, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
// Handle all of the possible menu actions.
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case DELETE_ID:
|
|
||||||
deleteNote();
|
|
||||||
finish();
|
|
||||||
break;
|
|
||||||
case DISCARD_ID:
|
|
||||||
cancelNote();
|
|
||||||
break;
|
|
||||||
case REVERT_ID:
|
|
||||||
cancelNote();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -322,7 +346,7 @@ public class NoteEditor extends Activity {
|
|||||||
mCursor.close();
|
mCursor.close();
|
||||||
mCursor = null;
|
mCursor = null;
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(Notes.NOTE, mOriginalContent);
|
values.put(NoteColumns.NOTE, mOriginalContent);
|
||||||
getContentResolver().update(mUri, values, null, null);
|
getContentResolver().update(mUri, values, null, null);
|
||||||
} else if (mState == STATE_INSERT) {
|
} else if (mState == STATE_INSERT) {
|
||||||
// We inserted an empty note, make sure to delete it
|
// We inserted an empty note, make sure to delete it
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import android.provider.BaseColumns;
|
|||||||
* Convenience definitions for NotePadProvider
|
* Convenience definitions for NotePadProvider
|
||||||
*/
|
*/
|
||||||
public final class NotePad {
|
public final class NotePad {
|
||||||
public static final String AUTHORITY = "com.google.provider.NotePad";
|
public static final String AUTHORITY = "com.example.notepad.provider.NotePad";
|
||||||
|
|
||||||
// This class cannot be instantiated
|
// This class cannot be instantiated
|
||||||
private NotePad() {}
|
private NotePad() {}
|
||||||
@@ -31,9 +31,9 @@ public final class NotePad {
|
|||||||
/**
|
/**
|
||||||
* Notes table
|
* Notes table
|
||||||
*/
|
*/
|
||||||
public static final class Notes implements BaseColumns {
|
public static final class NoteColumns implements BaseColumns {
|
||||||
// This class cannot be instantiated
|
// This class cannot be instantiated
|
||||||
private Notes() {}
|
private NoteColumns() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The content:// style URL for this table
|
* The content:// style URL for this table
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.example.android.notepad;
|
package com.example.android.notepad;
|
||||||
|
|
||||||
import com.example.android.notepad.NotePad.Notes;
|
import com.example.android.notepad.NotePad.NoteColumns;
|
||||||
|
|
||||||
import android.content.ContentProvider;
|
import android.content.ContentProvider;
|
||||||
import android.content.ContentUris;
|
import android.content.ContentUris;
|
||||||
@@ -44,7 +44,7 @@ public class NotePadProvider extends ContentProvider {
|
|||||||
|
|
||||||
private static final String TAG = "NotePadProvider";
|
private static final String TAG = "NotePadProvider";
|
||||||
|
|
||||||
private static final String DATABASE_NAME = "note_pad.db";
|
private static final String DATABASE_NAME = "notepad.db";
|
||||||
private static final int DATABASE_VERSION = 2;
|
private static final int DATABASE_VERSION = 2;
|
||||||
private static final String NOTES_TABLE_NAME = "notes";
|
private static final String NOTES_TABLE_NAME = "notes";
|
||||||
|
|
||||||
@@ -69,11 +69,11 @@ public class NotePadProvider extends ContentProvider {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(SQLiteDatabase db) {
|
public void onCreate(SQLiteDatabase db) {
|
||||||
db.execSQL("CREATE TABLE " + NOTES_TABLE_NAME + " ("
|
db.execSQL("CREATE TABLE " + NOTES_TABLE_NAME + " ("
|
||||||
+ Notes._ID + " INTEGER PRIMARY KEY,"
|
+ NoteColumns._ID + " INTEGER PRIMARY KEY,"
|
||||||
+ Notes.TITLE + " TEXT,"
|
+ NoteColumns.TITLE + " TEXT,"
|
||||||
+ Notes.NOTE + " TEXT,"
|
+ NoteColumns.NOTE + " TEXT,"
|
||||||
+ Notes.CREATED_DATE + " INTEGER,"
|
+ NoteColumns.CREATED_DATE + " INTEGER,"
|
||||||
+ Notes.MODIFIED_DATE + " INTEGER"
|
+ NoteColumns.MODIFIED_DATE + " INTEGER"
|
||||||
+ ");");
|
+ ");");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ public class NotePadProvider extends ContentProvider {
|
|||||||
|
|
||||||
case NOTE_ID:
|
case NOTE_ID:
|
||||||
qb.setProjectionMap(sNotesProjectionMap);
|
qb.setProjectionMap(sNotesProjectionMap);
|
||||||
qb.appendWhere(Notes._ID + "=" + uri.getPathSegments().get(1));
|
qb.appendWhere(NoteColumns._ID + "=" + uri.getPathSegments().get(1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIVE_FOLDER_NOTES:
|
case LIVE_FOLDER_NOTES:
|
||||||
@@ -121,7 +121,7 @@ public class NotePadProvider extends ContentProvider {
|
|||||||
// If no sort order is specified use the default
|
// If no sort order is specified use the default
|
||||||
String orderBy;
|
String orderBy;
|
||||||
if (TextUtils.isEmpty(sortOrder)) {
|
if (TextUtils.isEmpty(sortOrder)) {
|
||||||
orderBy = NotePad.Notes.DEFAULT_SORT_ORDER;
|
orderBy = NoteColumns.DEFAULT_SORT_ORDER;
|
||||||
} else {
|
} else {
|
||||||
orderBy = sortOrder;
|
orderBy = sortOrder;
|
||||||
}
|
}
|
||||||
@@ -140,10 +140,10 @@ public class NotePadProvider extends ContentProvider {
|
|||||||
switch (sUriMatcher.match(uri)) {
|
switch (sUriMatcher.match(uri)) {
|
||||||
case NOTES:
|
case NOTES:
|
||||||
case LIVE_FOLDER_NOTES:
|
case LIVE_FOLDER_NOTES:
|
||||||
return Notes.CONTENT_TYPE;
|
return NoteColumns.CONTENT_TYPE;
|
||||||
|
|
||||||
case NOTE_ID:
|
case NOTE_ID:
|
||||||
return Notes.CONTENT_ITEM_TYPE;
|
return NoteColumns.CONTENT_ITEM_TYPE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown URI " + uri);
|
throw new IllegalArgumentException("Unknown URI " + uri);
|
||||||
@@ -167,27 +167,27 @@ public class NotePadProvider extends ContentProvider {
|
|||||||
Long now = Long.valueOf(System.currentTimeMillis());
|
Long now = Long.valueOf(System.currentTimeMillis());
|
||||||
|
|
||||||
// Make sure that the fields are all set
|
// Make sure that the fields are all set
|
||||||
if (values.containsKey(NotePad.Notes.CREATED_DATE) == false) {
|
if (values.containsKey(NoteColumns.CREATED_DATE) == false) {
|
||||||
values.put(NotePad.Notes.CREATED_DATE, now);
|
values.put(NoteColumns.CREATED_DATE, now);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values.containsKey(NotePad.Notes.MODIFIED_DATE) == false) {
|
if (values.containsKey(NoteColumns.MODIFIED_DATE) == false) {
|
||||||
values.put(NotePad.Notes.MODIFIED_DATE, now);
|
values.put(NoteColumns.MODIFIED_DATE, now);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values.containsKey(NotePad.Notes.TITLE) == false) {
|
if (values.containsKey(NoteColumns.TITLE) == false) {
|
||||||
Resources r = Resources.getSystem();
|
Resources r = Resources.getSystem();
|
||||||
values.put(NotePad.Notes.TITLE, r.getString(android.R.string.untitled));
|
values.put(NoteColumns.TITLE, r.getString(android.R.string.untitled));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values.containsKey(NotePad.Notes.NOTE) == false) {
|
if (values.containsKey(NoteColumns.NOTE) == false) {
|
||||||
values.put(NotePad.Notes.NOTE, "");
|
values.put(NoteColumns.NOTE, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
|
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
|
||||||
long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values);
|
long rowId = db.insert(NOTES_TABLE_NAME, NoteColumns.NOTE, values);
|
||||||
if (rowId > 0) {
|
if (rowId > 0) {
|
||||||
Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId);
|
Uri noteUri = ContentUris.withAppendedId(NoteColumns.CONTENT_URI, rowId);
|
||||||
getContext().getContentResolver().notifyChange(noteUri, null);
|
getContext().getContentResolver().notifyChange(noteUri, null);
|
||||||
return noteUri;
|
return noteUri;
|
||||||
}
|
}
|
||||||
@@ -206,7 +206,7 @@ public class NotePadProvider extends ContentProvider {
|
|||||||
|
|
||||||
case NOTE_ID:
|
case NOTE_ID:
|
||||||
String noteId = uri.getPathSegments().get(1);
|
String noteId = uri.getPathSegments().get(1);
|
||||||
count = db.delete(NOTES_TABLE_NAME, Notes._ID + "=" + noteId
|
count = db.delete(NOTES_TABLE_NAME, NoteColumns._ID + "=" + noteId
|
||||||
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
|
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -229,7 +229,7 @@ public class NotePadProvider extends ContentProvider {
|
|||||||
|
|
||||||
case NOTE_ID:
|
case NOTE_ID:
|
||||||
String noteId = uri.getPathSegments().get(1);
|
String noteId = uri.getPathSegments().get(1);
|
||||||
count = db.update(NOTES_TABLE_NAME, values, Notes._ID + "=" + noteId
|
count = db.update(NOTES_TABLE_NAME, values, NoteColumns._ID + "=" + noteId
|
||||||
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
|
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -248,17 +248,17 @@ public class NotePadProvider extends ContentProvider {
|
|||||||
sUriMatcher.addURI(NotePad.AUTHORITY, "live_folders/notes", LIVE_FOLDER_NOTES);
|
sUriMatcher.addURI(NotePad.AUTHORITY, "live_folders/notes", LIVE_FOLDER_NOTES);
|
||||||
|
|
||||||
sNotesProjectionMap = new HashMap<String, String>();
|
sNotesProjectionMap = new HashMap<String, String>();
|
||||||
sNotesProjectionMap.put(Notes._ID, Notes._ID);
|
sNotesProjectionMap.put(NoteColumns._ID, NoteColumns._ID);
|
||||||
sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE);
|
sNotesProjectionMap.put(NoteColumns.TITLE, NoteColumns.TITLE);
|
||||||
sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE);
|
sNotesProjectionMap.put(NoteColumns.NOTE, NoteColumns.NOTE);
|
||||||
sNotesProjectionMap.put(Notes.CREATED_DATE, Notes.CREATED_DATE);
|
sNotesProjectionMap.put(NoteColumns.CREATED_DATE, NoteColumns.CREATED_DATE);
|
||||||
sNotesProjectionMap.put(Notes.MODIFIED_DATE, Notes.MODIFIED_DATE);
|
sNotesProjectionMap.put(NoteColumns.MODIFIED_DATE, NoteColumns.MODIFIED_DATE);
|
||||||
|
|
||||||
// Support for Live Folders.
|
// Support for Live Folders.
|
||||||
sLiveFolderProjectionMap = new HashMap<String, String>();
|
sLiveFolderProjectionMap = new HashMap<String, String>();
|
||||||
sLiveFolderProjectionMap.put(LiveFolders._ID, Notes._ID + " AS " +
|
sLiveFolderProjectionMap.put(LiveFolders._ID, NoteColumns._ID + " AS " +
|
||||||
LiveFolders._ID);
|
LiveFolders._ID);
|
||||||
sLiveFolderProjectionMap.put(LiveFolders.NAME, Notes.TITLE + " AS " +
|
sLiveFolderProjectionMap.put(LiveFolders.NAME, NoteColumns.TITLE + " AS " +
|
||||||
LiveFolders.NAME);
|
LiveFolders.NAME);
|
||||||
// Add more columns here for more robust Live Folders.
|
// Add more columns here for more robust Live Folders.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.example.android.notepad;
|
package com.example.android.notepad;
|
||||||
|
|
||||||
import com.example.android.notepad.NotePad.Notes;
|
|
||||||
|
|
||||||
import android.app.ListActivity;
|
import android.app.ListActivity;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.ContentUris;
|
import android.content.ContentUris;
|
||||||
@@ -28,6 +26,7 @@ import android.os.Bundle;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
import android.view.ContextMenu.ContextMenuInfo;
|
||||||
@@ -35,24 +34,22 @@ import android.widget.AdapterView;
|
|||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.SimpleCursorAdapter;
|
import android.widget.SimpleCursorAdapter;
|
||||||
|
|
||||||
|
import com.example.android.notepad.NotePad.NoteColumns;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays a list of notes. Will display notes from the {@link Uri}
|
* Displays a list of notes. Will display notes from the {@link Uri}
|
||||||
* provided in the intent if there is one, otherwise defaults to displaying the
|
* provided in the intent if there is one, otherwise defaults to displaying the
|
||||||
* contents of the {@link NotePadProvider}
|
* contents of the {@link NoteProvider}
|
||||||
*/
|
*/
|
||||||
public class NotesList extends ListActivity {
|
public class NotesList extends ListActivity {
|
||||||
private static final String TAG = "NotesList";
|
private static final String TAG = "NotesList";
|
||||||
|
|
||||||
// Menu item ids
|
|
||||||
public static final int MENU_ITEM_DELETE = Menu.FIRST;
|
|
||||||
public static final int MENU_ITEM_INSERT = Menu.FIRST + 1;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The columns we are interested in from the database
|
* The columns we are interested in from the database
|
||||||
*/
|
*/
|
||||||
private static final String[] PROJECTION = new String[] {
|
private static final String[] PROJECTION = new String[] {
|
||||||
Notes._ID, // 0
|
NoteColumns._ID, // 0
|
||||||
Notes.TITLE, // 1
|
NoteColumns.TITLE, // 1
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The index of the title column */
|
/** The index of the title column */
|
||||||
@@ -68,7 +65,7 @@ public class NotesList extends ListActivity {
|
|||||||
// as a MAIN activity), then use our default content provider.
|
// as a MAIN activity), then use our default content provider.
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
if (intent.getData() == null) {
|
if (intent.getData() == null) {
|
||||||
intent.setData(Notes.CONTENT_URI);
|
intent.setData(NoteColumns.CONTENT_URI);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inform the list we provide context menus for items
|
// Inform the list we provide context menus for items
|
||||||
@@ -77,23 +74,19 @@ public class NotesList extends ListActivity {
|
|||||||
// Perform a managed query. The Activity will handle closing and requerying the cursor
|
// Perform a managed query. The Activity will handle closing and requerying the cursor
|
||||||
// when needed.
|
// when needed.
|
||||||
Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null,
|
Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null,
|
||||||
Notes.DEFAULT_SORT_ORDER);
|
NoteColumns.DEFAULT_SORT_ORDER);
|
||||||
|
|
||||||
// Used to map notes entries from the database to views
|
// Used to map notes entries from the database to views
|
||||||
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.noteslist_item, cursor,
|
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.noteslist_item, cursor,
|
||||||
new String[] { Notes.TITLE }, new int[] { android.R.id.text1 });
|
new String[] { NoteColumns.TITLE }, new int[] { android.R.id.text1 });
|
||||||
setListAdapter(adapter);
|
setListAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
super.onCreateOptionsMenu(menu);
|
// Inflate menu from XML resource
|
||||||
|
MenuInflater inflater = getMenuInflater();
|
||||||
// This is our one standard application action -- inserting a
|
inflater.inflate(R.menu.list_options_menu, menu);
|
||||||
// new note into the list.
|
|
||||||
menu.add(0, MENU_ITEM_INSERT, 0, R.string.menu_insert)
|
|
||||||
.setShortcut('3', 'a')
|
|
||||||
.setIcon(android.R.drawable.ic_menu_add);
|
|
||||||
|
|
||||||
// Generate any additional actions that can be performed on the
|
// Generate any additional actions that can be performed on the
|
||||||
// overall list. In a normal install, there are no additional
|
// overall list. In a normal install, there are no additional
|
||||||
@@ -104,55 +97,20 @@ public class NotesList extends ListActivity {
|
|||||||
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
|
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
|
||||||
new ComponentName(this, NotesList.class), null, intent, 0, null);
|
new ComponentName(this, NotesList.class), null, intent, 0, null);
|
||||||
|
|
||||||
return true;
|
return super.onCreateOptionsMenu(menu);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
|
||||||
super.onPrepareOptionsMenu(menu);
|
|
||||||
final boolean haveItems = getListAdapter().getCount() > 0;
|
|
||||||
|
|
||||||
// If there are any notes in the list (which implies that one of
|
|
||||||
// them is selected), then we need to generate the actions that
|
|
||||||
// can be performed on the current selection. This will be a combination
|
|
||||||
// of our own specific actions along with any extensions that can be
|
|
||||||
// found.
|
|
||||||
if (haveItems) {
|
|
||||||
// This is the selected item.
|
|
||||||
Uri uri = ContentUris.withAppendedId(getIntent().getData(), getSelectedItemId());
|
|
||||||
|
|
||||||
// Build menu... always starts with the EDIT action...
|
|
||||||
Intent[] specifics = new Intent[1];
|
|
||||||
specifics[0] = new Intent(Intent.ACTION_EDIT, uri);
|
|
||||||
MenuItem[] items = new MenuItem[1];
|
|
||||||
|
|
||||||
// ... is followed by whatever other actions are available...
|
|
||||||
Intent intent = new Intent(null, uri);
|
|
||||||
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
|
|
||||||
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0,
|
|
||||||
items);
|
|
||||||
|
|
||||||
// Give a shortcut to the edit action.
|
|
||||||
if (items[0] != null) {
|
|
||||||
items[0].setShortcut('1', 'e');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
menu.removeGroup(Menu.CATEGORY_ALTERNATIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case MENU_ITEM_INSERT:
|
case R.id.menu_add:
|
||||||
// Launch activity to insert a new item
|
// Launch activity to insert a new item
|
||||||
startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));
|
startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));
|
||||||
return true;
|
return true;
|
||||||
}
|
default:
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
|
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
|
||||||
@@ -170,11 +128,23 @@ public class NotesList extends ListActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the menu header
|
// Inflate menu from XML resource
|
||||||
|
MenuInflater inflater = getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.list_context_menu, menu);
|
||||||
|
|
||||||
|
// Set the context menu header
|
||||||
menu.setHeaderTitle(cursor.getString(COLUMN_INDEX_TITLE));
|
menu.setHeaderTitle(cursor.getString(COLUMN_INDEX_TITLE));
|
||||||
|
|
||||||
// Add a menu item to delete the note
|
// Append to the
|
||||||
menu.add(0, MENU_ITEM_DELETE, 0, R.string.menu_delete);
|
// menu items for any other activities that can do stuff with it
|
||||||
|
// as well. This does a query on the system for any activities that
|
||||||
|
// implement the ALTERNATIVE_ACTION for our data, adding a menu item
|
||||||
|
// for each one that is found.
|
||||||
|
Intent intent = new Intent(null, Uri.withAppendedPath(getIntent().getData(),
|
||||||
|
Integer.toString((int) info.id) ));
|
||||||
|
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
|
||||||
|
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
|
||||||
|
new ComponentName(this, NotesList.class), null, intent, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -187,29 +157,34 @@ public class NotesList extends ListActivity {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case MENU_ITEM_DELETE: {
|
|
||||||
// Delete the note that the context menu is for
|
|
||||||
Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id);
|
Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id);
|
||||||
|
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.context_open:
|
||||||
|
// Launch activity to view/edit the currently selected item
|
||||||
|
startActivity(new Intent(Intent.ACTION_EDIT, noteUri));
|
||||||
|
return true;
|
||||||
|
case R.id.context_delete:
|
||||||
|
// Delete the note that the context menu is for
|
||||||
getContentResolver().delete(noteUri, null, null);
|
getContentResolver().delete(noteUri, null, null);
|
||||||
return true;
|
return true;
|
||||||
|
default:
|
||||||
|
return super.onContextItemSelected(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||||
Uri uri = ContentUris.withAppendedId(getIntent().getData(), id);
|
Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), id);
|
||||||
|
|
||||||
String action = getIntent().getAction();
|
String action = getIntent().getAction();
|
||||||
if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) {
|
if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) {
|
||||||
// The caller is waiting for us to return a note selected by
|
// The caller is waiting for us to return a note selected by
|
||||||
// the user. The have clicked on one, so return it now.
|
// the user. The have clicked on one, so return it now.
|
||||||
setResult(RESULT_OK, new Intent().setData(uri));
|
setResult(RESULT_OK, new Intent().setData(noteUri));
|
||||||
} else {
|
} else {
|
||||||
// Launch activity to view/edit the currently selected item
|
// Launch activity to view/edit the currently selected item
|
||||||
startActivity(new Intent(Intent.ACTION_EDIT, uri));
|
startActivity(new Intent(Intent.ACTION_EDIT, noteUri));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.example.android.notepad;
|
package com.example.android.notepad;
|
||||||
|
|
||||||
import com.example.android.notepad.NotePad.Notes;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
@@ -27,6 +25,8 @@ import android.view.View;
|
|||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import com.example.android.notepad.NotePad.NoteColumns;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An activity that will edit the title of a note. Displays a floating
|
* An activity that will edit the title of a note. Displays a floating
|
||||||
* window with a text field.
|
* window with a text field.
|
||||||
@@ -42,8 +42,8 @@ public class TitleEditor extends Activity implements View.OnClickListener {
|
|||||||
* An array of the columns we are interested in.
|
* An array of the columns we are interested in.
|
||||||
*/
|
*/
|
||||||
private static final String[] PROJECTION = new String[] {
|
private static final String[] PROJECTION = new String[] {
|
||||||
NotePad.Notes._ID, // 0
|
NoteColumns._ID, // 0
|
||||||
NotePad.Notes.TITLE, // 1
|
NoteColumns.TITLE, // 1
|
||||||
};
|
};
|
||||||
/** Index of the title column */
|
/** Index of the title column */
|
||||||
private static final int COLUMN_INDEX_TITLE = 1;
|
private static final int COLUMN_INDEX_TITLE = 1;
|
||||||
@@ -102,7 +102,7 @@ public class TitleEditor extends Activity implements View.OnClickListener {
|
|||||||
if (mCursor != null) {
|
if (mCursor != null) {
|
||||||
// Write the title back to the note
|
// Write the title back to the note
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(Notes.TITLE, mText.getText().toString());
|
values.put(NoteColumns.TITLE, mText.getText().toString());
|
||||||
getContentResolver().update(mUri, values, null, null);
|
getContentResolver().update(mUri, values, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.google.provider;
|
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.provider.BaseColumns;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenience definitions for NotePadProvider
|
|
||||||
*/
|
|
||||||
public final class NotePad {
|
|
||||||
/**
|
|
||||||
* Notes table
|
|
||||||
*/
|
|
||||||
public static final class Notes implements BaseColumns {
|
|
||||||
/**
|
|
||||||
* The content:// style URL for this table
|
|
||||||
*/
|
|
||||||
public static final Uri CONTENT_URI
|
|
||||||
= Uri.parse("content://com.google.provider.NotePad/notes");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default sort order for this table
|
|
||||||
*/
|
|
||||||
public static final String DEFAULT_SORT_ORDER = "modified DESC";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The title of the note
|
|
||||||
* <P>Type: TEXT</P>
|
|
||||||
*/
|
|
||||||
public static final String TITLE = "title";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The note itself
|
|
||||||
* <P>Type: TEXT</P>
|
|
||||||
*/
|
|
||||||
public static final String NOTE = "note";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The timestamp for when the note was created
|
|
||||||
* <P>Type: INTEGER (long)</P>
|
|
||||||
*/
|
|
||||||
public static final String CREATED_DATE = "created";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The timestamp for when the note was last modified
|
|
||||||
* <P>Type: INTEGER (long)</P>
|
|
||||||
*/
|
|
||||||
public static final String MODIFIED_DATE = "modified";
|
|
||||||
}
|
|
||||||
}
|
|
||||||