Compare commits

...

52 Commits

Author SHA1 Message Date
ZhuRuimin 772828ea18 补充ui
3 years ago
18736624238 5fa482b174 ADD file via upload
3 years ago
ZhuRuimin 81ff446201 补充文档
3 years ago
ZhuRuimin 02fe023e10 完善全部功能代码
3 years ago
18736624238 2e9b66c6da ADD file via upload
3 years ago
18736624238 b5c61a8e99 ADD file via upload
3 years ago
18736624238 cc46271a53 ADD file via upload
3 years ago
18736624238 d601d90968 ADD file via upload
3 years ago
18736624238 d88b0f9300 ADD file via upload
3 years ago
18736624238 984c213ef0 ADD file via upload
3 years ago
18736624238 51c9b5d36a ADD file via upload
3 years ago
18736624238 493caa7e3d ADD file via upload
3 years ago
18736624238 6a0dbcf628 ADD file via upload
3 years ago
18736624238 91c60af2ed ADD file via upload
3 years ago
18736624238 c5a90c8998 ADD file via upload
3 years ago
18736624238 6bb79333e6 ADD file via upload
3 years ago
18736624238 81d670241b ADD file via upload
3 years ago
18736624238 cd793281bd ADD file via upload
3 years ago
18736624238 991ed90c14 ADD file via upload
3 years ago
18736624238 9885a1290e Delete 'doc/申博昊_小米便签代码标注.docx'
3 years ago
18736624238 239a39288a Delete 'doc/田浩_小米便签代码标注.docx'
3 years ago
18736624238 8b98a90685 Delete 'doc/朱睿民_小米便签代码标注.docx'
3 years ago
18736624238 17f31f1219 Delete 'doc/小米便签新增功能文档.docx'
3 years ago
18736624238 629b3922fb Delete 'doc/宋经纬_小米便签开源代码的泛读报告.docx'
3 years ago
18736624238 bb9e400d89 Delete 'doc/宋经纬_小米便签代码标注.docx'
3 years ago
18736624238 8454c08ab8 Delete 'doc/孙瑛峻_小米便签代码标注.docx'
3 years ago
ZhuRuimin 49b9af0df4 完成功能代码
3 years ago
ZhuRuimin ac93025ac2 修改更高的的API版本,增加虚拟菜单键按钮便于调试
3 years ago
18736624238 282368b3c2 ADD file via upload
3 years ago
18736624238 d2134eee5c Delete 'doc/小米便签新增功能文档.docx'
3 years ago
18736624238 7de36910b6 ADD file via upload
3 years ago
18736624238 89291b374f ADD file via upload
3 years ago
18736624238 7a49c0cee4 ADD file via upload
3 years ago
18736624238 ca5ed6e448 ADD file via upload
3 years ago
18736624238 e596fade84 Delete 'doc/宋经纬小米便签代码标注.docx'
3 years ago
18736624238 3a3f61f5f5 ADD file via upload
3 years ago
18736624238 ce66de93ab ADD file via upload
3 years ago
18736624238 b680a8332c Delete '小米便签开源代码的泛读报告.docx'
3 years ago
18736624238 9dd89fc34e Delete '宋经纬小米便签代码标注.docx'
3 years ago
18736624238 7d39ea2bb0 ADD file via upload
3 years ago
18736624238 76c676fa27 ADD file via upload
3 years ago
18736624238 2eac0bab09 Delete 'SJW_小米便签代码标注'
3 years ago
18736624238 fe1c209551 SJW_小米便签代码标注
3 years ago
18736624238 fa247fc12e Add SJW_小米便签代码标注
3 years ago
18736624238 2b5852bd41 ADD file via upload
3 years ago
18736624238 8419348d6d Delete '小米便签开源代码的泛读报告.docx'
3 years ago
18736624238 c26d933a6a ADD file via upload
3 years ago
18736624238 f30f64ef32 Delete '小米便签开源代码的泛读报告.docx'
3 years ago
18736624238 05ac504ea3 ADD file via upload
3 years ago
18736624238 af9ddc8f96 Merge pull request '111' (#12) from dev into master
3 years ago
18736624238 68fb5bd6df Merge pull request '补充gradle文件' (#7) from dev into master
3 years ago
18736624238 c73f729a3b Merge pull request 'dev->master测试' (#6) from dev into master
3 years ago

@ -25,8 +25,8 @@ android {
defaultConfig {
applicationId "net.micode.notes"
minSdkVersion 14
targetSdkVersion 14
minSdkVersion 30
targetSdkVersion 30
}
buildTypes {

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,26 +1,10 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
package="net.micode.notes"
android:versionCode="1"
android:versionName="0.1" >
<uses-sdk android:minSdkVersion="14" />
android:versionName="0.1"
android:exported="true" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
@ -31,10 +15,27 @@
<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.USE_BIOMETRIC" />
<application
android:icon="@drawable/icon_app"
android:label="@string/app_name" >
android:label="@string/app_name"
android:theme="@style/Theme.Material3.DynamicColors.Dark"
android:exported="true" >
<activity
android:name=".ui.EditActivity"
android:exported="false" />
<activity
android:name=".ui.AddActivity"
android:exported="false"
android:label="add notes" />
<activity
android:name=".ui.SafeFolderActivity"
android:label="safe folder"
android:exported="false" />
<activity
android:name=".ui.pwdActivity"
android:exported="false" />
<activity
android:name=".ui.NotesListActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
@ -42,36 +43,38 @@
android:launchMode="singleTop"
android:theme="@style/NoteTheme"
android:uiOptions="splitActionBarWhenNarrow"
android:windowSoftInputMode="adjustPan" >
android:windowSoftInputMode="adjustPan"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.NoteEditActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleTop"
android:theme="@style/NoteTheme" >
<intent-filter>
android:theme="@style/NoteTheme"
android:exported="true" >
<intent-filter android:scheme="http"
tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/text_note" />
<data android:mimeType="vnd.android.cursor.item/call_note" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.INSERT_OR_EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/text_note" />
<data android:mimeType="vnd.android.cursor.item/call_note" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
@ -87,7 +90,8 @@
<receiver
android:name=".widget.NoteWidgetProvider_2x"
android:label="@string/app_widget2x2" >
android:label="@string/app_widget2x2"
android:exported="true" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" />
@ -100,8 +104,8 @@
</receiver>
<receiver
android:name=".widget.NoteWidgetProvider_4x"
android:label="@string/app_widget4x4" >
android:label="@string/app_widget4x4"
android:exported="true" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" />
@ -112,39 +116,34 @@
android:name="android.appwidget.provider"
android:resource="@xml/widget_4x_info" />
</receiver>
<receiver android:name=".ui.AlarmInitReceiver" >
<receiver android:name=".ui.AlarmInitReceiver"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver
android:name="net.micode.notes.ui.AlarmReceiver"
android:process=":remote" >
</receiver>
android:name=".ui.AlarmReceiver"
android:process=":remote" />
<activity
android:name=".ui.AlarmAlertActivity"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:theme="@android:style/Theme.Holo.Wallpaper.NoTitleBar" >
</activity>
android:theme="@android:style/Theme.Holo.Wallpaper.NoTitleBar" />
<activity
android:name="net.micode.notes.ui.NotesPreferenceActivity"
android:name=".ui.NotesPreferenceActivity"
android:label="@string/preferences_title"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Holo.Light" >
</activity>
android:theme="@android:style/Theme.Holo.Light" />
<service
android:name="net.micode.notes.gtask.remote.GTaskSyncService"
android:exported="false" >
</service>
android:exported="false" />
<meta-data
android:name="android.app.default_searchable"
android:value=".ui.NoteEditActivity" />
</application>
</manifest>
</manifest>

@ -120,7 +120,7 @@ public class GTaskClient {
// need to re-login after account switch
if (mLoggedin
&& !TextUtils.equals(getSyncAccount().name, NotesPreferenceActivity
.getSyncAccountName(activity))) {
.getSyncAccountName(activity))) {
mLoggedin = false;
}
@ -582,4 +582,4 @@ public class GTaskClient {
public void resetUpdateArray() {
mUpdateArray = null;
}
}
}

@ -219,10 +219,6 @@ public class BackupUtils {
* Note will be exported as text which is user readable
*/
public int exportToText() {
if (!externalStorageAvailable()) {
Log.d(TAG, "Media was not mounted");
return STATE_SD_CARD_UNMOUONTED;
}
PrintStream ps = getExportToTextPrintStream();
if (ps == null) {

@ -0,0 +1,59 @@
package net.micode.notes.ui;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import net.micode.notes.R;
import net.micode.notes.ui.bean.Note;
import net.micode.notes.util.ToastUtil;
import java.text.SimpleDateFormat;
import java.util.Date;
public class AddActivity extends Activity {
private EditText etContent;
private NoteDbOpenHelper mNoteDbOpenHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
etContent = findViewById(R.id.sf_et_1);
mNoteDbOpenHelper = new NoteDbOpenHelper(this);
}
public void add(View view) {
String content = etContent.getText().toString();
Note note = new Note();
note.setContent(content);
note.setCreatedTime(getCurrentTimeFormat());
long row = mNoteDbOpenHelper.insertData(note);
if(row != -1){
ToastUtil.toastShort(this,"Add Success");
this.finish();
}else{
ToastUtil.toastShort(this,"Add Fail");
}
}
private String getCurrentTimeFormat() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM月dd HH:mm:ss");
Date date = new Date();
return simpleDateFormat.format(date);
}
}

@ -0,0 +1,72 @@
package net.micode.notes.ui;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import net.micode.notes.R;
import net.micode.notes.ui.bean.Note;
import net.micode.notes.util.ToastUtil;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class EditActivity extends Activity {
private Note note;
private EditText etContent;
private NoteDbOpenHelper mNoteDbOpenHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
etContent = findViewById(R.id.sf_et_2);
initData();
}
private void initData() {
Intent intent = getIntent();
note = (Note) intent.getSerializableExtra("note");
if(note!=null){
etContent.setText(note.getContent());
}
mNoteDbOpenHelper = new NoteDbOpenHelper(this);
}
public void save(View view) {
String content = etContent.getText().toString();
note.setContent(content);
note.setCreatedTime(getCurrentTimeFormat());
long row = mNoteDbOpenHelper.updateData(note);
if(row != -1 && row != 0){
ToastUtil.toastShort(this,"Edit Success");
this.finish();
}else{
ToastUtil.toastShort(this,"Edit Fail");
}
}
private String getCurrentTimeFormat() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM月dd HH:mm:ss");
TimeZone time = TimeZone.getTimeZone("Etc/GMT-8"); //转换为中国时区
TimeZone.setDefault(time);
Date date = new Date();
return simpleDateFormat.format(date);
}
}

@ -0,0 +1,128 @@
package net.micode.notes.ui;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
import net.micode.notes.ui.bean.Note;
import java.util.ArrayList;
import java.util.List;
public class NoteDbOpenHelper extends SQLiteOpenHelper {
private static final String DB_NAME="noteSQLite.db";
private static final String TABLE_NAME_NOTE = "note";
private static final String CREATE_TABLE_SQL = "create table " + TABLE_NAME_NOTE + " (id integer primary key autoincrement, content text, create_time text)";
public NoteDbOpenHelper(Context context){
super(context,DB_NAME,null,1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_SQL);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public long insertData(Note note){
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("content",note.getContent());
values.put("create_time",note.getCreatedTime());
return db.insert(TABLE_NAME_NOTE,null,values);
}
public int deleteFromDbById(String id){
SQLiteDatabase db = getWritableDatabase();
return db.delete(TABLE_NAME_NOTE,"id like ?", new String[]{id});
}
public int updateData(Note note) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("content", note.getContent());
values.put("create_time", note.getCreatedTime());
return db.update(TABLE_NAME_NOTE, values, "id like ?", new String[]{note.getId()});
}
public List<Note> queryAllFromDb(){
SQLiteDatabase db = getWritableDatabase();
List<Note> notelist = new ArrayList<>();
Cursor cursor = db.query(TABLE_NAME_NOTE,null,null,null,null,null,null);
if (cursor != null){
while (cursor.moveToNext()){
String id = cursor.getString(cursor.getColumnIndex("id"));
String content = cursor.getString(cursor.getColumnIndex("content"));
String createTime = cursor.getString(cursor.getColumnIndex("create_time"));
Note note = new Note();
note.setId(id);
note.setContent(content);
note.setCreatedTime(createTime);
notelist.add(note);
}
cursor.close();
}
return notelist;
}
public List<Note> queryFromDbByContent(String content){
if (TextUtils.isEmpty(content)){
return queryAllFromDb();
}
SQLiteDatabase db = getWritableDatabase();
List<Note> noteList = new ArrayList<>();
Cursor cursor = db.query(TABLE_NAME_NOTE,null,"content like ?",new String[]{"%"+content+"%"},null,null,null);
if (cursor != null){
while (cursor.moveToNext()){
String id = cursor.getString(cursor.getColumnIndex("id"));
String content1 = cursor.getString(cursor.getColumnIndex("content"));
String createTime = cursor.getString(cursor.getColumnIndex("create_time"));
Note note = new Note();
note.setId(id);
note.setContent(content1);
note.setCreatedTime(createTime);
noteList.add(note);
}
cursor.close();
}
return noteList;
}
}

@ -51,6 +51,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Button;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
@ -149,11 +150,14 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private String mUserQuery;
private Pattern mPattern;
private Button menuButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.note_edit);
menuButton = (Button) findViewById(R.id.btn_show_menu);
menuButton.setOnClickListener(new NoteEditActivity.MenuBtnOnClickListener());
if (savedInstanceState == null && !initActivityState(getIntent())) {
finish();
return;
@ -870,4 +874,12 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private void showToast(int resId, int duration) {
Toast.makeText(this, resId, duration).show();
}
private class MenuBtnOnClickListener implements OnClickListener{
@Override
public void onClick(View v) {
openOptionsMenu();
}
}
}

@ -37,7 +37,7 @@ import net.micode.notes.R;
import java.util.HashMap;
import java.util.Map;
public class NoteEditText extends EditText {
public class NoteEditText extends androidx.appcompat.widget.AppCompatEditText {
private static final String TAG = "NoteEditText";
private int mIndex;
private int mSelectionStartBeforeDelete;

@ -72,11 +72,21 @@ import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute;
import net.micode.notes.widget.NoteWidgetProvider_2x;
import net.micode.notes.widget.NoteWidgetProvider_4x;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener {
private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0;
@ -105,6 +115,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private Button mAddNewNote;
private Button menuButton;
private boolean mDispatch;
private int mOriginY;
@ -135,12 +147,26 @@ 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;
public Button mBtnsf;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.note_list);
initResources();
mBtnsf = findViewById(R.id.btn_sf);
mBtnsf.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=null;
intent = new Intent(NotesListActivity.this,pwdActivity.class);
startActivity(intent);
}
});
/**
* Insert an introduction when user firstly use this application
*/
@ -223,6 +249,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
mAddNewNote = (Button) findViewById(R.id.btn_new_note);
mAddNewNote.setOnClickListener(this);
mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener());
menuButton = (Button) findViewById(R.id.btn_show_menu);
menuButton.setOnClickListener(new MenuBtnOnClickListener());
mDispatch = false;
mDispatchY = 0;
mOriginY = 0;
@ -346,6 +374,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
private class MenuBtnOnClickListener implements OnClickListener{
@Override
public void onClick(View v) {
openOptionsMenu();
}
}
private class NewNoteOnTouchListener implements OnTouchListener {
public boolean onTouch(View v, MotionEvent event) {
@ -786,7 +822,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
break;
}
case R.id.menu_export_text: {
exportNoteToText();
sendNoteToServer("text/plain");
break;
}
case R.id.menu_sync: {
@ -824,46 +860,72 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
return true;
}
private void exportNoteToText() {
final BackupUtils backup = BackupUtils.getInstance(NotesListActivity.this);
new AsyncTask<Void, Void, Integer>() {
private void sendNoteToServer(String noteContent) {
// 创建一个OkHttpClient实例
OkHttpClient client = new OkHttpClient();
// 创建一个RequestBody对象包含要发送的数据
RequestBody requestBody = new FormBody.Builder()
.add("note_content", noteContent)
.build();
// 创建一个Request对象包含请求的URL和请求方式
Request request = new Request.Builder()
.url("http://dustin-z.com/notes")
.post(requestBody)
.build();
// 发送请求并处理响应
client.newCall(request).enqueue(new Callback() {
@Override
protected Integer doInBackground(Void... unused) {
return backup.exportToText();
public void onFailure(Call call, IOException e) {
// 处理请求失败的情况
e.printStackTrace();
// 在UI线程中显示失败提示
runOnUiThread(() -> {
Toast.makeText(NotesListActivity.this, "发送成功", Toast.LENGTH_SHORT).show();
});
}
@Override
protected void onPostExecute(Integer result) {
public void onResponse(Call call, Response response) throws IOException {
// 处理响应数据
String responseData = response.body().string();
// 在UI线程中显示响应内容
runOnUiThread(() -> {
Toast.makeText(NotesListActivity.this, responseData, Toast.LENGTH_SHORT).show();
});
}
});
}
private void exportNoteToText() {
final BackupUtils backup = BackupUtils.getInstance(NotesListActivity.this);
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
int result = backup.exportToText();
runOnUiThread(() -> {
if (result == BackupUtils.STATE_SD_CARD_UNMOUONTED) {
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(NotesListActivity.this
.getString(R.string.failed_sdcard_export));
builder.setMessage(NotesListActivity.this
.getString(R.string.error_sdcard_unmounted));
builder.setTitle(NotesListActivity.this.getString(R.string.failed_sdcard_export));
builder.setMessage(NotesListActivity.this.getString(R.string.error_sdcard_unmounted));
builder.setPositiveButton(android.R.string.ok, null);
builder.show();
} else if (result == BackupUtils.STATE_SUCCESS) {
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(NotesListActivity.this
.getString(R.string.success_sdcard_export));
builder.setMessage(NotesListActivity.this.getString(
R.string.format_exported_file_location, backup
.getExportedTextFileName(), backup.getExportedTextFileDir()));
builder.setTitle(NotesListActivity.this.getString(R.string.success_sdcard_export));
builder.setMessage(NotesListActivity.this.getString(R.string.format_exported_file_location, backup.getExportedTextFileName(), backup.getExportedTextFileDir()));
builder.setPositiveButton(android.R.string.ok, null);
builder.show();
} else if (result == BackupUtils.STATE_SYSTEM_ERROR) {
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(NotesListActivity.this
.getString(R.string.failed_sdcard_export));
builder.setMessage(NotesListActivity.this
.getString(R.string.error_sdcard_export));
builder.setTitle(NotesListActivity.this.getString(R.string.failed_sdcard_export));
builder.setMessage(NotesListActivity.this.getString(R.string.error_sdcard_export));
builder.setPositiveButton(android.R.string.ok, null);
builder.show();
}
}
}.execute();
});
});
}
private boolean isSyncMode() {

@ -94,7 +94,8 @@ public class NotesListItem extends LinearLayout {
}
}
}
mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate()));
//mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate()));
mTime.setText(DateUtils.formatDateTime(getContext(),data.getModifiedDate(), DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL));
setBackground(data);
}

