├── app
├── .gitignore
├── libs
│ ├── quicknotecore.aar
│ └── bdasr_V3_20180801_d6f298a.jar
├── src
│ ├── main
│ │ ├── assets
│ │ │ └── WakeUp.bin
│ │ ├── jniLibs
│ │ │ ├── armeabi
│ │ │ │ ├── libvad.dnn.so
│ │ │ │ ├── libbdSpilWakeup.so
│ │ │ │ ├── libBaiduSpeechSDK.so
│ │ │ │ ├── libbdEASRAndroid.so
│ │ │ │ └── libbd_easr_s1_merge_normal_20151216.dat.so
│ │ │ └── armeabi-v7a
│ │ │ │ ├── libvad.dnn.so
│ │ │ │ ├── libbdEASRAndroid.so
│ │ │ │ ├── libbdSpilWakeup.so
│ │ │ │ ├── libBaiduSpeechSDK.so
│ │ │ │ └── libbd_easr_s1_merge_normal_20151216.dat.so
│ │ ├── res
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── thumbtack.png
│ │ │ │ ├── purchase_wx.jpg
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── values
│ │ │ │ ├── drawables.xml
│ │ │ │ ├── arrays.xml
│ │ │ │ ├── colors.xml
│ │ │ │ ├── styles.xml
│ │ │ │ └── dimens.xml
│ │ │ ├── drawable-v21
│ │ │ │ ├── shape_bg_pop_window_input.xml
│ │ │ │ └── ic_menu_share.xml
│ │ │ ├── xml
│ │ │ │ ├── file_provider_paths.xml
│ │ │ │ └── preferences_setting.xml
│ │ │ ├── layout
│ │ │ │ ├── fragment_dialog_list.xml
│ │ │ │ ├── content_main.xml
│ │ │ │ ├── fragment_note_detail.xml
│ │ │ │ ├── activity_note_detail.xml
│ │ │ │ ├── view_pop_content_input.xml
│ │ │ │ ├── fragment_main_page.xml
│ │ │ │ ├── no_data_view.xml
│ │ │ │ ├── popup_menu_attachment_item.xml
│ │ │ │ ├── fragment_dialog_list_item.xml
│ │ │ │ ├── activity_search.xml
│ │ │ │ ├── activity_main.xml
│ │ │ │ ├── nav_header_main.xml
│ │ │ │ ├── fragment_purchase.xml
│ │ │ │ ├── activity_welcome.xml
│ │ │ │ ├── fragment_about.xml
│ │ │ │ ├── activity_voice_shorthand.xml
│ │ │ │ ├── recycle_main_page_note_item.xml
│ │ │ │ ├── activity_lock.xml
│ │ │ │ ├── activity_freehand.xml
│ │ │ │ └── app_bar_main.xml
│ │ │ ├── values-v21
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── values-night
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ ├── drawable
│ │ │ │ ├── check_update_btn_bg.xml
│ │ │ │ ├── ic_done_white_24dp.xml
│ │ │ │ ├── ic_sort_white_24dp.xml
│ │ │ │ ├── ic_waste_basket.xml
│ │ │ │ ├── ic_auto_update_24dp.xml
│ │ │ │ ├── ic_photo_black_24dp.xml
│ │ │ │ ├── ic_rename_black_24dp.xml
│ │ │ │ ├── ic_record_white_24dp.xml
│ │ │ │ ├── ic_revert_unactivated_24dp.xml
│ │ │ │ ├── ic_all_notes.xml
│ │ │ │ ├── ic_delete_forever_24dp.xml
│ │ │ │ ├── ic_revert_activated_24dp.xml
│ │ │ │ ├── ic_revocation_unactivated_24dp.xml
│ │ │ │ ├── ic_recent_edit.xml
│ │ │ │ ├── ic_revocation_activated_24dp.xml
│ │ │ │ ├── ic_text_note_white_24dp.xml
│ │ │ │ ├── ic_attachment_white_24dp.xml
│ │ │ │ ├── ic_search_white_24dp.xml
│ │ │ │ ├── ic_record_black_24dp.xml
│ │ │ │ ├── ic_delete_black_24dp.xml
│ │ │ │ ├── ic_encrypt_black_24dp.xml
│ │ │ │ ├── ic_record_active_24dp.xml
│ │ │ │ ├── ic_attachment_white_vertical_24dp.xml
│ │ │ │ ├── ic_brush_activated_24dp.xml
│ │ │ │ ├── ic_brush_unactivated_24dp.xml
│ │ │ │ ├── ic_restore_black_24dp.xml
│ │ │ │ ├── ic_camera_white_24dp.xml
│ │ │ │ ├── ic_freehand_white_24dp.xml
│ │ │ │ ├── ic_freehand_black_24dp.xml
│ │ │ │ ├── ic_settings.xml
│ │ │ │ ├── ic_language_24dp.xml
│ │ │ │ ├── ic_default_avatar_24dp.xml
│ │ │ │ ├── ic_gesture_24dp.xml
│ │ │ │ ├── ic_donate_24dp.xml
│ │ │ │ ├── ic_about_24dp.xml
│ │ │ │ ├── ic_recommend_24dp.xml
│ │ │ │ ├── ic_eraser_unactivated_24dp.xml
│ │ │ │ ├── ic_eraser_activated_24dp.xml
│ │ │ │ ├── ic_skin_24dp.xml
│ │ │ │ ├── ic_app.xml
│ │ │ │ └── ic_app_welcome.xml
│ │ │ ├── drawable-night
│ │ │ │ ├── ic_revert_activated_24dp.xml
│ │ │ │ ├── ic_auto_update_24dp.xml
│ │ │ │ ├── ic_revocation_activated_24dp.xml
│ │ │ │ ├── ic_record_active_24dp.xml
│ │ │ │ ├── ic_brush_activated_24dp.xml
│ │ │ │ ├── ic_language_24dp.xml
│ │ │ │ ├── ic_gesture_24dp.xml
│ │ │ │ ├── ic_donate_24dp.xml
│ │ │ │ ├── ic_about_24dp.xml
│ │ │ │ ├── ic_recommend_24dp.xml
│ │ │ │ ├── ic_eraser_activated_24dp.xml
│ │ │ │ └── ic_skin_24dp.xml
│ │ │ ├── menu
│ │ │ │ ├── menu_toolbar_sort.xml
│ │ │ │ ├── activity_main_drawer.xml
│ │ │ │ ├── menu_search_activity.xml
│ │ │ │ ├── menu_toolbar_detail.xml
│ │ │ │ └── menu_toolbar_common.xml
│ │ │ └── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ ├── java
│ │ │ └── tech
│ │ │ │ └── huqi
│ │ │ │ └── quicknote
│ │ │ │ ├── adapter
│ │ │ │ ├── base
│ │ │ │ │ ├── OnItemClickListener.java
│ │ │ │ │ ├── OnItemLongClickListener.java
│ │ │ │ │ ├── IAdapterItem.java
│ │ │ │ │ └── BaseAdapter.java
│ │ │ │ ├── PopUpMenuAdapter.java
│ │ │ │ ├── MainPageAdapter.java
│ │ │ │ └── MainPageAdapter2.java
│ │ │ │ ├── QuickNoteApplication.java
│ │ │ │ ├── util
│ │ │ │ ├── TimeUtil.java
│ │ │ │ ├── QuickNoteContextWrapper.java
│ │ │ │ ├── AttachmentHelper.java
│ │ │ │ ├── PopupWindowFactory.java
│ │ │ │ ├── DialogFactory.java
│ │ │ │ ├── SharedPreferencesUtil.java
│ │ │ │ └── BitmapUtil.java
│ │ │ │ ├── entity
│ │ │ │ ├── Attachment.java
│ │ │ │ └── Note.java
│ │ │ │ ├── ui
│ │ │ │ ├── fragment
│ │ │ │ │ ├── PurchaseFragment.java
│ │ │ │ │ ├── RecentEditFragment.java
│ │ │ │ │ ├── NoteDetailFragment.java
│ │ │ │ │ ├── AboutFragment.java
│ │ │ │ │ ├── WasteBasketFragment.java
│ │ │ │ │ └── AllNoteFragment.java
│ │ │ │ └── activity
│ │ │ │ │ ├── WelcomeActivity.java
│ │ │ │ │ ├── BaseActivity.java
│ │ │ │ │ ├── SearchActivity.java
│ │ │ │ │ └── VoiceShorthandActivity.java
│ │ │ │ ├── config
│ │ │ │ ├── Constants.java
│ │ │ │ └── QuickNote.java
│ │ │ │ ├── db
│ │ │ │ └── DatabaseHelper.java
│ │ │ │ └── view
│ │ │ │ └── ItemListDialogFragment.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── tech
│ │ │ └── huqi
│ │ │ └── quicknote
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── tech
│ │ └── huqi
│ │ └── quicknote
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── _config.yml
├── settings.gradle
├── screenshort
├── download.png
└── screen_short_all.jpg
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── gradle.properties
├── README.md
└── gradlew.bat
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-slate
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/screenshort/download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/screenshort/download.png
--------------------------------------------------------------------------------
/app/libs/quicknotecore.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/libs/quicknotecore.aar
--------------------------------------------------------------------------------
/app/src/main/assets/WakeUp.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/assets/WakeUp.bin
--------------------------------------------------------------------------------
/screenshort/screen_short_all.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/screenshort/screen_short_all.jpg
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | .idea
4 | /local.properties
5 | .DS_Store
6 | /build
7 | /captures
8 | .externalNativeBuild
9 |
--------------------------------------------------------------------------------
/app/libs/bdasr_V3_20180801_d6f298a.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/libs/bdasr_V3_20180801_d6f298a.jar
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi/libvad.dnn.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/jniLibs/armeabi/libvad.dnn.so
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/thumbtack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/res/mipmap-mdpi/thumbtack.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/purchase_wx.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/res/mipmap-mdpi/purchase_wx.jpg
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi-v7a/libvad.dnn.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/jniLibs/armeabi-v7a/libvad.dnn.so
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi/libbdSpilWakeup.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/jniLibs/armeabi/libbdSpilWakeup.so
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi/libBaiduSpeechSDK.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/jniLibs/armeabi/libBaiduSpeechSDK.so
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi/libbdEASRAndroid.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/jniLibs/armeabi/libbdEASRAndroid.so
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi-v7a/libbdEASRAndroid.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/jniLibs/armeabi-v7a/libbdEASRAndroid.so
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi-v7a/libbdSpilWakeup.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/jniLibs/armeabi-v7a/libbdSpilWakeup.so
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi-v7a/libBaiduSpeechSDK.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/jniLibs/armeabi-v7a/libBaiduSpeechSDK.so
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi/libbd_easr_s1_merge_normal_20151216.dat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/jniLibs/armeabi/libbd_easr_s1_merge_normal_20151216.dat.so
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi-v7a/libbd_easr_s1_merge_normal_20151216.dat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuTianQi/QuickNote/HEAD/app/src/main/jniLibs/armeabi-v7a/libbd_easr_s1_merge_normal_20151216.dat.so
--------------------------------------------------------------------------------
/app/src/main/res/values/drawables.xml:
--------------------------------------------------------------------------------
1 |
2 | - @android:drawable/ic_menu_share
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/shape_bg_pop_window_input.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Apr 06 17:34:39 CST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/file_provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
11 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/adapter/base/OnItemClickListener.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.adapter.base;
2 |
3 | import android.view.View;
4 |
5 | /**
6 | * Created by hzhuqi on 2019/4/10
7 | */
8 | public interface OnItemClickListener {
9 | void onItemClick(View v, int position);
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_dialog_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/adapter/base/OnItemLongClickListener.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.adapter.base;
2 |
3 | import android.view.View;
4 |
5 | /**
6 | * Created by hzhuqi on 2019/4/10
7 | */
8 | public interface OnItemLongClickListener {
9 | void onItemLongClick(View v, int position);
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #212121
4 | @color/colorPrimary
5 | #3dadf9
6 | @color/colorPrimary
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/check_update_btn_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_done_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/adapter/base/IAdapterItem.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.adapter.base;
2 |
3 | /**
4 | * Created by hzhuqi on 2019/4/10
5 | */
6 | public interface IAdapterItem {
7 | /**
8 | * 将数据data绑定到position位置的View上
9 | *
10 | * @param data
11 | * @param position
12 | */
13 | void bindDataToView(T data, int position);
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_sort_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/QuickNoteApplication.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote;
2 |
3 | import android.app.Application;
4 |
5 | import tech.huqi.quicknote.config.QuickNote;
6 |
7 | /**
8 | * Created by hzhuqi on 2019/4/15
9 | */
10 | public class QuickNoteApplication extends Application {
11 |
12 | @Override
13 | public void onCreate() {
14 | super.onCreate();
15 | QuickNote.init(this);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_waste_basket.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_auto_update_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_photo_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/test/java/tech/huqi/quicknote/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_rename_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_record_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_revert_activated_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_revert_unactivated_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_auto_update_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_all_notes.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_delete_forever_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_revert_activated_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_revocation_unactivated_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_revocation_activated_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_recent_edit.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_revocation_activated_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_text_note_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_attachment_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_search_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_record_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_delete_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/util/TimeUtil.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.util;
2 |
3 | /**
4 | * Created by hzhuqi on 2019/4/15
5 | */
6 |
7 | import java.text.SimpleDateFormat;
8 | import java.util.Date;
9 |
10 | /**
11 | * 和时间以及日期操作相关的工具类
12 | */
13 | public class TimeUtil {
14 |
15 | /**
16 | * 根据指定格式format返回当前系统时间
17 | *
18 | * @param format
19 | * @return
20 | */
21 | public static String getDataTime(String format) {
22 | SimpleDateFormat df = new SimpleDateFormat(format);
23 | return df.format(new Date());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_encrypt_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_record_active_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_record_active_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_attachment_white_vertical_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_brush_activated_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_brush_activated_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_brush_unactivated_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_restore_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_camera_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_share.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_note_detail.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
18 |
19 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_note_detail.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_pop_content_input.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # QuickNote(随心记)
2 |
3 | ## 前言
4 | 一直想开发一个个人App,但是一方面工作太忙没时间,另一方面方向不好确定,在今年3月份的时候看到了一则关于字节跳动(今日头条母公司,下文简称头条)收购幕布的消息,当时很好奇,幕布是个什么鬼?为何头条会收购它,然后第一次了解了下幕布,是一个办公软件,下载体验了下,被其一键生成思维导图功能给吸引了,很好奇它是怎么实现的,原本想着破解它,看它的实现思路。结果发现里面大量用到了RN,说明里面的一些关键的富文本编辑功能很可能是js端实现的,仔细想想也对,幕布作为一个支持PC客户端,移动端(Android/IOS)以及Web端的办公软件,不论是从开发成本还是维护成本上来考虑,这些功能使用JS实现能够尽可能做到多端复用的效果。另一方面富文本编辑功能在JS端已经有相对成熟的框架,纯移动端实现的话一般是EditText + Span方案或者多布局方案,但这2种方案都存在一个很大的缺陷就是不够灵活,开发与维护成本高。因为核心功能是使用JS代码来实现的,所以就没破解的欲望了,但是方向却因此确定下来了就是做一个个人笔记类App,大概花了一个月的时间(主要是非工作日的碎片化时间)开发了以下这个1.0.0版本,考虑到以后可能会逐步增加更多功能以及考虑上架,因此以下开源版功能及代码做了精简
5 |
6 | ## 简约好用的笔记类App
7 |
8 | > 这是一款简约好用的笔记App,支持图文混淆,手写涂鸦,语音速记等高级功能。贴心的最近编辑,废纸篓,夜间模式,排序,搜索,误删恢复,手势密码等功能无不透露着作者对用户使用体验的重视与追求!
9 |
10 | 
11 |
12 | ## 开源版扫码下载
13 | 因平时工作较忙,正式版业余时间开发进度较慢,还未上线,可扫码体验开源版
14 | 
--------------------------------------------------------------------------------
/app/src/androidTest/java/tech/huqi/quicknote/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("tech.huqi.quicknote", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_main_page.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - @string/preference_theme_entry_default
5 | - @string/preference_theme_entry_night
6 |
7 |
8 | - @string/theme_value_default
9 | - @string/theme_value_night
10 |
11 |
12 |
13 | - @string/preference_lang_entry_chinese
14 | - @string/preference_lang_entry_english
15 |
16 |
17 |
18 | - @string/lang_value_chinese
19 | - @string/lang_value_english
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3dadf9
4 | #98d0f7
5 | #3dadf9
6 |
7 |
8 | #FFFFFFFF
9 | #F8EFF2
10 | #8a8a8a
11 | #3dadf9
12 |
13 |
14 | #999999
15 | #EDEDED
16 |
17 |
18 | #666666
19 | #F3323B
20 | @color/colorPrimary
21 | @color/gesture_inner_color
22 | @color/gesture_border_color_error
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/no_data_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_freehand_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/popup_menu_attachment_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
14 |
15 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_dialog_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_search.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
11 |
12 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_freehand_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/entity/Attachment.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.entity;
2 |
3 | import android.net.Uri;
4 |
5 | /**
6 | * Created by hzhuqi on 2019/4/14
7 | */
8 | public class Attachment {
9 | /**
10 | * 附件的Uri描述
11 | */
12 | private Uri uri;
13 | /**
14 | * 附件的路径
15 | */
16 | private String path;
17 | /**
18 | * 附件类型
19 | */
20 | private int type;
21 |
22 | public Attachment() {
23 | }
24 |
25 | public Attachment(Uri uri, String path, int type) {
26 | this.uri = uri;
27 | this.path = path;
28 | this.type = type;
29 | }
30 |
31 | public Uri getUri() {
32 | return uri;
33 | }
34 |
35 | public void setUri(Uri uri) {
36 | this.uri = uri;
37 | }
38 |
39 | public String getPath() {
40 | return path;
41 | }
42 |
43 | public void setPath(String path) {
44 | this.path = path;
45 | }
46 |
47 | public int getType() {
48 | return type;
49 | }
50 |
51 | public void setType(int type) {
52 | this.type = type;
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_toolbar_sort.xml:
--------------------------------------------------------------------------------
1 |
17 |
25 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/ui/fragment/PurchaseFragment.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 |
11 | import tech.huqi.quicknote.R;
12 |
13 | /**
14 | * Created by hzhuqi on 2019/4/6
15 | */
16 | public class PurchaseFragment extends Fragment {
17 |
18 | @Nullable
19 | @Override
20 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
21 | return inflater.inflate(R.layout.fragment_purchase, container, false);
22 | }
23 |
24 | @Override
25 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
26 | super.onViewCreated(view, savedInstanceState);
27 | initView(view);
28 | initData();
29 | }
30 |
31 | private void initView(View root) {
32 |
33 | }
34 |
35 | private void initData() {
36 |
37 | }
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_settings.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
16 |
17 |
20 |
21 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_language_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_language_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_search_activity.xml:
--------------------------------------------------------------------------------
1 |
17 |
19 |
20 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_default_avatar_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_gesture_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_gesture_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/config/Constants.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.config;
2 |
3 |
4 | /**
5 | * Created by hzhuqi on 2019/4/6
6 | */
7 | public interface Constants {
8 | /**
9 | * 启动页延时
10 | */
11 | int DELAY_TIME = 1000 * 2;
12 | /**
13 | * 附件类型
14 | */
15 | int ATTACHMENT_TYPE_IMAGE = 0;
16 | int ATTACHMENT_TYPE_AUDIO = 1;
17 |
18 | /**
19 | * 文件存储名称的时间戳格式
20 | */
21 | String FILE_NAME_DATE_FORMAT = "yyyyMMdd_HHmmss_SSS";
22 |
23 | /**
24 | * 笔记编辑日期格式
25 | */
26 | String TIME_FORMAT_Y_M_D = "yyyy/MM/dd";
27 | String TIME_FORMAT_Y_M_D_H_M = "yyyy/MM/dd HH:mm";
28 | String TIME_FORMAT_Y_M_D_H_M_S = "yyyy-MM-dd HH:mm:ss";
29 |
30 | /**
31 | * Intent数据传递
32 | */
33 | String INTENT_FROM_WELCOME_ACTIVITY = "from_welcome_activity";
34 | String INTENT_NOTE_ITEM = "note_item";
35 | String INTENT_QUICK_ACTION = "quick_action";
36 | String INTENT_QUICK_ACTION_CAMERA = "quick_action_camera";
37 | String INTENT_QUICK_ACTION_RECORD = "quick_action_record";
38 | String INTENT_QUICK_ACTION_FREEHAND = "quick_action_freehand";
39 | String INTENT_IMAGE_PATH = "image_path";
40 | String INTENT_VOICE_RECOGNIZED = "voice_recognized";
41 |
42 | /**
43 | * 最近编辑显示的item数
44 | */
45 | int RECENT_EDIT_MAX_NUM = 10;
46 |
47 | String SHARED_PREFERENCE_NAME = "quick_note";
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/ui/activity/WelcomeActivity.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.ui.activity;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.app.AppCompatActivity;
8 |
9 | import tech.huqi.quicknote.R;
10 | import tech.huqi.quicknote.config.Constants;
11 | import tech.huqi.quicknote.config.QuickNote;
12 |
13 | /**
14 | * Created by hzhuqi on 2019/4/26
15 | */
16 | public class WelcomeActivity extends BaseActivity {
17 | @Override
18 | protected void onCreate(@Nullable Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | setContentView(R.layout.activity_welcome);
21 | delay();
22 | }
23 |
24 | private void delay() {
25 | new Handler().postDelayed(new Runnable() {
26 | @Override
27 | public void run() {
28 | Intent intent;
29 | if (QuickNote.isSetPatternLock()) {
30 | intent = new Intent(WelcomeActivity.this, LockActivity.class);
31 | intent.putExtra(Constants.INTENT_FROM_WELCOME_ACTIVITY, true);
32 | } else {
33 | intent = new Intent(WelcomeActivity.this, MainActivity.class);
34 | }
35 | startActivity(intent);
36 | WelcomeActivity.this.finish();
37 | }
38 | }, Constants.DELAY_TIME);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
20 |
21 |
26 |
27 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/util/QuickNoteContextWrapper.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.util;
2 |
3 | import android.content.Context;
4 | import android.content.ContextWrapper;
5 | import android.content.res.Configuration;
6 | import android.content.res.Resources;
7 | import android.os.Build;
8 | import android.os.LocaleList;
9 |
10 | import java.util.Locale;
11 |
12 | /**
13 | * Created by hzhuqi on 2019/4/28
14 | */
15 | public class QuickNoteContextWrapper extends ContextWrapper {
16 | public QuickNoteContextWrapper(Context base) {
17 | super(base);
18 | }
19 |
20 | public static Context wrap(Context context, Locale locale) {
21 | Context newContext = context;
22 | Resources resources = context.getResources();
23 | Configuration config = resources.getConfiguration();
24 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//8.0及以上系统
25 | config.setLocale(locale);
26 | LocaleList localeList = new LocaleList(locale);
27 | LocaleList.setDefault(localeList);
28 | config.setLocales(localeList);
29 | newContext = context.createConfigurationContext(config);//对于8.0系统必须先调用该语句,否则后面的updateConfiguration不起作用
30 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//4.4及以上系统
31 | config.setLocale(locale);
32 | newContext = context.createConfigurationContext(config);
33 | } else {
34 | config.locale = locale;
35 | }
36 | return new QuickNoteContextWrapper(newContext);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/ui/fragment/RecentEditFragment.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | import java.util.List;
11 |
12 | import tech.huqi.quicknote.R;
13 | import tech.huqi.quicknote.db.NoteDatabaseHelper;
14 | import tech.huqi.quicknote.entity.Note;
15 |
16 | import tech.huqi.quicknote.config.Constants;
17 |
18 | /**
19 | * Created by hzhuqi on 2019/4/16
20 | */
21 | public class RecentEditFragment extends BaseNoteListFragment {
22 | @Override
23 | View createView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
24 | return inflater.inflate(R.layout.fragment_main_page, container, false);
25 | }
26 |
27 | @Override
28 | void initData() {
29 |
30 | }
31 |
32 | @Override
33 | List onGetNotes() {
34 | mNotes = NoteDatabaseHelper.getInstance().getRecentlyNotes(Constants.RECENT_EDIT_MAX_NUM);
35 | return mNotes;
36 | }
37 |
38 | @Override
39 | void onNoteItemLongClick(View v, int position) {
40 |
41 | }
42 |
43 | @Override
44 | void initView() {
45 |
46 | }
47 |
48 | @Override
49 | void onRefreshData() {
50 | mNotes = NoteDatabaseHelper.getInstance().getRecentlyNotes(Constants.RECENT_EDIT_MAX_NUM);
51 | mAdapter.refreshData(mNotes);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/util/AttachmentHelper.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.util;
2 |
3 | import android.content.Context;
4 | import android.net.Uri;
5 | import android.support.v4.content.FileProvider;
6 |
7 | import java.io.File;
8 | import java.io.IOException;
9 | import java.text.SimpleDateFormat;
10 | import java.util.Calendar;
11 |
12 | import tech.huqi.quicknote.config.Constants;
13 |
14 | /**
15 | * Created by hzhuqi on 2019/4/14
16 | */
17 | public class AttachmentHelper {
18 |
19 | public static Uri getFileProviderUri(Context context, File file) {
20 | return FileProvider.getUriForFile(context, context.getPackageName() + ".authority", file);
21 | }
22 |
23 | public static File createNewAttachmentFile(Context context, String subDirName, String extension) {
24 | File file = new File(context.getExternalFilesDir(subDirName), createNewAttachmentName(extension));
25 | if (!file.exists()) {
26 | try {
27 | file.createNewFile();
28 | } catch (IOException e) {
29 | e.printStackTrace();
30 | return null;
31 | }
32 | }
33 | return file;
34 | }
35 |
36 | private static synchronized String createNewAttachmentName(String extension) {
37 | Calendar calendar = Calendar.getInstance();
38 | SimpleDateFormat sdf = new SimpleDateFormat(Constants.FILE_NAME_DATE_FORMAT);
39 | String name = sdf.format(calendar.getTime());
40 | name += extension != null ? extension : "";
41 | return name;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/ui/activity/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.ui.activity;
2 |
3 | import android.Manifest;
4 | import android.content.Context;
5 | import android.support.annotation.NonNull;
6 | import android.support.v7.app.AppCompatActivity;
7 |
8 | import pub.devrel.easypermissions.EasyPermissions;
9 | import tech.huqi.quicknote.config.QuickNote;
10 | import tech.huqi.quicknote.util.QuickNoteContextWrapper;
11 |
12 | /**
13 | * Created by hzhuqi on 2019/4/28
14 | */
15 | public class BaseActivity extends AppCompatActivity {
16 | protected final int RC_ALL_PERM = 10000;
17 | protected final int RC_READ_EXTERNAL_STORAGE = 10001;
18 | protected final String[] PERMISSIONS = {Manifest.permission.WRITE_EXTERNAL_STORAGE,
19 | Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_PHONE_STATE};
20 |
21 | @Override
22 | protected void attachBaseContext(Context newBase) {
23 | Context context = QuickNoteContextWrapper.wrap(newBase, QuickNote.getLangLocale());
24 | super.attachBaseContext(context);
25 | }
26 |
27 | @Override
28 | public void onRequestPermissionsResult(int requestCode,
29 | @NonNull String[] permissions,
30 | @NonNull int[] grantResults) {
31 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
32 |
33 | // EasyPermissions handles the request result.
34 | EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 | # 设置混淆的压缩比率 0 ~ 7
23 | -optimizationpasses 5
24 | # 混淆时不使用大小写混合,混淆后的类名为小写
25 | -dontusemixedcaseclassnames
26 | # 指定不去忽略非公共库的类
27 | -dontskipnonpubliclibraryclasses
28 | # 指定不去忽略非公共库的成员
29 | -dontskipnonpubliclibraryclassmembers
30 | # 混淆时不做预校验
31 | -dontpreverify
32 | # 混淆时不记录日志
33 | -verbose
34 | # 忽略警告
35 | -ignorewarning
36 | # 代码优化
37 | -dontshrink
38 | # 不优化输入的类文件
39 | -dontoptimize
40 | # 保留注解不混淆
41 | -keepattributes *Annotation*,InnerClasses
42 | # 避免混淆泛型
43 | -keepattributes Signature
44 | # 保留代码行号,方便异常信息的追踪
45 | -keepattributes SourceFile,LineNumberTable
46 | # 混淆采用的算法
47 | -optimizations !code/simplification/cast,!field/*,!class/merging/*
48 | # 关闭Log
49 | -assumenosideeffects class android.util.Log {
50 | public static *** d(...);
51 | public static *** v(...);
52 | public static *** i(...);
53 | public static *** e(...);
54 | public static *** w(...);
55 | }
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/db/DatabaseHelper.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.db;
2 |
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteDatabase;
5 | import android.database.sqlite.SQLiteOpenHelper;
6 |
7 | /**
8 | * Created by hzhuqi on 2019/4/14
9 | */
10 | public class DatabaseHelper extends SQLiteOpenHelper {
11 | public static final String DATABASE_NAME = "quick_note";
12 | public static final String ALL_NOTE_TABLE_NAME = "all_notes";
13 | public static final String WASTED_NOTE_TABLE_NAME = "wasted_notes";
14 | public static final String CREATE_NOTE_TABLE = "create table " + ALL_NOTE_TABLE_NAME
15 | + " (_id integer primary key autoincrement, title text, content text,"
16 | + " date varchar(10), address text, timestamp float,lastmodify float, iswasted integer)";
17 | public static final String CREATE_WASTED_TABLE = "create table " + WASTED_NOTE_TABLE_NAME
18 | + " (_id integer primary key autoincrement, title text, content text,"
19 | + " date varchar(10), address text,timestamp float, lastmodify float, iswasted integer)";
20 |
21 | public DatabaseHelper(Context context) {
22 | super(context, DATABASE_NAME, null, 1);
23 | }
24 |
25 | public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
26 | super(context, name, factory, version);
27 | }
28 |
29 | @Override
30 | public void onCreate(SQLiteDatabase db) {
31 | db.execSQL(CREATE_NOTE_TABLE);
32 | db.execSQL(CREATE_WASTED_TABLE);
33 | }
34 |
35 | @Override
36 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_purchase.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
27 |
28 |
33 |
34 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | applicationId "tech.huqi.quicknote"
7 | minSdkVersion 16
8 | targetSdkVersion 28
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled true
16 | shrinkResources true
17 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
18 | }
19 | debug {
20 | minifyEnabled false
21 | }
22 | }
23 | repositories {
24 | flatDir {
25 | dirs 'libs'
26 | }
27 | }
28 | }
29 |
30 | dependencies {
31 | implementation fileTree(include: ['*.jar'], dir: 'libs')
32 | implementation 'com.android.support:appcompat-v7:28.0.0'
33 | implementation 'com.android.support:preference-v7:28.+'
34 | implementation 'com.android.support:design:28.0.0'
35 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
36 | testImplementation 'junit:junit:4.12'
37 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
38 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
39 | implementation(name: 'quicknotecore', ext: 'aar')
40 | implementation 'com.google.guava:guava:27.1-android'
41 | implementation 'com.github.clans:fab:1.6.4'
42 | debugImplementation 'com.amitshekhar.android:debug-db:1.0.1'
43 | implementation 'de.hdodenhof:circleimageview:3.0.0'
44 | implementation files('libs/bdasr_V3_20180801_d6f298a.jar')
45 | implementation 'com.github.Jay-Goo:WaveLineView:v1.0.3'
46 | implementation 'pub.devrel:easypermissions:2.0.1'
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_toolbar_detail.xml:
--------------------------------------------------------------------------------
1 |
17 |
19 |
20 |
26 |
32 |
33 |
38 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_toolbar_common.xml:
--------------------------------------------------------------------------------
1 |
17 |
19 |
20 |
26 |
32 |
37 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/ui/fragment/NoteDetailFragment.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.view.LayoutInflater;
8 | import android.view.Menu;
9 | import android.view.MenuInflater;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 |
13 | import tech.huqi.quicknote.R;
14 | import tech.huqi.quicknote.ui.activity.MainActivity;
15 |
16 | /**
17 | * Created by hzhuqi on 2019/4/9
18 | */
19 | @Deprecated
20 | public class NoteDetailFragment extends Fragment {
21 | private MainActivity mMainActivity;
22 |
23 | @Nullable
24 | @Override
25 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
26 | return inflater.inflate(R.layout.fragment_note_detail, container, false);
27 | }
28 |
29 | @Override
30 | public void onActivityCreated(@Nullable Bundle savedInstanceState) {
31 | super.onActivityCreated(savedInstanceState);
32 | mMainActivity = (MainActivity) getActivity();
33 | mMainActivity.getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(true);
34 | setHasOptionsMenu(true);
35 | }
36 |
37 | @Override
38 | public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
39 | inflater.inflate(R.menu.menu_toolbar_detail, menu);
40 | super.onCreateOptionsMenu(menu, inflater);
41 | }
42 |
43 | @Override
44 | public void onPrepareOptionsMenu(Menu menu) {
45 | super.onPrepareOptionsMenu(menu);
46 | menu.findItem(R.id.menu_search).setVisible(false);
47 | menu.findItem(R.id.menu_sort).setVisible(false);
48 | menu.findItem(R.id.switch_mode).setVisible(false);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_welcome.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
15 |
16 |
26 |
27 |
37 |
38 |
39 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_donate_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_donate_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
17 |
18 |
25 |
26 |
34 |
35 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/ui/fragment/AboutFragment.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.text.TextUtils;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.Button;
12 | import android.widget.TextView;
13 |
14 | import tech.huqi.quicknote.R;
15 | import tech.huqi.quicknote.config.QuickNote;
16 | import tech.huqi.quicknote.util.CommonUtil;
17 |
18 | /**
19 | * Created by hzhuqi on 2019/4/6
20 | */
21 | public class AboutFragment extends Fragment {
22 | private Button mBtnCheckUpdate;
23 | private TextView mTvAppVersion;
24 |
25 | @Nullable
26 | @Override
27 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
28 | return inflater.inflate(R.layout.fragment_about, container, false);
29 | }
30 |
31 | @Override
32 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
33 | super.onViewCreated(view, savedInstanceState);
34 | initView(view);
35 | initData();
36 | }
37 |
38 | private void initView(View root) {
39 | mBtnCheckUpdate = root.findViewById(R.id.btn_about_check_update);
40 | mTvAppVersion = root.findViewById(R.id.tv_about_version);
41 | }
42 |
43 | private void initData() {
44 | String appVersion = CommonUtil.getAppVersion();
45 | if (TextUtils.isEmpty(appVersion)) {
46 | mTvAppVersion.setText(appVersion);
47 | }
48 | mBtnCheckUpdate.setOnClickListener(new View.OnClickListener() {
49 | @Override
50 | public void onClick(View v) {
51 | checkAndUpdateVersion();
52 | }
53 | });
54 | }
55 |
56 | private void checkAndUpdateVersion() {
57 | // 开源版本直接返回最新版本
58 | CommonUtil.showToastOnUiThread(QuickNote.getString(R.string.check_update_no_new_version));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/adapter/PopUpMenuAdapter.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.BaseAdapter;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 |
11 |
12 | import tech.huqi.quicknote.R;
13 |
14 |
15 | public class PopUpMenuAdapter extends BaseAdapter {
16 | private int[] mIcons;
17 | private String[] mTexts;
18 | private Context mContext;
19 |
20 | public PopUpMenuAdapter(Context context, int[] icons, String[] texts) {
21 | mIcons = icons;
22 | mTexts = texts;
23 | mContext = context;
24 | }
25 |
26 | @Override
27 | public View getView(int position, View convertView, ViewGroup parent) {
28 | ViewHolder viewHolder;
29 | if (convertView == null) {
30 | viewHolder = new ViewHolder();
31 | convertView = LayoutInflater.from(mContext).inflate(R.layout.popup_menu_attachment_item, null);
32 | viewHolder.ivItemIcon = (ImageView) convertView.findViewById(R.id.popup_menu_item_iv);
33 | viewHolder.tvItemText = convertView.findViewById(R.id.popup_menu_item_tv);
34 | convertView.setTag(viewHolder);
35 | } else {
36 | viewHolder = (ViewHolder) convertView.getTag();
37 | }
38 | viewHolder.tvItemText.setText(mTexts[position]);
39 | viewHolder.ivItemIcon.setImageResource(mIcons[position]);
40 | return convertView;
41 | }
42 |
43 | static class ViewHolder {
44 | ImageView ivItemIcon;
45 | TextView tvItemText;
46 | }
47 |
48 | @Override
49 | public int getCount() {
50 | return mTexts == null ? 0 : mTexts.length;
51 | }
52 |
53 | @Override
54 | public Object getItem(int position) {
55 | return mTexts[position];
56 | }
57 |
58 | // @Override
59 | // public String getItem(int position) {
60 | // return mTexts[position];
61 | // }
62 |
63 | @Override
64 | public long getItemId(int position) {
65 | return position;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/util/PopupWindowFactory.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.util;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.ListPopupWindow;
5 | import android.support.v7.widget.PopupMenu;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.AdapterView;
9 |
10 | import tech.huqi.quicknote.adapter.PopUpMenuAdapter;
11 |
12 |
13 | /**
14 | * Created by hzhuqi on 2019/4/21
15 | */
16 | public class PopupWindowFactory {
17 |
18 | public static ListPopupWindow createListPopUpWindow(Context context, View anchor, int[] icons,
19 | String[] texts, final ListPopUpWindowItemClickListener listener) {
20 | final ListPopupWindow listPopupWindow = new ListPopupWindow(context);
21 | PopUpMenuAdapter adapter = new PopUpMenuAdapter(context, icons, texts);
22 | listPopupWindow.setAdapter(adapter);
23 | listPopupWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
24 | listPopupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
25 | listPopupWindow.setAnchorView(anchor);
26 | listPopupWindow.setModal(true);
27 | listPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
28 | @Override
29 | public void onItemClick(AdapterView> parent, View view,
30 | int position, long id) {
31 | listener.onItemClick(parent, view, position, id);
32 | listPopupWindow.dismiss();
33 | }
34 | });
35 | return listPopupWindow;
36 | }
37 |
38 | public static PopupMenu createAndShowPopupMenu(Context context, View anchor, int menuRes, PopupMenu.OnMenuItemClickListener listener) {
39 | PopupMenu popup = new PopupMenu(context, anchor);
40 | popup.getMenuInflater().inflate(menuRes, popup.getMenu());
41 | popup.setOnMenuItemClickListener(listener);
42 | popup.show();
43 | return popup;
44 | }
45 |
46 | public interface ListPopUpWindowItemClickListener {
47 | void onItemClick(AdapterView> parent, View view, int position, long id);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_about_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_about_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_voice_shorthand.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
27 |
28 |
36 |
37 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/recycle_main_page_note_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
17 |
18 |
22 |
23 |
30 |
31 |
36 |
37 |
38 |
44 |
45 |
50 |
51 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 220dp
4 | 320dp
5 | 4dp
6 |
7 | 8dp
8 | 15dp
9 | 20dp
10 | 35dp
11 | 50dp
12 | 65dp
13 | 80dp
14 | 90dp
15 | 120dp
16 | 200dp
17 | 300dp
18 |
19 | 7dp
20 | 10dp
21 | 10.0dip
22 | 12.0dip
23 | 30dp
24 | 16sp
25 | 70dp
26 |
27 | 20sp
28 | 18sp
29 | 16sp
30 | 15sp
31 | 14sp
32 |
33 | @dimen/text_size_18
34 |
35 | @dimen/text_size_16
36 |
37 |
38 | 50dp
39 | 20dp
40 |
41 | 30dp
42 | 10dp
43 |
44 | 8dp
45 | 10dp
46 | 6dp
47 |
48 |
49 | 30dp
50 | 54dp
51 | 30dp
52 | 28dp
53 | 25dp
54 | 45dp
55 | 40dp
56 |
57 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_lock.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
21 |
22 |
31 |
32 |
42 |
43 |
47 |
48 |
57 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/adapter/MainPageAdapter.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.MotionEvent;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.LinearLayout;
9 | import android.widget.TextView;
10 |
11 | import java.util.List;
12 |
13 |
14 | import tech.huqi.quicknote.R;
15 | import tech.huqi.quicknote.adapter.base.BaseAdapter;
16 | import tech.huqi.quicknote.adapter.base.IAdapterItem;
17 | import tech.huqi.quicknote.core.view.ImageTextView;
18 | import tech.huqi.quicknote.entity.Note;
19 | import tech.huqi.quicknote.util.CommonUtil;
20 |
21 | /**
22 | * Created by hzhuqi on 2019/4/10
23 | */
24 | public class MainPageAdapter extends BaseAdapter {
25 | private static boolean isGridMode = true;
26 |
27 | public MainPageAdapter(Context context, List datas) {
28 | super(context, datas);
29 | }
30 |
31 | @Override
32 | protected MainPageNoteItemView inflateView(Context context, ViewGroup parent) {
33 | return new MainPageNoteItemView(context);
34 | }
35 |
36 | public void setIsGridMode(boolean isGridMode) {
37 | this.isGridMode = isGridMode;
38 | }
39 |
40 | public class MainPageNoteItemView extends LinearLayout implements IAdapterItem {
41 | private TextView tvNoteTitle;
42 | private ImageTextView tvNoteMainBody;
43 | private TextView tvNoteDate;
44 |
45 | public MainPageNoteItemView(Context context) {
46 | super(context);
47 | View v = LayoutInflater.from(context).inflate(R.layout.recycle_main_page_note_item, this, true);
48 | tvNoteTitle = v.findViewById(R.id.tv_note_title);
49 | tvNoteMainBody = v.findViewById(R.id.tv_note_main_body);
50 | tvNoteDate = v.findViewById(R.id.tv_note_date);
51 | adjustBodyLayoutParams();
52 | }
53 |
54 | @Override
55 | public void bindDataToView(Note note, int position) {
56 | tvNoteTitle.setText(note.getTitle());
57 | tvNoteMainBody.setText(note.getContent());
58 | tvNoteDate.setText(note.getDate());
59 | }
60 |
61 | private void adjustBodyLayoutParams() {
62 | ViewGroup.LayoutParams params = tvNoteMainBody.getLayoutParams();
63 | params.width = CommonUtil.getScreenWidthPixels(mContext);
64 | if (isGridMode) {
65 | params.height = params.width / 2;
66 | } else {
67 | params.height = params.width / 6;
68 | }
69 | tvNoteMainBody.setLayoutParams(params);
70 | }
71 |
72 | @Override
73 | public boolean onInterceptTouchEvent(MotionEvent ev) {
74 | return true;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_recommend_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_recommend_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
15 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/adapter/MainPageAdapter2.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.util.Log;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.TextView;
11 |
12 | import java.util.List;
13 |
14 | import tech.huqi.quicknote.R;
15 | import tech.huqi.quicknote.entity.Note;
16 |
17 | /**
18 | * Created by hzhuqi on 2019/4/7
19 | */
20 | @Deprecated
21 | public class MainPageAdapter2 extends RecyclerView.Adapter {
22 | private static final String TAG = "QuickNote.MainPageAdapter2";
23 | private Context mContext;
24 | private List mNotes;
25 | private boolean isGridMode = true;
26 |
27 | public MainPageAdapter2(Context context, List notes) {
28 | mContext = context;
29 | mNotes = notes;
30 | }
31 |
32 | @NonNull
33 | @Override
34 | public MainPageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
35 | Log.d(TAG, "==============onCreateViewHolder=================" + parent);
36 | View v = LayoutInflater.from(mContext).inflate(R.layout.recycle_main_page_note_item, parent, false);
37 | return new MainPageViewHolder(v);
38 | }
39 |
40 | @Override
41 | public void onBindViewHolder(@NonNull MainPageViewHolder viewHolder, int position) {
42 | Note note = mNotes.get(position);
43 | viewHolder.tvNoteTitle.setText(note.getTitle());
44 | viewHolder.tvNoteMainBody.setText(note.getContent());
45 | viewHolder.tvNoteDate.setText(note.getDate());
46 | }
47 |
48 | @Override
49 | public int getItemCount() {
50 | return mNotes == null ? 0 : mNotes.size();
51 | }
52 |
53 | public void setIsGridMode(boolean isGridMode) {
54 | this.isGridMode = isGridMode;
55 | }
56 |
57 | class MainPageViewHolder extends RecyclerView.ViewHolder {
58 | private TextView tvNoteTitle;
59 | private TextView tvNoteMainBody;
60 | private TextView tvNoteDate;
61 | private int defaultWidth = mContext.getResources().getDisplayMetrics().widthPixels / 2;
62 | private int defaultHeight = (int) mContext.getResources().getDimension(R.dimen.space_12);
63 |
64 | public MainPageViewHolder(@NonNull View itemView) {
65 | super(itemView);
66 | tvNoteTitle = itemView.findViewById(R.id.tv_note_title);
67 | tvNoteMainBody = itemView.findViewById(R.id.tv_note_main_body);
68 | if (isGridMode) {
69 | adjustBodyLayoutParams();
70 | }
71 | tvNoteDate = itemView.findViewById(R.id.tv_note_date);
72 | }
73 |
74 | private void adjustBodyLayoutParams() {
75 | ViewGroup.LayoutParams params = tvNoteMainBody.getLayoutParams();
76 | params.width = defaultWidth;
77 | params.height = (params.width - defaultHeight);
78 | tvNoteMainBody.setLayoutParams(params);
79 | }
80 | }
81 |
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
22 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
37 |
38 |
39 |
40 |
43 |
44 |
45 |
46 |
51 |
54 |
55 |
56 |
59 |
62 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_eraser_unactivated_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_freehand.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
23 |
24 |
34 |
35 |
43 |
44 |
52 |
53 |
62 |
63 |
64 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/ui/fragment/WasteBasketFragment.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.util.Log;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 |
11 | import java.util.List;
12 |
13 | import tech.huqi.quicknote.R;
14 | import tech.huqi.quicknote.db.NoteDatabaseHelper;
15 | import tech.huqi.quicknote.entity.Note;
16 | import tech.huqi.quicknote.view.ItemListDialogFragment;
17 |
18 | /**
19 | * Created by hzhuqi on 2019/4/6
20 | * 废纸篓Fragment,用来显示用户最近删除的笔记的视图
21 | */
22 | public class WasteBasketFragment extends BaseNoteListFragment implements ItemListDialogFragment.Listener {
23 | private static final String TAG = "QuickNote.WasteBasketFragment";
24 | private static final int BOTTOM_SHEET_ITEM_RECOVERY = 0;
25 | private static final int BOTTOM_SHEET_ITEM_DELETE_FOREVER = 1;
26 | private int mLongClickNoteId;
27 |
28 | @Override
29 | View createView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
30 | return inflater.inflate(R.layout.fragment_main_page, container, false);
31 | }
32 |
33 | @Override
34 | void initData() {
35 |
36 | }
37 |
38 | @Override
39 | List onGetNotes() {
40 | mNotes = NoteDatabaseHelper.getInstance().getAllWastedNotes();
41 | return mNotes;
42 | }
43 |
44 | @Override
45 | void onNoteItemLongClick(View v, int position) {
46 | mLongClickNoteId = position;
47 | createAndShowDialog();
48 | }
49 |
50 | @Override
51 | void initView() {
52 | }
53 |
54 | @Override
55 | void onRefreshData() {
56 | Log.d(TAG, "刷新WasteBasketFragment数据");
57 | mNotes = NoteDatabaseHelper.getInstance().getAllWastedNotes();
58 | mAdapter.refreshData(mNotes);
59 | }
60 |
61 | private void createAndShowDialog() {
62 | int[] icons = {R.drawable.ic_restore_black_24dp, R.drawable.ic_delete_forever_24dp};
63 | String[] texts = {getString(R.string.recovery), getString(R.string.delete)};
64 | ItemListDialogFragment.newInstance(icons, texts).setListener(this).show(getActivity().getSupportFragmentManager(), TAG);
65 | }
66 |
67 | @Override
68 | public void onItemClicked(int position) {
69 | switch (position) {
70 | case BOTTOM_SHEET_ITEM_RECOVERY: {
71 | recoveryNote();
72 | }
73 | break;
74 | case BOTTOM_SHEET_ITEM_DELETE_FOREVER: {
75 | deleteNote();
76 | }
77 | break;
78 | }
79 | }
80 |
81 | private void recoveryNote() {
82 | NoteDatabaseHelper.getInstance().recovery(mNotes.get(mLongClickNoteId).getId());
83 | mNotes = NoteDatabaseHelper.getInstance().getAllWastedNotes();
84 | mAdapter.refreshData(mNotes);
85 | }
86 |
87 | private void deleteNote() {
88 | NoteDatabaseHelper.getInstance().delete(mNotes.get(mLongClickNoteId).getId());
89 | mNotes = NoteDatabaseHelper.getInstance().getAllWastedNotes();
90 | mAdapter.refreshData(mNotes);
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_eraser_activated_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_eraser_activated_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
15 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/util/DialogFactory.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.util;
2 |
3 | /**
4 | * Created by hzhuqi on 2019/4/21
5 | */
6 |
7 | import android.content.Context;
8 | import android.content.DialogInterface;
9 | import android.support.v7.app.AlertDialog.Builder;
10 | import android.support.v7.widget.AppCompatEditText;
11 | import android.view.View;
12 | import android.widget.EditText;
13 |
14 | import tech.huqi.quicknote.R;
15 | import tech.huqi.quicknote.config.QuickNote;
16 |
17 | public class DialogFactory {
18 | private static final int PADDING = 20;
19 | private static final String CANCEL_TIP = QuickNote.getString(R.string.popup_window_cancel);
20 | private static final String SURE_TIP = QuickNote.getString(R.string.popup_window_sure);
21 |
22 | public static void createAndShowDialog(Context context, String title, String content,
23 | DialogInterface.OnClickListener positiveListener) {
24 | createAndShowDialog(context, title, content, CANCEL_TIP, null, SURE_TIP, positiveListener);
25 | }
26 |
27 | public static void createAndShowDialog(Context context, String title, String content,
28 | DialogInterface.OnClickListener negativeListener,
29 | DialogInterface.OnClickListener positiveListener) {
30 | createAndShowDialog(context, title, content, CANCEL_TIP, negativeListener, SURE_TIP, positiveListener);
31 | }
32 |
33 | public static void createAndShowDialog(Context context, String title, String content,
34 | String negativeButtonTip, DialogInterface.OnClickListener negativeListener,
35 | String positiveButtonTip, DialogInterface.OnClickListener positiveListener) {
36 | Builder builder = new Builder(context);
37 | builder.setTitle(title);
38 | builder.setMessage(content);
39 | builder.setNegativeButton(negativeButtonTip, negativeListener);
40 | builder.setPositiveButton(positiveButtonTip, positiveListener);
41 | builder.show();
42 | }
43 |
44 | public static EditText showInputDialog(Context context, String title, String content, DialogInterface.OnClickListener positiveListener) {
45 | Builder builder = new Builder(context);
46 | builder.setTitle(title);
47 | builder.setMessage(content);
48 | AppCompatEditText input = new AppCompatEditText(context);
49 | builder.setView(input, PADDING, PADDING, PADDING, PADDING);
50 | builder.setNegativeButton(CANCEL_TIP, null);
51 | builder.setPositiveButton(SURE_TIP, positiveListener);
52 | builder.show();
53 | return input;
54 | }
55 |
56 | public static void showInputDialog(Context context, String title, View contentView, DialogInterface.OnClickListener positiveListener) {
57 | Builder builder = new Builder(context);
58 | builder.setTitle(title);
59 | builder.setMessage(null);
60 | builder.setView(contentView, 3 * PADDING, PADDING, 3 * PADDING, PADDING);
61 | builder.setNegativeButton(QuickNote.getString(R.string.popup_window_cancel), null);
62 | builder.setPositiveButton(QuickNote.getString(R.string.popup_window_sure), positiveListener);
63 | builder.show();
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/util/SharedPreferencesUtil.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.util;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.preference.PreferenceManager;
6 |
7 | import java.util.HashMap;
8 | import java.util.Map;
9 |
10 | import tech.huqi.quicknote.config.Constants;
11 | import tech.huqi.quicknote.config.QuickNote;
12 |
13 | /**
14 | * Created by hzhuqi on 2019/4/23
15 | */
16 | public class SharedPreferencesUtil {
17 | private static final Map SP_MAP = new HashMap<>();
18 | private static SharedPreferences sp;
19 |
20 | public static SharedPreferencesUtil getInstance() {
21 | return getInstance(Constants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE);
22 | }
23 |
24 | public static SharedPreferencesUtil getInstance(String name) {
25 | return getInstance(name, Context.MODE_PRIVATE);
26 | }
27 |
28 | private SharedPreferencesUtil(String name, int mode) {
29 | sp = QuickNote.getAppContext().getSharedPreferences(name, mode);
30 |
31 | }
32 |
33 | private SharedPreferencesUtil(Context context) {
34 | sp = PreferenceManager.getDefaultSharedPreferences(context);
35 | }
36 |
37 | public static SharedPreferencesUtil getInstance(String name, int mode) {
38 | SharedPreferencesUtil spUtil = SP_MAP.get(name);
39 | if (spUtil == null) {
40 | synchronized (SharedPreferencesUtil.class) {
41 | spUtil = SP_MAP.get(name);
42 | if (spUtil == null) {
43 | // spUtil = new SharedPreferencesUtil(name, mode);
44 | spUtil = new SharedPreferencesUtil(QuickNote.getAppContext());
45 | SP_MAP.put(name, spUtil);
46 | }
47 | }
48 | }
49 | return spUtil;
50 | }
51 |
52 | public String getString(String key, final String defaultValue) {
53 | return sp.getString(key, defaultValue);
54 | }
55 |
56 | public void setString(final String key, final String value) {
57 | sp.edit().putString(key, value).apply();
58 | }
59 |
60 | public boolean getBoolean(final String key, final boolean defaultValue) {
61 | return sp.getBoolean(key, defaultValue);
62 | }
63 |
64 | public boolean hasKey(final String key) {
65 | return sp.contains(key);
66 | }
67 |
68 | public void setBoolean(final String key, final boolean value) {
69 | sp.edit().putBoolean(key, value).apply();
70 | }
71 |
72 | public void setInt(final String key, final int value) {
73 | sp.edit().putInt(key, value).apply();
74 | }
75 |
76 | public int getInt(final String key, final int defaultValue) {
77 | return sp.getInt(key, defaultValue);
78 | }
79 |
80 | public void setFloat(final String key, final float value) {
81 | sp.edit().putFloat(key, value).apply();
82 | }
83 |
84 | public float getFloat(final String key, final float defaultValue) {
85 | return sp.getFloat(key, defaultValue);
86 | }
87 |
88 | public void setLong(final String key, final long value) {
89 | sp.edit().putLong(key, value).apply();
90 | }
91 |
92 | public long getLong(final String key, final long defaultValue) {
93 | return sp.getLong(key, defaultValue);
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/adapter/base/BaseAdapter.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.adapter.base;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.util.Log;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | import java.util.List;
11 |
12 |
13 | /**
14 | * Created by hzhuqi on 2019/4/10
15 | */
16 |
17 | /**
18 | * RecycleView Adapter的抽象基类,用来定义一些所有Adapter通用的属性方法
19 | *
20 | * @param Adapter需要的数据类型的泛型表示
21 | * @param Adapter对应的Item视图的泛型表示,必须实现IAdapterItem接口
22 | */
23 | public abstract class BaseAdapter extends RecyclerView.Adapter {
24 | private static final String TAG = "QuickNote.BaseAdapter";
25 | protected Context mContext;
26 | protected List mDatas;
27 | private OnItemClickListener mItemClickListener;
28 | private OnItemLongClickListener mItemLongClickListener;
29 |
30 | public BaseAdapter(Context context, List datas) {
31 | mContext = context;
32 | mDatas = datas;
33 | }
34 |
35 | protected abstract V inflateView(Context context, ViewGroup parent);
36 |
37 | public void refreshData(List datas) {
38 | if (datas == null) return;
39 | this.mDatas = datas;
40 | notifyDataSetChanged();
41 | }
42 |
43 | @NonNull
44 | @Override
45 | public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
46 | Log.w(TAG, "[BaseAdapter]#onCreateViewHolder");
47 | View itemView = (View) inflateView(mContext, parent);
48 | if (mItemClickListener != null) {
49 | itemView.setOnClickListener(new View.OnClickListener() {
50 | @Override
51 | public void onClick(View v) {
52 | mItemClickListener.onItemClick(v, (int) v.getTag());
53 | }
54 | });
55 | }
56 | if (mItemLongClickListener != null) {
57 | itemView.setOnLongClickListener(new View.OnLongClickListener() {
58 | @Override
59 | public boolean onLongClick(View v) {
60 | mItemLongClickListener.onItemLongClick(v, (Integer) v.getTag());
61 | return true; // 返回true,拦截onClick事件
62 | }
63 | });
64 | }
65 | return new RecyclerView.ViewHolder(itemView) {
66 | };
67 | }
68 |
69 | @Override
70 | public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
71 | Log.d(TAG, "[BaseAdapter]#onBindViewHolder");
72 | IAdapterItem itemView = (V) viewHolder.itemView;
73 | viewHolder.itemView.setTag(position);
74 | itemView.bindDataToView(getItemData(position), position);
75 | }
76 |
77 | T getItemData(int position) {
78 | return mDatas == null ? null : mDatas.get(position);
79 | }
80 |
81 | @Override
82 | public int getItemCount() {
83 | return mDatas == null ? 0 : mDatas.size();
84 | }
85 |
86 | public void setOnItemClickListener(OnItemClickListener listener) {
87 | mItemClickListener = listener;
88 | }
89 |
90 | public void setOnItemLongClickListener(OnItemLongClickListener listener) {
91 | mItemLongClickListener = listener;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/ic_skin_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
15 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_skin_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
15 |
18 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/ui/activity/SearchActivity.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.ui.activity;
2 |
3 |
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v7.widget.LinearLayoutManager;
7 | import android.support.v7.widget.SearchView;
8 | import android.support.v7.widget.RecyclerView;
9 | import android.view.Menu;
10 | import android.view.MenuItem;
11 | import android.view.View;
12 |
13 | import java.util.List;
14 |
15 | import tech.huqi.quicknote.R;
16 | import tech.huqi.quicknote.adapter.MainPageAdapter;
17 | import tech.huqi.quicknote.db.NoteDatabaseHelper;
18 | import tech.huqi.quicknote.entity.Note;
19 |
20 |
21 | /**
22 | * Created by hzhuqi on 2019/4/22
23 | */
24 | public class SearchActivity extends BaseActivity {
25 | private RecyclerView mRvSearchResult;
26 | private View mNoContentView;
27 | private SearchView mSearchView;
28 | protected MainPageAdapter mAdapter;
29 |
30 | @Override
31 | protected void onCreate(@Nullable Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | setContentView(R.layout.activity_search);
34 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
35 | getSupportActionBar().setTitle(R.string.title_search);
36 | initView();
37 | }
38 |
39 | private void initView() {
40 | mRvSearchResult = findViewById(R.id.rv_search_items_result);
41 | mRvSearchResult.setLayoutManager(new LinearLayoutManager(this));
42 | mNoContentView = findViewById(R.id.no_content_view);
43 | }
44 |
45 | @Override
46 | public boolean onCreateOptionsMenu(Menu menu) {
47 | // Inflate the menu; this adds items to the action bar if it is present.
48 | getMenuInflater().inflate(R.menu.menu_search_activity, menu);
49 | initSearchView(menu);
50 | return true;
51 | }
52 |
53 | private void initSearchView(Menu menu) {
54 | mSearchView = (SearchView) menu.findItem(R.id.menu_search_view).getActionView();
55 | mSearchView.setFocusable(true);
56 | mSearchView.setIconified(false);
57 | mSearchView.requestFocusFromTouch();
58 | mSearchView.setOnQueryTextListener(new android.support.v7.widget.SearchView.OnQueryTextListener() {
59 | @Override
60 | public boolean onQueryTextSubmit(String query) {
61 | searchAndShowResult(query);
62 | return true;
63 | }
64 |
65 | @Override
66 | public boolean onQueryTextChange(String pattern) {
67 | return false;
68 | }
69 | });
70 | }
71 |
72 | private void searchAndShowResult(String query) {
73 | List notes = NoteDatabaseHelper.getInstance().getNotesByPattern(query);
74 | if (notes == null || notes.size() == 0) {
75 | mRvSearchResult.setVisibility(View.INVISIBLE);
76 | mNoContentView.setVisibility(View.VISIBLE);
77 | } else {
78 | mNoContentView.setVisibility(View.INVISIBLE);
79 | mRvSearchResult.setVisibility(View.VISIBLE);
80 | mAdapter = new MainPageAdapter(this, notes);
81 | mAdapter.setIsGridMode(false);
82 | mRvSearchResult.setAdapter(mAdapter);
83 | mAdapter.notifyDataSetChanged();
84 | }
85 | }
86 |
87 | @Override
88 | public boolean onOptionsItemSelected(MenuItem item) {
89 | switch (item.getItemId()) {
90 | case android.R.id.home: {
91 | finish();
92 | }
93 | break;
94 | }
95 | return super.onOptionsItemSelected(item);
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/preferences_setting.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
21 |
26 |
31 |
32 |
33 |
34 |
39 |
40 |
45 |
48 |
49 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/config/QuickNote.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.config;
2 |
3 | /**
4 | * Created by hzhuqi on 2019/4/17
5 | */
6 |
7 | import android.content.Context;
8 | import android.os.Build;
9 | import android.os.Handler;
10 | import android.os.Looper;
11 | import android.support.v7.app.AppCompatDelegate;
12 | import android.widget.Toast;
13 |
14 | import java.lang.reflect.Method;
15 | import java.util.Locale;
16 |
17 | import tech.huqi.quicknote.BuildConfig;
18 | import tech.huqi.quicknote.R;
19 | import tech.huqi.quicknote.ui.activity.LockActivity;
20 | import tech.huqi.quicknote.util.SharedPreferencesUtil;
21 |
22 | /**
23 | * App的一些全局配置信息
24 | */
25 | public class QuickNote {
26 | private static Context sContext;
27 | private static Handler sHandler;
28 |
29 | public static void init(Context context) {
30 | sContext = context;
31 | sHandler = new Handler(Looper.getMainLooper());
32 | initTheme();
33 | initDD(sContext);
34 | }
35 |
36 | private static void initTheme() {
37 | String themeKey = getString(R.string.preference_key_theme);
38 | String themeValueNight = getString(R.string.theme_value_night);
39 | String themeValueDefault = getString(R.string.theme_value_default);
40 | if (SharedPreferencesUtil.getInstance().getString(themeKey, themeValueDefault).equals(themeValueNight)) {
41 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
42 | }
43 | }
44 |
45 | public static Locale getLangLocale() {
46 | Locale locale = Locale.getDefault();
47 | String langKey = getString(R.string.preference_key_lang);
48 | String langValueDefault = getString(R.string.lang_value_default);
49 | String langValueChinese = getString(R.string.lang_value_chinese);
50 | String langValueEnglish = getString(R.string.lang_value_english);
51 | if (SharedPreferencesUtil.getInstance().getString(langKey, langValueChinese).equals(langValueDefault)) {
52 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 8.0及以上系统
53 | locale = QuickNote.getAppContext().getResources().getConfiguration().getLocales().get(0);
54 | } else {
55 | locale = QuickNote.getAppContext().getResources().getConfiguration().locale;
56 | }
57 | } else if (SharedPreferencesUtil.getInstance().getString(langKey, langValueChinese).equals(langValueEnglish)) {
58 | locale = Locale.US;
59 | } else if (SharedPreferencesUtil.getInstance().getString(langKey, langValueChinese).equals(langValueChinese)) {
60 | locale = Locale.SIMPLIFIED_CHINESE;
61 | }
62 | return locale;
63 | }
64 |
65 | private static void initDD(Context context) {
66 | if (BuildConfig.DEBUG) {
67 | try {
68 | Class> debugDB = Class.forName("com.amitshekhar.DebugDB");
69 | Method getAddressLog = debugDB.getMethod("getAddressLog");
70 | Object value = getAddressLog.invoke(null);
71 | Toast.makeText(context, (String) value, Toast.LENGTH_LONG).show();
72 | } catch (Exception ignore) {
73 | // do nothing
74 | }
75 | }
76 | }
77 |
78 | public static Handler getMainThreadHandler() {
79 | return sHandler;
80 | }
81 |
82 | public static Context getAppContext() {
83 | return sContext;
84 | }
85 |
86 | public static String getString(int id) {
87 | return getAppContext().getResources().getString(id);
88 | }
89 |
90 | public static int getColor(int colorId) {
91 | return getAppContext().getResources().getColor(colorId);
92 | }
93 |
94 | public static int getDimen(int dimenId) {
95 | return getAppContext().getResources().getDimensionPixelSize(dimenId);
96 | }
97 |
98 | public static String getSavedPattern() {
99 | return LockActivity.getSavedPattern();
100 | }
101 |
102 | public static boolean isSetPatternLock() {
103 | return SharedPreferencesUtil.getInstance().getBoolean(getString(R.string.preference_key_gesture_pwd), false);
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/entity/Note.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.entity;
2 |
3 |
4 | import android.os.Parcel;
5 | import android.os.Parcelable;
6 |
7 | import tech.huqi.quicknote.config.Constants;
8 | import tech.huqi.quicknote.util.TimeUtil;
9 |
10 | /**
11 | * Created by hzhuqi on 2019/4/7
12 | */
13 | public class Note implements Parcelable, Comparable {
14 | private int id;
15 | private String title;
16 | private String content;
17 | private String date;
18 | private String address;
19 | private long timestamp;
20 | private long lastModify;
21 | private int isWasted;
22 |
23 | public Note() {
24 | date = TimeUtil.getDataTime(Constants.TIME_FORMAT_Y_M_D_H_M);
25 | timestamp = System.currentTimeMillis();
26 | isWasted = 0;
27 | }
28 |
29 | public Note(String title, String content, String date, String address, long lastModify,
30 | int isWasted) {
31 | this.title = title;
32 | this.content = content;
33 | this.date = date;
34 | this.address = address;
35 | this.lastModify = lastModify;
36 | this.isWasted = isWasted;
37 | }
38 |
39 | protected Note(Parcel in) {
40 | id = in.readInt();
41 | title = in.readString();
42 | content = in.readString();
43 | date = in.readString();
44 | address = in.readString();
45 | timestamp = in.readLong();
46 | lastModify = in.readLong();
47 | isWasted = in.readInt();
48 | }
49 |
50 | public static final Creator CREATOR = new Creator() {
51 | @Override
52 | public Note createFromParcel(Parcel in) {
53 | return new Note(in);
54 | }
55 |
56 | @Override
57 | public Note[] newArray(int size) {
58 | return new Note[size];
59 | }
60 | };
61 |
62 | public int getId() {
63 | return id;
64 | }
65 |
66 | public void setId(int id) {
67 | this.id = id;
68 | }
69 |
70 | public String getTitle() {
71 | return title;
72 | }
73 |
74 | public void setTitle(String title) {
75 | this.title = title;
76 | }
77 |
78 | public String getContent() {
79 | return content;
80 | }
81 |
82 | public void setContent(String content) {
83 | this.content = content;
84 | }
85 |
86 | public String getDate() {
87 | return date;
88 | }
89 |
90 | public void setDate(String date) {
91 | this.date = date;
92 | }
93 |
94 | public String getAddress() {
95 | return address;
96 | }
97 |
98 | public void setAddress(String address) {
99 | this.address = address;
100 | }
101 |
102 | public long getTimestamp() {
103 | return timestamp;
104 | }
105 |
106 | public void setTimestamp(long timestamp) {
107 | this.timestamp = timestamp;
108 | }
109 |
110 | public long getLastModify() {
111 | return lastModify;
112 | }
113 |
114 | public void setLastModify(long lastModify) {
115 | this.lastModify = lastModify;
116 | }
117 |
118 | public int getIsWasted() {
119 | return isWasted;
120 | }
121 |
122 | public void setWasted(int wasted) {
123 | isWasted = wasted;
124 | }
125 |
126 | public boolean isWasted() {
127 | return isWasted == 1;
128 | }
129 |
130 | /**
131 | * 将字符串文本解析为Note格式对象
132 | *
133 | * @return
134 | */
135 | public static Note paraseString2Note() {
136 | Note note = null;
137 | return note;
138 | }
139 |
140 | @Override
141 | public int describeContents() {
142 | return 0;
143 | }
144 |
145 | @Override
146 | public void writeToParcel(Parcel dest, int flags) {
147 | dest.writeInt(id);
148 | dest.writeString(title);
149 | dest.writeString(content);
150 | dest.writeString(date);
151 | dest.writeString(address);
152 | dest.writeLong(lastModify);
153 | dest.writeLong(timestamp);
154 | dest.writeInt(isWasted);
155 | }
156 |
157 | @Override
158 | public int compareTo(Note o) {
159 | return (int) (this.timestamp - o.timestamp);
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/app_bar_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
21 |
22 |
23 |
24 |
25 |
26 |
39 |
40 |
49 |
50 |
60 |
61 |
70 |
71 |
80 |
81 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/ui/fragment/AllNoteFragment.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.ui.fragment;
2 |
3 | import android.content.DialogInterface;
4 | import android.os.Bundle;
5 | import android.support.annotation.NonNull;
6 | import android.support.annotation.Nullable;
7 | import android.text.TextUtils;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.EditText;
12 |
13 |
14 | import java.util.List;
15 |
16 | import tech.huqi.quicknote.R;
17 | import tech.huqi.quicknote.config.QuickNote;
18 | import tech.huqi.quicknote.db.NoteDatabaseHelper;
19 | import tech.huqi.quicknote.entity.Note;
20 | import tech.huqi.quicknote.util.CommonUtil;
21 | import tech.huqi.quicknote.util.DialogFactory;
22 | import tech.huqi.quicknote.view.ItemListDialogFragment;
23 |
24 |
25 | /**
26 | * Created by hzhuqi on 2019/4/6
27 | * 主页Fragment,即默认显示的所有笔记的视图页面
28 | */
29 | public class AllNoteFragment extends BaseNoteListFragment implements ItemListDialogFragment.Listener {
30 | private static final String TAG = "QuickNote.AllNoteFragment";
31 | private static final int BOTTOM_SHEET_ITEM_RENAME = 0;
32 | private static final int BOTTOM_SHEET_ITEM_REMOVE = 1;
33 | private static final int BOTTOM_SHEET_ITEM_ENCRYPT = 2;
34 | private int mLongClickNoteId;
35 |
36 | @Override
37 | View createView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
38 | return inflater.inflate(R.layout.fragment_main_page, container, false);
39 | }
40 |
41 | @Override
42 | List onGetNotes() {
43 | mNotes = NoteDatabaseHelper.getInstance().getAllActiveNotes();
44 | return mNotes;
45 | }
46 |
47 | @Override
48 | void onNoteItemLongClick(View v, int position) {
49 | mLongClickNoteId = position;
50 | createAndShowDialog();
51 | }
52 |
53 | @Override
54 | protected void initView() {
55 | }
56 |
57 | @Override
58 | protected void initData() {
59 | }
60 |
61 | @Override
62 | void onRefreshData() {
63 | mNotes = NoteDatabaseHelper.getInstance().getAllActiveNotes();
64 | mAdapter.refreshData(mNotes);
65 | }
66 |
67 | private void createAndShowDialog() {
68 | int[] icons = {R.drawable.ic_rename_black_24dp, R.drawable.ic_delete_black_24dp, R.drawable.ic_encrypt_black_24dp};
69 | String[] texts = {getString(R.string.rename), getString(R.string.remove), getString(R.string.encrypt)};
70 | ItemListDialogFragment.newInstance(icons, texts).setListener(this).show(getActivity().getSupportFragmentManager(), TAG);
71 | }
72 |
73 | @Override
74 | public void onItemClicked(int position) {
75 | switch (position) {
76 | case BOTTOM_SHEET_ITEM_RENAME: {
77 | showRenameDialog();
78 | }
79 | break;
80 | case BOTTOM_SHEET_ITEM_REMOVE: {
81 | removeNote();
82 | }
83 | break;
84 | case BOTTOM_SHEET_ITEM_ENCRYPT: {
85 | CommonUtil.showToastOnUiThread(R.string.purchase_vip_tip);
86 | }
87 | break;
88 | }
89 | }
90 |
91 | private void removeNote() {
92 | NoteDatabaseHelper.getInstance().remove(mNotes.get(mLongClickNoteId).getId());
93 | mNotes = NoteDatabaseHelper.getInstance().getAllActiveNotes();
94 | mAdapter.refreshData(mNotes);
95 | }
96 |
97 | private void showRenameDialog() {
98 | final EditText popContentView = (EditText) View.inflate(getContext(), R.layout.view_pop_content_input, null);
99 | DialogFactory.showInputDialog(getActivity(), QuickNote.getString(R.string.rename), popContentView, new DialogInterface.OnClickListener() {
100 | @Override
101 | public void onClick(DialogInterface dialog, int which) {
102 | String newTitle = popContentView.getText().toString();
103 | if (!TextUtils.isEmpty(newTitle)) {
104 | Note current = mNotes.get(mLongClickNoteId);
105 | current.setTitle(newTitle);
106 | NoteDatabaseHelper.getInstance().update(current);
107 | }
108 | mAdapter.refreshData(mNotes);
109 | }
110 | });
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/view/ItemListDialogFragment.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.view;
2 |
3 |
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.design.widget.BottomSheetDialogFragment;
7 | import android.support.v7.widget.LinearLayoutManager;
8 | import android.support.v7.widget.RecyclerView;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.widget.ImageView;
13 | import android.widget.LinearLayout;
14 | import android.widget.TextView;
15 |
16 | import tech.huqi.quicknote.R;
17 |
18 | /**
19 | * Created by hzhuqi on 2019/4/16
20 | * activity (or fragment) needs to implement {@link ItemListDialogFragment.Listener}.
21 | */
22 | public class ItemListDialogFragment extends BottomSheetDialogFragment {
23 | public static final String TAG = "ItemListDialogFragment";
24 | private static int[] mIcons;
25 | private static String[] mTexts;
26 | private Listener mListener;
27 |
28 | public static ItemListDialogFragment newInstance(int[] icons, String[] texts) {
29 | final ItemListDialogFragment fragment = new ItemListDialogFragment();
30 | mIcons = icons;
31 | mTexts = texts;
32 | return fragment;
33 | }
34 |
35 | public ItemListDialogFragment setListener(Listener listener) {
36 | mListener = listener;
37 | return this;
38 | }
39 |
40 | @Nullable
41 | @Override
42 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
43 | @Nullable Bundle savedInstanceState) {
44 | return inflater.inflate(R.layout.fragment_dialog_list, container, false);
45 | }
46 |
47 | @Override
48 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
49 | final RecyclerView recyclerView = (RecyclerView) view;
50 | recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
51 | recyclerView.setAdapter(new ItemAdapter());
52 | }
53 |
54 | // @Override
55 | // public void onAttach(Context context) {
56 | // super.onAttach(context);
57 | // final Fragment parent = getParentFragment();
58 | // if (parent != null) {
59 | // mListener = (Listener) parent;
60 | // } else {
61 | // mListener = (Listener) context;
62 | // }
63 | // }
64 |
65 | @Override
66 | public void onDetach() {
67 | mListener = null;
68 | super.onDetach();
69 | }
70 |
71 | public interface Listener {
72 | void onItemClicked(int position);
73 | }
74 |
75 | private class ViewHolder extends RecyclerView.ViewHolder {
76 | final LinearLayout background;
77 | final ImageView icon;
78 | final TextView text;
79 |
80 | ViewHolder(LayoutInflater inflater, ViewGroup parent) {
81 | super(inflater.inflate(R.layout.fragment_dialog_list_item, parent, false));
82 | background = itemView.findViewById(R.id.fragment_dialog_list_item_rl);
83 | icon = itemView.findViewById(R.id.fragment_dialog_list_item_iv);
84 | text = (TextView) itemView.findViewById(R.id.fragment_dialog_list_item_tv);
85 | background.setOnClickListener(new View.OnClickListener() {
86 | @Override
87 | public void onClick(View v) {
88 | if (mListener != null) {
89 | mListener.onItemClicked(getAdapterPosition());
90 | dismiss();
91 | }
92 | }
93 | });
94 | }
95 |
96 | }
97 |
98 | private class ItemAdapter extends RecyclerView.Adapter {
99 |
100 | @Override
101 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
102 | return new ViewHolder(LayoutInflater.from(parent.getContext()), parent);
103 | }
104 |
105 | @Override
106 | public void onBindViewHolder(ViewHolder holder, int position) {
107 | holder.icon.setImageResource(mIcons[position]);
108 | holder.text.setText(mTexts[position]);
109 | }
110 |
111 | @Override
112 | public int getItemCount() {
113 | return mIcons == null ? 0 : mIcons.length;
114 | }
115 |
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/ui/activity/VoiceShorthandActivity.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.ui.activity;
2 |
3 | import android.content.DialogInterface;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.widget.AppCompatTextView;
8 | import android.view.MenuItem;
9 | import android.view.View;
10 |
11 | import de.hdodenhof.circleimageview.CircleImageView;
12 | import jaygoo.widget.wlv.WaveLineView;
13 | import tech.huqi.quicknote.R;
14 | import tech.huqi.quicknote.config.QuickNote;
15 | import tech.huqi.quicknote.util.BaiduVoiceHelper;
16 | import tech.huqi.quicknote.util.DialogFactory;
17 |
18 | import static tech.huqi.quicknote.config.Constants.INTENT_IMAGE_PATH;
19 | import static tech.huqi.quicknote.config.Constants.INTENT_VOICE_RECOGNIZED;
20 |
21 | /**
22 | * Created by hzhuqi on 2019/4/22
23 | */
24 | public class VoiceShorthandActivity extends BaseActivity implements BaiduVoiceHelper.VoiceHelperCallback {
25 | private BaiduVoiceHelper mVoiceHelper;
26 | private AppCompatTextView mTvVoiceRecognizeResult;
27 | private CircleImageView mBtnStart;
28 | private WaveLineView mWaveLineView;
29 |
30 | @Override
31 | protected void onCreate(@Nullable Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | setContentView(R.layout.activity_voice_shorthand);
34 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
35 | initView();
36 | initData();
37 | }
38 |
39 | private void initView() {
40 | mBtnStart = findViewById(R.id.btn_voice_recognized_start);
41 | mWaveLineView = findViewById(R.id.wave_line_view);
42 | mTvVoiceRecognizeResult = findViewById(R.id.tv_voice_recognized_result);
43 | }
44 |
45 | private void initData() {
46 | mVoiceHelper = BaiduVoiceHelper.getInstance(this);
47 | mVoiceHelper.setVoiceHelperCallback(this);
48 | mBtnStart.setOnClickListener(new View.OnClickListener() {
49 | @Override
50 | public void onClick(View v) {
51 | mWaveLineView.startAnim();
52 | mVoiceHelper.start();
53 | }
54 | });
55 | }
56 |
57 | @Override
58 | protected void onPause() {
59 | super.onPause();
60 | mVoiceHelper.onPause();
61 | mWaveLineView.stopAnim();
62 | }
63 |
64 | @Override
65 | protected void onDestroy() {
66 | super.onDestroy();
67 | mVoiceHelper.onDestroy();
68 | mVoiceHelper.stop();
69 | mWaveLineView.stopAnim();
70 | }
71 |
72 |
73 | @Override
74 | public void onVoiceStart() {
75 | mTvVoiceRecognizeResult.setText("");
76 | }
77 |
78 |
79 | @Override
80 | public void onProcess(String text) {
81 |
82 | }
83 |
84 |
85 | @Override
86 | public void onCompleted(String resultText) {
87 | mTvVoiceRecognizeResult.setText(resultText);
88 | mWaveLineView.stopAnim();
89 | }
90 |
91 | @Override
92 | public void onFailure(String msg) {
93 | mTvVoiceRecognizeResult.setText(QuickNote.getString(R.string.recognize_failed) + ":" + msg);
94 | mWaveLineView.stopAnim();
95 | }
96 |
97 | @Override
98 | public boolean onOptionsItemSelected(MenuItem item) {
99 | switch (item.getItemId()) {
100 | case android.R.id.home: {
101 | DialogFactory.createAndShowDialog(this, QuickNote.getString(R.string.is_use_voice_auto_recognize_result),
102 | null, new DialogInterface.OnClickListener() {
103 | @Override
104 | public void onClick(DialogInterface dialog, int which) {
105 | finish();
106 | }
107 | }, new DialogInterface.OnClickListener() {
108 | @Override
109 | public void onClick(DialogInterface dialog, int which) {
110 | String result = mTvVoiceRecognizeResult.getText().toString();
111 | Intent intent = getIntent();
112 | intent.putExtra(INTENT_VOICE_RECOGNIZED, result);
113 | setResult(RESULT_OK, intent);
114 | finish();
115 | }
116 | });
117 | }
118 | break;
119 | }
120 | return super.onOptionsItemSelected(item);
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/huqi/quicknote/util/BitmapUtil.java:
--------------------------------------------------------------------------------
1 | package tech.huqi.quicknote.util;
2 |
3 | /**
4 | * Created by hzhuqi on 2019/4/15
5 | */
6 |
7 | import android.content.Context;
8 | import android.graphics.Bitmap;
9 | import android.graphics.BitmapFactory;
10 | import android.graphics.Matrix;
11 | import android.media.ExifInterface;
12 |
13 | import java.io.ByteArrayOutputStream;
14 | import java.io.File;
15 | import java.io.FileNotFoundException;
16 | import java.io.FileOutputStream;
17 | import java.io.IOException;
18 |
19 | /**
20 | * 图像操作相关的工具类
21 | */
22 | public class BitmapUtil {
23 | /**
24 | * 将相机图片存储到磁盘上的压缩比
25 | */
26 | private static final int COMPRESS_QUALITY = 80;
27 |
28 | /**
29 | * 调整拍照后图像的显示方向,在某些机型上,比如三星拍照后图像是横着的,调整为竖直的
30 | *
31 | * @param context
32 | * @param photoPath
33 | * @return
34 | */
35 | public static String adjustPhotoImageOrientation(Context context, String photoPath) {
36 | int degree = getPhotoDegree(photoPath);
37 | Bitmap bitmap = BitmapFactory.decodeFile(photoPath);
38 | if (degree != 0) {
39 | Bitmap newBitmap = rotatePhotoByDegree(degree, bitmap);
40 | FileOutputStream fos = null;
41 | try {
42 | fos = new FileOutputStream(photoPath);
43 | } catch (FileNotFoundException e) {
44 | e.printStackTrace();
45 | return photoPath;
46 | }
47 | newBitmap.compress(Bitmap.CompressFormat.JPEG, COMPRESS_QUALITY, fos);
48 | }
49 | return photoPath;
50 | }
51 |
52 | private static int getPhotoDegree(String photoPath) {
53 | int degree = 0;
54 | ExifInterface exifInterface;
55 | try {
56 | exifInterface = new ExifInterface(photoPath);
57 | } catch (IOException e) {
58 | e.printStackTrace();
59 | return degree;
60 | }
61 | int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
62 | switch (orientation) {
63 | case ExifInterface.ORIENTATION_ROTATE_90: {
64 | degree = 90;
65 | }
66 | break;
67 | case ExifInterface.ORIENTATION_ROTATE_180: {
68 | degree = 180;
69 | }
70 | break;
71 | case ExifInterface.ORIENTATION_ROTATE_270: {
72 | degree = 270;
73 | }
74 | break;
75 | default: {
76 | degree = 0;
77 | }
78 | break;
79 | }
80 | return degree;
81 | }
82 |
83 | private static Bitmap rotatePhotoByDegree(int degree, Bitmap bitmap) {
84 | Matrix matrix = new Matrix();
85 | matrix.postRotate(degree);
86 | Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
87 | if (result == null) {
88 | return bitmap;
89 | }
90 | bitmap.recycle();
91 | return result;
92 | }
93 |
94 | public static boolean saveBitmap(Bitmap pBitmap, File file) {
95 | if (file == null) {
96 | return false;
97 | }
98 | FileOutputStream fos = null;
99 | try {
100 | fos = new FileOutputStream(file);
101 | if (fos != null) {
102 | pBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
103 | fos.flush();
104 | }
105 | } catch (IOException io) {
106 | return false;
107 | } finally {
108 | if (fos != null) {
109 | try {
110 | fos.close();
111 | } catch (IOException e) {
112 | e.printStackTrace();
113 | }
114 | }
115 | }
116 | return true;
117 | }
118 |
119 | public static void saveBitmap(Bitmap pBitmap, String savePath, String fileName, Bitmap.CompressFormat format) {
120 | if (format == null) {
121 | format = Bitmap.CompressFormat.JPEG;
122 | }
123 | FileOutputStream fos = null;
124 | try {
125 | fos = new FileOutputStream(new File(savePath, fileName));
126 | if (fos != null) {
127 | pBitmap.compress(format, 100, fos);
128 | fos.flush();
129 | }
130 | } catch (IOException io) {
131 |
132 | } finally {
133 | if (fos != null) {
134 | try {
135 | fos.close();
136 | } catch (IOException e) {
137 | e.printStackTrace();
138 | }
139 | }
140 | }
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_app.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_app_welcome.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
--------------------------------------------------------------------------------