list = new ArrayList<>();
82 | Pattern pattern = Pattern.compile("");
83 | Matcher matcher = pattern.matcher(html);
84 | while (matcher.find()) {
85 | Matcher ms = Pattern.compile("src=['\"].+?['\"]").matcher(matcher.group());
86 | while (ms.find()) {
87 | list.add(ms.group().replaceAll("['\"]", "").replace("src=", ""));
88 | }
89 | }
90 | return list;
91 | }
92 |
93 |
94 | /**
95 | * 匹配图片,用于上传图片
96 | *
97 | * 注意,仅仅匹配带有后缀名的图片url
98 | *
99 | * @param markText
100 | * @return
101 | */
102 | public static List getImgUrlFromMarkDownText(String markText) {
103 | ArrayList list = new ArrayList<>();
104 | // !\[.*?\]\(.*?\)
105 | Pattern pattern = Pattern.compile("!\\[.*?\\]\\(.*?\\..*?\\)");
106 | Matcher matcher = pattern.matcher(markText);
107 |
108 | while (matcher.find()) {
109 | Matcher ms = Pattern.compile("\\(.+\\)").matcher(matcher.group());
110 | while (ms.find()) {
111 | String str = ms.group();
112 | if (str.startsWith("("))
113 | str = str.substring(1, str.length());
114 | if (str.endsWith(")"))
115 | str = str.substring(0, str.length() - 1);
116 | list.add(str);
117 | }
118 | }
119 | return list;
120 | }
121 |
122 | /**
123 | * 获得系统当前时间
124 | *
125 | * @return
126 | */
127 | @SuppressLint("SimpleDateFormat")
128 | public static String getCurrentTime() {
129 | SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
130 | return mDateFormat.format(new Date());
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/source/src/cn/krait/nabo/module/markdown/utils/OperationType.java:
--------------------------------------------------------------------------------
1 | package cn.krait.nabo.module.markdown.utils;
2 |
3 |
4 | import cn.krait.nabo.R;
5 |
6 | /**
7 | * Created by zk on 2018/1/27.
8 | */
9 |
10 | public enum OperationType {
11 |
12 | BOLD("bold", R.string.format_bold, R.drawable.selector_format_bold, 8),
13 | ITALIC("italic", R.string.format_italic, R.drawable.selector_format_italic, 7),
14 | HEADER_1("header_1", R.string.format_header_1, R.drawable.selector_format_header_1, 0),
15 | HEADER_2("header_2", R.string.format_header_2, R.drawable.selector_format_header_2, 0),
16 | HEADER_3("header_3", R.string.format_header_3, R.drawable.selector_format_header_3, 0),
17 | HEADER_4("header_4", R.string.format_header_4, R.drawable.selector_format_header_4, 0),
18 | HEADER_5("header_5", R.string.format_header_5, R.drawable.selector_format_header_5, 0),
19 | QUOTE("quote", R.string.format_quote, R.drawable.selector_format_quote, 5),
20 | STRIKE("strike", R.string.format_strike, R.drawable.selector_format_strike, 6),
21 | IMG("img", R.string.edit_img, R.drawable.selector_edit_img, 10),
22 | LINK("link", R.string.link, R.drawable.selector_link, 9),
23 | LIST("list", R.string.list, R.drawable.selector_list, 4),
24 | UNDO("undo", R.string.undo, R.drawable.selector_undo, 100001),
25 | REDO("redo", R.string.redo, R.drawable.selector_redo, 100000),
26 | TIME("time", R.string.ot_time, R.drawable.selector_time, 3);
27 |
28 | public String key;
29 | public int describe;
30 | public int src;
31 | public int order = 0;
32 |
33 | OperationType(String key, int describe, int src, int order) {
34 | this.key = key;
35 | this.describe = describe;
36 | this.src = src;
37 | this.order = order;
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/source/src/cn/krait/nabo/module/markdown/utils/PermissionUtils.java:
--------------------------------------------------------------------------------
1 | package cn.krait.nabo.module.markdown.utils;
2 |
3 | import android.Manifest;
4 | import android.app.Activity;
5 | import android.content.pm.PackageManager;
6 |
7 | import androidx.core.app.ActivityCompat;
8 |
9 | /**
10 | * Created by zk on 2017/6/16.
11 | * 权限请求管理
12 | */
13 |
14 | public class PermissionUtils {
15 |
16 | public static final int REQUEST_EXTERNAL_STORAGE = 101;
17 | private static String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
18 |
19 | /**
20 | * SD卡读写权限
21 | *
22 | * @param activity
23 | * @return 是否获得改权限
24 | */
25 | public static boolean storage(Activity activity) {
26 | if (!(ActivityCompat.checkSelfPermission(activity,
27 | Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) {
28 | ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,
29 | REQUEST_EXTERNAL_STORAGE);
30 | return false;
31 | }
32 | return true;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/source/src/cn/krait/nabo/module/markdown/widget/MarkdownView.java:
--------------------------------------------------------------------------------
1 | package cn.krait.nabo.module.markdown.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.webkit.JavascriptInterface;
6 | import android.webkit.WebSettings;
7 | import android.webkit.WebView;
8 | import android.webkit.WebViewClient;
9 |
10 | import cn.krait.nabo.util.Log;
11 | import cn.krait.nabo.module.markdown.utils.MarkdownHandler;
12 | import cn.krait.nabo.module.markdown.utils.MarkdownUtils;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * Created by zk on 2017/9/14.
18 | */
19 |
20 | public class MarkdownView extends WebView {
21 |
22 | private static final String TAG = MarkdownView.class.getSimpleName();
23 |
24 | private String text;
25 | private List imgList;
26 |
27 | private LinkClickListener linkClickListener;
28 | private ImgClickListener imgClickListener;
29 |
30 | public MarkdownView(Context context) {
31 | super(context);
32 | addClient();
33 | }
34 |
35 | public MarkdownView(Context context, AttributeSet attrs) {
36 | super(context, attrs);
37 | addClient();
38 | }
39 |
40 | public MarkdownView(Context context, AttributeSet attrs, int defStyleAttr) {
41 | super(context, attrs, defStyleAttr);
42 | addClient();
43 | }
44 |
45 | public void setTextInBackground(String text) {
46 | this.text = text;
47 | MarkdownHandler.getInstance().toHtml(text, new MarkdownHandler.Callback() {
48 | @Override
49 | public void done(String html) {
50 | if (html != null) {
51 | imgList = MarkdownUtils.getImgUrl(html);
52 | loadDataWithBaseURL(null, html, "text/html", "utf8mb4", null);
53 | }
54 | }
55 | });
56 | }
57 |
58 | /**
59 | * 使用此方法会导致界面卡顿
60 | *
61 | * @param text
62 | */
63 | @Deprecated
64 | public void setText(String text) {
65 | this.text = text;
66 | String html = MarkdownHandler.getInstance().toHtml(text);
67 | imgList = MarkdownUtils.getImgUrl(html);
68 | loadDataWithBaseURL(null, html, "text/html", "utf8mb4", null);
69 | }
70 |
71 | public String getText() {
72 | return text;
73 | }
74 |
75 | private void addClient() {
76 | setWebViewClient(new MyWebClient());
77 |
78 | setHorizontalScrollBarEnabled(false);
79 | setVerticalScrollBarEnabled(false);
80 |
81 | getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
82 | getSettings().setJavaScriptEnabled(true);
83 | addJavascriptInterface(new AndroidBridge(), "android");
84 | }
85 |
86 | public void setLinkClickListener(LinkClickListener listener) {
87 | this.linkClickListener = listener;
88 | }
89 |
90 | public void setImgClickListener(ImgClickListener listener) {
91 | this.imgClickListener = listener;
92 | }
93 |
94 | private final class MyWebClient extends WebViewClient {
95 | @Override
96 | public boolean shouldOverrideUrlLoading(WebView view, String url) {
97 | if (linkClickListener != null) {
98 | linkClickListener.click(url);
99 | }
100 | return true;
101 | }
102 | }
103 |
104 | private class AndroidBridge {
105 | @JavascriptInterface
106 | public void callAndroidImg(String arg) {
107 | Log.d(TAG, arg);
108 | int index = Integer.parseInt(arg);
109 | if (index >= 0 && index < imgList.size()) {
110 | if (imgClickListener != null) {
111 | String[] strs = new String[imgList.size()];
112 | strs = imgList.toArray(strs);
113 | imgClickListener.click(strs, index);
114 | }
115 | }
116 | }
117 | }
118 |
119 | public interface LinkClickListener {
120 | void click(String url);
121 | }
122 |
123 | public interface ImgClickListener {
124 | void click(String[] urls, int index);
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/source/src/cn/krait/nabo/module/method/CheckVersion.java:
--------------------------------------------------------------------------------
1 | package cn.krait.nabo.module.method;
2 |
3 | import android.content.Context;
4 |
5 | import org.json.JSONException;
6 | import org.json.JSONObject;
7 |
8 | import java.io.IOException;
9 | import java.util.Objects;
10 |
11 | import cn.krait.nabo.util.ManifestUtils;
12 | import okhttp3.Call;
13 | import okhttp3.OkHttpClient;
14 | import okhttp3.Request;
15 | import okhttp3.Response;
16 |
17 | /**
18 | * @author 权那他(Kraity)
19 | * @date 2019/11/3.
20 | * GitHub:https://github.com/kraity
21 | * WebSite:https://krait.cn
22 | * email:kraits@qq.com
23 | */
24 | public abstract class CheckVersion {
25 | protected CheckVersion(Context context) {
26 | OkHttpClient okHttpClient = new OkHttpClient();
27 | Request request = new Request.Builder()
28 | .url("https://lib.krait.cn/release/nabo.json")
29 | .get()
30 | .build();
31 | Call call = okHttpClient.newCall(request);
32 | try {
33 | Response response = call.execute();
34 | String back = Objects.requireNonNull(response.body()).string();
35 | JSONObject object = new JSONObject(back);
36 | if (object.getInt("versionCode") > ManifestUtils.getVersionCode(context))
37 | successful(object);
38 | } catch (IOException | JSONException e) {
39 | e.printStackTrace();
40 | failing();
41 | }
42 | }
43 |
44 | protected abstract void successful(JSONObject o);
45 |
46 | protected abstract void failing();
47 |
48 | protected abstract void Continue();
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/source/src/cn/krait/nabo/module/method/ObtainExperience.java:
--------------------------------------------------------------------------------
1 | package cn.krait.nabo.module.method;
2 |
3 | import android.content.Context;
4 |
5 | import org.json.JSONException;
6 | import org.json.JSONObject;
7 |
8 | import java.io.IOException;
9 | import java.util.Objects;
10 |
11 | import cn.krait.nabo.util.ManifestUtils;
12 | import okhttp3.Call;
13 | import okhttp3.OkHttpClient;
14 | import okhttp3.Request;
15 | import okhttp3.Response;
16 |
17 | /**
18 | * @author 权那他(Kraity)
19 | * @date 2019/11/30.
20 | * GitHub:https://github.com/kraity
21 | * WebSite:https://krait.cn
22 | * email:kraits@qq.com
23 | */
24 | public abstract class ObtainExperience {
25 | protected ObtainExperience(Context context) {
26 | OkHttpClient okHttpClient = new OkHttpClient();
27 | Request request = new Request.Builder()
28 | .url("https://lib.krait.cn/release/obtainExperience.json")
29 | .get()
30 | .build();
31 | Call call = okHttpClient.newCall(request);
32 | try {
33 | Response response = call.execute();
34 | String back = Objects.requireNonNull(response.body()).string();
35 | JSONObject object = new JSONObject(back);
36 | successful(object);
37 | } catch (IOException | JSONException e) {
38 | e.printStackTrace();
39 | failing();
40 | }
41 | }
42 |
43 | protected abstract void successful(JSONObject o);
44 |
45 | protected abstract void failing();
46 |
47 | protected abstract void Continue();
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/source/src/cn/krait/nabo/module/object/AccountObject.java:
--------------------------------------------------------------------------------
1 | package cn.krait.nabo.module.object;
2 |
3 | import java.util.ArrayList;
4 |
5 | /**
6 | * @author 权那他(Kraity)
7 | * @date 2019/11/3.
8 | * GitHub:https://github.com/kraity
9 | * WebSite:https://krait.cn
10 | * email:kraits@qq.com
11 | */
12 | public class AccountObject {
13 | private ArrayList