one try from cjn

main
4dphencurry 10 months ago
parent 392338e60c
commit ee2aedb5cf

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
Licensed under the Apache License, Version 2.0 (the "License");
@ -31,6 +30,9 @@
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:icon="@drawable/icon_app"
@ -39,15 +41,22 @@
android:name=".ui.NotesListActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTop"
android:launchMode="standard"
android:theme="@style/NoteTheme"
android:uiOptions="splitActionBarWhenNarrow"
android:windowSoftInputMode="adjustPan" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
<activity
@ -143,8 +152,8 @@
android:exported="false" >
</service>
<meta-data
android:name="android.app.default_searchable"
android:value=".ui.NoteEditActivity" />
<!-- <meta-data-->
<!-- android:name="android.app.default_searchable"-->
<!-- android:value=".ui.NoteEditActivity" />-->
</application>
</manifest>

@ -1,9 +0,0 @@
# generated files
bin/
gen/
# Local configuration file (sdk path, etc)
project.properties
.settings/
.classpath
.project

@ -1,190 +0,0 @@
Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
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.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

@ -1,23 +0,0 @@
[中文]
1. MiCode便签是小米便签的社区开源版由MIUI团队(www.miui.com) 发起并贡献第一批代码遵循NOTICE文件所描述的开源协议
今后为MiCode社区(www.micode.net) 拥有,并由社区发布和维护。
2. Bug反馈和跟踪请访问Github,
https://github.com/MiCode/Notes/issues?sort=created&direction=desc&state=open
3. 功能建议和综合讨论请访问MiCode,
http://micode.net/forum.php?mod=forumdisplay&fid=38
[English]
1. MiCode Notes is open source edition of XM notepad, it's first initiated and sponsored by MIUI team (www.miui.com).
It's opened under license described by NOTICE file. It's owned by the MiCode community (www.micode.net). In future,
the MiCode community will release and maintain this project.
2. Regarding issue tracking, please visit Github,
https://github.com/MiCode/Notes/issues?sort=created&direction=desc&state=open
3. Regarding feature request and general discussion, please visit Micode forum,
http://micode.net/forum.php?mod=forumdisplay&fid=38

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -25,6 +25,15 @@ import android.util.Log;
import java.util.HashMap;
/**
*
* @ProjectName: minode
* @Package: net.micode.notes.data
* @ClassName: Contact
* @Description:
* @Author:
* @Date: 2023-12-16 17:57
*/
public class Contact {
private static HashMap<String, String> sContactCache;
private static final String TAG = "Contact";
@ -35,18 +44,29 @@ public class Contact {
+ "(SELECT raw_contact_id "
+ " FROM phone_lookup"
+ " WHERE min_match = '+')";
/**
* @method getContact
* @description
* @date: 2023-12-16 19:24
* @author:
* @return string
*/
public static String getContact(Context context, String phoneNumber) {
if(sContactCache == null) {
sContactCache = new HashMap<String, String>();
}
// 查找HashMap中是否有phoneNumber的信息
// 2023-12-16 19:43
if(sContactCache.containsKey(phoneNumber)) {
return sContactCache.get(phoneNumber);
}
String selection = CALLER_ID_SELECTION.replace("+",
PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));
// 查找数据库中phoneNumber的信息
// 2023-12-16 19:43
Cursor cursor = context.getContentResolver().query(
Data.CONTENT_URI,
new String [] { Phone.DISPLAY_NAME },
@ -54,6 +74,8 @@ public class Contact {
new String[] { phoneNumber },
null);
// 检查是否查询到联系人找到则将相关信息加入HashMap中未找到则处理异常
// 2023-12-16 19:41
if (cursor != null && cursor.moveToFirst()) {
try {
String name = cursor.getString(0);

@ -33,7 +33,7 @@ public class Notes {
public static final int ID_ROOT_FOLDER = 0;
public static final int ID_TEMPARAY_FOLDER = -1;
public static final int ID_CALL_RECORD_FOLDER = -2;
public static final int ID_TRASH_FOLER = -3;
public static final int ID_TRASH_FOLER = -3; // TODO: 2023/12/25 有trash文件夹
public static final String INTENT_EXTRA_ALERT_DATE = "net.micode.notes.alert_date";
public static final String INTENT_EXTRA_BACKGROUND_ID = "net.micode.notes.background_color_id";
@ -161,10 +161,16 @@ public class Notes {
public static final String GTASK_ID = "gtask_id";
/**
* The version code
* <P> Type : INTEGER (long) </P>
* the version code
* <p> type : integer (long) </p>
*/
public static final String VERSION = "version";
/**
* set top state
* <p> type : integer (long) </p>
*/
public static final String TOP = "top";
}
public interface DataColumns {

@ -30,7 +30,7 @@ import net.micode.notes.data.Notes.NoteColumns;
public class NotesDatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "note.db";
private static final int DB_VERSION = 4;
private static final int DB_VERSION = 5;
public interface TABLE {
public static final String NOTE = "note";
@ -60,7 +60,8 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
NoteColumns.LOCAL_MODIFIED + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.ORIGIN_PARENT_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.GTASK_ID + " TEXT NOT NULL DEFAULT ''," +
NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0" +
NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.TOP + " INTEGER NOT NULL DEFAULT 0" +
")";
private static final String CREATE_DATA_TABLE_SQL =
@ -322,6 +323,11 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
oldVersion++;
}
if (oldVersion == 4) {
upgradeToV5(db);
oldVersion++;
}
if (reCreateTriggers) {
reCreateNoteTableTriggers(db);
reCreateDataTableTriggers(db);
@ -359,4 +365,9 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.VERSION
+ " INTEGER NOT NULL DEFAULT 0");
}
private void upgradeToV5(SQLiteDatabase db) {
db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.TOP
+ " INTEGER NOT NULL DEFAULT 0");
}
}

@ -48,6 +48,7 @@ public class NotesProvider extends ContentProvider {
private static final int URI_DATA_ITEM = 4;
private static final int URI_SEARCH = 5;
private static final int URI_SEARCH_SUGGEST = 6;
static {

@ -15,7 +15,6 @@
*/
package net.micode.notes.gtask.exception;
public class NetworkFailureException extends Exception {
private static final long serialVersionUID = 2107610287180234136L;
@ -26,8 +25,7 @@ public class NetworkFailureException extends Exception {
public NetworkFailureException(String paramString) {
super(paramString);
}
public NetworkFailureException(String paramString, Throwable paramThrowable) {
super(paramString, paramThrowable);
}
}
}

@ -47,7 +47,15 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
/**
*
* @ProjectName: minode
* @Package: net.micode.notes.gtask.remote
* @ClassName: GTaskManager
* @Description: 便便
* @Author:
* @Date: 2023-12-18 0:17
*/
public class GTaskManager {
private static final String TAG = GTaskManager.class.getSimpleName();
@ -247,6 +255,13 @@ public class GTaskManager {
}
}
/**
* @method syncContent
* @description 便
* @date: 2023-12-18 0:01
* @author:
* @return void
*/
private void syncContent() throws NetworkFailureException {
int syncType;
Cursor c = null;
@ -351,6 +366,13 @@ public class GTaskManager {
}
/**
* @method syncFolder
* @description
* @date: 2023-12-18 0:04
* @author:
* @return void
*/
private void syncFolder() throws NetworkFailureException {
Cursor c = null;
String gid;
@ -476,6 +498,13 @@ public class GTaskManager {
GTaskClient.getInstance().commitUpdate();
}
/**
* @method doContentSync
* @description syncType便
* @date: 2023-12-18 0:08
* @author:
* @return void
*/
private void doContentSync(int syncType, Node node, Cursor c) throws NetworkFailureException {
if (mCancelled) {
return;

@ -22,7 +22,15 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
/**
*
* @ProjectName: minode
* @Package: net.micode.notes.gtask.remote
* @ClassName: GTaskSyncService
* @Description: Gtask
* @Author:
* @Date: 2023-12-17 23:38
*/
public class GTaskSyncService extends Service {
public final static String ACTION_STRING_NAME = "sync_action_type";
@ -42,6 +50,13 @@ public class GTaskSyncService extends Service {
private static String mSyncProgress = "";
/**
* @method startSync
* @description Gtask
* @date: 2023-12-17 23:42
* @author:
* @return void
*/
private void startSync() {
if (mSyncTask == null) {
mSyncTask = new GTaskASyncTask(this, new GTaskASyncTask.OnCompleteListener() {
@ -52,10 +67,19 @@ public class GTaskSyncService extends Service {
}
});
sendBroadcast("");
// 使同步任务以单线程队列方式开启运行
// 2023-12-17 23:46
mSyncTask.execute();
}
}
/**
* @method cancelSync
* @description Gtask
* @date: 2023-12-17 23:49
* @author:
* @return void
*/
private void cancelSync() {
if (mSyncTask != null) {
mSyncTask.cancelSync();
@ -67,11 +91,20 @@ public class GTaskSyncService extends Service {
mSyncTask = null;
}
/**
* @method onStartCommand
* @description 使GtaskSyncService
* @date: 2023-12-17 23:53
* @author:
* @return int
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle bundle = intent.getExtras();
if (bundle != null && bundle.containsKey(ACTION_STRING_NAME)) {
switch (bundle.getInt(ACTION_STRING_NAME, ACTION_INVALID)) {
// 开始同步或取消同步
// 2023-12-17 23:52
case ACTION_START_SYNC:
startSync();
break;

@ -70,6 +70,10 @@ public class Note {
mNoteData = new NoteData();
}
public void setTopState(String key, int value) {
mNoteDiffValues.put(key, value);
}
public void setNoteValue(String key, String value) {
mNoteDiffValues.put(key, value);
mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);

@ -52,6 +52,8 @@ public class WorkingNote {
private int mWidgetType;
private int mTop;
private long mFolderId;
private Context mContext;
@ -78,7 +80,8 @@ public class WorkingNote {
NoteColumns.BG_COLOR_ID,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
NoteColumns.MODIFIED_DATE
NoteColumns.MODIFIED_DATE,
NoteColumns.TOP
};
private static final int DATA_ID_COLUMN = 0;
@ -101,6 +104,8 @@ public class WorkingNote {
private static final int NOTE_MODIFIED_DATE_COLUMN = 5;
private static final int NOTE_TOP_STATE_COLUMN = 6;
// New note construct
private WorkingNote(Context context, long folderId) {
mContext = context;
@ -111,6 +116,7 @@ public class WorkingNote {
mNoteId = 0;
mIsDeleted = false;
mMode = 0;
mTop = 0;
mWidgetType = Notes.TYPE_WIDGET_INVALIDE;
}
@ -137,6 +143,7 @@ public class WorkingNote {
mWidgetType = cursor.getInt(NOTE_WIDGET_TYPE_COLUMN);
mAlertDate = cursor.getLong(NOTE_ALERTED_DATE_COLUMN);
mModifiedDate = cursor.getLong(NOTE_MODIFIED_DATE_COLUMN);
mTop = cursor.getInt(NOTE_TOP_STATE_COLUMN);
}
cursor.close();
} else {
@ -176,6 +183,14 @@ public class WorkingNote {
public static WorkingNote createEmptyNote(Context context, long folderId, int widgetId,
int widgetType, int defaultBgColorId) {
/**
* @method: createEmptyNote
* @description: 便便
* @date: 2023/12/20 23:55
* @author: zhoukexing
* @param: [context, folderId, widgetId, widgetType, defaultBgColorId]
* @return: net.micode.notes.model.WorkingNote WorkingNote
*/
WorkingNote note = new WorkingNote(context, folderId);
note.setBgColorId(defaultBgColorId);
note.setWidgetId(widgetId);
@ -187,16 +202,24 @@ public class WorkingNote {
return new WorkingNote(context, id, 0);
}
public synchronized boolean saveNote() {
if (isWorthSaving()) {
if (!existInDatabase()) {
public synchronized boolean saveNote() {// TODO: 2023/12/19 要仔细溯源看看
/**
* @method: saveNote
* @description: 便true
* @date: 2023/12/19 23:44
* @author: zhoukexing
* @param: []
* @return: boolean
*/
if (isWorthSaving()) { // 判断是否有新内容-->是否值得注释 @zhoukexing 2023/12/19 23:45
if (!existInDatabase()) { // 判断是否在数据库里存在==是新便签还是已有便签 @zhoukexing 2023/12/19 23:45
if ((mNoteId = Note.getNewNoteId(mContext, mFolderId)) == 0) {
Log.e(TAG, "Create new note fail with id:" + mNoteId);
return false;
}
}
mNote.syncNote(mContext, mNoteId);
mNote.syncNote(mContext, mNoteId); // 和远程同步 @zhoukexing 2023/12/19 23:46
/**
* Update widget content if there exist any widget of this note
@ -208,7 +231,7 @@ public class WorkingNote {
}
return true;
} else {
return false;
return false; // 没有需要保存的就返回false @zhoukexing 2023/12/19 23:46
}
}
@ -225,20 +248,56 @@ public class WorkingNote {
}
}
/**
* @method: setOnSettingStatusChangedListener
* @description: NoteEditActivityNoteSettingChangedListener
* @date: 2023/12/21 0:10
* @author: zhoukexing
* @param: [l] NoteEditActivity
* @return: void
*/
public void setOnSettingStatusChangedListener(NoteSettingChangedListener l) {
//Q: 这里的l是怎么获取的。l是NoteEditActivity @zkx 2023/12/21
mNoteSettingStatusListener = l;
}
public void reverseTopState() {
mTop ^= 1;
mNote.setTopState(NoteColumns.TOP, mTop);
}
public int getmTop(){
return mTop;
}
/**
* @Method setAlertDate
* @Date 2023/12/13 11:43
* @param date
* @param set
* @Author lenovo
* @Return void
* @Description
*/
public void setAlertDate(long date, boolean set) {
// 更新便签项中的提醒日期
if (date != mAlertDate) {
mAlertDate = date;
mNote.setNoteValue(NoteColumns.ALERTED_DATE, String.valueOf(mAlertDate));
}
// 设置提醒的监听事件
if (mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onClockAlertChanged(date, set);
}
}
/**
* @method: markDeleted
* @description:
* @date: 2023/12/21 0:50
* @author: zhoukexing
* @param: [mark]
* @return: void
*/
public void markDeleted(boolean mark) {
mIsDeleted = mark;
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID

@ -80,8 +80,15 @@ public class DataUtils {
resolver.update(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id), values, null, null);
}
public static boolean batchMoveToFolder(ContentResolver resolver, HashSet<Long> ids,
long folderId) {
/**
* @method: batchMoveToFolder
* @description: idsfolderId
* @date: 2024/12/26 3:32
* @author: zhoukexing
* @param: [resolver, ids, folderId]
* @return: boolean
*/
public static boolean batchMoveToFolder(ContentResolver resolver, HashSet<Long> ids, long folderId) {
if (ids == null) {
Log.d(TAG, "the ids is null");
return true;
@ -135,8 +142,22 @@ public class DataUtils {
}
return count;
}
/**
* @Method visibleInNoteDatabase
* @Date 2024/12/13 9:08
* @param resolver
* @param noteId
* @param type
* @Author lenovo
* @Return boolean
* @Description 访 noteId 便
*/
public static boolean visibleInNoteDatabase(ContentResolver resolver, long noteId, int type) {
/**
* withAppendedId URI ID URI
* query Uri selection
* lenovo 2024/12/13 9:06
*/
Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId),
null,
NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER,
@ -292,4 +313,13 @@ public class DataUtils {
}
return snippet;
}
}
public static Cursor searchInNoteDatabase(ContentResolver resolver, String query) {
Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI,
new String[]{NoteColumns.ID},
Notes.DataColumns.CONTENT + " LIKE'%" + query +"%'",
null,
null);
return cursor;
}
}

@ -37,6 +37,7 @@ public class ResourceParser {
public static final int TEXT_LARGE = 2;
public static final int TEXT_SUPER = 3;
public static final int BG_DEFAULT_FONT_SIZE = TEXT_MEDIUM;
public static class NoteBgResources {

@ -47,13 +47,28 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
MediaPlayer mPlayer;
@Override
/**
* @Method onCreate
* @Date 2024/12/25 8:15
* @param savedInstanceState
* @Author lenovo
* @Return void
* @Description
*/
protected void onCreate(Bundle savedInstanceState) {
/**
* Bundel mapkey-value
* super , onCreate
* lenovo 2024/12/25 8:39
*/
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
final Window win = getWindow();
// 在屏幕锁定时显示
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
// 锁屏时到闹钟提示时间后,点亮屏幕
if (!isScreenOn()) {
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
@ -66,6 +81,7 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
try {
mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1));
mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId);
// 超出长度则变为 substr + "..."
mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN ? mSnippet.substring(0,
SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info)
: mSnippet;
@ -75,6 +91,7 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
}
mPlayer = new MediaPlayer();
// 查找数据库中有没有 mNoteId 的便签, 如果有则激发对话框 + 闹钟提示音
if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) {
showActionDialog();
playAlarmSound();
@ -119,7 +136,7 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
}
}
private void showActionDialog() {
private void showActionDialog() {// TODO: 2024/1/2 可以模仿这个写一个xxx条件下弹出来的Dialog
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle(R.string.app_name);
dialog.setMessage(mSnippet);

@ -35,6 +35,8 @@ import android.text.SpannableString;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.style.BackgroundColorSpan;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@ -51,6 +53,10 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Environment;
import android.graphics.Bitmap;
import android.graphics.Typeface; // 自带四种字体
import net.micode.notes.R;
import net.micode.notes.data.Notes;
@ -65,15 +71,27 @@ import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener;
import net.micode.notes.widget.NoteWidgetProvider_2x;
import net.micode.notes.widget.NoteWidgetProvider_4x;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Vector;
import java.io.File;
import java.io.FileOutputStream;
public class NoteEditActivity extends Activity implements OnClickListener,
NoteSettingChangedListener, OnTextViewChangeListener {
public class NoteEditActivity extends Activity //NOTE: extends--单继承,但可多重继承 @zhoukexing 2023/12/17 23:29
implements OnClickListener, NoteSettingChangedListener, OnTextViewChangeListener {
private Intent intent; //NOTE: implements--实现接口 @zhoukexing 2023/12/17 23:24
/** NOTE:
*
* @zhoukexing 2023/12/17 23:39
*/
private class HeadViewHolder {
public TextView tvModified;
@ -81,6 +99,12 @@ public class NoteEditActivity extends Activity implements OnClickListener,
public TextView tvAlertDate;
// 顶部置顶文本
public TextView tvTopText;
// 顶部长度统计文本
public TextView tvTextNum;
public ImageView ibSetBgColor;
}
@ -118,8 +142,13 @@ public class NoteEditActivity extends Activity implements OnClickListener,
sFontSelectorSelectionMap.put(ResourceParser.TEXT_SUPER, R.id.iv_super_select);
}
private static final String TAG = "NoteEditActivity";
private static int mMaxRevokeTimes = 10;
private HeadViewHolder mNoteHeaderHolder;
private View mHeadViewPanel;
@ -136,8 +165,10 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private SharedPreferences mSharedPrefs;
private int mFontSizeId;
private int mFontStyleId;
private static final String PREFERENCE_FONT_SIZE = "pref_font_size";
private static final String PREFERENCE_FONT_STYLE = "pref_font_style";
private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10;
@ -149,15 +180,36 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private String mUserQuery;
private Pattern mPattern;
// 存储改变的数据
private Vector<SpannableString> mHistory = new Vector<SpannableString>(mMaxRevokeTimes);
private boolean mIsRvoke;
/*--- 以上是此类中的数据区,以下是方法区 ---*/
/**
* @zkx 2023/12/18 ActivityonCreate
*/
/**
* @method: onCreate
* @description: list便
* allinall
*
* @date: 2023/12/18 23:22
* @author: zhoukexing
* @param: [savedInstanceState]
* @return: void
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.note_edit);
if (savedInstanceState == null && !initActivityState(getIntent())) {
// 表示之前保存的状态,用于还原数据 @lzk 2024/1/3 23:33
finish();
return;
}
// 初始化资源。我要的设置字体就在这儿
initResources();
}
@ -180,18 +232,26 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private boolean initActivityState(Intent intent) {
/**
* @method: initActivityState
* @description: intentKey-Value便
* @date: 2023/12/18 23:31
* @author: zhoukexing
* @param: [intent]
* @return: boolean callloadintent
*/
/**
* If the user specified the {@link Intent#ACTION_VIEW} but not provided with id,
* then jump to the NotesListActivity
*/
mWorkingNote = null;
if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) {
// 进入场景:点进一个已有便签 @zhoukexing 2023/12/21 0:14
long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0);
mUserQuery = "";
/**
* Starting from the searched result
*/
// 高亮搜索内容 @lzk 2024/1/3 10:10
if (intent.hasExtra(SearchManager.EXTRA_DATA_KEY)) {
noteId = Long.parseLong(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY);
@ -203,7 +263,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
showToast(R.string.error_note_not_exist);
finish();
return false;
} else {
}
else {// 如果在数据库里存在就根据noteId从数据库中加载到工作便签里来 @zhoukexing 2023/12/21 0:16
mWorkingNote = WorkingNote.load(this, noteId);
if (mWorkingNote == null) {
Log.e(TAG, "load note failed with note id" + noteId);
@ -211,20 +272,22 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return false;
}
}
getWindow().setSoftInputMode(
getWindow().setSoftInputMode(// 猜:平滑地展示便签内容 @zhoukexing 2023/12/21 0:18
WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
} else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) {
// New note
}
else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) {
// 进入场景一个New note
long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0);
int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
int widgetType = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_TYPE,
Notes.TYPE_WIDGET_INVALIDE);
Notes.TYPE_WIDGET_INVALIDE); // widgetType=0: 新建的挂件,空的 @zhoukexing 2023/12/21 0:02
int bgResId = intent.getIntExtra(Notes.INTENT_EXTRA_BACKGROUND_ID,
ResourceParser.getDefaultBgId(this));
ResourceParser.getDefaultBgId(this));// TODO: 2023/12/21 背景色的设置
// Parse call-record note
// Parse call-record note todo
// 解析文档,看是否有号码存在,以便展示的时候渲染 @zhoukexing 2023/12/20 23:49
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
long callDate = intent.getLongExtra(Notes.INTENT_EXTRA_CALL_DATE, 0);
if (callDate != 0 && phoneNumber != null) {
@ -234,6 +297,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
long noteId = 0;
if ((noteId = DataUtils.getNoteIdByPhoneNumberAndCallDate(getContentResolver(),
phoneNumber, callDate)) > 0) {
// TODO: 2023/12/20
mWorkingNote = WorkingNote.load(this, noteId);
if (mWorkingNote == null) {
Log.e(TAG, "load call note failed with note id" + noteId);
@ -245,7 +309,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
widgetType, bgResId);
mWorkingNote.convertToCallNote(phoneNumber, callDate);
}
} else {
}
else { // 没有要显示的电话
mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType,
bgResId);
}
@ -253,12 +318,14 @@ public class NoteEditActivity extends Activity implements OnClickListener,
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
| WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
} else {
}
else {
Log.e(TAG, "Intent not specified action, should not support");
finish();
return false;
}
mWorkingNote.setOnSettingStatusChangedListener(this);
// this是WorkingNote @zhoukexing 2023/12/21 0:08
return true;
}
@ -268,9 +335,20 @@ public class NoteEditActivity extends Activity implements OnClickListener,
initNoteScreen();
}
private void showTopHeader(){
if(mWorkingNote.getmTop() == 1){
mNoteHeaderHolder.tvTopText.setText("已置顶");
mNoteHeaderHolder.tvTopText.setVisibility(View.VISIBLE);
}
else{
mNoteHeaderHolder.tvTopText.setVisibility(View.GONE);
}
}
private void initNoteScreen() {
mNoteEditor.setTextAppearance(this, TextAppearanceResources
.getTexAppearanceResource(mFontSizeId));
initFontStyle(mNoteEditor, mFontStyleId);
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
switchToListMode(mWorkingNote.getContent());
} else {
@ -293,17 +371,57 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* is not ready
*/
showAlertHeader();
showTopHeader();
}
private void initFontStyle(EditText edit, int i) {
if (i == 0) {
edit.setTypeface(Typeface.DEFAULT);
} else if (i == 1) {
edit.setTypeface(Typeface.DEFAULT_BOLD);
} else if (i == 2) {
edit.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
} else if (i == 3) {
edit.setTypeface(Typeface.SERIF);
} else if (i == 4) {
Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/FZSTK.ttf");
edit.setTypeface(tf);
} else if (i == 5) {
Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/STXINGKA.ttf");
edit.setTypeface(tf);
} else if (i == 6) {
Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/VINERITC.ttf");
edit.setTypeface(tf);
}
}
/**
* @Method showAlertHeader
* @Date 2023/12/13 11:32
* @Author lenovo
* @Return void
* @Description 便
*/
private void showAlertHeader() {
if (mWorkingNote.hasClockAlert()) {
long time = System.currentTimeMillis();
if (time > mWorkingNote.getAlertDate()) {
// 闹钟时间大于当前时间, 显示 "Expired" 闹钟失效
mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired);
} else {
// 显示正常闹钟信息
mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString(
mWorkingNote.getAlertDate(), time, DateUtils.MINUTE_IN_MILLIS));
}
/**
* setVisibility()
*
* VISIBLE
* INVISIBLE
* GNONE
* lenovo 2023/12/13 11:28
*/
mNoteHeaderHolder.tvAlertDate.setVisibility(View.VISIBLE);
mNoteHeaderHolder.ivAlertIcon.setVisibility(View.VISIBLE);
} else {
@ -315,7 +433,15 @@ public class NoteEditActivity extends Activity implements OnClickListener,
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
initActivityState(intent);
// 若为搜索事件则设置高亮
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
mUserQuery = intent.getStringExtra(SearchManager.QUERY);
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
mNoteEditor.setSelection(mNoteEditor.getText().length());
}
else if(!initActivityState(intent)) {
Log.e(TAG, "Intent Type Error");
};
}
@Override
@ -363,15 +489,61 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return true;
}
/**
* @Method textFilter
* @Date 2024/1/18 9:45
* @param oriText
* @Author lenovo
* @Return java.lang.String
* @Description
*/
private String textFilter(String oriText){
String newText = oriText;
newText = newText.replaceAll("\\s", "");
return newText;
}
/**
* @method: initResources
* @description: onCreate
* @date: 2023/12/18 23:36
* @author: zhoukexing
* @param: []
* @return: void
*/
private void initResources() {
mHeadViewPanel = findViewById(R.id.note_title);
mNoteHeaderHolder = new HeadViewHolder();
mNoteHeaderHolder.tvModified = (TextView) findViewById(R.id.tv_modified_date);
mNoteHeaderHolder.ivAlertIcon = (ImageView) findViewById(R.id.iv_alert_icon);
mNoteHeaderHolder.tvAlertDate = (TextView) findViewById(R.id.tv_alert_date);
mNoteHeaderHolder.tvTopText = (TextView) findViewById(R.id.tv_top_text);
mNoteHeaderHolder.tvTextNum = (TextView) findViewById(R.id.tv_text_num);
mNoteHeaderHolder.ibSetBgColor = (ImageView) findViewById(R.id.btn_set_bg_color);
mNoteHeaderHolder.ibSetBgColor.setOnClickListener(this);
mNoteEditor = (EditText) findViewById(R.id.note_edit_view);
mNoteEditor.addTextChangedListener(new TextWatcher() {
int currentLength = 0;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
mNoteHeaderHolder.tvTextNum.setVisibility(View.VISIBLE);
mNoteHeaderHolder.tvTextNum.setText("长度" + String.valueOf(currentLength));
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
currentLength = textFilter(mNoteEditor.getText().toString()).length();
}
@Override
public void afterTextChanged(Editable s) {//储存文本更改的编辑
if(!mIsRvoke) {
saveHistory();
}else {
mIsRvoke = false;
}
mNoteHeaderHolder.tvTextNum.setText("长度" + String.valueOf(currentLength));
}
});
mNoteEditorPanel = findViewById(R.id.sv_note_edit);
mNoteBgColorSelector = findViewById(R.id.note_bg_color_selector);
for (int id : sBgSelectorBtnsMap.keySet()) {
@ -394,6 +566,10 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) {
mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE;
}
mFontStyleId = mSharedPrefs.getInt(PREFERENCE_FONT_STYLE, 0); // defult style id--0,即对应“默认”字体 @zkx
if(mFontStyleId >= 7) {
mFontStyleId = 0;
}
mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list);
}
@ -406,6 +582,13 @@ public class NoteEditActivity extends Activity implements OnClickListener,
clearSettingState();
}
/**
* @method updateWidget
* @description
* @date: 2023-12-18 21:37
* @author:
* @return void
*/
private void updateWidget() {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_2X) {
@ -430,7 +613,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if (id == R.id.btn_set_bg_color) {
mNoteBgColorSelector.setVisibility(View.VISIBLE);
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
- View.VISIBLE);
View.VISIBLE);
} else if (sBgSelectorBtnsMap.containsKey(id)) {
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
View.GONE);
@ -442,13 +625,15 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mSharedPrefs.edit().putInt(PREFERENCE_FONT_SIZE, mFontSizeId).commit();
findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE);
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
getWorkingText();
getWorkingText(); // DONE切换到清单模式后字体保留
switchToListMode(mWorkingNote.getContent());
} else {
mNoteEditor.setTextAppearance(this,
TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
initFontStyle(mNoteEditor, mFontStyleId); // 因为上面的操作会覆盖掉style的显示所以在这里重新设置一下 @zkx
}
mFontSizeSelector.setVisibility(View.GONE);
}
}
@ -502,59 +687,122 @@ public class NoteEditActivity extends Activity implements OnClickListener,
} else {
menu.findItem(R.id.menu_delete_remind).setVisible(false);
}
if(mWorkingNote.getmTop() == 1){
menu.findItem(R.id.menu_top).setTitle(R.string.cancel_top);
}
else{
menu.findItem(R.id.menu_top).setTitle(R.string.menu_top);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_new_note:
createNewNote();
break;
case R.id.menu_delete:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_note));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
deleteCurrentNote();
finish();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
case R.id.menu_font_size:
mFontSizeSelector.setVisibility(View.VISIBLE);
findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE);
break;
case R.id.menu_list_mode:
mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ?
TextNote.MODE_CHECK_LIST : 0);
break;
case R.id.menu_share:
getWorkingText();
sendTo(this, mWorkingNote.getContent());
break;
case R.id.menu_send_to_desktop:
sendToDesktop();
break;
case R.id.menu_alert:
setReminder();
break;
case R.id.menu_delete_remind:
mWorkingNote.setAlertDate(0, false);
break;
default:
break;
/**
* @method: onOptionsItemSelected
* @description: Activity.javaonOptionsItemSelected线menu-->item
* item
* @date: 2023/12/19 23:35
* @author: zhoukexing
* @param: [item]
* @return: boolean
*/
int itemId = item.getItemId();
if (itemId == R.id.menu_new_note) { // 从item到itemid用itemid导向对应的不同的动作 @zhoukexing 2023/12/19 23:38
createNewNote();
} else if (itemId == R.id.menu_delete) {
// 构建一个警告⚠对话框,让用户确认是否真的要删除便签 @zhoukexing 2023/12/21 0:41
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_note));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {// TODO: 2023/12/21 传入了一个函数作为参数?
public void onClick(DialogInterface dialog, int which) {
deleteCurrentNote(); //TODO: 修改这里达成“在便签内点删除进回收站”
finish();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
} else if (itemId == R.id.menu_font_size) {
mFontSizeSelector.setVisibility(View.VISIBLE);
findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE);
} else if (itemId == R.id.menu_list_mode) {
mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ?
TextNote.MODE_CHECK_LIST : 0);
} else if (itemId == R.id.menu_share) {
getWorkingText();
sendTo(this, mWorkingNote.getContent());
} else if (itemId == R.id.menu_send_to_desktop) {
sendToDesktop();
} else if (itemId == R.id.menu_alert) {
setReminder();
} else if (itemId == R.id.menu_delete_remind) {
mWorkingNote.setAlertDate(0, false);
} else if (itemId == R.id.menu_search) {
onSearchRequested();
} else if (itemId == R.id.menu_top) {
mWorkingNote.reverseTopState();
showTopHeader();
} else if (itemId == R.id.menu_revoke) {
doRevoke();
} else if (itemId == R.id.menu_screenshot) {
doScreenshot();
} else if (itemId == R.id.menu_font_select) {
setFontStyle();
}
return true;
}
public boolean onSearchRequested() {
startSearch(null, false, null /* appData */, false);
return true;
}
private void setFontStyle() {
final String[] items = {"普通", "加粗", "斜体", "等宽", "方正舒体", "行楷", "VINERITC-en"};
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("设置字体");
dialog.setCancelable(true);
dialog.setSingleChoiceItems(items, 0, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {
mFontStyleId = i;
}
});
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {
mSharedPrefs.edit().putInt(PREFERENCE_FONT_STYLE, mFontStyleId).commit();
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
getWorkingText(); // DONE切换到清单模式后字体保留
switchToListMode(mWorkingNote.getContent());
} else {
initFontStyle(mNoteEditor, mFontStyleId);
}
}
});
dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {
}
});
dialog.show();
}
/**
* @Method setReminder
* @Date 2023/12/13 12:52
* @Author lenovo
* @Return void
* @Description
*/
private void setReminder() {
DateTimePickerDialog d = new DateTimePickerDialog(this, System.currentTimeMillis());
// 设置时间选择器的监听事件,当选中 date 之后调用 setAlertDate 设置提醒时间
d.setOnDateTimeSetListener(new OnDateTimeSetListener() {
public void OnDateTimeSet(AlertDialog dialog, long date) {
mWorkingNote.setAlertDate(date , true);
@ -567,25 +815,53 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* Share note to apps that support {@link Intent#ACTION_SEND} action
* and {@text/plain} type
*/
/**
* @method sendTo
* @description 便
* @date: 2023-12-18 0:57
* @author:
* @return void
*/
private void sendTo(Context context, String info) {
// 新建intent消息
// 2023-12-18 1:00
Intent intent = new Intent(Intent.ACTION_SEND);
// 将要分享的便签内容放入intent中
// 2023-12-18 1:01
intent.putExtra(Intent.EXTRA_TEXT, info);
intent.setType("text/plain");
context.startActivity(intent);
}
private void createNewNote() {
/**
* @method: createNewNote
* @description: add note便
* 便NoteEditActivityintent
* intent
* @date: 2023/12/19 23:03
* @author: zhoukexing
* @param: []
* @return: void
*/
// Firstly, save current editing notes
saveNote();
// For safety, start a new NoteEditActivity
finish();
Intent intent = new Intent(this, NoteEditActivity.class);
intent.setAction(Intent.ACTION_INSERT_OR_EDIT);
Intent intent = new Intent(this, NoteEditActivity.class); //Q: 在类的内部,还没有实现完全时,启动这个类自己?@zkx 2023/12/17
intent.setAction(Intent.ACTION_INSERT_OR_EDIT); // 创建便签后要插入或者编辑。Q: 为什么要插入 @zhoukexing 2023/12/19 22:57
intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mWorkingNote.getFolderId());
startActivity(intent);
}
/**
* @method: deleteCurrentNote
* @description: 便
* @date: 2023/12/21 0:48
* @author: zhoukexing
* @param: []
* @return: void
*/
private void deleteCurrentNote() {
if (mWorkingNote.existInDatabase()) {
HashSet<Long> ids = new HashSet<Long>();
@ -595,11 +871,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
} else {
Log.d(TAG, "Wrong note id, should not happen");
}
if (!isSyncMode()) {
if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) {
Log.e(TAG, "Delete Note error");
}
} else {
if (mWorkingNote.getFolderId() == Notes.ID_TRASH_FOLER) {
if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) {
Log.e(TAG, "Delete Note error");
}
} else {
if (!DataUtils.batchMoveToFolder(getContentResolver(), ids, Notes.ID_TRASH_FOLER)) {
Log.e(TAG, "Move notes to trash folder error, should not happens");
}
@ -612,6 +888,15 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0;
}
/**
* @Method onClockAlertChanged
* @Date 2023/12/13 9:52
* @param date
* @param set 0 1
* @Author lenovo
* @Return void
* @Description
*/
public void onClockAlertChanged(long date, boolean set) {
/**
* User could set clock to an unsaved note, so before setting the
@ -627,8 +912,10 @@ public class NoteEditActivity extends Activity implements OnClickListener,
AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE));
showAlertHeader();
if(!set) {
// 取消监听事件
alarmManager.cancel(pendingIntent);
} else {
// 设置监听事件,到时间启动提醒
alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent);
}
} else {
@ -691,7 +978,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
private void switchToListMode(String text) {
private void switchToListMode(String text) { // TODO: 在清单模式下设置的字体大小、样式没法保留
mEditTextList.removeAllViews();
String[] items = text.split("\n");
int index = 0;
@ -729,6 +1016,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null);
final NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);
edit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
initFontStyle(edit, mFontStyleId);
CheckBox cb = ((CheckBox) view.findViewById(R.id.cb_edit_item));
cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
@ -806,8 +1094,16 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private boolean saveNote() {
/**
* @method: saveNote
* @description: 便便list
* @date: 2023/12/19 23:50
* @author: zhoukexing
* @param: []
* @return: boolean
*/
getWorkingText();
boolean saved = mWorkingNote.saveNote();
boolean saved = mWorkingNote.saveNote();// TODO: 2023/12/19 工作便签下的saveNote
if (saved) {
/**
* There are two modes from List view to edit view, open one note,
@ -816,11 +1112,19 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* new node requires to the top of the list. This code
* {@link #RESULT_OK} is used to identify the create/edit state
*/
setResult(RESULT_OK);
setResult(RESULT_OK); // RESULT_OK指示将该便签保存到list界面的顶端因为这是新建的便签 @zhoukexing 2023/12/19 23:41
//Q: 这个setResult只在这里调用了怎么实现的 @zkx 2023/12/19
}
return saved;
}
/**
* @method sendToDesktop
* @description 便
* @date: 2023-12-18 17:27
* @author:
* @return void
*/
private void sendToDesktop() {
/**
* Before send message to home, we should make sure that current
@ -832,9 +1136,13 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
if (mWorkingNote.getNoteId() > 0) {
// 新建intent消息为创建桌面快捷方式的连接器
// 2023-12-18 17:29
Intent sender = new Intent();
Intent shortcutIntent = new Intent(this, NoteEditActivity.class);
shortcutIntent.setAction(Intent.ACTION_VIEW);
// 将便签的相关信息添加进intent中
// 2023-12-18 17:36
shortcutIntent.putExtra(Intent.EXTRA_UID, mWorkingNote.getNoteId());
sender.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
sender.putExtra(Intent.EXTRA_SHORTCUT_NAME,
@ -844,6 +1152,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
sender.putExtra("duplicate", true);
sender.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
showToast(R.string.info_note_enter_desktop);
// 将便签显示于桌面
// 2023-12-18 17:38
sendBroadcast(sender);
} else {
/**
@ -870,4 +1180,86 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private void showToast(int resId, int duration) {
Toast.makeText(this, resId, duration).show();
}
}
/**
* @method saveHistory
* @description
* @date: 2024-01-08 8:56
* @author:
* @return void
*/
private void saveHistory() {
SpannableString text = new SpannableString(mNoteEditor.getText());
if (mHistory.size() >= mMaxRevokeTimes) {
mHistory.removeElementAt(0);
mHistory.add(text);
}
else {
mHistory.add(text);
}
}
/**
* @method doRevoke
* @description
* @date: 2024-01-08 15:56
* @author:
* @return void
*/
private void doRevoke() {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle(R.string.tips_of_revoke);
dialog.setCancelable(true);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
mIsRvoke = true;
if(mHistory.size() <= 1){
dialog.setMessage(R.string.cannot_revoke_anything);
dialog.show();
}
else {
mNoteEditor.setText((CharSequence)mHistory.elementAt(mHistory.size() - 2));
mHistory.removeElementAt(mHistory.size() - 1);
}
}
/**
* @method doScreenshot
* @description
* @date: 2024-01-17 17:20
* @author:
* @return
*/
private void doScreenshot() {
// 调用 getWindow().getDecorView().getRootView() 获取屏幕的根视图
// 使用 getDrawingCache() 获取视图的缓存位图
// 2024-01-17 23:22
View view = getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
// 保存Bitmap对象至文件中
// 2024-01-17 23:21
if (bitmap != null) {
try {
String sdCardPath = Environment.getExternalStorageDirectory().getPath();
String filePath = sdCardPath + File.separator + "screenshot.png";
File file = new File(filePath);
FileOutputStream fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
// showToast(R.string.success_screenshot_saved);
Toast.makeText(this, "Successfully saved the screenshot to" + filePath, Toast.LENGTH_LONG).show();
} catch (Exception e) {
Log.e(TAG, "Take a screenshot error");
showToast(R.string.error_screenshot_saved);
}
}
}
} //NOTE: 这一整个文件就是这一个类 @zhoukexing 2023/12/17 23:41

@ -137,11 +137,19 @@ public class NoteEditText extends EditText {
}
return super.onKeyDown(keyCode, event);
}
/**
* @method: onKeyUp
* @description: deleteenter
* 退
* @date: 2023/12/21 0:28
* @author: zhoukexing
* @param: [keyCode, event]
* @return: boolean
*/
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch(keyCode) {
case KeyEvent.KEYCODE_DEL:
case KeyEvent.KEYCODE_DEL: // delete键的号为67 @zhoukexing 2023/12/21 0:31
if (mOnTextViewChangeListener != null) {
if (0 == mSelectionStartBeforeDelete && mIndex != 0) {
mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString());
@ -151,7 +159,7 @@ public class NoteEditText extends EditText {
Log.d(TAG, "OnTextViewChangeListener was not seted");
}
break;
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_ENTER: // enter键的号为66 @zhoukexing 2023/12/21 0:31
if (mOnTextViewChangeListener != null) {
int selectionStart = getSelectionStart();
String text = getText().subSequence(selectionStart, length()).toString();

@ -40,6 +40,7 @@ public class NoteItemData {
NoteColumns.TYPE,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
NoteColumns.TOP,
};
private static final int ID_COLUMN = 0;
@ -54,7 +55,11 @@ public class NoteItemData {
private static final int TYPE_COLUMN = 9;
private static final int WIDGET_ID_COLUMN = 10;
private static final int WIDGET_TYPE_COLUMN = 11;
private static final int TOP_STATE_COLUMN = 12;
/** NotesDatabaseHelper.java
*
* @zhoukexing 2023/12/25 20:22 */
private long mId;
private long mAlertDate;
private int mBgColorId;
@ -67,6 +72,7 @@ public class NoteItemData {
private int mType;
private int mWidgetId;
private int mWidgetType;
private int mTop;
private String mName;
private String mPhoneNumber;
@ -76,8 +82,16 @@ public class NoteItemData {
private boolean mIsOneNoteFollowingFolder;
private boolean mIsMultiNotesFollowingFolder;
public NoteItemData(Context context, Cursor cursor) {
mId = cursor.getLong(ID_COLUMN);
/**
* @method: NoteItemData
* @description:
* @date: 2023/12/25 19:58
* @author: zhoukexing
* @param: [context, cursor]
* @return:
*/
public NoteItemData(Context context, Cursor cursor) { // 把cursor理解为这样一个指针指向一个表格 @zhoukexing 2023/12/25 20:12
mId = cursor.getLong(ID_COLUMN); // 可以根据传入的列号获取到表格里对应列的值 @zhoukexing 2023/12/25 20:12
mAlertDate = cursor.getLong(ALERTED_DATE_COLUMN);
mBgColorId = cursor.getInt(BG_COLOR_ID_COLUMN);
mCreatedDate = cursor.getLong(CREATED_DATE_COLUMN);
@ -91,10 +105,12 @@ public class NoteItemData {
mType = cursor.getInt(TYPE_COLUMN);
mWidgetId = cursor.getInt(WIDGET_ID_COLUMN);
mWidgetType = cursor.getInt(WIDGET_TYPE_COLUMN);
mTop = cursor.getInt(TOP_STATE_COLUMN);
mPhoneNumber = "";
if (mParentId == Notes.ID_CALL_RECORD_FOLDER) {
if (mParentId == Notes.ID_CALL_RECORD_FOLDER) { //Q: 文件夹为什么有电话记录之说?怎么是通过一个便签的父文件夹来判断便签内有无电话号码?@zkx 2023/12/25
mPhoneNumber = DataUtils.getCallNumberByNoteId(context.getContentResolver(), mId);
// 根据电话号码锁定联系人名称,若不在联系人里,直接使用电话号码 @zhoukexing 2023/12/25 20:17
if (!TextUtils.isEmpty(mPhoneNumber)) {
mName = Contact.getContact(context, mPhoneNumber);
if (mName == null) {
@ -158,6 +174,10 @@ public class NoteItemData {
return mIsOnlyOneItem;
}
public int getTop(){
return mTop;
}
public long getId() {
return mId;
}

@ -16,9 +16,11 @@
package net.micode.notes.ui;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.SearchManager;
import android.appwidget.AppWidgetManager;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
@ -77,7 +79,19 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Queue;
/**
* @Package: net.micode.notes.ui
* @ClassName: NotesListActivity
* @Description: 便
* @Author: zhoukexing
* @CreateDate: 2024/1/18 15:25
* @UpdateUser: none
* @UpdateDate: 2024/1/18 15:25
* @UpdateRemark: none
* @Version: 1.0
*/
public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener {
private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0;
@ -89,11 +103,15 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private static final int MENU_FOLDER_CHANGE_NAME = 2;
private static final int DAY_MODE = 0;
private static final int NIGHT_MODE = 1;
private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction";
private static final String SEARCH_RESULTS = "Search Results: ";
private enum ListEditState {
NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER
};
NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER, TRASH_FOLDER
} //NOTE: 三种编辑状态@zhoukexing 2024/1/2 19:31 新增一个
private ListEditState mState;
@ -135,12 +153,23 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private final static int REQUEST_CODE_OPEN_NODE = 102;
private final static int REQUEST_CODE_NEW_NODE = 103;
private String mTitle;
private String mMessage;
private int mBackground = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.note_list);
if (mBackground == DAY_MODE) {
getWindow().setBackgroundDrawableResource(R.drawable.list_day_mode_background);
} else if (mBackground == NIGHT_MODE) {
getWindow().setBackgroundDrawableResource(R.drawable.list_night_mode_background);
} else {
getWindow().setBackgroundDrawableResource(R.drawable.list_background);
}
initResources();
/**
* Insert an introduction when user firstly use this application
*/
@ -204,9 +233,26 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
@Override
/**
* @Method onStart
* @Date 2024/1/4 8:56
* @Author lenovo
* @Return void
* @Description
*/
protected void onStart() {
super.onStart();
startAsyncNotesListQuery();
Intent intent = getIntent();
// 如果是搜索引起的实体创建,说明需要展示搜索页面
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
mTitleBar.setText(SEARCH_RESULTS + query);
mTitleBar.setVisibility(View.VISIBLE);
mAddNewNote.setVisibility(View.GONE);
// 将搜索数据同步
startAsyncNotesSearchListQuery(query);
}
else startAsyncNotesListQuery();
}
private void initResources() {
@ -218,7 +264,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
null, false);
mNotesListView.setOnItemClickListener(new OnListItemClickListener());
mNotesListView.setOnItemLongClickListener(this);
mNotesListAdapter = new NotesListAdapter(this);
mNotesListAdapter = new NotesListAdapter(this, null);
mNotesListView.setAdapter(mNotesListAdapter);
mAddNewNote = (Button) findViewById(R.id.btn_new_note);
mAddNewNote.setOnClickListener(this);
@ -319,28 +365,41 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
return true;
}
switch (item.getItemId()) {
case R.id.delete:
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_notes,
mNotesListAdapter.getSelectedCount()));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
batchDelete();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
case R.id.move:
startQueryDestinationFolders();
break;
default:
return false;
int itemId = item.getItemId();
if (itemId == R.id.delete) {
switch (mState) {
case SUB_FOLDER:
case CALL_RECORD_FOLDER:
case NOTE_LIST:
mTitle = getString(R.string.alert_title_delete);
mMessage = getString(R.string.alert_message_delete_notes,
mNotesListAdapter.getSelectedCount());
break;
case TRASH_FOLDER:
mTitle = getString(R.string.alert_title_delete_true);
mMessage = getString(R.string.alert_message_delete_notes_true,
mNotesListAdapter.getSelectedCount());
break;
default:
break;
}
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(mTitle);
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(mMessage);
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
batchDelete();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
} else if (itemId == R.id.move) {
startQueryDestinationFolders();
} else {
return false;
}
return true;
}
@ -359,7 +418,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
/**
* Minus TitleBar's height
*/
if (mState == ListEditState.SUB_FOLDER) {
if (mState == ListEditState.SUB_FOLDER ||
mState == ListEditState.TRASH_FOLDER) {
// 回收站的ui显示 @zkx
eventY -= mTitleBar.getHeight();
start -= mTitleBar.getHeight();
}
@ -407,14 +468,33 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
};
/**
* @Method startAsyncNotesListQuery
* @Date 2023/12/19 8:34
* @Author lenovo
* @Return void
* @Description 便便
*/
private void startAsyncNotesListQuery() {
String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION
: NORMAL_SELECTION;
// 按照 Top 降序
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[] {
String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}, NoteColumns.TOP + " DESC," + NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
// DESC 降序
}
private void startAsyncNotesSearchListQuery(String query) {
// 模糊匹配 query
String selection = NoteColumns.SNIPPET + " LIKE'%" + query +"%'";
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI,
NoteItemData.PROJECTION,
selection,
null,
NoteColumns.TOP + " DESC," + NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
private final class BackgroundQueryHandler extends AsyncQueryHandler {
@ -469,20 +549,29 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE);
}
/**
* @method: batchDelete
* @description: 便
* NotesListAdaptermSelectedIndex
* @date: 2024/1/3 23:02
* @author: zhoukexing
* @param: []
* @return: void
*/
private void batchDelete() {
new AsyncTask<Void, Void, HashSet<AppWidgetAttribute>>() {
@SuppressLint("StaticFieldLeak")
protected HashSet<AppWidgetAttribute> doInBackground(Void... unused) {
HashSet<AppWidgetAttribute> widgets = mNotesListAdapter.getSelectedWidget();
if (!isSyncMode()) {
// if not synced, delete notes directly
if (mCurrentFolderId == Notes.ID_TRASH_FOLER){
// if in trash, really delete notes
if (DataUtils.batchDeleteNotes(mContentResolver, mNotesListAdapter
.getSelectedItemIds())) {
} else {
Log.e(TAG, "Delete notes error, should not happens");
}
} else {
// in sync mode, we'll move the deleted note into the trash
// folder
// move notes to trash
if (!DataUtils.batchMoveToFolder(mContentResolver, mNotesListAdapter
.getSelectedItemIds(), Notes.ID_TRASH_FOLER)) {
Log.e(TAG, "Move notes to trash folder error, should not happens");
@ -495,8 +584,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
protected void onPostExecute(HashSet<AppWidgetAttribute> widgets) {
if (widgets != null) {
for (AppWidgetAttribute widget : widgets) {
// widget挂件的Id和Type都不是非法的《==》存在这个widget挂件 @zkx
if (widget.widgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& widget.widgetType != Notes.TYPE_WIDGET_INVALIDE) {
// ==》 删除这个挂件
updateWidget(widget.widgetId, widget.widgetType);
}
}
@ -506,6 +597,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}.execute();
}
/**
* @Method deleteFolder
* @Date 2023/12/19 8:37
* @param folderId
* @Author lenovo
* @Return void
* @Description (sync mode )
*/
private void deleteFolder(long folderId) {
if (folderId == Notes.ID_ROOT_FOLDER) {
Log.e(TAG, "Wrong folder id, should not happen " + folderId);
@ -514,15 +613,17 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
HashSet<Long> ids = new HashSet<Long>();
ids.add(folderId);
// 所有与要删除文件夹相关的 widgets
HashSet<AppWidgetAttribute> widgets = DataUtils.getFolderNoteWidget(mContentResolver,
folderId);
if (!isSyncMode()) {
// if not synced, delete folder directly
if (mCurrentFolderId == Notes.ID_TRASH_FOLER) {
// if in trash, delete folder directly
DataUtils.batchDeleteNotes(mContentResolver, ids);
} else {
// in sync mode, we'll move the deleted folder into the trash folder
// move the deleted folder into the trash folder
DataUtils.batchMoveToFolder(mContentResolver, ids, Notes.ID_TRASH_FOLER);
}
// 更新 widgets
if (widgets != null) {
for (AppWidgetAttribute widget : widgets) {
if (widget.widgetId != AppWidgetManager.INVALID_APPWIDGET_ID
@ -540,33 +641,47 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE);
}
/**
* @Method openFolder
* @Date 2023/12/19 7:55
* @param data
* @Author lenovo
* @Return void
* @Description
*/
private void openFolder(NoteItemData data) {
mCurrentFolderId = data.getId();
startAsyncNotesListQuery();
if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {
// TODO store all records 暂时没太搞明白这个代表什么
mState = ListEditState.CALL_RECORD_FOLDER;
mAddNewNote.setVisibility(View.GONE);
} else {
// 正常打开文件夹
mState = ListEditState.SUB_FOLDER;
}
if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {
mTitleBar.setText(R.string.call_record_folder_name);
} else {
// 将顶部栏设置为 data.getSnippet 文件夹名称
mTitleBar.setText(data.getSnippet());
}
mTitleBar.setVisibility(View.VISIBLE);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_new_note:
createNewNote();
break;
default:
break;
if (v.getId() == R.id.btn_new_note) {
createNewNote();
}
}
/**
* @Method showSoftInput
* @Date 2023/12/17 23:46
* @Author lenovo
* @Return void
* @Description
*/
private void showSoftInput() {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputMethodManager != null) {
@ -579,14 +694,23 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
/**
* @Method showCreateOrModifyFolderDialog
* @Date 2023/12/17 22:32
* @param create true false
* @Author lenovo
* @Return void
* @Description
*/
private void showCreateOrModifyFolderDialog(final boolean create) {
// final 关键字, 初始化之后无法修改 (const)
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
View view = LayoutInflater.from(this).inflate(R.layout.dialog_edit_text, null);
final EditText etName = (EditText) view.findViewById(R.id.et_foler_name);
showSoftInput();
if (!create) {
if (mFocusNoteDataItem != null) {
etName.setText(mFocusNoteDataItem.getSnippet());
etName.setText(mFocusNoteDataItem.getSnippet()); // 显示之前的名称
builder.setTitle(getString(R.string.menu_folder_change_name));
} else {
Log.e(TAG, "The long click data item is null");
@ -596,7 +720,11 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
etName.setText("");
builder.setTitle(this.getString(R.string.menu_create_folder));
}
/**
* OK
* Cancel
* lenovo 2023/12/18 0:03
*/
builder.setPositiveButton(android.R.string.ok, null);
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
@ -610,12 +738,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
public void onClick(View v) {
hideSoftInput(etName);
String name = etName.getText().toString();
// 如果该名称已经存在
if (DataUtils.checkVisibleFolderName(mContentResolver, name)) {
Toast.makeText(NotesListActivity.this, getString(R.string.folder_exist, name),
Toast.LENGTH_LONG).show();
etName.setSelection(0, etName.length());
etName.setSelection(0, etName.length()); //全选输入文件名(准备修改/删除)
return;
}
// 更新数据库中文件夹名称 插入/修改
if (!create) {
if (!TextUtils.isEmpty(name)) {
ContentValues values = new ContentValues();
@ -633,6 +763,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
values.put(NoteColumns.TYPE, Notes.TYPE_FOLDER);
mContentResolver.insert(Notes.CONTENT_NOTE_URI, values);
}
//关闭对话框
dialog.dismiss();
}
});
@ -646,7 +777,6 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
etName.addTextChangedListener(new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
@ -659,21 +789,25 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
}
@Override
public void onBackPressed() {
// 在list清单界面按回退键就会被捕捉到这里执行这个函数 @zhoukexing 2024/1/2 19:33
switch (mState) {
case SUB_FOLDER:
case SUB_FOLDER: // 当前状态是子文件夹,要回退到主文件夹 @zkx
// 特殊情况子文件夹是“回收站”要显式地说明展示底部栏模仿下面的call_record_folder @zkx
// 添加mAddNewNote.setVisibility(View.VISIBLE);此行后,
// sub_folder 和 call_record_folder 两种情况无差别,无需分开处理
mCurrentFolderId = Notes.ID_ROOT_FOLDER;
mState = ListEditState.NOTE_LIST;
startAsyncNotesListQuery();
mTitleBar.setVisibility(View.GONE);
startAsyncNotesListQuery();
break;
case CALL_RECORD_FOLDER:
case TRASH_FOLDER:
mCurrentFolderId = Notes.ID_ROOT_FOLDER;
mState = ListEditState.NOTE_LIST;
mAddNewNote.setVisibility(View.VISIBLE);
@ -688,8 +822,17 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
/**
* @method updateWidget
* @description
* @date: 2023-12-18 21:37
* @author:
* @return void
*/
private void updateWidget(int appWidgetId, int appWidgetType) {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
// 根据不同大小类型的widget更新Widget
// 2023-12-18 21:41
if (appWidgetType == Notes.TYPE_WIDGET_2X) {
intent.setClass(this, NoteWidgetProvider_2x.class);
} else if (appWidgetType == Notes.TYPE_WIDGET_4X) {
@ -726,6 +869,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
super.onContextMenuClosed(menu);
}
/**
* @Method onContextItemSelected
* @Date 2023/12/17 23:51
* @param item
* @Author lenovo
* @Return boolean
* @Description
*/
@Override
public boolean onContextItemSelected(MenuItem item) {
if (mFocusNoteDataItem == null) {
@ -739,7 +890,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
case MENU_FOLDER_DELETE:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setIcon(android.R.drawable.divider_horizontal_dark);
builder.setMessage(getString(R.string.alert_message_delete_folder));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@ -770,72 +921,170 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
GTaskSyncService.isSyncing() ? R.string.menu_sync_cancel : R.string.menu_sync);
} else if (mState == ListEditState.SUB_FOLDER) {
getMenuInflater().inflate(R.menu.sub_folder, menu);
} else if (mState == ListEditState.TRASH_FOLDER) {
getMenuInflater().inflate(R.menu.trash_folder, menu);
} else if (mState == ListEditState.CALL_RECORD_FOLDER) {
getMenuInflater().inflate(R.menu.call_record_folder, menu);
} else {
Log.e(TAG, "Wrong state:" + mState);
}
// 实现交替显示白天和夜间模式
// 2024-01-18 9:09
if (mBackground == DAY_MODE) {
menu.findItem(R.id.menu_day_mode).setVisible(false);
} else if (mBackground == NIGHT_MODE) {
menu.findItem(R.id.menu_night_mode).setVisible(false);
}
return true;
}
/**
* @Method onOptionsItemSelected
* @Date 2023/12/17 23:49
* @param item
* @Author lenovo
* @Return boolean
* @Description
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_new_folder: {
showCreateOrModifyFolderDialog(true);
break;
}
case R.id.menu_export_text: {
exportNoteToText();
break;
}
case R.id.menu_sync: {
if (isSyncMode()) {
if (TextUtils.equals(item.getTitle(), getString(R.string.menu_sync))) {
GTaskSyncService.startSync(this);
} else {
GTaskSyncService.cancelSync(this);
}
int itemId = item.getItemId();
if (itemId == R.id.menu_new_folder) {
showCreateOrModifyFolderDialog(true);
} else if (itemId == R.id.menu_export_text) {
exportNoteToText();
} else if (itemId == R.id.menu_sync) {
if (isSyncMode()) {
if (TextUtils.equals(item.getTitle(), getString(R.string.menu_sync))) {
GTaskSyncService.startSync(this);
} else {
startPreferenceActivity();
GTaskSyncService.cancelSync(this);
}
break;
}
case R.id.menu_setting: {
} else {
startPreferenceActivity();
break;
}
case R.id.menu_new_note: {
createNewNote();
break;
}
case R.id.menu_search:
onSearchRequested();
break;
default:
break;
} else if (itemId == R.id.menu_setting) {
startPreferenceActivity();
} else if (itemId == R.id.menu_new_note) {
createNewNote();
} else if (itemId == R.id.menu_search) {
onSearchRequested();
} else if (itemId == R.id.menu_trash) {
openTrashFolder();
} else if (itemId == R.id.menu_empty_trash) {
emptyTrashFolder();
} else if (itemId == R.id.menu_count_notes) {
countTotalNotes();
} else if (itemId == R.id.menu_day_mode) {
mBackground = DAY_MODE;
getWindow().setBackgroundDrawableResource(R.drawable.list_day_mode_background);
} else if (itemId == R.id.menu_night_mode) {
mBackground = NIGHT_MODE;
getWindow().setBackgroundDrawableResource(R.drawable.list_night_mode_background);
}
return true;
}
private void countTotalNotes() {
AlertDialog.Builder btr =new AlertDialog.Builder(this);
btr.setTitle("目前便签数");
btr.setMessage("目前有 "+Integer.toString(mNotesListAdapter.getMNotesCount())+"个便签");
btr.show();
}
/**
* @method: emptyTrashFolder
* @description: 便
* @date: 2024/1/3 22:59
* @author: zhoukexing
* @param: []
* @return: void
*/
private void emptyTrashFolder() {
// 利用已有函数,在数据结构上“选中”所有便签 @zkx
mNotesListAdapter.selectAll(true);
// 模仿选中R.id.delete构建对话框
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(getString(R.string.alert_title_delete_true));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_notes_true,
mNotesListAdapter.getMNotesCount()));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
// 这里体现了【层次化/模块化】的软件哲学。
// 当时实现这个功能有两条路可以走,
// 一条是修改已有batchDelete里的select函数改为选中所有实现一个alldelete函数
// 一条是利用batchDelete的功能删除选中的便签在进入batchDelete前选中所有
// 后者是更好的。前者需要修改方法,是侵入式的,而且会造成许多代码的重复,没有做到方法与方法之间的低耦合。
batchDelete();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
}
/**
* @method: openTrashFolder
* @description: todo30
* @date: 2024/1/2 19:04
* @author: zhoukexing
* @param: []
* @return: void
*/
private void openTrashFolder() {
mCurrentFolderId = Notes.ID_TRASH_FOLER;
startAsyncNotesListQuery();
// 正常打开文件夹
mState = ListEditState.TRASH_FOLDER;
// 将顶部栏设置为 data.getSnippet 文件夹名称
mTitleBar.setText(NotesListActivity.this
.getString(R.string.menu_trash));
// 不显示底部的“写便签” todoclosed:从子文件夹回到主页面时,展示底部栏
mAddNewNote.setVisibility(View.GONE);
mTitleBar.setVisibility(View.VISIBLE);
}
@Override
/**
* @Method onSearchRequested
* @Date 2023/12/19 8:53
* @Author lenovo
* @Return boolean
* @Description
*/
public boolean onSearchRequested() {
startSearch(null, false, null /* appData */, false);
return true;
}
/**
* @Method exportNoteToText
* @Date 2023/12/19 8:44
* @Author lenovo
* @Return void
* @Description 便
*/
private void exportNoteToText() {
final BackupUtils backup = BackupUtils.getInstance(NotesListActivity.this);
/**
* UI 线
* Warning: deprecated in API level 30
* would cause Context leaks, missed callbacks, or crashes on configuration changes.
* lenovo 2023/12/19 9:04
*/
new AsyncTask<Void, Void, Integer>() {
@Override
// 后台运行导出文本
protected Integer doInBackground(Void... unused) {
return backup.exportToText();
}
@Override
// 线程运行结束后的结果处理程序
protected void onPostExecute(Integer result) {
if (result == BackupUtils.STATE_SD_CARD_UNMOUONTED) {
if (result == BackupUtils.STATE_SD_CARD_UNMOUONTED) { // 没插 SD 卡
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(NotesListActivity.this
.getString(R.string.failed_sdcard_export));
@ -903,6 +1152,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
break;
case SUB_FOLDER:
case CALL_RECORD_FOLDER:
case TRASH_FOLDER:
if (item.getType() == Notes.TYPE_NOTE) {
openNode(item);
} else {
@ -917,6 +1167,13 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
/**
* @Method startQueryDestinationFolders
* @Date 2023/12/19 8:59
* @Author lenovo
* @Return void
* @Description
*/
private void startQueryDestinationFolders() {
String selection = NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>? AND " + NoteColumns.ID + "<>?";
selection = (mState == ListEditState.NOTE_LIST) ? selection:

@ -16,12 +16,14 @@
package net.micode.notes.ui;
import android.text.TextUtils;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.LinearLayout;
import net.micode.notes.data.Notes;
@ -34,22 +36,41 @@ import java.util.Iterator;
public class NotesListAdapter extends CursorAdapter {
private static final String TAG = "NotesListAdapter";
private Context mContext;
/** 键-值对值为true时表示被选中 @zhoukexing 2024/1/2 20:50 */
private HashMap<Integer, Boolean> mSelectedIndex;
// private HashMap<Integer, String> mSnippetPosition;
private int mNotesCount;
private boolean mChoiceMode;
// private String mQuery; // 搜索串
public static class AppWidgetAttribute {
public int widgetId;
public int widgetType;
};
}
public NotesListAdapter(Context context) {
super(context, null);
public NotesListAdapter(Context context, Cursor cursor) {
super(context, cursor);
mSelectedIndex = new HashMap<Integer, Boolean>();
// mSnippetPosition = new HashMap<Integer, String>();
mContext = context;
mNotesCount = 0;
// mQuery="";
}
// @Override
// public View getView(int position, View convertView, ViewGroup parent) {
// View view = super.getView(position, convertView, parent);
// // 仅显示便签项中包含搜索串的便签
// String snippet = mSnippetPosition.get(position);
// Log.e(TAG, snippet);
// if(!TextUtils.isEmpty(mQuery) && !mSnippetPosition.get(position).contains(mQuery)) {
// view.setVisibility(View.GONE);
// LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(0,1);
// view.setLayoutParams(param);
// }
// return view;
// }
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return new NotesListItem(context);
@ -78,6 +99,17 @@ public class NotesListAdapter extends CursorAdapter {
mChoiceMode = mode;
}
/**
* @method: selectAll
* @description: boolean
* setCheckedItemmSelectedIndex
*
* or
* @date: 2024/1/3 22:36
* @author: zhoukexing
* @param: [checked]
* @return: void
*/
public void selectAll(boolean checked) {
Cursor cursor = getCursor();
for (int i = 0; i < getCount(); i++) {
@ -143,11 +175,27 @@ public class NotesListAdapter extends CursorAdapter {
return count;
}
public int getMNotesCount() {
return mNotesCount;
}
/**
* @method: isAllSelected
* @description: truefalse
* @date: 2024/1/2 20:47
* @author: zhoukexing
* @param: []
* @return: boolean
*/
public boolean isAllSelected() {
int checkedCount = getSelectedCount();
return (checkedCount != 0 && checkedCount == mNotesCount);
}
// public void setmQuery(String Query) {
// mQuery = Query;
// }
public boolean isSelectedItem(final int position) {
if (null == mSelectedIndex.get(position)) {
return false;
@ -159,14 +207,46 @@ public class NotesListAdapter extends CursorAdapter {
protected void onContentChanged() {
super.onContentChanged();
calcNotesCount();
// updateSnippetMap(); // 在数据发生改变时更新 Snippet 到 Position 的映射
}
/**
* @Method changeCursor
* @Date 2024/1/18 15:36
* @param cursor
* @Author lenovo
* @Return void
* @Description cursor
*/
@Override
public void changeCursor(Cursor cursor) {
super.changeCursor(cursor);
calcNotesCount();
// updateSnippetMap(); // 在数据发生改变时更新 Snippet 到 Position 的映射
}
// private void updateSnippetMap() {
// mSnippetPosition = new HashMap<Integer, String>();
// for (int i = 0; i < getCount(); i++) {
// Cursor c = (Cursor) getItem(i);
// if (c != null) {
// int position = c.getPosition();
// NoteItemData item = new NoteItemData(mContext, c);
// mSnippetPosition.put(position, item.getSnippet());
// } else {
// Log.e(TAG, "Invalid cursor");
// break;
// }
// }
// }
/**
* @Method calcNotesCount
* @Date 2024/1/18 15:36
* @Author lenovo
* @Return void
* @Description 便
*/
private void calcNotesCount() {
mNotesCount = 0;
for (int i = 0; i < getCount(); i++) {

@ -30,8 +30,16 @@ import net.micode.notes.tool.DataUtils;
import net.micode.notes.tool.ResourceParser.NoteItemBgResources;
/**
* @Package:
* @Class: NotesListItem
* @Author lenovo
* @Date 2024/1/18 15:43
* @Description: 便
*/
public class NotesListItem extends LinearLayout {
private ImageView mAlert;
private ImageView mTop;
private TextView mTitle;
private TextView mTime;
private TextView mCallName;
@ -42,6 +50,7 @@ public class NotesListItem extends LinearLayout {
super(context);
inflate(context, R.layout.note_item, this);
mAlert = (ImageView) findViewById(R.id.iv_alert_icon);
mTop = (ImageView) findViewById(R.id.iv_top_icon);
mTitle = (TextView) findViewById(R.id.tv_title);
mTime = (TextView) findViewById(R.id.tv_time);
mCallName = (TextView) findViewById(R.id.tv_name);
@ -95,6 +104,14 @@ public class NotesListItem extends LinearLayout {
}
}
mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate()));
// 设置置顶图标
if(data.getTop() == 1){
mTop.setImageResource(R.drawable.set_top);
mTop.setVisibility(View.VISIBLE);
}
else{
mTop.setVisibility(View.GONE);
}
setBackground(data);
}

@ -32,11 +32,20 @@ import net.micode.notes.tool.ResourceParser;
import net.micode.notes.ui.NoteEditActivity;
import net.micode.notes.ui.NotesListActivity;
/**
*
* @ProjectName: minode
* @Package: net.micode.notes.widget
* @ClassName: NoteWidgetProvider
* @Description: AppWidgetProvider
* @Date: 2024-12-18 21:13
*/
public abstract class NoteWidgetProvider extends AppWidgetProvider {
public static final String [] PROJECTION = new String [] {
NoteColumns.ID,
NoteColumns.BG_COLOR_ID,
NoteColumns.SNIPPET
NoteColumns.ID,
NoteColumns.BG_COLOR_ID,
NoteColumns.SNIPPET
};
public static final int COLUMN_ID = 0;
@ -45,6 +54,12 @@ public abstract class NoteWidgetProvider extends AppWidgetProvider {
private static final String TAG = "NoteWidgetProvider";
/**
* @method onDeleted
* @description Widget
* @date: 2024-12-18 21:18
* @return void
*/
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
ContentValues values = new ContentValues();
@ -65,12 +80,18 @@ public abstract class NoteWidgetProvider extends AppWidgetProvider {
null);
}
/**
* @method update
* @description Widget
* @date: 2024-12-18 21:11
* @return void
*/
protected void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
update(context, appWidgetManager, appWidgetIds, false);
}
private void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds,
boolean privacyMode) {
boolean privacyMode) {
for (int i = 0; i < appWidgetIds.length; i++) {
if (appWidgetIds[i] != AppWidgetManager.INVALID_APPWIDGET_ID) {
int bgId = ResourceParser.getDefaultBgId(context);

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 KiB

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save