修改UI/DateTimePickerDialog部分

origin/main
Osako 11 months ago
parent b8bb25dbff
commit 66cb6bbfe1

@ -23,46 +23,52 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.MiNote" android:theme="@style/Theme.MiNote"
tools:targetApi="31"> tools:targetApi="31">
<activity
android:name=".ui.LoginActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity <activity
android:name=".ui.NotesListActivity" android:name=".ui.NotesListActivity"
android:configChanges="keyboardHidden|orientation|screenSize" android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:label="@string/app_name" android:label="@string/app_name"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@style/Theme.AppCompat.Light.DarkActionBar" android:theme="@style/Theme.AppCompat.Light.DarkActionBar"
android:uiOptions="splitActionBarWhenNarrow" android:uiOptions="splitActionBarWhenNarrow"
android:windowSoftInputMode="adjustPan" android:windowSoftInputMode="adjustPan">
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> </activity>
<activity <activity
android:name=".ui.NoteEditActivity" android:name=".ui.NoteEditActivity"
android:configChanges="keyboardHidden|orientation|screenSize" android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@style/Theme.AppCompat.Light.DarkActionBar" android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
android:exported="true">
<intent-filter tools:ignore="AppLinkUrlError"> <intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/text_note" /> <data android:mimeType="vnd.android.cursor.item/text_note" />
<data android:mimeType="vnd.android.cursor.item/call_note" /> <data android:mimeType="vnd.android.cursor.item/call_note" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.INSERT_OR_EDIT" /> <action android:name="android.intent.action.INSERT_OR_EDIT" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/text_note" /> <data android:mimeType="vnd.android.cursor.item/text_note" />
<data android:mimeType="vnd.android.cursor.item/call_note" /> <data android:mimeType="vnd.android.cursor.item/call_note" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.SEARCH" /> <action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter> </intent-filter>
@ -71,16 +77,15 @@
android:resource="@xml/searchable" /> android:resource="@xml/searchable" />
</activity> </activity>
<provider <provider
android:name="net.micode.notes.data.NotesProvider" android:name=".data.NotesProvider"
android:authorities="micode_notes" android:authorities="micode_notes"
android:multiprocess="true" /> android:multiprocess="true" />
<receiver <receiver
android:name=".widget.NoteWidgetProvider_2x" android:name=".widget.NoteWidgetProvider_2x"
android:label="@string/app_widget2x2" android:exported="true"
android:exported="true"> android:label="@string/app_widget2x2">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" /> <action android:name="android.appwidget.action.APPWIDGET_DELETED" />
@ -93,9 +98,8 @@
</receiver> </receiver>
<receiver <receiver
android:name=".widget.NoteWidgetProvider_4x" android:name=".widget.NoteWidgetProvider_4x"
android:label="@string/app_widget4x4" android:exported="true"
android:exported="true"> android:label="@string/app_widget4x4">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" /> <action android:name="android.appwidget.action.APPWIDGET_DELETED" />
@ -106,52 +110,35 @@
android:name="android.appwidget.provider" android:name="android.appwidget.provider"
android:resource="@xml/widget_4x_info" /> android:resource="@xml/widget_4x_info" />
</receiver> </receiver>
<receiver
<receiver android:name=".ui.AlarmInitReceiver" android:name=".ui.AlarmInitReceiver"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver <receiver
android:name="net.micode.notes.ui.AlarmReceiver" android:name=".ui.AlarmReceiver"
android:process=":remote" > android:process=":remote" />
</receiver>
<activity <activity
android:name=".ui.AlarmAlertActivity" android:name=".ui.AlarmAlertActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:launchMode="singleInstance" android:launchMode="singleInstance"
android:theme="@android:style/Theme.Holo.Wallpaper.NoTitleBar" > android:theme="@android:style/Theme.Holo.Wallpaper.NoTitleBar" />
</activity>
<activity <activity
android:name="net.micode.notes.ui.NotesPreferenceActivity" android:name=".ui.NotesPreferenceActivity"
android:label="@string/preferences_title" android:label="@string/preferences_title"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@android:style/Theme.Holo.Light" > android:theme="@android:style/Theme.Holo.Light" />
</activity>
<service <service
android:name="net.micode.notes.gtask.remote.GTaskSyncService" android:name=".gtask.remote.GTaskSyncService"
android:exported="false" > android:exported="false" />
</service>
<meta-data <meta-data
android:name="android.app.default_searchable" android:name="android.app.default_searchable"
android:value=".ui.NoteEditActivity" /> android:value=".ui.NoteEditActivity" />
<!-- <activity-->
<!-- android:name=".MainActivity"-->
<!-- android:exported="true">-->
<!-- <intent-filter>-->
<!-- <action android:name="android.intent.action.MAIN" />-->
<!-- <category android:name="android.intent.category.LAUNCHER" />-->
<!-- </intent-filter>-->
<!-- </activity>-->
</application> </application>
</manifest> </manifest>