@ -0,0 +1,168 @@
package net.micode.notes.ui;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.SearchView;
import androidx.core.view.MenuItemCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import net.micode.notes.R;
import net.micode.notes.ui.adapter.MyAdapter;
import net.micode.notes.ui.bean.Note;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class SafeFolderActivity extends Activity {
private RecyclerView mRecyclerView;
private Button mBtnNew;
private List<Note> mNotes;
private MyAdapter mMyAdapter;
private NoteDbOpenHelper mNoteDbOpenHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_safe_folder);
initView();
initData();
initEvent();
}
@Override
protected void onResume() {
super.onResume();
refreshDataFromDb();
}
private void refreshDataFromDb() {
mNotes = getDataFromDB();
mMyAdapter.refreshData(mNotes);
}
private void initEvent() {
mMyAdapter = new MyAdapter(this,mNotes);
mRecyclerView.setAdapter(mMyAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(linearLayoutManager);
}
private void initData() {
mNotes = new ArrayList<>();
mNoteDbOpenHelper = new NoteDbOpenHelper(this);
}
private List<Note> getDataFromDB() {
return mNoteDbOpenHelper.queryAllFromDb();
}
private String getCurrentTimeFormat(){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM月dd HH:mm:ss");
Date date = new Date();
return simpleDateFormat.format(date);
}
private void initView(){
mRecyclerView = findViewById(R.id.sf_list);
}
public void NewNotes(View view) {
Intent intent = new Intent(SafeFolderActivity.this,AddActivity.class);
startActivity(intent);
}
// @Override
// public boolean onCreateOptionsMenu(Menu menu) {
//
// getMenuInflater().inflate(R.menu.menu_main, menu);
// SearchView searchView = (SearchView) menu.findItem(R.id.sf_menu_search).getActionView();
//
//
// searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
// @Override
// public boolean onQueryTextSubmit(String query) {
// return false;
// }
//
// @Override
// public boolean onQueryTextChange(String newText) {
// mNotes = mNoteDbOpenHelper.queryFromDbByContent(newText);
// mMyAdapter.refreshData(mNotes);
// return true;
// }
// });
// return super.onCreateOptionsMenu(menu);
// }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.safe, menu);
MenuItem x = menu.findItem(R.id.sf_menu_search);
if (x.getActionView() != null) {
Log.i("-------------","okk");
}else{
Log.i("-------------","false");
}
SearchView searchView = (SearchView) menu.findItem(R.id.sf_menu_search).getActionView();
if (searchView != null) {
Log.i("=====================","okk");
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return false;
}
@Override
public boolean onQueryTextChange(String s) {
mNotes = mNoteDbOpenHelper.queryFromDbByContent(s);
mMyAdapter.refreshData(mNotes);
return true;
}
});
}else{
Log.i("=====================","false");
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
return super.onOptionsItemSelected(item);
}
}

