最终代码合并

wushuxian_branch
SheYu 10 months ago
parent d59eca4218
commit adf5cfc4bd

@ -1,20 +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");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!--- 定义应用程序的名称和版本号 -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.micode.notes"
@ -48,9 +32,10 @@
<!--- 应用程序组件声明 -->
<!--- 定义应用程序的图标和名称 -->
<application
android:icon="@drawable/icon_app"
android:icon="@drawable/icon_app_1"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true">
android:requestLegacyExternalStorage="true"
android:testOnly="true" >
<activity
android:name=".ui.SplashActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
@ -65,6 +50,7 @@
<!--- 应用程序的入口 NotesListActivity -->
<activity
android:name=".ui.NotesListActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"

@ -28,14 +28,7 @@ import net.micode.notes.R;
import net.micode.notes.ui.NotesListActivity;
import net.micode.notes.ui.NotesPreferenceActivity;
/**
* @Package: net.micode.notes.gtask.remote
* @ClassName: GTaskASyncTask
* @Description: GTask
* @Author: WuShuxian
* @CreateDate: 2023/12/24 20:49
* @Version: 1.0
*/
public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
private static int GTASK_SYNC_NOTIFICATION_ID = 5234235;
@ -69,22 +62,9 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
message
});
}
/**
* @method showNotification
* @description:
* @date: 2023/12/24 20:50
* @author: WuShuxian
* @param:
* @return:
*/
private void showNotification(int tickerId, String content) {
Notification notification = new Notification(R.drawable.notification, mContext
.getString(tickerId), System.currentTimeMillis());
notification.defaults = Notification.DEFAULT_LIGHTS;
notification.flags = Notification.FLAG_AUTO_CANCEL;
PendingIntent pendingIntent;
//如果同步不成功那么从系统取得一个用于启动一个NotesPreferenceActivity的PendingIntent对象
//如果同步成功那么从系统取得一个用于启动一个NotesListActivity的PendingIntent对象
if (tickerId != R.string.ticker_success) {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesPreferenceActivity.class), 0);
@ -93,18 +73,21 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesListActivity.class), 0);
}
//notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content,
//pendingIntent);
Notification.Builder builder = new Notification.Builder(mContext)
.setAutoCancel(true)
.setContentTitle(mContext.getString(R.string.app_name))
.setContentText(content)
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.setOngoing(true);
Notification notification=builder.getNotification();
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
}
/**
* @method doInBackground
* @description: 线
* @date: 2023/12/24 20:51
* @author: WuShuxian
* @param:
* @return:
*/
@Override
protected Integer doInBackground(Void... unused) {
publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity
@ -112,14 +95,6 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
return mTaskManager.sync(mContext, this);
}
/**
* @method onProgressUpdate
* @description: 使 线
* @date: 2023/12/24 20:51
* @author: WuShuxian
* @param:
* @return:
*/
@Override
protected void onProgressUpdate(String... progress) {
showNotification(R.string.ticker_syncing, progress[0]);
@ -128,14 +103,6 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
}
}
/**
* @method onPostExecute
* @description: Handler UI使doInBackground UI
* @date: 2023/12/24 20:51
* @author: WuShuxian
* @param:
* @return:
*/
@Override
protected void onPostExecute(Integer result) {
if (result == GTaskManager.STATE_SUCCESS) {

@ -60,14 +60,7 @@ import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
/**
* @Package: net.micode.notes.gtask.remote
* @ClassName: GTaskClient
* @Description: GTASKGTASK
* @Author: WuShuxian
* @CreateDate: 2023/12/24 20:55
* @Version: 1.0
*/
public class GTaskClient {
private static final String TAG = GTaskClient.class.getSimpleName();
@ -97,12 +90,6 @@ public class GTaskClient {
private JSONArray mUpdateArray;
/**
* @method GTaskClient
* @description:
* @date: 2023/12/24 20:56
* @author: WuShuxian
*/
private GTaskClient() {
mHttpClient = null;
mGetUrl = GTASK_GET_URL;
@ -121,40 +108,35 @@ public class GTaskClient {
}
return mInstance;
}
/**
* @method login
* @description: 使URL使URL
* @date: 2023/12/24 21:15
* @author: WuShuxian
* @param: activity
* @return: boolean
*/
public boolean login(Activity activity) {
//判断距离最后一次登录操作是否超过5分钟
// we suppose that the cookie would expire after 5 minutes
// then we need to re-login
final long interval = 1000 * 60 * 5;
if (mLastLoginTime + interval < System.currentTimeMillis()) {
mLoggedin = false;
}
// 重新登陆操作
// need to re-login after account switch
if (mLoggedin
&& !TextUtils.equals(getSyncAccount().name, NotesPreferenceActivity
.getSyncAccountName(activity))) {
mLoggedin = false;
}
//如果没超过时间,则不需要重新登录
if (mLoggedin) {
Log.d(TAG, "already logged in");
return true;
}
mLastLoginTime = System.currentTimeMillis();//更新最后登录时间为系统当前的时间
String authToken = loginGoogleAccount(activity, false);//判断是否登录到谷歌账户
mLastLoginTime = System.currentTimeMillis();
String authToken = loginGoogleAccount(activity, false);
if (authToken == null) {
Log.e(TAG, "login google account failed");
return false;
}
// login with custom domain if necessary
if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || mAccount.name.toLowerCase()
.endsWith("googlemail.com"))) {
StringBuilder url = new StringBuilder(GTASK_URL).append("a/");
@ -168,7 +150,8 @@ public class GTaskClient {
mLoggedin = true;
}
}
//如果用户账户无法登录则使用谷歌官方的URI进行登录
// try to login with google official url
if (!mLoggedin) {
mGetUrl = GTASK_GET_URL;
mPostUrl = GTASK_POST_URL;
@ -180,14 +163,7 @@ public class GTaskClient {
mLoggedin = true;
return true;
}
/**
* @method loginGoogleAccount
* @description:
* @date: 2023/12/24 23:07
* @author: WuShuxian
* @param: activity
* @return: String
*/
private String loginGoogleAccount(Activity activity, boolean invalidateToken) {
String authToken;
AccountManager accountManager = AccountManager.get(activity);
@ -200,7 +176,6 @@ public class GTaskClient {
String accountName = NotesPreferenceActivity.getSyncAccountName(activity);
Account account = null;
//遍历获得的accounts信息寻找已经记录过的账户信息
for (Account a : accounts) {
if (a.name.equals(accountName)) {
account = a;
@ -214,7 +189,7 @@ public class GTaskClient {
return null;
}
//获取令牌
// get the token now
AccountManagerFuture<Bundle> accountManagerFuture = accountManager.getAuthToken(account,
"goanna_mobile", null, activity, null, null);
try {
@ -231,16 +206,11 @@ public class GTaskClient {
return authToken;
}
/**
* @method tryToLoginGtask
* @description: GtaskGTask,
* @date: 2023/12/24 21:01
* @author: WuShuxian
* @param:
* @return:
*/
private boolean tryToLoginGtask(Activity activity, String authToken) {
if (!loginGtask(authToken)) {
// maybe the auth token is out of date, now let's invalidate the
// token and try again
authToken = loginGoogleAccount(activity, true);
if (authToken == null) {
Log.e(TAG, "login google account failed");
@ -254,33 +224,26 @@ public class GTaskClient {
}
return true;
}
/**
* @method loginGtask
* @description:
* @date: 2023/12/24 21:05
* @author: WuShuxian
* @param:
* @return:
*/
private boolean loginGtask(String authToken) {
int timeoutConnection = 10000;
int timeoutSocket = 15000; //socket是一种通信连接实现数据的交换的端口
HttpParams httpParameters = new BasicHttpParams(); //实例化一个新的HTTP参数类
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);//设置连接超时时间
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);//设置设置端口超时时间
int timeoutSocket = 15000;
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
mHttpClient = new DefaultHttpClient(httpParameters);
BasicCookieStore localBasicCookieStore = new BasicCookieStore();
mHttpClient.setCookieStore(localBasicCookieStore);
HttpProtocolParams.setUseExpectContinue(mHttpClient.getParams(), false);
//登录操作
// login gtask
try {
String loginUrl = mGetUrl + "?auth=" + authToken;//设置登录的URL
HttpGet httpGet = new HttpGet(loginUrl);//通过登录的uri实例化网页上资源的查找
String loginUrl = mGetUrl + "?auth=" + authToken;
HttpGet httpGet = new HttpGet(loginUrl);
HttpResponse response = null;
response = mHttpClient.execute(httpGet);
//获取CookieStore里存放的cookie,如果存有“GTL”则cookie有效
// get the cookie now
List<Cookie> cookies = mHttpClient.getCookieStore().getCookies();
boolean hasAuthCookie = false;
for (Cookie cookie : cookies) {
@ -292,7 +255,7 @@ public class GTaskClient {
Log.w(TAG, "it seems that there is no auth cookie");
}
//获取client的内容
// get the client version
String resString = getResponseContent(response.getEntity());
String jsBegin = "_setup(";
String jsEnd = ")}</script>";
@ -309,6 +272,7 @@ public class GTaskClient {
e.printStackTrace();
return false;
} catch (Exception e) {
// simply catch all exceptions
Log.e(TAG, "httpget gtask_url failed");
return false;
}
@ -319,24 +283,14 @@ public class GTaskClient {
private int getActionId() {
return mActionId++;
}
/**
* @method createHttpPost
* @description:
* @date: 2023/12/24 23:13
* @author: WuShuxian
*/
private HttpPost createHttpPost() {
HttpPost httpPost = new HttpPost(mPostUrl);
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
httpPost.setHeader("AT", "1");
return httpPost;
}
/**
* @method getResponseContent
* @description: URL
* @date: 2023/12/24 21:06
* @author: WuShuxian
*/
private String getResponseContent(HttpEntity entity) throws IOException {
String contentEncoding = null;
if (entity.getContentEncoding() != null) {
@ -368,20 +322,13 @@ public class GTaskClient {
input.close();
}
}
/**
* @method postRequest
* @description: Json
* @date: 2023/12/24 21:07
* @author: WuShuxian
* @param: js
* @return:
*/
private JSONObject postRequest(JSONObject js) throws NetworkFailureException {
if (!mLoggedin) {
Log.e(TAG, "please login first");
throw new ActionFailureException("not logged in");
}
//实例化一个httpPost的对象用来向服务器传输数据在这里就是发送请求而请求的内容在js里
HttpPost httpPost = createHttpPost();
try {
LinkedList<BasicNameValuePair> list = new LinkedList<BasicNameValuePair>();
@ -389,8 +336,9 @@ public class GTaskClient {
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
httpPost.setEntity(entity);
// execute the post
HttpResponse response = mHttpClient.execute(httpPost);
String jsString = getResponseContent(response.getEntity());//得到返回的数据和资源
String jsString = getResponseContent(response.getEntity());
return new JSONObject(jsString);
} catch (ClientProtocolException e) {
@ -411,25 +359,21 @@ public class GTaskClient {
throw new ActionFailureException("error occurs when posting request");
}
}
/**
* @method createTask
* @description:
* @date: 2023/12/24 21:08
* @author: WuShuxian
* @param: task
* @return: void
*/
public void createTask(Task task) throws NetworkFailureException {
commitUpdate();
try {
JSONObject jsPost = new JSONObject();
JSONArray actionList = new JSONArray();
// action_list
actionList.put(task.getCreateAction(getActionId()));
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);
// client_version
jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);
// post
JSONObject jsResponse = postRequest(jsPost);
JSONObject jsResult = (JSONObject) jsResponse.getJSONArray(
GTaskStringUtils.GTASK_JSON_RESULTS).get(0);
@ -441,29 +385,25 @@ public class GTaskClient {
throw new ActionFailureException("create task: handing jsonobject failed");
}
}
/**
* @method createTaskList
* @description: createTasktasklistgid
* @date: 2023/12/24 21:09
* @author: WuShuxian
* @param: tasklist
* @return: void
*/
public void createTaskList(TaskList tasklist) throws NetworkFailureException {
commitUpdate();
try {
JSONObject jsPost = new JSONObject();
JSONArray actionList = new JSONArray();
// action_list
actionList.put(tasklist.getCreateAction(getActionId()));
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);
// client version
jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);
JSONObject jsResponse = postRequest(jsPost);//得到任务的返回信息
// post
JSONObject jsResponse = postRequest(jsPost);
JSONObject jsResult = (JSONObject) jsResponse.getJSONArray(
GTaskStringUtils.GTASK_JSON_RESULTS).get(0);
tasklist.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID));//设置task的new_id
tasklist.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID));
} catch (JSONException e) {
Log.e(TAG, e.toString());
@ -477,8 +417,10 @@ public class GTaskClient {
try {
JSONObject jsPost = new JSONObject();
// action_list
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, mUpdateArray);
// client_version
jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);
postRequest(jsPost);
@ -490,17 +432,11 @@ public class GTaskClient {
}
}
}
/**
* @method addUpdateNode
* @description:
* @date: 2023/12/24 23:19
* @author: WuShuxian
* @param: node
* @return: void
*/
public void addUpdateNode(Node node) throws NetworkFailureException {
if (node != null) {
//设置更新同步项目数量上限10
// too many update items may result in an error
// set max to 10 items
if (mUpdateArray != null && mUpdateArray.length() > 10) {
commitUpdate();
}
@ -510,14 +446,7 @@ public class GTaskClient {
mUpdateArray.put(node.getUpdateAction(getActionId()));
}
}
/**
* @method moveTask
* @description: task,tasktask
* @date: 2023/12/24 23:19
* @author: WuShuxian
* @param: taskpreParentcurParent
* @return: void
*/
public void moveTask(Task task, TaskList preParent, TaskList curParent)
throws NetworkFailureException {
commitUpdate();
@ -526,22 +455,26 @@ public class GTaskClient {
JSONArray actionList = new JSONArray();
JSONObject action = new JSONObject();
// 动作序列
// action_list
action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_MOVE);
action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId());
action.put(GTaskStringUtils.GTASK_JSON_ID, task.getGid());
if (preParent == curParent && task.getPriorSibling() != null) {
action.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, task.getPriorSibling());//设置优先级ID只有当移动是发生在文件中
// put prioring_sibing_id only if moving within the tasklist and
// it is not the first one
action.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, task.getPriorSibling());
}
action.put(GTaskStringUtils.GTASK_JSON_SOURCE_LIST, preParent.getGid());
action.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT, curParent.getGid());
if (preParent != curParent) {
action.put(GTaskStringUtils.GTASK_JSON_DEST_LIST, curParent.getGid());//仅当在任务列表之间移动时才放入dest_list
// put the dest_list only if moving between tasklists
action.put(GTaskStringUtils.GTASK_JSON_DEST_LIST, curParent.getGid());
}
actionList.put(action);
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);//将ACTION_LIST加入到jsPost中
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);
// client_version
jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);
postRequest(jsPost);
@ -552,27 +485,22 @@ public class GTaskClient {
throw new ActionFailureException("move task: handing jsonobject failed");
}
}
/**
* @method deleteNode
* @description:
* @date: 2023/12/24 23:22
* @author: WuShuxian
* @param: node
* @return: void
*/
public void deleteNode(Node node) throws NetworkFailureException {
commitUpdate();
try {
JSONObject jsPost = new JSONObject();
JSONArray actionList = new JSONArray();
// action_list
node.setDeleted(true);
actionList.put(node.getUpdateAction(getActionId()));//获取删除操作的ID加入actionLiast
actionList.put(node.getUpdateAction(getActionId()));
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);
// client_version
jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);
postRequest(jsPost);//使用postRequest发送删除后的结果
postRequest(jsPost);
mUpdateArray = null;
} catch (JSONException e) {
Log.e(TAG, e.toString());
@ -580,14 +508,7 @@ public class GTaskClient {
throw new ActionFailureException("delete node: handing jsonobject failed");
}
}
/**
* @method getTaskLists
* @description:
* @date: 2023/12/24 23:24
* @author: WuShuxian
* @param: void
* @return:
*/
public JSONArray getTaskLists() throws NetworkFailureException {
if (!mLoggedin) {
Log.e(TAG, "please login first");
@ -599,8 +520,8 @@ public class GTaskClient {
HttpResponse response = null;
response = mHttpClient.execute(httpGet);
// 获取任务列表把筛选出的字符串放入jsString
String resString = getResponseContent(response.getEntity());//从网上获取数据
// get the task list
String resString = getResponseContent(response.getEntity());
String jsBegin = "_setup(";
String jsEnd = ")}</script>";
int begin = resString.indexOf(jsBegin);
@ -625,14 +546,7 @@ public class GTaskClient {
throw new ActionFailureException("get task lists: handing jasonobject failed");
}
}
/**
* @method getTaskList
* @description: TASKListgid,
* @date: 2023/12/24 23:28
* @author: WuShuxian
* @param: listGid
* @return:
*/
public JSONArray getTaskList(String listGid) throws NetworkFailureException {
commitUpdate();
try {
@ -640,6 +554,7 @@ public class GTaskClient {
JSONArray actionList = new JSONArray();
JSONObject action = new JSONObject();
// action_list
action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_GETALL);
action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId());
@ -648,6 +563,7 @@ public class GTaskClient {
actionList.put(action);
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);
// client_version
jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);
JSONObject jsResponse = postRequest(jsPost);

@ -47,14 +47,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
/**
* @Package: net.micode.notes.gtask.remote
* @ClassName: GTaskManager
* @Description:
* @Author: WuShuxian
* @CreateDate: 2023/12/24 21:13
* @Version: 1.0
*/
public class GTaskManager {
private static final String TAG = GTaskManager.class.getSimpleName();
@ -93,17 +86,10 @@ public class GTaskManager {
private HashMap<String, Long> mGidToNid;
private HashMap<Long, String> mNidToGid;
/**
* @method GTaskManager
* @description:
* @date: 2023/12/24 23:30
* @author: WuShuxian
* @param: void
* @return: void
*/
private GTaskManager() {
mSyncing = false;//正在同步,flase代表未执行
mCancelled = false;//全局标识flase代表可以执行
mSyncing = false;
mCancelled = false;
mGTaskListHashMap = new HashMap<String, TaskList>();
mGTaskHashMap = new HashMap<String, Node>();
mMetaHashMap = new HashMap<String, MetaData>();
@ -112,14 +98,7 @@ public class GTaskManager {
mGidToNid = new HashMap<String, Long>();
mNidToGid = new HashMap<Long, String>();
}
/**
* @method getInstance
* @description: synchronized线
* @date: 2023/12/24 23:31
* @author: WuShuxian
* @param: void
* @return: GTaskManager
*/
public static synchronized GTaskManager getInstance() {
if (mInstance == null) {
mInstance = new GTaskManager();
@ -128,17 +107,10 @@ public class GTaskManager {
}
public synchronized void setActivityContext(Activity activity) {
// used for getting authtoken
mActivity = activity;
}
/**
* @method sync
* @description:
* @date: 2023/12/24 23:32
* @author: WuShuxian
* @param: context
* asyncTask
* @return: int
*/
public int sync(Context context, GTaskASyncTask asyncTask) {
if (mSyncing) {
Log.d(TAG, "Sync is in progress");
@ -155,9 +127,8 @@ public class GTaskManager {
mGidToNid.clear();
mNidToGid.clear();
//进行同步操作,并作异常处理:网络异常、操作异常
try {
GTaskClient client = GTaskClient.getInstance();//创建一个实例client
GTaskClient client = GTaskClient.getInstance();
client.resetUpdateArray();
// login google task
@ -168,19 +139,18 @@ public class GTaskManager {
}
// get the task list from google
//从google获取task list
asyncTask.publishProgess(mContext.getString(R.string.sync_progress_init_list));
initGTaskList();
//进行同步操作
// do content sync work
asyncTask.publishProgess(mContext.getString(R.string.sync_progress_syncing));
syncContent();
} catch (NetworkFailureException e) {
Log.e(TAG, e.toString());
return STATE_NETWORK_ERROR;//网络异常
return STATE_NETWORK_ERROR;
} catch (ActionFailureException e) {
Log.e(TAG, e.toString());
return STATE_INTERNAL_ERROR;//操作异常
return STATE_INTERNAL_ERROR;
} catch (Exception e) {
Log.e(TAG, e.toString());
e.printStackTrace();
@ -197,14 +167,7 @@ public class GTaskManager {
return mCancelled ? STATE_SYNC_CANCELLED : STATE_SUCCESS;
}
/**
* @method initGTaskList
* @description: GtaskListGoogleJSONtasklistTaskList
* @date: 2023/12/24 23:39
* @author: WuShuxian
* @param:
* @return:
*/
private void initGTaskList() throws NetworkFailureException {
if (mCancelled)
return;
@ -212,7 +175,7 @@ public class GTaskManager {
try {
JSONArray jsTaskLists = client.getTaskLists();
//初始化元列表
// init meta list first
mMetaList = null;
for (int i = 0; i < jsTaskLists.length(); i++) {
JSONObject object = jsTaskLists.getJSONObject(i);

@ -23,6 +23,14 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
/**
* @Package: net.micode.notes.gtask.remote
* @ClassName: GTaskSyncService
* @Description:
* @Author: WuShuxian
* @CreateDate: 2024/1/15 21:36
* @Version: 1.0
*/
public class GTaskSyncService extends Service {
public final static String ACTION_STRING_NAME = "sync_action_type";
@ -118,10 +126,17 @@ public class GTaskSyncService extends Service {
context.startService(intent);
}
/**
* @method isSyncing
* @description:
* @date: 2024/1/15 21:38
* @author: WuShuxian
*/
public static boolean isSyncing() {
return mSyncTask != null;
}
public static String getProgressString() {
return mSyncProgress;
}

@ -14,6 +14,8 @@ import android.content.SharedPreferences;
import android.graphics.Paint;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
@ -71,6 +73,9 @@ import java.util.regex.Pattern;
*/
public class NoteEditActivity extends Activity implements OnClickListener,
NoteSettingChangedListener, OnTextViewChangeListener {
/**
*
*/
private class HeadViewHolder {
public TextView tvModified;
@ -82,6 +87,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
public TextView textNum;
}
private static final Map<Integer, Integer> sBgSelectorBtnsMap = new HashMap<Integer, Integer>();
static {
sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW);
@ -123,13 +129,21 @@ public class NoteEditActivity extends Activity implements OnClickListener,
"android.permission.WRITE_EXTERNAL_STORAGE" };//权限名称
private static final String TAG = "NoteEditActivity";
private HeadViewHolder mNoteHeaderHolder;
private View mHeadViewPanel;
private View mNoteBgColorSelector;
private View mFontSizeSelector;
private EditText mNoteEditor;
private View mNoteEditorPanel;
public WorkingNote mWorkingNote;
private WorkingNote mWorkingNote;
private SharedPreferences mSharedPrefs;
private int mFontSizeId;
@ -215,6 +229,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.note_edit);
checkStoragePermissions(this);//动态申请权限
if (savedInstanceState == null && !initActivityState(getIntent())) {
finish();
return;
@ -237,6 +253,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
});
convertToImage();//将路径显示为图片
count();
}
/**
@ -257,7 +274,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
private boolean initActivityState(Intent intent) {
/**
* If the user specified the {@link Intent#ACTION_VIEW} but not provided with id,
@ -298,6 +314,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
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
long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0);
int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
@ -305,6 +322,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
Notes.TYPE_WIDGET_INVALIDE);
int bgResId = intent.getIntExtra(Notes.INTENT_EXTRA_BACKGROUND_ID,
ResourceParser.getDefaultBgId(this));
// Parse call-record note
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
long callDate = intent.getLongExtra(Notes.INTENT_EXTRA_CALL_DATE, 0);
if (callDate != 0 && phoneNumber != null) {
@ -398,8 +417,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
long time = System.currentTimeMillis();
if (time > mWorkingNote.getAlertDate()) {
mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired);
}
else {
} else {
mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString(
mWorkingNote.getAlertDate(), time, DateUtils.MINUTE_IN_MILLIS));
}
@ -411,12 +429,12 @@ public class NoteEditActivity extends Activity implements OnClickListener,
};
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
initActivityState(intent);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
@ -431,6 +449,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId());
Log.d(TAG, "Save working note id: " + mWorkingNote.getNoteId() + " onSaveInstanceState");
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mNoteBgColorSelector.getVisibility() == View.VISIBLE
@ -455,10 +474,9 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if (ev.getX() < x
|| ev.getX() > (x + view.getWidth())
|| ev.getY() < y
|| ev.getY() > (y + view.getHeight()))
{
return false;
}
|| ev.getY() > (y + view.getHeight())) {
return false;
}
return true;
}
@ -495,6 +513,24 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE;
}
mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list);
//朗读
mTTS = new TextToSpeech(this,new TextToSpeech.OnInitListener(){
@Override
public void onInit(int status){
// 判断是否转化成功
if (status == TextToSpeech.SUCCESS){
//默认设定语言为中文
int result = mTTS.setLanguage(Locale.CHINESE);
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED){
Toast.makeText(NoteEditActivity.this, "Language not available.", Toast.LENGTH_SHORT).show();
}else{
//不支持中文就将语言设置为英文
mTTS.setLanguage(Locale.US);
}
}
}
});
}
@Override
@ -530,7 +566,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
setResult(RESULT_OK, intent);
}
public void onClick(View v) {
int id = v.getId();
if (id == R.id.btn_set_bg_color) {
@ -596,6 +631,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId());
mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId());
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (isFinishing()) {
@ -620,6 +656,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
return true;
}
@Override
/**
* @method onOptionsItemSelected
@ -662,6 +699,9 @@ public class NoteEditActivity extends Activity implements OnClickListener,
setReminder();
} else if (itemId == R.id.menu_delete_remind) {
mWorkingNote.setAlertDate(0, false);
} else if (itemId == R.id.menu_voice){
Log.d("voiceOut","in");
textToSpeach();
}
return true;
}
@ -683,7 +723,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
d.show();
}
/**
* Share note to apps that support {@link Intent#ACTION_SEND} action
* and {@text/plain} type
@ -940,16 +979,20 @@ public class NoteEditActivity extends Activity implements OnClickListener,
public void onCheckListModeChanged(int oldMode, int newMode) {
if (newMode == TextNote.MODE_CHECK_LIST) {
switchToListMode(mNoteEditor.getText().toString());
//检查模式切换到列表模式
} else {
if (!getWorkingText()) {
mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ",
""));
}
//若是获取到文本就改变其检查标记
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
mEditTextList.setVisibility(View.GONE);
mNoteEditor.setVisibility(View.VISIBLE);
//修改文本编辑器的内容和可见性
}
}
/**
* @method getWorkingText
* @description
@ -958,26 +1001,23 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* @return
*/
private boolean getWorkingText() {
boolean hasChecked = false;//初始化check标记
boolean hasChecked = false;
//初始化check标记
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
/**
* CHECK_LIST
*
*
*/
// 若模式为CHECK_LIST
StringBuilder sb = new StringBuilder();
//创建可变字符串
for (int i = 0; i < mEditTextList.getChildCount(); i++) {
View view = mEditTextList.getChildAt(i);
//遍历所有子编辑框的视图
NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);
if (!TextUtils.isEmpty(edit.getText())) {
/**
*
*
* true
*/
//若文本不为空
if (((CheckBox) view.findViewById(R.id.cb_edit_item)).isChecked()) {
//该选项框已打钩
sb.append(TAG_CHECKED).append(" ").append(edit.getText()).append("\n");
hasChecked = true;
//扩展字符串为已打钩并把标记置true
} else {
//扩展字符串添加未打钩
sb.append(TAG_UNCHECKED).append(" ").append(edit.getText()).append("\n");
@ -985,8 +1025,14 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
mWorkingNote.setWorkingText(sb.toString());//利用编辑好的字符串设置运行便签的内容
//利用编辑好的字符串设置运行便签的内容
} else {// 若不是该模式直接用编辑器中的内容设置运行中标签的内容
mWorkingNote.setWorkingText(mNoteEditor.getText().toString());
//若是获取到文本就改变其检查标记
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
mEditTextList.setVisibility(View.GONE);
mNoteEditor.setVisibility(View.VISIBLE);
//修改文本编辑器的内容和可见性
}
return hasChecked;
}
@ -1000,6 +1046,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private boolean saveNote() {
getWorkingText();
boolean saved = mWorkingNote.saveNote();
//如果便签内容为空,则删除
if (TextUtils.isEmpty(mWorkingNote.getContent())) {
deleteCurrentNote();//删除当前便签
saved = false; // 标记为未保存
}
//运行 getWorkingText()之后保存
if (saved) {
/**
@ -1055,6 +1106,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
showToast(R.string.error_note_empty_for_send_to_desktop);
}
}
/**
* @method makeShortcutIconTitle
* @description
@ -1069,9 +1121,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return content.length() > SHORTCUT_ICON_TITLE_MAX_LEN ? content.substring(0,
SHORTCUT_ICON_TITLE_MAX_LEN) : content;
}
private void showToast(int resId) {
showToast(resId, Toast.LENGTH_SHORT);
}
private void showToast(int resId, int duration) {
Toast.makeText(this, resId, duration).show();
}
@ -1292,4 +1346,14 @@ public class NoteEditActivity extends Activity implements OnClickListener,
e.printStackTrace();
}
}
/**
* @method textToSpeach
* @description:
* @date: 2024/1/16 20:21
* @author: WuShuxian
*/
private void textToSpeach(){
mTTS.speak(mNoteEditor.getText().toString(),TextToSpeech.QUEUE_FLUSH,null);
}
}

@ -405,13 +405,4 @@
android:src="@drawable/selected" />
</FrameLayout>
</LinearLayout>
<ImageButton
android:id="@+id/add_img_btn"
android:layout_width="51dp"
android:layout_height="54dp"
android:layout_marginLeft="7dp"
android:layout_marginTop="600dp"
android:layout_marginBottom="7dp"
android:src="@drawable/ic_menu_gallery_new" />
</FrameLayout>

@ -39,7 +39,6 @@
<string name="file_name_txt_format">notes_%s.txt</string>
<!-- notes list string -->
<string name="format_folder_files_count">(%d)</string>
<string name="add_img_btn">Add picture</string>
<string name="menu_create_folder">New Folder</string>
<string name="menu_export_text">Export text</string>
<string name="menu_sync">Sync</string>

Loading…
Cancel
Save