@ -299,6 +299,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
Log.d(TAG, "data table has been created"); Log.d(TAG, "data table has been created");
} }
// 同上文的execSQL
private void reCreateDataTableTriggers(SQLiteDatabase db) { private void reCreateDataTableTriggers(SQLiteDatabase db) {
db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_insert"); db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_insert");
db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_update"); db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_update");
@ -309,6 +310,11 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER); db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER);
} }
/*
* 线
* 使
* 使
*/
static synchronized NotesDatabaseHelper getInstance(Context context) { static synchronized NotesDatabaseHelper getInstance(Context context) {
if (mInstance == null) { if (mInstance == null) {
mInstance = new NotesDatabaseHelper(context); mInstance = new NotesDatabaseHelper(context);
@ -316,12 +322,14 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
return mInstance; return mInstance;
} }
// 实现上面创建的两个表格
@Override @Override
public void onCreate(SQLiteDatabase db) { public void onCreate(SQLiteDatabase db) {
createNoteTable(db); createNoteTable(db);
createDataTable(db); createDataTable(db);
} }
// 数据库版本的更新
@Override @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
boolean reCreateTriggers = false; boolean reCreateTriggers = false;
@ -355,6 +363,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
} }
} }
// 更新到V2版本
private void upgradeToV2(SQLiteDatabase db) { private void upgradeToV2(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE.NOTE); db.execSQL("DROP TABLE IF EXISTS " + TABLE.NOTE);
db.execSQL("DROP TABLE IF EXISTS " + TABLE.DATA); db.execSQL("DROP TABLE IF EXISTS " + TABLE.DATA);
@ -362,6 +371,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
createDataTable(db); createDataTable(db);
} }
// 更新到V3版本
private void upgradeToV3(SQLiteDatabase db) { private void upgradeToV3(SQLiteDatabase db) {
// drop unused triggers // drop unused triggers
db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_insert"); db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_insert");
@ -377,6 +387,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.insert(TABLE.NOTE, null, values); db.insert(TABLE.NOTE, null, values);
} }
// 更新到V4版本
private void upgradeToV4(SQLiteDatabase db) { private void upgradeToV4(SQLiteDatabase db) {
db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.VERSION db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.VERSION
+ " INTEGER NOT NULL DEFAULT 0"); + " INTEGER NOT NULL DEFAULT 0");