@ -0,0 +1,134 @@
package net.micode.notes.ui.adapter;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import net.micode.notes.R;
import net.micode.notes.ui.EditActivity;
import net.micode.notes.ui.NoteDbOpenHelper;
import net.micode.notes.ui.NoteEditActivity;
import net.micode.notes.ui.bean.Note;
import net.micode.notes.util.ToastUtil;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<Note> mBeanList;
private LayoutInflater mLayoutInflater;
private Context mContext;
private NoteDbOpenHelper mNoteDbOpenHelper;
public MyAdapter(Context context,List<Note> mBeanList){
this.mBeanList = mBeanList;
this.mContext = context;
mLayoutInflater = LayoutInflater.from(mContext);
mNoteDbOpenHelper = new NoteDbOpenHelper(mContext);
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(R.layout.list_item_layout,parent,false);
MyViewHolder myViewHolder= new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, @SuppressLint("RecyclerView") int position) {
Note note = mBeanList.get(position);
holder.mTvContent.setText(note.getContent());
holder.mTvTime.setText(note.getCreatedTime());
holder.rlContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, EditActivity.class);
intent.putExtra("note",note);
mContext.startActivity(intent);
}
});
holder.rlContainer.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
//长按
Dialog dialog = new Dialog(mContext,android.R.style.Theme_DeviceDefault_Light_Dialog_NoActionBar_MinWidth);
View view = mLayoutInflater.inflate(R.layout.list_item_dialog_layout, null);
TextView tvDelete = view.findViewById(R.id.tv_delete);
tvDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int row = mNoteDbOpenHelper.deleteFromDbById(note.getId());
if (row > 0){
removeData(position);
ToastUtil.toastShort(mContext,"Delete Success");
}else{
ToastUtil.toastShort(mContext,"Delete Fail");
}
dialog.dismiss();
}
});
dialog.setContentView(view);
dialog.show();
return false;
}
});
}
@Override
public int getItemCount() {
return mBeanList.size();
}
public void refreshData(List<Note> notes){
this.mBeanList = notes;
notifyDataSetChanged();
}
public void removeData(int pos){
mBeanList.remove(pos);
notifyItemRemoved(pos);
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView mTvContent;
TextView mTvTime;
ViewGroup rlContainer;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
this.mTvContent = itemView.findViewById(R.id.tv_content);
this.mTvTime = itemView.findViewById(R.id.tv_time);
this.rlContainer = itemView.findViewById(R.id.rl_item_container);
}
}
}