@ -25,6 +25,7 @@ import android.content.Intent;
import android.content.UriMatcher; import android.content.UriMatcher;
import android.database.Cursor; import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
// Uri代表所要操作的数据Android上可用的每种资源 -包括 图像、视频片段、音频资源等都可以用Uri来表示
import android.net.Uri; import android.net.Uri;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@ -33,10 +34,18 @@ import net.micode.notes.R;
import net.micode.notes.data.Notes.DataColumns; import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.NoteColumns; import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.NotesDatabaseHelper.TABLE; import net.micode.notes.data.NotesDatabaseHelper.TABLE;
/*
*
* ContentProvider
* query
* insert
* update
* delete
* getType
* */
public class NotesProvider extends ContentProvider { public class NotesProvider extends ContentProvider {
private static final UriMatcher mMatcher; private static final UriMatcher mMatcher;// UriMatcher用于匹配Uri
private NotesDatabaseHelper mHelper; private NotesDatabaseHelper mHelper;
@ -51,7 +60,9 @@ public class NotesProvider extends ContentProvider {
private static final int URI_SEARCH_SUGGEST = 6; private static final int URI_SEARCH_SUGGEST = 6;
static { static {
// 创建UriMatcher时调用UriMatcher(UriMatcher.NO_MATCH)表示不匹配任何路径的返回码
mMatcher = new UriMatcher(UriMatcher.NO_MATCH); mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// 把需要匹配的Uri路径全部注册
mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE); mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE);
mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM); mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM);
mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA); mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA);
@ -65,6 +76,7 @@ public class NotesProvider extends ContentProvider {
* x'0A' represents the '\n' character in sqlite. For title and content in the search result, * x'0A' represents the '\n' character in sqlite. For title and content in the search result,
* we will trim '\n' and white space in order to show more information. * we will trim '\n' and white space in order to show more information.
*/ */
// 声明NOTES_SEARCH_PROJECTION
private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + "," private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + ","
+ NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + "," + NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + ","
+ "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_1 + "," + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_1 + ","
@ -73,25 +85,32 @@ public class NotesProvider extends ContentProvider {
+ "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + "," + "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + ","
+ "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA; + "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA;
//声明NOTES_SNIPPET_SEARCH_QUERY
private static String NOTES_SNIPPET_SEARCH_QUERY = "SELECT " + NOTES_SEARCH_PROJECTION private static String NOTES_SNIPPET_SEARCH_QUERY = "SELECT " + NOTES_SEARCH_PROJECTION
+ " FROM " + TABLE.NOTE + " FROM " + TABLE.NOTE
+ " WHERE " + NoteColumns.SNIPPET + " LIKE ?" + " WHERE " + NoteColumns.SNIPPET + " LIKE ?"
+ " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER
+ " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE; + " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE;
// Context只用在onCreate()中才能被初始化
// 对mHelper进行实例化
@Override @Override
public boolean onCreate() { public boolean onCreate() {
mHelper = NotesDatabaseHelper.getInstance(getContext()); mHelper = NotesDatabaseHelper.getInstance(getContext());
return true; return true;
} }
// 查询Uri在数据库中对应的位置
@Override @Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) { String sortOrder) {
Cursor c = null; Cursor c = null;
// 获取可读数据库
SQLiteDatabase db = mHelper.getReadableDatabase(); SQLiteDatabase db = mHelper.getReadableDatabase();
String id = null; String id = null;
// 匹配查找uri
switch (mMatcher.match(uri)) { switch (mMatcher.match(uri)) {
// 对于不同的匹配值,在数据库中查找相应的条目
case URI_NOTE: case URI_NOTE:
c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null, c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null,
sortOrder); sortOrder);
@ -113,6 +132,7 @@ public class NotesProvider extends ContentProvider {
case URI_SEARCH: case URI_SEARCH:
case URI_SEARCH_SUGGEST: case URI_SEARCH_SUGGEST:
if (sortOrder != null || projection != null) { if (sortOrder != null || projection != null) {
// 不合法的参数异常
throw new IllegalArgumentException( throw new IllegalArgumentException(
"do not specify sortOrder, selection, selectionArgs, or projection" + "with this query"); "do not specify sortOrder, selection, selectionArgs, or projection" + "with this query");
} }
@ -120,6 +140,8 @@ public class NotesProvider extends ContentProvider {
String searchString = null; String searchString = null;
if (mMatcher.match(uri) == URI_SEARCH_SUGGEST) { if (mMatcher.match(uri) == URI_SEARCH_SUGGEST) {
if (uri.getPathSegments().size() > 1) { if (uri.getPathSegments().size() > 1) {
// getPathSegments()方法得到一个String的List
// 在uri.getPathSegments().get(1)为第二个元素
searchString = uri.getPathSegments().get(1); searchString = uri.getPathSegments().get(1);
} }
} else { } else {
@ -139,6 +161,7 @@ public class NotesProvider extends ContentProvider {
} }
break; break;
default: default:
// 抛出未知uri的异常
throw new IllegalArgumentException("Unknown URI " + uri); throw new IllegalArgumentException("Unknown URI " + uri);
} }
if (c != null) { if (c != null) {
@ -148,14 +171,18 @@ public class NotesProvider extends ContentProvider {
} }
@Override @Override
// 插入一个uri
public Uri insert(Uri uri, ContentValues values) { public Uri insert(Uri uri, ContentValues values) {
// 获得一个可写的数据库
SQLiteDatabase db = mHelper.getWritableDatabase(); SQLiteDatabase db = mHelper.getWritableDatabase();
long dataId = 0, noteId = 0, insertedId = 0; long dataId = 0, noteId = 0, insertedId = 0;
switch (mMatcher.match(uri)) { switch (mMatcher.match(uri)) {
// 新增一个条目
case URI_NOTE: case URI_NOTE:
insertedId = noteId = db.insert(TABLE.NOTE, null, values); insertedId = noteId = db.insert(TABLE.NOTE, null, values);
break; break;
case URI_DATA: case URI_DATA:
// 如果存在查找NOTE_ID
if (values.containsKey(DataColumns.NOTE_ID)) { if (values.containsKey(DataColumns.NOTE_ID)) {
noteId = values.getAsLong(DataColumns.NOTE_ID); noteId = values.getAsLong(DataColumns.NOTE_ID);
} else { } else {
@ -167,6 +194,7 @@ public class NotesProvider extends ContentProvider {
throw new IllegalArgumentException("Unknown URI " + uri); throw new IllegalArgumentException("Unknown URI " + uri);
} }
// Notify the note uri // Notify the note uri
// notifyChange()获得一个ContextResolver对象并且更新里面的内容
if (noteId > 0) { if (noteId > 0) {
getContext().getContentResolver().notifyChange( getContext().getContentResolver().notifyChange(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null); ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null);
@ -178,13 +206,16 @@ public class NotesProvider extends ContentProvider {
ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null); ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null);
} }
// 返回插入的uri路径
return ContentUris.withAppendedId(uri, insertedId); return ContentUris.withAppendedId(uri, insertedId);
} }
@Override @Override
// 删除一个uri
public int delete(Uri uri, String selection, String[] selectionArgs) { public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0; int count = 0;
String id = null; String id = null;
// 获得可写的数据库
SQLiteDatabase db = mHelper.getWritableDatabase(); SQLiteDatabase db = mHelper.getWritableDatabase();
boolean deleteData = false; boolean deleteData = false;
switch (mMatcher.match(uri)) { switch (mMatcher.match(uri)) {
@ -228,6 +259,7 @@ public class NotesProvider extends ContentProvider {
} }
@Override @Override
// 更新一个uri
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int count = 0; int count = 0;
String id = null; String id = null;
@ -267,10 +299,12 @@ public class NotesProvider extends ContentProvider {
return count; return count;
} }
// 将字符串解析成规定格式
private String parseSelection(String selection) { private String parseSelection(String selection) {
return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""); return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : "");
} }
// 增加一个noteVersion
private void increaseNoteVersion(long id, String selection, String[] selectionArgs) { private void increaseNoteVersion(long id, String selection, String[] selectionArgs) {
StringBuilder sql = new StringBuilder(120); StringBuilder sql = new StringBuilder(120);
sql.append("UPDATE "); sql.append("UPDATE ");
@ -293,6 +327,7 @@ public class NotesProvider extends ContentProvider {
sql.append(selectString); sql.append(selectString);
} }
// execSQL()方法可以执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句
mHelper.getWritableDatabase().execSQL(sql.toString()); mHelper.getWritableDatabase().execSQL(sql.toString());
} }

@ -24,31 +24,43 @@ import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
public class MetaData extends Task { public class MetaData extends Task {
/*
* TAG
* getSimpleName
* */
private final static String TAG = MetaData.class.getSimpleName(); private final static String TAG = MetaData.class.getSimpleName();
private String mRelatedGid = null; private String mRelatedGid = null;
/*
*
* JSONObjectputTasksetNotessetName
* */
public void setMeta(String gid, JSONObject metaInfo) { public void setMeta(String gid, JSONObject metaInfo) {
try { try {
// 将这对键值放入metaInfo这个jsonObject对象中
metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid); metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid);
} catch (JSONException e) { } catch (JSONException e) {
// 输出错误信息
Log.e(TAG, "failed to put related gid"); Log.e(TAG, "failed to put related gid");
} }
setNotes(metaInfo.toString()); setNotes(metaInfo.toString());
setName(GTaskStringUtils.META_NOTE_NAME); setName(GTaskStringUtils.META_NOTE_NAME);
} }
// 获取相关联的Gid
public String getRelatedGid() { public String getRelatedGid() {
return mRelatedGid; return mRelatedGid;
} }
// 判断当前数据是否为空,若为空则返回真,即值得保存
@Override @Override
public boolean isWorthSaving() { public boolean isWorthSaving() {
return getNotes() != null; return getNotes() != null;
} }
// 使用远程json数据对象设置元数据内容
@Override @Override
public void setContentByRemoteJSON(JSONObject js) { public void setContentByRemoteJSON(JSONObject js) {
super.setContentByRemoteJSON(js); super.setContentByRemoteJSON(js);
@ -63,17 +75,20 @@ public class MetaData extends Task {
} }
} }
// 使用本地json数据对象设置元数据内容一般不会用到若用到则抛出异常
@Override @Override
public void setContentByLocalJSON(JSONObject js) { public void setContentByLocalJSON(JSONObject js) {
// this function should not be called // this function should not be called
throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called"); throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");
} }
// 从元数据内容中获取本地json对象一般不会用到若用到则抛出异常
@Override @Override
public JSONObject getLocalJSONFromContent() { public JSONObject getLocalJSONFromContent() {
throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called"); throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called");
} }
// 获取同步动作状态,一般不会用到,若用到,则抛出异常
@Override @Override
public int getSyncAction(Cursor c) { public int getSyncAction(Cursor c) {
throw new IllegalAccessError("MetaData:getSyncAction should not be called"); throw new IllegalAccessError("MetaData:getSyncAction should not be called");

@ -13,7 +13,7 @@
* 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.
*/ */
/*同步操作的基础数据类型,定义了相关指示同步操作的常量*/
package net.micode.notes.gtask.data; package net.micode.notes.gtask.data;
import android.database.Cursor; import android.database.Cursor;
@ -21,31 +21,31 @@ import android.database.Cursor;
import org.json.JSONObject; import org.json.JSONObject;
public abstract class Node { public abstract class Node {
public static final int SYNC_ACTION_NONE = 0; public static final int SYNC_ACTION_NONE = 0;// 本地和云端都无可更新内容
public static final int SYNC_ACTION_ADD_REMOTE = 1; public static final int SYNC_ACTION_ADD_REMOTE = 1;// 需要在远程云端增加内容
public static final int SYNC_ACTION_ADD_LOCAL = 2; public static final int SYNC_ACTION_ADD_LOCAL = 2;// 需要在本地增加内容
public static final int SYNC_ACTION_DEL_REMOTE = 3; public static final int SYNC_ACTION_DEL_REMOTE = 3;// 需要在本地增加内容
public static final int SYNC_ACTION_DEL_LOCAL = 4; public static final int SYNC_ACTION_DEL_LOCAL = 4;// 需要在远程云端删除内容
public static final int SYNC_ACTION_UPDATE_REMOTE = 5; public static final int SYNC_ACTION_UPDATE_REMOTE = 5;// 需要将本地内容更新到远程云端
public static final int SYNC_ACTION_UPDATE_LOCAL = 6; public static final int SYNC_ACTION_UPDATE_LOCAL = 6;// 需要将远程云端内容更新到本地
public static final int SYNC_ACTION_UPDATE_CONFLICT = 7; public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;// 同步出现冲突
public static final int SYNC_ACTION_ERROR = 8; public static final int SYNC_ACTION_ERROR = 8;// 同步出现错误
private String mGid; private String mGid;
private String mName; private String mName;
private long mLastModified; private long mLastModified;// 记录最后一次修改时间
private boolean mDeleted; private boolean mDeleted;// 节点是否被删除
public Node() { public Node() {
mGid = null; mGid = null;

@ -13,7 +13,7 @@
* 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.
*/ */
/*用于支持小米便签最底层的数据库相关操作和sqlNode的关系上是子集关系即data是node的子集节点*/
package net.micode.notes.gtask.data; package net.micode.notes.gtask.data;
import android.content.ContentResolver; import android.content.ContentResolver;
@ -36,41 +36,33 @@ import org.json.JSONObject;
public class SqlData { public class SqlData {
// 得到类的简写名称存入字符串TAG中
private static final String TAG = SqlData.class.getSimpleName(); private static final String TAG = SqlData.class.getSimpleName();
private static final int INVALID_ID = -99999; private static final int INVALID_ID = -99999;// 为nDAtaID置初值-99999
/*来自Notes类中定义的DataColumn中的一些常量*/
public static final String[] PROJECTION_DATA = new String[] { public static final String[] PROJECTION_DATA = new String[] {
DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1, DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1,
DataColumns.DATA3 DataColumns.DATA3
}; };
public static final int DATA_ID_COLUMN = 0; public static final int DATA_ID_COLUMN = 0; // 数据ID列索引
public static final int DATA_MIME_TYPE_COLUMN = 1; // 数据MIME类型列索引
public static final int DATA_MIME_TYPE_COLUMN = 1; public static final int DATA_CONTENT_COLUMN = 2; // 数据内容列索引
public static final int DATA_CONTENT_DATA_1_COLUMN = 3; // 数据内容DATA1列索引
public static final int DATA_CONTENT_COLUMN = 2; public static final int DATA_CONTENT_DATA_3_COLUMN = 4; // 数据内容DATA3列索引
public static final int DATA_CONTENT_DATA_1_COLUMN = 3; private ContentResolver mContentResolver; // 内容解析器
private boolean mIsCreate; // 是否为新建数据
public static final int DATA_CONTENT_DATA_3_COLUMN = 4; private long mDataId; // 数据ID
private String mDataMimeType; // 数据MIME类型
private ContentResolver mContentResolver; private String mDataContent; // 数据内容
private long mDataContentData1; // 数据内容DATA1
private boolean mIsCreate; private String mDataContentData3; // 数据内容DATA3
private ContentValues mDiffDataValues; // 记录数据变化的ContentValues
private long mDataId;
// 构造函数,用于新建数据
private String mDataMimeType;
private String mDataContent;
private long mDataContentData1;
private String mDataContentData3;
private ContentValues mDiffDataValues;
public SqlData(Context context) { public SqlData(Context context) {
mContentResolver = context.getContentResolver(); mContentResolver = context.getContentResolver();
mIsCreate = true; mIsCreate = true;
@ -82,6 +74,7 @@ public class SqlData {
mDiffDataValues = new ContentValues(); mDiffDataValues = new ContentValues();
} }
// 构造函数,用于从数据库读取数据
public SqlData(Context context, Cursor c) { public SqlData(Context context, Cursor c) {
mContentResolver = context.getContentResolver(); mContentResolver = context.getContentResolver();
mIsCreate = false; mIsCreate = false;
@ -89,6 +82,7 @@ public class SqlData {
mDiffDataValues = new ContentValues(); mDiffDataValues = new ContentValues();
} }
// 从游标加载数据
private void loadFromCursor(Cursor c) { private void loadFromCursor(Cursor c) {
mDataId = c.getLong(DATA_ID_COLUMN); mDataId = c.getLong(DATA_ID_COLUMN);
mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN); mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);
@ -97,6 +91,7 @@ public class SqlData {
mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN); mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN);
} }
// 设置内容根据JSON对象
public void setContent(JSONObject js) throws JSONException { public void setContent(JSONObject js) throws JSONException {
long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID; long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;
if (mIsCreate || mDataId != dataId) { if (mIsCreate || mDataId != dataId) {
@ -130,9 +125,10 @@ public class SqlData {
mDataContentData3 = dataContentData3; mDataContentData3 = dataContentData3;
} }
// 获取内容返回JSON对象
public JSONObject getContent() throws JSONException { public JSONObject getContent() throws JSONException {
if (mIsCreate) { if (mIsCreate) {
Log.e(TAG, "it seems that we haven't created this in database yet"); Log.e(TAG, "看起来我们还没有在数据库中创建这个");
return null; return null;
} }
JSONObject js = new JSONObject(); JSONObject js = new JSONObject();
@ -144,8 +140,8 @@ public class SqlData {
return js; return js;
} }
// 提交数据到数据库
public void commit(long noteId, boolean validateVersion, long version) { public void commit(long noteId, boolean validateVersion, long version) {
if (mIsCreate) { if (mIsCreate) {
if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) { if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) {
mDiffDataValues.remove(DataColumns.ID); mDiffDataValues.remove(DataColumns.ID);
@ -156,8 +152,8 @@ public class SqlData {
try { try {
mDataId = Long.valueOf(uri.getPathSegments().get(1)); mDataId = Long.valueOf(uri.getPathSegments().get(1));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
Log.e(TAG, "Get note id error :" + e.toString()); Log.e(TAG, "获取便签ID错误" + e.toString());
throw new ActionFailureException("create note failed"); throw new ActionFailureException("创建便签失败");
} }
} else { } else {
if (mDiffDataValues.size() > 0) { if (mDiffDataValues.size() > 0) {
@ -174,7 +170,7 @@ public class SqlData {
}); });
} }
if (result == 0) { if (result == 0) {
Log.w(TAG, "there is no update. maybe user updates note when syncing"); Log.w(TAG, "没有更新。可能用户在同步时更新了便签");
} }
} }
} }
@ -183,6 +179,7 @@ public class SqlData {
mIsCreate = false; mIsCreate = false;
} }
// 获取数据ID
public long getId() { public long getId() {
return mDataId; return mDataId;
} }

@ -13,7 +13,7 @@
* 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.
*/ */
/**/
package net.micode.notes.gtask.data; package net.micode.notes.gtask.data;
import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetManager;

@ -32,18 +32,25 @@ import android.text.format.DateUtils;
public class DateTimePickerDialog extends AlertDialog implements OnClickListener { public class DateTimePickerDialog extends AlertDialog implements OnClickListener {
private Calendar mDate = Calendar.getInstance(); private Calendar mDate = Calendar.getInstance();
//创建一个Calendar类型的变量 mDate方便时间的操作
private boolean mIs24HourView; private boolean mIs24HourView;
private OnDateTimeSetListener mOnDateTimeSetListener; private OnDateTimeSetListener mOnDateTimeSetListener;
//声明一个时间日期滚动选择控件 mOnDateTimeSetListener
private DateTimePicker mDateTimePicker; private DateTimePicker mDateTimePicker;
//DateTimePicker控件控件一般用于让用户可以从日期列表中选择单个值。
//运行时,单击控件边上的下拉箭头,会显示为两个部分:一个下拉列表,一个用于选择日期的
public interface OnDateTimeSetListener { public interface OnDateTimeSetListener {
void OnDateTimeSet(AlertDialog dialog, long date); void OnDateTimeSet(AlertDialog dialog, long date);
} }
public DateTimePickerDialog(Context context, long date) { public DateTimePickerDialog(Context context, long date) {
//对该界面对话框的实例化
super(context); super(context);
//对数据库的操作
mDateTimePicker = new DateTimePicker(context); mDateTimePicker = new DateTimePicker(context);
setView(mDateTimePicker); setView(mDateTimePicker);
//添加一个子视图
mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() { mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() {
public void onDateTimeChanged(DateTimePicker view, int year, int month, public void onDateTimeChanged(DateTimePicker view, int year, int month,
int dayOfMonth, int hourOfDay, int minute) { int dayOfMonth, int hourOfDay, int minute) {
@ -52,26 +59,33 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener
mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); mDate.set(Calendar.HOUR_OF_DAY, hourOfDay);
mDate.set(Calendar.MINUTE, minute); mDate.set(Calendar.MINUTE, minute);
//将视图中的各选项设置为系统当前时间
updateTitle(mDate.getTimeInMillis()); updateTitle(mDate.getTimeInMillis());
} }
}); });
mDate.setTimeInMillis(date); mDate.setTimeInMillis(date);
//得到系统时间
mDate.set(Calendar.SECOND, 0); mDate.set(Calendar.SECOND, 0);
//将秒数设置为0
mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); mDateTimePicker.setCurrentDate(mDate.getTimeInMillis());
setButton(context.getString(R.string.datetime_dialog_ok), this); setButton(context.getString(R.string.datetime_dialog_ok), this);
setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null); setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null);
//设置按钮
set24HourView(DateFormat.is24HourFormat(this.getContext())); set24HourView(DateFormat.is24HourFormat(this.getContext()));
updateTitle(mDate.getTimeInMillis()); updateTitle(mDate.getTimeInMillis());
//时间标准化打印
} }
public void set24HourView(boolean is24HourView) { public void set24HourView(boolean is24HourView) {
mIs24HourView = is24HourView; mIs24HourView = is24HourView;
} }
//将时间日期滚动选择控件实例化
public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) {
mOnDateTimeSetListener = callBack; mOnDateTimeSetListener = callBack;
} }
//android开发中常见日期管理工具类API——DateUtils按照上下午显示时间
private void updateTitle(long date) { private void updateTitle(long date) {
int flag = int flag =
DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_YEAR |
@ -86,5 +100,7 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener
mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis());
} }
} }
//第一个参数arg0是接收到点击事件的对话框
//第二个参数arg1是该对话框上的按钮
} }

@ -0,0 +1,72 @@
package net.micode.notes.ui;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import net.micode.notes.R;
public class LoginActivity extends Activity {
private EditText accountEdict;
private EditText passwordEdict;
private Button login;
private Button cancel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// EdgeToEdge.enable(this);
setContentView(R.layout.activity_login);
accountEdict = (EditText) findViewById(R.id.account);
accountEdict.setSingleLine();
passwordEdict = (EditText) findViewById(R.id.password);
passwordEdict.setSingleLine();
login = (Button) findViewById(R.id.login);
cancel = (Button) findViewById(R.id.cancel);
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(LoginActivity.this,R.string.app_already_quit,Toast.LENGTH_LONG).show();
finish();
}
});
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String account = accountEdict.getText().toString();
String password = passwordEdict.getText().toString();
if(account.equals("czx") && password.equals("123456")){
AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
builder.setMessage(getString(R.string.Loading));
builder.setCancelable(true);
AlertDialog progressDialog = builder.create();
progressDialog.show();
Intent intent = new Intent(LoginActivity.this,NotesListActivity.class);
startActivity(intent);
finish();
}else {
Toast.makeText(LoginActivity.this, R.string.invalid,Toast.LENGTH_SHORT).show();
}
}
});
// ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
// Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
// v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
// return insets;
// });
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.LoginActivity"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="center">
<TextView
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="18sp"
android:text="@string/prompt_account" />
<EditText
android:id="@+id/account"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:maxLines="1" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="center">
<TextView
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="18sp"
android:text="@string/prompt_password" />
<EditText
android:id="@+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:maxLines="1"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="center">
<Button
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/prompt_login"/>
<Button
android:id="@+id/cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cancel"/>
</LinearLayout>
</LinearLayout>