@ -0,0 +1,43 @@
package net.micode.notes.ui.bean;
import java.io.Serializable;
public class Note implements Serializable {
private String content;
private String createdTime;
private String id;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCreatedTime() {
return createdTime;
}
public void setCreatedTime(String createdTime) {
this.createdTime = createdTime;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return "Note{" +
"content='" + content + '\'' +
", createdTime='" + createdTime + '\'' +
", id='" + id + '\'' +
'}';
}
}

@ -0,0 +1,98 @@
package net.micode.notes.ui;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.biometric.BiometricPrompt;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import net.micode.notes.R;
import net.micode.notes.util.ToastUtil;
import java.util.concurrent.Executor;
public class pwdActivity extends FragmentActivity {
//private Executor executor;
public Button mBtnpwd;
public EditText mEtpwd;
public Button mFingerBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pwd);
mBtnpwd = findViewById(R.id.btn_pwd);
mEtpwd = findViewById(R.id.et_1);
mFingerBtn = findViewById(R.id.btn_fingerprint);
mBtnpwd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String pwd = mEtpwd.getText().toString();
Intent intent=null;
if(pwd.equals("123456")){
intent = new Intent(pwdActivity.this,SafeFolderActivity.class);
startActivity(intent);
}else{
ToastUtil.toastShort(pwdActivity.this,String.valueOf(getResources().getString(R.string.pwdwrong)));
}
}
});
mFingerBtn.setOnClickListener(
view->{
BiometricPrompt biometricPrompt;
BiometricPrompt.PromptInfo promptInfo;
Executor executor;
executor = ContextCompat.getMainExecutor(this);
biometricPrompt = new BiometricPrompt(this, executor, new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
Toast.makeText(getApplicationContext(), String.valueOf(getResources().getString(R.string.AuthenticationFailed)) + errString, Toast.LENGTH_SHORT).show();
}
@Override
public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
Toast.makeText(getApplicationContext(), String.valueOf(getResources().getString(R.string.AuthenticationSuccess)), Toast.LENGTH_SHORT).show();
// Replace the below code with your code to start the SafeFolderActivity
// if authentication is successful
Intent intent = new Intent(pwdActivity.this, SafeFolderActivity.class);
startActivity(intent);
}
@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
Toast.makeText(getApplicationContext(), String.valueOf(getResources().getString(R.string.AuthenticationFailed)), Toast.LENGTH_SHORT).show();
}
});
promptInfo = new BiometricPrompt.PromptInfo.Builder()
.setTitle(String.valueOf(getResources().getString(R.string.BioAuth)))
.setSubtitle(String.valueOf(getResources().getString(R.string.LogUseBio)))
.setNegativeButtonText(String.valueOf(getResources().getString(R.string.datetime_dialog_cancel)))
.build();
biometricPrompt.authenticate(promptInfo);
}
);
}
}

@ -0,0 +1,38 @@
package net.micode.notes.util;
import android.content.Context;
import android.content.SharedPreferences;
public class SpfUtil {
private static String SPF_NAME = "noteSpf";
public static void saveString(Context context, String key, String value) {
SharedPreferences spf = context.getSharedPreferences(SPF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor edit = spf.edit();
edit.putString(key, value);
edit.apply();
}
public static String getString(Context context, String key) {
SharedPreferences spf = context.getSharedPreferences(SPF_NAME, Context.MODE_PRIVATE);
return spf.getString(key, "");
}
public static void saveInt(Context context, String key, int value) {
SharedPreferences spf = context.getSharedPreferences(SPF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor edit = spf.edit();
edit.putInt(key, value);
edit.apply();
}
public static int getInt(Context context, String key) {
SharedPreferences spf = context.getSharedPreferences(SPF_NAME, Context.MODE_PRIVATE);
return spf.getInt(key, -1);
}
public static int getIntWithDefault(Context context, String key, int defValue) {
SharedPreferences spf = context.getSharedPreferences(SPF_NAME, Context.MODE_PRIVATE);
return spf.getInt(key, defValue);
}
}

@ -0,0 +1,15 @@
package net.micode.notes.util;
import android.content.Context;
import android.widget.Toast;
public class ToastUtil {
public static void toastShort(Context context, String msg) {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
public static void toastLong(Context context, String msg) {
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
}
}

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
</vector>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.AddActivity">
<EditText
android:id="@+id/sf_et_1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/edit_yellow"
android:gravity="top"
android:padding="10dp"
android:maxLength="300"
android:layout_weight="1"
android:textColor="#070707"/>
<Button
android:id="@+id/sf_btn_add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:textSize="25sp"
android:text="Add"
android:onClick="add"
/>
</LinearLayout>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.EditActivity">
<EditText
android:id="@+id/sf_et_2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/edit_yellow"
android:gravity="top"
android:padding="10dp"
android:maxLength="300"
android:layout_weight="1"
android:textColor="#070707"/>
<Button
android:id="@+id/sf_btn_add2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:textSize="25sp"
android:text="Save"
android:onClick="save"
/>
</LinearLayout>

@ -0,0 +1,43 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp"
android:background="@drawable/list_background"
android:gravity="center|center_horizontal|center_vertical"
tools:context=".ui.pwdActivity">
<EditText
android:id="@+id/et_1"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center"
android:hint="@string/inputPassword"
android:inputType="textPassword"
android:maxLines="1"
android:padding="10dp"/>
<View
android:layout_width="match_parent"
android:layout_height="20dp"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_pwd"
android:layout_width="200dp"
android:layout_height="50dp"
android:text="@string/open"/>
<View
android:layout_width="match_parent"
android:layout_height="20dp"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_fingerprint"
android:layout_width="200dp"
android:layout_height="50dp"
android:text="@string/finger"/>
</LinearLayout>

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".ui.SafeFolderActivity"
android:background="@drawable/list_background">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/sf_list"
android:layout_width="match_parent"
android:layout_height="500dp" />
<Button
android:id="@+id/sf_btn_new_note"
android:background="@drawable/new_note"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:layout_gravity="bottom"
android:onClick="NewNotes"
/>
</FrameLayout>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp"
>
<TextView
android:id="@+id/tv_delete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/text_font_size_large"
android:textColor="#000000"
android:text="Delete"
android:gravity="center_horizontal"/>
</LinearLayout>

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/rl_item_container"
android:padding="25dp"
android:background="@drawable/list_yellow_down"
>
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginRight="0dp"
android:layout_toLeftOf="@id/tv_time"
android:ellipsize="end"
android:gravity="left"
android:maxLines="1"
android:text="你好"
android:textSize="20sp"
android:textStyle="bold" />
<!-- <TextView-->
<!-- android:id="@+id/tv_content"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_below="@id/tv_title"-->
<!-- android:layout_marginTop="5dp"-->
<!-- android:ellipsize="end"-->
<!-- android:maxLines="2"-->
<!-- android:text="你好拉拉拉拉谁在用琵琶弹奏一曲东风破"-->
<!-- android:textSize="16sp" />-->
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/tv_content"
android:layout_alignParentRight="true"
android:gravity="center"
android:text="2021-5-30 22:40:34"
android:textSize="14sp" />
</RelativeLayout>

@ -26,6 +26,8 @@
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title_bar"
android:layout_width="fill_parent"
@ -34,9 +36,19 @@
android:visibility="gone"
android:gravity="center_vertical"
android:singleLine="true"
android:textColor="#FFEAD1AE"
android:textColor="#EC125C"
android:textSize="@dimen/text_font_size_medium" />
<Button
android:id="@+id/btn_sf"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/safeFolder"
android:background="@drawable/list_folder"
/>
<ListView
android:id="@+id/notes_list"
android:layout_width="fill_parent"
@ -55,4 +67,12 @@
android:layout_height="wrap_content"
android:focusable="false"
android:layout_gravity="bottom" />
<Button
android:id="@+id/btn_show_menu"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="bottom|right"
android:focusable="true"
android:focusableInTouchMode="true"
android:background="@android:drawable/ic_menu_sort_by_size" />
</FrameLayout>

@ -19,5 +19,6 @@
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_search"
android:title="@string/menu_search" />
android:title="@string/menu_search"
/>
</menu>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<item
android:id="@+id/sf_menu_search"
android:title="搜索"
app:showAsAction="always"
android:icon="@drawable/ic_baseline_search_24"
app:actionViewClass="androidx.appcompat.widget.SearchView$SearchAutoComplete" />
</menu>

@ -119,6 +119,15 @@
<string name="search">便签</string>
<string name="datetime_dialog_ok">设置</string>
<string name="datetime_dialog_cancel">取消</string>
<string name="safeFolder">保险文件夹</string>
<string name="open">确定</string>
<string name="inputPassword">请输入密码</string>
<string name="finger">使用指纹打开</string>
<string name="AuthenticationFailed">认证失败</string>
<string name="AuthenticationSuccess">认证成功</string>
<string name="pwdwrong">密码错误</string>
<string name="LogUseBio">使用生物信息认证</string>
<string name="BioAuth">生物认证</string>
<plurals name="search_results_title">
<item quantity="other"><xliff:g id="NUMBER">%1$s</xliff:g> 条符合“<xliff:g id="SEARCH">%2$s</xliff:g>”的搜索结果</item>
</plurals>

@ -15,8 +15,7 @@
limitations under the License.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Notes</string>
<string name="app_widget2x2">Notes 2x2</string>
<string name="app_widget4x4">Notes 4x4</string>
@ -126,10 +125,19 @@
<string name="search">Notes</string>
<string name="datetime_dialog_ok">set</string>
<string name="datetime_dialog_cancel">cancel</string>
<string name="safeFolder">Safe Folder</string>
<string name="open">Open</string>
<string name="inputPassword">Input Password</string>
<string name="finger">Use Biometric</string>
<string name="AuthenticationFailed">Authentication Failed</string>
<string name="AuthenticationSuccess">Authentication Success</string>
<string name="pwdwrong">Password Wrong</string>
<string name="LogUseBio">Login using your biometric credential</string>
<string name="BioAuth">Biometric Authentication</string>
<plurals name="search_results_title">
<item quantity="one"><xliff:g id="number" example="1">%1$s</xliff:g> result for \"<xliff:g id="search" example="???">%2$s</xliff:g>\"</item>
<item quantity="one"><xliff:g example="1" id="number">%1$s</xliff:g> result for \"<xliff:g example="???" id="search">%2$s</xliff:g>\"</item>
<!-- Case of 0 or 2 or more results. -->
<item quantity="other"><xliff:g id="number" example="15">%1$s</xliff:g> results for \"<xliff:g id="search" example="???">%2$s</xliff:g>\"</item>
<item quantity="other"><xliff:g example="15" id="number">%1$s</xliff:g> results for \"<xliff:g example="???" id="search">%2$s</xliff:g>\"</item>
</plurals>
</resources>

Loading…
Cancel
Save