@ -113,7 +113,9 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="7dip" android:layout_height="7dip"
android:background="@drawable/bg_color_btn_mask" /> android:background="@drawable/bg_color_btn_mask" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<ImageView <ImageView

@ -38,6 +38,9 @@
<!-- note list string --> <!-- note list string -->
<string name="menu_secret">私密模式</string> <string name="menu_secret">私密模式</string>
<string name="menu_quit_secret">退出私密模式</string> <string name="menu_quit_secret">退出私密模式</string>
<string name="menu_flower">背景: 花</string>
<string name="menu_saying">背景: 山</string>
<string name="menu_water">背景: 水</string>
<string name="menu_create_folder">新建文件夹</string> <string name="menu_create_folder">新建文件夹</string>
<string name="menu_export_text">导出文本</string> <string name="menu_export_text">导出文本</string>
<string name="menu_sync">同步</string> <string name="menu_sync">同步</string>

@ -15,8 +15,7 @@
limitations under the License. limitations under the License.
--> -->
<resources xmlns:android="http://schemas.android.com/apk/res/android" <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Notes</string> <string name="app_name">Notes</string>
<string name="app_widget2x2">Notes 2x2</string> <string name="app_widget2x2">Notes 2x2</string>
<string name="app_widget4x4">Notes 4x4</string> <string name="app_widget4x4">Notes 4x4</string>
@ -35,6 +34,10 @@
<string name="note_link_email">Send email</string> <string name="note_link_email">Send email</string>
<string name="note_link_web">Browse web</string> <string name="note_link_web">Browse web</string>
<string name="note_link_other">Open map</string> <string name="note_link_other">Open map</string>
<string name="prompt_account">UserName</string>
<string name="prompt_password">Password</string>
<string name="prompt_login">Login</string>
<string name="cancel">Cancel</string>
<!-- Text export file information --> <!-- Text export file information -->
<string name="file_path">/MIUI/notes/</string> <string name="file_path">/MIUI/notes/</string>
<string name="file_name_txt_format">notes_%s.txt</string> <string name="file_name_txt_format">notes_%s.txt</string>
@ -131,10 +134,13 @@
<string name="search">Notes</string> <string name="search">Notes</string>
<string name="datetime_dialog_ok">set</string> <string name="datetime_dialog_ok">set</string>
<string name="datetime_dialog_cancel">cancel</string> <string name="datetime_dialog_cancel">cancel</string>
<string name="app_already_quit">App already quit</string>
<string name="Loading">Loading</string>
<string name="invalid">Invalid</string>
<plurals name="search_results_title"> <plurals name="search_results_title">
<item quantity="one"><xliff:g id="number" example="1">%1$s</xliff:g> result for \"<xliff:g id="search" example="???">%2$s</xliff:g>\"</item> <item quantity="one"><xliff:g example="1" id="number">%1$s</xliff:g> result for \"<xliff:g example="???" id="search">%2$s</xliff:g>\"</item>
<!-- Case of 0 or 2 or more results. --> <!-- Case of 0 or 2 or more results. -->
<item quantity="other"><xliff:g id="number" example="15">%1$s</xliff:g> results for \"<xliff:g id="search" example="???">%2$s</xliff:g>\"</item> <item quantity="other"><xliff:g example="15" id="number">%1$s</xliff:g> results for \"<xliff:g example="???" id="search">%2$s</xliff:g>\"</item>
</plurals> </plurals>
</resources> </resources>

Loading…
Cancel
Save