Browse Source

sdk 2.0

master
leiyun 5 years ago
parent
commit
9d45348c95
17 changed files with 1839 additions and 129 deletions
  1. +27
    -6
      app/build.gradle
  2. BIN
      app/libs/wenote.jar
  3. +4
    -0
      app/src/main/AndroidManifest.xml
  4. +6
    -0
      app/src/main/java/com/yzx/webebook/MainActivity.kt
  5. +61
    -67
      app/src/main/java/com/yzx/webebook/activity/BookActivity.java
  6. +725
    -0
      app/src/main/java/com/yzx/webebook/activity/Main1Activity.java
  7. +85
    -54
      app/src/main/java/com/yzx/webebook/activity/NoteActivity.kt
  8. +16
    -0
      app/src/main/java/com/yzx/webebook/utils/AppInstance.java
  9. +192
    -0
      app/src/main/java/com/yzx/webebook/utils/FileUtils.java
  10. +58
    -0
      app/src/main/java/com/yzx/webebook/utils/GsonHelper.java
  11. +204
    -0
      app/src/main/java/com/yzx/webebook/utils/ListUtils.java
  12. +332
    -0
      app/src/main/java/com/yzx/webebook/utils/StringUtils.java
  13. +0
    -1
      app/src/main/jniLibs/armeabi/libpaintworker.so
  14. +9
    -1
      app/src/main/res/layout/activity_main.xml
  15. +120
    -0
      app/src/main/res/layout/activity_main1.xml
  16. BIN
      buildKey/wenote.jks
  17. BIN
      buildKey/wetao_app_key

+ 27
- 6
app/build.gradle View File

@@ -6,9 +6,9 @@ apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 30
buildToolsVersion "31.0.0 rc1"
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.yzx.webebook"
applicationId "com.yzx1.webebook"
minSdkVersion 26
targetSdkVersion 30
versionCode 2
@@ -23,16 +23,30 @@ android {
storePassword KEY_PWD
v2SigningEnabled false
}
release {
storeFile file("../buildKey/wenote.jks")
keyAlias 'wetao'
keyPassword 'lhb@123'
storePassword 'lhb@123'
v2SigningEnabled false
}
debug {
storeFile file("../buildKey/wenote.jks")
keyAlias 'wetao'
keyPassword 'lhb@123'
storePassword 'lhb@123'
v2SigningEnabled false
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
zipAlignEnabled true
debuggable false
signingConfig signingConfigs.yzx
// zipAlignEnabled true
// debuggable false
signingConfig signingConfigs.release
// 移除无用的resource文件
shrinkResources false
// shrinkResources false
}

debug {
@@ -52,6 +66,13 @@ android {
}
}
}

lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
}

dependencies {


BIN
app/libs/wenote.jar View File


+ 4
- 0
app/src/main/AndroidManifest.xml View File

@@ -49,6 +49,10 @@
android:configChanges="orientation|keyboard"
android:screenOrientation="portrait" />

<activity android:name=".activity.Main1Activity"
android:configChanges="orientation|keyboard"
android:screenOrientation="portrait"/>

<provider
android:name=".utils.YzxFileProvider"
android:authorities="${applicationId}.fileProvider"


+ 6
- 0
app/src/main/java/com/yzx/webebook/MainActivity.kt View File

@@ -6,11 +6,13 @@ import android.content.Intent
import android.text.TextUtils
import com.bumptech.glide.Glide
import com.yzx.webebook.activity.BookActivity
import com.yzx.webebook.activity.Main1Activity
import com.yzx.webebook.activity.NoteActivity
import com.yzx.webebook.activity.WebActivity
import com.yzx.webebook.activity.base.BaseActivity
import com.yzx.webebook.presenter.base.BasePresenter
import kotlinx.android.synthetic.main.activity_main.*
import org.jetbrains.anko.startActivity
import java.io.File

/**
@@ -54,6 +56,10 @@ class MainActivity : BaseActivity<BasePresenter<*>>() {
NoteActivity.active(this, "测试笔记写字", json,1)
}

btn7.setOnClickListener {
startActivity<Main1Activity>()
}

/*OkGo.post<String>("https://fileupload.oa.qbjjyyun.net/edufile/fileUpload")
.tag(this)
.params("token","0fc58a8df03c46d3f85b1047c4693cf6")


+ 61
- 67
app/src/main/java/com/yzx/webebook/activity/BookActivity.java View File

@@ -41,6 +41,7 @@ import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.model.Response;
import com.wetao.note.NotePageInfo;
import com.wetao.note.OnInitedListener;
import com.wetao.note.WeNoteView;
import com.wetao.note.WePoint;
import com.yzx.webebook.R;
@@ -101,8 +102,8 @@ public class BookActivity extends Activity {
private Button mPenWidthSubBtn;
private Button mEraserWidthBtn;
private Button mCancelBtn;
private CheckBox mCBEraser;
private CheckBox mCBStrokes;
// private CheckBox mCBEraser;
// private CheckBox mCBStrokes;
private TextView mPenBtn;
private TextView mRubberBtn;

@@ -137,7 +138,7 @@ public class BookActivity extends Activity {
}
Log.d(TAG, "Flash test : ++++++++ mView.getHeight() = " + mView.getHeight() + ", count = " + count);
//mView.initNative(new Rect(mScreenW, mScreenH - mView.getHeight(), 0, mScreenH), SAVE_PIC_PATH);
mView.initNative(new Rect(mScreenW, mScreenH - mView.getHeight(), 0, mScreenH));
// mView.initNative(new Rect(mScreenW, mScreenH - mView.getHeight(), 0, mScreenH));
mView.setTouchEventHander(mPointHandler);

Log.d(TAG, "Flash test : ++++++ mRunnable() start loader notepageinfo");
@@ -194,6 +195,16 @@ public class BookActivity extends Activity {
}
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
mView.onResume();
} else {
mView.onPause();
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -230,7 +241,7 @@ public class BookActivity extends Activity {
mView.setEnable(false);
mBGId++;
if (mBGId >= mBGDrawableList.length) mBGId = 0;
mView.updateBackground(mBGDrawableList[mBGId]);
mView.setBackgroundResource(mBGDrawableList[mBGId]);
mPicBtn.setText("背景" + mBGId);
saveBGId();
}
@@ -325,36 +336,9 @@ public class BookActivity extends Activity {
}
});

mCBEraser = (CheckBox) findViewById(R.id.eraser);
mCBEraser.setSelected(false);
mCBEraser.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mView.isEraserEnable()) {
mCBEraser.setSelected(false);
mView.setEraserEnable(false);
} else {
mCBEraser.setSelected(true);
mView.setEraserEnable(true);
}
}
});

//mCBEraser.setVisibility(View.GONE);

mCBStrokes = (CheckBox) findViewById(R.id.strokes);
mCBStrokes.setSelected(false);
mCBStrokes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mView.isStrokesEnable()) {
mCBStrokes.setSelected(false);
mView.setStrokesEnable(false);
} else {
mCBStrokes.setSelected(true);
mView.setStrokesEnable(true);
}
}
});

mWePointList = new ArrayList<WePoint>();
mWePointList.clear();
@@ -367,14 +351,24 @@ public class BookActivity extends Activity {
mHandler = new Handler();
// mHandler.postDelayed(mRunnable, 1000);

mView.setOnFinishListener(new OnInitedListener() {
@Override
public void onInited() {
mView.post(new Runnable() {
@Override
public void run() {
mHandler.post(mRunnable);
}
});
}

mView.post(new Runnable() {
@Override
public void run() {
mHandler.post(mRunnable);
public void onSizeChanged() {
}
});


IntentFilter filter = new IntentFilter();
filter.addAction(SCREEN_ON);
filter.addAction(SCREEN_OFF);
@@ -384,10 +378,10 @@ public class BookActivity extends Activity {
mPenBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mView.isEraserEnable()){
mView.setEraserEnable(false);
mPenBtn.setCompoundDrawablesWithIntrinsicBounds(0,R.mipmap.ic_book_pen_select,0,0);
mRubberBtn.setCompoundDrawablesWithIntrinsicBounds(0,R.mipmap.ic_book_rubber,0,0);
if (mView.getPenType() == WeNoteView.TYPE_DRAW_ERASER) {
mView.setPenType(WeNoteView.TYPE_DRAW_CURVE);
mPenBtn.setCompoundDrawablesWithIntrinsicBounds(0, R.mipmap.ic_book_pen_select, 0, 0);
mRubberBtn.setCompoundDrawablesWithIntrinsicBounds(0, R.mipmap.ic_book_rubber, 0, 0);
}
}
});
@@ -396,10 +390,10 @@ public class BookActivity extends Activity {
mRubberBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!mView.isEraserEnable()){
mView.setEraserEnable(true);
mPenBtn.setCompoundDrawablesWithIntrinsicBounds(0,R.mipmap.ic_book_pen,0,0);
mRubberBtn.setCompoundDrawablesWithIntrinsicBounds(0,R.mipmap.ic_book_rubber_select,0,0);
if (mView.getPenType() != WeNoteView.TYPE_DRAW_ERASER) {
mView.setPenType(WeNoteView.TYPE_DRAW_ERASER);
mPenBtn.setCompoundDrawablesWithIntrinsicBounds(0, R.mipmap.ic_book_pen, 0, 0);
mRubberBtn.setCompoundDrawablesWithIntrinsicBounds(0, R.mipmap.ic_book_rubber_select, 0, 0);
}
}
});
@@ -413,11 +407,11 @@ public class BookActivity extends Activity {
mPenWidthBtn.setText("+宽度5");
mPenWidthSubBtn.setText("-宽度5");
//橡皮擦
mCBEraser.setSelected(false);
mView.setEraserEnable(false);
// mCBEraser.setSelected(false);
mView.setPenType(WeNoteView.TYPE_DRAW_CURVE);
mView.updateEnableStatus();
//笔锋
mCBStrokes.setSelected(false);
mView.setStrokesEnable(false);
// mCBStrokes.setSelected(false);
//橡皮擦
mView.setEraserWidth(20);
mEraserWidthBtn.setText("橡皮宽20");
@@ -660,21 +654,21 @@ public class BookActivity extends Activity {
}
Log.d(TAG, "Flash test : +++++ loadOldPage() mNotePageInfo = " + mNotePageInfo);
mBGId = mNotePageInfo.drwId;
mView.showExistPage(mNotePageInfo.notePath, mBGDrawableList[mBGId]);
mView.showExistPage(mNotePageInfo.notePath);
mView.setBackgroundResource(mBGDrawableList[mBGId]);
mPicBtn.setText("背景" + mBGId);
}

public void onResume() {
Log.d(TAG, "Flash test : +++++++ onResume()");
mView.setEnable(true);
mView.setSleepMode(true);
mView.onResume();
mReDrawEnable = true;
super.onResume();
}

public void onPause() {
Log.d(TAG, "Flash test : +++++++ onPause()");
mView.setEnable(false);
mView.onPause();
mReDrawEnable = false;
super.onPause();
}
@@ -683,7 +677,7 @@ public class BookActivity extends Activity {
Log.d(TAG, "Flash test : +++++++ onDestroy()");
//mView.exitView();
mHandler.removeCallbacks(mRunnable);
mView.exitNative();
mView.exitView();
if (mReceiver != null) {
mContext.unregisterReceiver(mReceiver);
mReceiver = null;
@@ -717,11 +711,11 @@ public class BookActivity extends Activity {
};

private void cancel(boolean save) {
mView.exitNativeOnly();
mView.exitView();
if (save && mView.isHandwritingExist()) {
saveNote();
}
mView.exit();
mView.exitView();
BookActivity.this.finish();
}

@@ -943,7 +937,7 @@ public class BookActivity extends Activity {
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//to-do
mView.exitNative();
mView.exitView();
if (mReceiver != null) {
mContext.unregisterReceiver(mReceiver);
mReceiver = null;
@@ -1004,18 +998,18 @@ public class BookActivity extends Activity {
@Override
public void onReceive(Context context, Intent intent) {
// 屏幕唤醒
if (SCREEN_ON.equals(intent.getAction())) {
Log.e(TAG, "Flash test : ++++++ " + SCREEN_ON);
/*if (mDialog != null && mDialog.isShowing()) {
mView.setEnable(false);
}*/
mView.setSleepMode(true);
}
// 屏幕休眠
else if (SCREEN_OFF.equals(intent.getAction())) {
Log.e(TAG, "Flash test : ++++++ " + SCREEN_OFF);
mView.setSleepMode(true);
}
// if (SCREEN_ON.equals(intent.getAction())) {
// Log.e(TAG, "Flash test : ++++++ " + SCREEN_ON);
// /*if (mDialog != null && mDialog.isShowing()) {
// mView.setEnable(false);
// }*/
// mView.setSleepMode(true);
// }
// // 屏幕休眠
// else if (SCREEN_OFF.equals(intent.getAction())) {
// Log.e(TAG, "Flash test : ++++++ " + SCREEN_OFF);
// mView.setSleepMode(true);
// }
}
};



+ 725
- 0
app/src/main/java/com/yzx/webebook/activity/Main1Activity.java View File

@@ -0,0 +1,725 @@
package com.yzx.webebook.activity;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.yzx.webebook.utils.FileUtils;
import com.yzx.webebook.utils.GsonHelper;
import com.yzx.webebook.utils.ListUtils;
import com.wetao.note.NotePageInfo;
import com.wetao.note.OnInitedListener;
import com.wetao.note.WeNoteView;
import com.wetao.note.WePoint;
import com.yzx.webebook.R;

import android.Manifest;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.RelativeLayout;


public class Main1Activity extends Activity {
private static final String TAG = "MainActivity";

private static final String NOTE1_FOLDER_DIR = "/mnt/sdcard/MyTestNote/Note/";

static final int[] mBGDrawableList = {-1, R.drawable.background1, R.drawable.background2,
R.drawable.background3, R.drawable.background4, R.drawable.background5, R.drawable.background6,
R.drawable.background7, R.drawable.background8, R.drawable.background9, R.drawable.background10};

private static final int MSG_SAVE_END = 2001;

private WeNoteView mView;

private Button mDeleteBtn;
private Button mPicBtn;
private Button mClearBtn;
private Button mZoomBtn;
private Button mUndoBtn;
private Button mRedoBtn;
private Button mPenWidthBtn;
private Button mEraserWidthBtn;
private Button mCancelBtn;
private Button mTypeBtn;

private CheckBox mVisibleCB;

private static int mBGId = 0;

private boolean mReDrawEnable = false;

private static ArrayList<WePoint> mWePointList = null;

private static NotePageInfo mNotePageInfo = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main1);
checkPermission();
Log.d(TAG, "Flash test : +++++++ onCreate()");

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

mView = findViewById(R.id.note_view);
mView.setBackground(null);
mBGId = 0;

mDeleteBtn = findViewById(R.id.delete);
mDeleteBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (deleteNote(NOTE1_FOLDER_DIR)) {
cancel(false);
Main1Activity.this.finish();
}
}
});

mPicBtn = findViewById(R.id.init);
mPicBtn.setText("背景" + mBGId);
mPicBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mBGId++;
if (mBGId >= mBGDrawableList.length) mBGId = 0;
if (mBGId == 0) {
mView.setBackground(new ColorDrawable());
mPicBtn.setText("背景0");
} else {
mView.setBackgroundResource(mBGDrawableList[mBGId]);
mPicBtn.setText("背景" + mBGId);
}
saveBGId(NOTE1_FOLDER_DIR, mBGId);
}
});

mClearBtn = findViewById(R.id.clear);
mClearBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mView.clear();
}
});

mPenWidthBtn = findViewById(R.id.pen_width);
mPenWidthBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int width = mView.getPenWidth();
if (width == 10) {
width = 1;
} else {
width++;
}

if (width > 0 && width <= 10) {
mView.setPenWidth(width);
mPenWidthBtn.setText("宽度" + width);
}
}
});

mZoomBtn = findViewById(R.id.zoom);
mZoomBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mView.getLayoutParams();
// 设置宽为100dp
params.width = 1000;
// 设置高为100dp
params.height = 200;
// 根据布局参数的设置,重新设置view(这里用了text view,当然其他的view也是通用的)的大小
mView.setLayoutParams(params);
}
});

mUndoBtn = findViewById(R.id.undo);
mUndoBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mView.unDo();
}
});

mRedoBtn = findViewById(R.id.redo);
mRedoBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mView.reDo();
}
});

mEraserWidthBtn = findViewById(R.id.eraser_width);
mEraserWidthBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int width = mView.getEraserWidth();
if (width == 20) {
width = 1;
} else {
width++;
}

if (width > 0 && width <= 20) {
mView.setEraserWidth(width);
mEraserWidthBtn.setText("橡皮宽" + width);
}
}
});

mCancelBtn = findViewById(R.id.cancel);
mCancelBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
cancel(true);
Main1Activity.this.finish();
}
});

mTypeBtn = findViewById(R.id.draw_circle);
mTypeBtn.setTypeface(null, Typeface.BOLD);
mTypeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int type = mView.getPenType();
Log.d(TAG, "Flash test : +++++++ onClick() type btn current type = " + type);
if (type == WeNoteView.TYPE_DRAW_CURVE) {
setPenType(WeNoteView.TYPE_DRAW_STROKES);
mTypeBtn.setText("笔锋");
} else if (type == WeNoteView.TYPE_DRAW_STROKES) {
setPenType(WeNoteView.TYPE_DRAW_LINE);
mTypeBtn.setText("直线");
} else if (type == WeNoteView.TYPE_DRAW_LINE) {
setPenType(WeNoteView.TYPE_DRAW_TRIANGLE);
mTypeBtn.setText("三角形");
} else if (type == WeNoteView.TYPE_DRAW_TRIANGLE) {
setPenType(WeNoteView.TYPE_DRAW_CIRCLE);
mTypeBtn.setText("圆形");
} else if (type == WeNoteView.TYPE_DRAW_CIRCLE) {
setPenType(WeNoteView.TYPE_DRAW_RECT);
mTypeBtn.setText("矩形");
} else if (type == WeNoteView.TYPE_DRAW_RECT) {
setPenType(WeNoteView.TYPE_DRAW_ERASER);
mTypeBtn.setText("橡皮擦");
} else if (type == WeNoteView.TYPE_DRAW_ERASER) {
setPenType(WeNoteView.TYPE_DRAW_CIRCLE_ERASER);
mTypeBtn.setText("圈涂");
} else if (type == WeNoteView.TYPE_DRAW_CIRCLE_ERASER) {
setPenType(WeNoteView.TYPE_DRAW_CURVE);
mTypeBtn.setText("曲线");
}

}
});

mVisibleCB = findViewById(R.id.visible);
mVisibleCB.setSelected(true);
mVisibleCB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mVisibleCB.isChecked()) {
mVisibleCB.setSelected(false);
mView.setVisibility(View.INVISIBLE);
} else {
mVisibleCB.setSelected(true);
mView.setVisibility(View.VISIBLE);
}
}
});

mWePointList = new ArrayList<WePoint>();
mWePointList.clear();

mView.setOnFinishListener(new OnInitedListener() {
@Override
public void onInited() {
//mView.setTouchEventHander(mPointHandler);

Log.d(TAG, "Flash test : ++++++ mRunnable() start loader notepageinfo");
if (mNotePageInfo == null) {
mNotePageInfo = getNotePageInfo(NOTE1_FOLDER_DIR);
}
if (mNotePageInfo == null) {
Log.d(TAG, "Flash test : +++++ no note, so init a page");
initPage(NOTE1_FOLDER_DIR, 0, mBGId);
}
loadOldPage();
}

@Override
public void onSizeChanged() {

}
});

}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.d(TAG, "Flash test : ++++++++++ onWindowFocusChanged() hasFocus = " + hasFocus);
if (hasFocus) {
mView.onResume();
mReDrawEnable = true;
} else {
mView.onPause();
mReDrawEnable = false;
}
}

private void setPenType(int type) {
mView.setPenType(type);
mView.updateEnableStatus();
}

private void loadOldPage() {
if (mNotePageInfo == null) {
return;
}
Log.d(TAG, "Flash test : +++++ loadOldPage() mNotePageInfo = " + mNotePageInfo);
mBGId = mNotePageInfo.drwId;
if (mBGDrawableList[mBGId] == -1) {
mView.setBackground(new ColorDrawable());
} else {
mView.setBackgroundResource(mBGDrawableList[mBGId]);
}
mView.showExistPage(mNotePageInfo.notePath);
mPicBtn.setText("背景" + mBGId);
}

public void onResume() {
Log.d(TAG, "Flash test : +++++++ onResume()");
//mView.setEnable(true);
mView.onResume();
mReDrawEnable = true;
super.onResume();
}

public void onPause() {
Log.d(TAG, "Flash test : +++++++ onPause()");
mView.onPause();
mReDrawEnable = false;
super.onPause();
}

public void onDestroy() {
Log.d(TAG, "Flash test : +++++++ onDestroy()");
mView.exitView();
super.onDestroy();
// System.exit(0);
}

private Handler mPointHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
int what = msg.what;
//同步获取的笔记点坐标信息msg
if (what == WeNoteView.TOUCH_EVENT) {
WePoint point = (WePoint) msg.obj;
Log.d(TAG, "Flash test : ++++++++ mPointHandler WePoint = " + point);
mWePointList.add(point);
transData(point);
}

//保存笔记结束msg
if (what == MSG_SAVE_END) {
int status = msg.arg1;
if (status > 0) { //保存成功
Log.d(TAG, "Flash test : ++++++++ mPointHandler page save ok");
//Toast.makeText(mContext, "Note saved OK", Toast.LENGTH_SHORT).show();
} else { //保存失败
Log.d(TAG, "Flash test : ++++++++ mPointHandler page save failed");
//Toast.makeText(mContext, "Note saved Fail", Toast.LENGTH_SHORT).show();
}
}
}
};

private void cancel(boolean save) {
if (save && mView.isHandwritingExist()) {
saveNote(NOTE1_FOLDER_DIR, mView, mBGId);
}
Main1Activity.this.finish();
}

private boolean initPage(String dir, int viewId, int bgId) {
Log.d(TAG, "Flash test : +++++++++ intPage()");
File file = new File(dir);
if(!file.exists()) {
Log.e(TAG, "Flash test : +++++++++ addPageFolder() no folder path = " + dir);
if (!makeDir(file)) {
return false;
}
}

String notePath = null;
file = new File(dir + "/note.png");
if(file.exists()) {
notePath = dir + "/note.png";
}
file = new File(dir + "/.drawable.txt");
if(!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
}
if (bgId == 1) bgId = 2;
saveBGId(dir, bgId);
mNotePageInfo = new NotePageInfo(notePath, bgId);
return true;
}

private boolean deleteNote(String dir) {
Log.d(TAG, "Flash test : +++++++++ deletdNote()");
File file = new File(dir);
if(!file.exists()) {
Log.e(TAG, "Flash test : +++++++++ deletdPageFolder() no folder path = " + dir);
return true;
}
deleteDirWithFile(file);
return true;
}

private boolean saveNote(String dir, WeNoteView view, int bgId) {
Log.d(TAG, "Flash test : ++++++++ saveNote()");
File f = new File(dir);
if(!f.exists()) {
Log.d(TAG, "Flash test : +++++++ saveNote() create folder " + dir);
if (!makeDir(f)) {
return false;
}
}

String noteName = "note.png";
final Bitmap bmp = Bitmap.createBitmap(view.getCurrentNoteBitmap());
if (bmp == null) {
Log.e(TAG, "Flash test : ++++ saveNote() getCurrentNoteBitmap is null");
return false;
}

String path = dir + "/" + noteName;
if (!saveNoteWithoutBG(path, bmp)) {
Log.e(TAG, "Flash test : ++++ saveNote() saveNoteWithoutBG fail");
freeBitmap(bmp);
return false;
}

saveBGId(dir, bgId);
freeBitmap(bmp);
Log.e(TAG, "Flash test : ++++ saveNote() OK !!!!!");
return true;
}

private static boolean saveBGId(String dir, int bgId) {
Log.d(TAG, "Flash test : ++++++++ saveBGId drwId = " + bgId);
File f = new File(dir);
if(!f.exists()) {
Log.d(TAG, "Flash test : +++++++ saveAllNote() create folder " + dir);
if (!makeDir(f)) {
return false;
}
}

String path = dir + "/.drawable.txt";
writeFileData(path, String.valueOf(bgId));
return true;
}

private static void freeBitmap(Bitmap bit) {
if (bit != null && !bit.isRecycled()) {
bit.recycle();
}
}



//保存不带背景的笔记为png
private boolean saveNoteWithoutBG(String picPath, Bitmap bmp) {
Log.d(TAG, "Flash test : +++++++ saveNoteWithoutBG() picPath = " + picPath);
File f = new File(picPath);
if(f.exists()) {
f.delete();
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.PNG, 90, fos);
try {
fos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}

//保存带背景的笔记为png
private boolean saveAll(String picPath, Bitmap bmp, Drawable drw) {
Log.d(TAG, "Flash test : ++++ saveAll() picPath = " + picPath);
int width = bmp.getWidth();
int height = bmp.getHeight();

Bitmap bitmap = Bitmap.createBitmap(width, height,
drw.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drw.setBounds(0, 0, width, height);
drw.draw(canvas);

canvas.drawBitmap(bmp, new Rect(0, 0, width, height),
new Rect(0, 0, width, height) , null);
canvas.save();//Canvas.ALL_SAVE_FLAG);
canvas.restore();

boolean result = saveNoteWithoutBG(picPath, bitmap);
if (bitmap != null && !bitmap.isRecycled()) {
bitmap.recycle();
bitmap = null;
}
System.gc();
return result;
}

//保存笔记背景为png
private boolean saveNoteBG(String picPath, Drawable drw, int width, int height) {
Log.d(TAG, "Flash test : ++++ saveNoteBG() picPath = " + picPath);
Bitmap bitmap = Bitmap.createBitmap(width, height,
drw.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drw.setBounds(0, 0, width, height);
drw.draw(canvas);

boolean result = saveNoteWithoutBG(picPath, bitmap);
if (bitmap != null && !bitmap.isRecycled()) {
bitmap.recycle();
bitmap = null;
}
System.gc();
return result;
}

//重绘之前绘制的画笔
private void drawWePointList() {
if (mView.isReDrawDoing()) {
Log.i(TAG, "Flash test : +++++ drawWePointList() return because isReDrawDoing is true");
return;
}
if (mWePointList != null && !mWePointList.isEmpty()) {
new Thread(new Runnable() {
@Override
public void run() {
mView.setReDrawEnable(true);
mReDrawEnable = true;
int size = mWePointList.size();
int i = 0;
while (i<size) {
while(!mReDrawEnable) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
WePoint wp = mWePointList.get(i);
mView.drawPoint(wp);
try {
if (i+1 < size) Thread.sleep(mWePointList.get(i+1).eventTime - wp.eventTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
i++;
}
mView.setReDrawEnable(false);
}
}).start();
}
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
Main1Activity.this.finish();
return true;
}
return super.onKeyDown(keyCode, event);
}

//从笔记文件夹中读取当前笔记的页面信息
private NotePageInfo getNotePageInfo(String path) {
Log.d(TAG, "Flash test : +++++++++ getNotePageInfo() path = " + path);
File file = new File(path);
if(!file.exists()) {
Log.e(TAG, "Flash test : +++++++++ getNotePageInfo() no folder path = " + path);
return null;
}
File[] files = file.listFiles();
if (files == null) {
Log.e(TAG, "Flash test : +++++++++ getNotePageInfo() no files in this Note folder = " + path);
return null;
}
NotePageInfo info = new NotePageInfo(null, 0);
String notePath = path + "/note.png";
file = new File(notePath);
if(file.exists()) {
info.notePath = notePath;
}
String drwId = readFileData(path + "/.drawable.txt");
info.drwId = Integer.parseInt(drwId);
return info;
}

private void checkPermission() {
boolean isGranted = true;
if (android.os.Build.VERSION.SDK_INT >= 23) {
if (this.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//如果没有写sd卡权限
isGranted = false;
}
if (this.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
isGranted = false;
}
Log.i("cbs","isGranted == "+isGranted);
if (!isGranted) {
this.requestPermissions(
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission
.ACCESS_FINE_LOCATION,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE},
102);
}
}
}

private static boolean makeDir(File folder) {
try {
//按照指定的路径创建文件夹
folder.mkdirs();
} catch (Exception e) {
// TODO: handle exception
Log.e(TAG, "Flash test : +++++ makeDir() create dir " + folder.getPath() + " error = " + e);
return false;
}
Log.d(TAG, "Flash test : +++++ makeDir() create dir " + folder.getPath());
return true;
}

private void deleteDirWithFile(File dir) {
if (dir == null || !dir.exists() || !dir.isDirectory())
return;
for (File file : dir.listFiles()) {
if (file.isFile())
file.delete(); // 删除所有文件
else if (file.isDirectory())
deleteDirWithFile(file); // 递规的方式删除文件夹
}
dir.delete();// 删除目录本身
}

public static void writeFileData(String fileName, String content) {
File file = new File(fileName);
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

try {
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
bw.write(content);
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//打开指定文件,读取其数据,返回字符串对象
public static String readFileData(String fileName) {
File file = new File(fileName);
if (!file.exists()) {
return "1";
}
BufferedReader br;
try {
br = new BufferedReader(new FileReader(file));
//System.out.println("br.readLine=" + br.readLine());
return br.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "1";
}

private List<String> stringList;
private void transData(WePoint point) {
if (ListUtils.isEmpty(stringList)) {
stringList = new ArrayList<>();
}
String s = GsonHelper.toJson(point);
stringList.add(s);
stringList.add("\r\n");
if (point.action == MotionEvent.ACTION_UP) {
String join = String.join("", stringList);
saveData(join);
stringList.clear();
}
}

private void saveData(String msg) {
File file = new File("/mnt/sdcard/point.txt");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileUtils.writeFile(file.getPath(), msg, true);
}
}

+ 85
- 54
app/src/main/java/com/yzx/webebook/activity/NoteActivity.kt View File

@@ -32,6 +32,7 @@ import com.lzy.okgo.OkGo
import com.lzy.okgo.callback.StringCallback
import com.lzy.okgo.model.Response
import com.wetao.note.NotePageInfo
import com.wetao.note.OnInitedListener
import com.wetao.note.WeNoteView
import com.wetao.note.WePoint
import com.yzx.webebook.R
@@ -104,12 +105,11 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {

//背景
new_init.setOnClickListener {
note_view.setEnable(false)
mBgId++
if (mBgId >= mBGDrawableList.size) {
mBgId = 0
}
note_view.updateBackground(mBGDrawableList[mBgId])
note_view.setBackgroundResource(mBGDrawableList[mBgId])
val note = notList[currIndex]
note.BGid = mBgId
}
@@ -119,8 +119,10 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
}
//笔
pen.setOnClickListener {
if (note_view.isEraserEnable) {
note_view.isEraserEnable = false
if (note_view.penType == WeNoteView.TYPE_DRAW_ERASER) {
note_view.penType = WeNoteView.TYPE_DRAW_CURVE
note_view.updateEnableStatus()
Log.d(TAG, "initNoteView: ${note_view.penType}")
pen.setCompoundDrawablesWithIntrinsicBounds(
0,
R.mipmap.ic_book_pen_select,
@@ -137,8 +139,10 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
}
//橡皮
new_eraser.setOnClickListener {
if (!note_view.isEraserEnable) {
note_view.isEraserEnable = true
if (note_view.penType != WeNoteView.TYPE_DRAW_ERASER) {
note_view.penType = WeNoteView.TYPE_DRAW_ERASER
note_view.updateEnableStatus()
Log.d(TAG, "initNoteView: ${note_view.penType}")
pen.setCompoundDrawablesWithIntrinsicBounds(0, R.mipmap.ic_book_pen, 0, 0)
new_eraser.setCompoundDrawablesWithIntrinsicBounds(
0,
@@ -150,7 +154,7 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
}
//加纸
new_add.setOnClickListener {
val lastBGid = notList[notList.size-1].BGid
val lastBGid = notList[notList.size - 1].BGid
val note = Note()
note.BGid = lastBGid
notList.add(note)
@@ -210,6 +214,15 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
}
}

override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus) {
note_view.onResume()
} else {
note_view.onPause()
}
}

@SuppressLint("SetTextI18n")
override fun initData() {
val json = intent.getStringExtra("note_info")
@@ -235,11 +248,36 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
notList.add(Note())
}

// Log.d(TAG, "初始化开始note_view")
// note_view.post {
// Log.d(TAG, "初始化开始note_view.post")
// mHandler.post(mRunnable)
// }
Log.d(TAG, "初始化开始note_view")
note_view.post {
Log.d(TAG, "初始化开始note_view.post")
mHandler.post(mRunnable)
}
note_view.setOnFinishListener(object : OnInitedListener {
override fun onSizeChanged() {

}

override fun onInited() {
// note_view.post {
// Log.d(TAG, "初始化开始note_view.post")
// mHandler.post(mRunnable)
// }


if (mNotePageInfo == null) {
mNotePageInfo = getNotePageInfo(NOTE_FOLDER_DIR)
}
if (mNotePageInfo == null) {
Log.d(TAG, "Flash test : +++++ no note, so init a page");
initPage()
}
initNoteView()
loadImage(0)
}

})

tv_page_index.text = "1/${notList.size}"
indexBox.visibility = if (notList.size > 1) {
@@ -251,7 +289,7 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
val canAddPage = intent.getIntExtra("can_add_page", 1)
if (canAddPage == 1) {
new_add.visibility = View.VISIBLE
}else{
} else {
new_add.visibility = View.GONE
}
}
@@ -263,10 +301,8 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
val bgId = note.BGid
if (TextUtils.isEmpty(key)) {
note.key = Date().time.toString()
note_view.showExistPage(
"",
mBGDrawableList[bgId]
)
note_view.showExistPage("")
note_view.setBackgroundResource(mBGDrawableList[bgId])
currKey = note.key
currIndex = index
mBgId = bgId
@@ -279,10 +315,8 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
return
}
mBgId = bgId ?: 0
note_view.showExistPage(
path,
mBGDrawableList[mBgId]
)
note_view.showExistPage(path)
note_view.setBackgroundResource(mBGDrawableList[bgId])
currKey = key
currIndex = index

@@ -312,10 +346,8 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
return
}
mBgId = bgId ?: 0
note_view.showExistPage(
path,
mBGDrawableList[mBgId]
)
note_view.showExistPage(path)
note_view.setBackgroundResource(mBGDrawableList[bgId])
currKey = key
currIndex = index

@@ -334,10 +366,8 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
.into(customTarget)
} else {
note.key = Date().time.toString()
note_view.showExistPage(
"",
mBGDrawableList[bgId]
)
note_view.showExistPage("")
note_view.setBackgroundResource(mBGDrawableList[bgId])
currKey = note.key
currIndex = index
mBgId = bgId ?: 0
@@ -468,20 +498,19 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
}

override fun onResume() {
note_view.setEnable(true)
note_view.setSleepMode(true)
note_view.onResume()
super.onResume()
}

override fun onPause() {
note_view.setEnable(false)
note_view.onPause()
super.onPause()
}

override fun onDestroy() {
//mView.exitView();
mHandler.removeCallbacks(mRunnable)
note_view.exitNative()
note_view.exitView()
if (mReceiver != null) {
unregisterReceiver(mReceiver)
mReceiver = null
@@ -491,7 +520,7 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK) {
note_view.exitNative()
note_view.exitView()
if (mReceiver != null) {
unregisterReceiver(mReceiver)
mReceiver = null
@@ -504,14 +533,15 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {

val SCREEN_ON = "android.intent.action.SCREEN_ON"
val SCREEN_OFF = "android.intent.action.SCREEN_OFF"

private var mReceiver: BroadcastReceiver? = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// 屏幕唤醒
if (SCREEN_ON == intent.action) {
note_view.setSleepMode(true)
} else if (SCREEN_OFF == intent.action) {
note_view.setSleepMode(true)
}
// if (SCREEN_ON == intent.action) {
// note_view.setSleepMode(true)
// } else if (SCREEN_OFF == intent.action) {
// note_view.setSleepMode(true)
// }
}
}

@@ -536,14 +566,14 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
TAG,
"Flash test : ++++++++ mView.getHeight() = " + note_view.height + ", count = " + count
);
note_view.initNative(
Rect(
mScreenW,
mScreenH - note_view.height,
0,
mScreenH
)
)
// note_view.initNative(
// Rect(
// mScreenW,
// mScreenH - note_view.height,
// 0,
// mScreenH
// )
// )
note_view.setTouchEventHander(mPointHandler)
Log.d(TAG, "Flash test : ++++++ mRunnable() start loader notepageinfo");
if (mNotePageInfo == null) {
@@ -562,14 +592,17 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {

private fun initNoteView() {
//写字板初始化
note_view.background = null
// note_view.setEnable(true)
note_view.penWidth = 3
note_view.isEraserEnable = false
note_view.penType = WeNoteView.TYPE_DRAW_STROKES
note_view.eraserWidth = 20
note_view.updateEnableStatus()

Log.d(TAG, "initNoteView: ${note_view.penType}")
}

override fun finish() {
note_view.exitNative()
note_view.exitView()
if (mReceiver != null) {
unregisterReceiver(mReceiver)
mReceiver = null
@@ -578,7 +611,7 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
}

override fun onBackPressed() {
note_view.exitNative()
note_view.exitView()
if (mReceiver != null) {
unregisterReceiver(mReceiver)
mReceiver = null
@@ -607,10 +640,8 @@ class NoteActivity : BaseActivity<BasePresenter<*>>() {
return
}
mBgId = mNotePageInfo?.drwId ?: 0
note_view.showExistPage(
mNotePageInfo?.notePath,
mBGDrawableList[mBgId]
)
note_view.showExistPage(mNotePageInfo?.notePath)
note_view.setBackgroundResource(mBGDrawableList[mBgId])
}

//从笔记文件夹中读取当前笔记的页面信息


+ 16
- 0
app/src/main/java/com/yzx/webebook/utils/AppInstance.java View File

@@ -0,0 +1,16 @@
package com.yzx.webebook.utils;

import android.app.Application;

public class AppInstance {

private static Application sApplication;

public static void init(Application application) {
sApplication = application;
}

public static Application get() {
return sApplication;
}
}

+ 192
- 0
app/src/main/java/com/yzx/webebook/utils/FileUtils.java View File

@@ -0,0 +1,192 @@
package com.yzx.webebook.utils;

import android.content.Context;

import com.wetao.note.WePoint;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;

/**
* Used 获取SD卡根目录、读写文件、移动、复制、删除文件、获取文件名、后缀名操作类(需要MyApplication中的getAppContext()方法)
*
* @author andrew 2015-9-2
*/
@SuppressWarnings("deprecation")
public class FileUtils {
private static final String TAG = "FileUtils";

/**
* read file to string list, a element of list is a line
*
* @param filePath
* @param charsetName The name of a supported {@link java.nio.charset.Charset </code>charset<code>}
* @return if file not exist, return null, else return content of file
* @throws RuntimeException if an error occurs while operator BufferedReader
*/
public static ArrayList<WePoint> readFileToList(String filePath, String charsetName) {
File file = new File(filePath);
ArrayList<WePoint> fileContent = new ArrayList<WePoint>();
if (file == null || !file.isFile()) {
return null;
}

BufferedReader reader = null;
try {
InputStreamReader is = new InputStreamReader(new FileInputStream(file), charsetName);
reader = new BufferedReader(is);
String line = null;
while ((line = reader.readLine()) != null) {
WePoint wePoint = GsonHelper.fromJson(line, WePoint.class);
if (wePoint == null) continue;
fileContent.add(wePoint);
}
reader.close();
return fileContent;
} catch (IOException e) {
throw new RuntimeException("Flash test : +++++++++ IOException occurred. ", e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
throw new RuntimeException("Flash test : +++++++++ IOException occurred. ", e);
}
}
}
}

public static ArrayList<WePoint> readAssetsFileToList(Context cxt, String filePath) {
ArrayList<WePoint> fileContent = new ArrayList<WePoint>();
BufferedReader reader = null;
try {
InputStreamReader is = new InputStreamReader(cxt.getAssets().open(filePath), "utf-8");
reader = new BufferedReader(is);
String line = null;
while ((line = reader.readLine()) != null) {
WePoint wePoint = GsonHelper.fromJson(line, WePoint.class);
if (wePoint == null) continue;
fileContent.add(wePoint);
}
reader.close();
return fileContent;
} catch (IOException e) {
throw new RuntimeException("Flash test : +++++++++ IOException occurred. ", e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
throw new RuntimeException("Flash test : +++++++++ IOException occurred. ", e);
}
}
}

}

/**
* write file【写文件:字符串】
*
* @param filePath
* @param content
* @param append is append, if true, write to the end of file, else clear content of file and write into it
* @return return false if content is empty, true otherwise
* @throws RuntimeException if an error occurs while operator FileWriter
*/
public static boolean writeFile(String filePath, String content, boolean append) {
//字符串判空
if (StringUtils.isEmpty(content)) {
return false;
}

FileWriter fileWriter = null;
try {
makeDirs(filePath);
fileWriter = new FileWriter(filePath, append);
fileWriter.write(content);
fileWriter.close();
//updateGallery(filePath);//媒体库数据更新
return true;
} catch (IOException e) {
throw new RuntimeException("IOException occurred. ", e);
} finally {
if (fileWriter != null) {
try {
fileWriter.close();
} catch (IOException e) {
throw new RuntimeException("IOException occurred. ", e);
}
}
}
}


/**
* write file
*
* @param file the file to be opened for writing.
* @param stream the input stream
* @param append if <code>true</code>, then bytes will be written to the end of the file rather than the beginning
* @return return true
* @throws RuntimeException if an error occurs while operator FileOutputStream
*/
public static boolean writeFile(File file, InputStream stream, boolean append) {
OutputStream o = null;
try {
makeDirs(file.getAbsolutePath());
if (!file.exists()) file.createNewFile();
o = new FileOutputStream(file, append);
byte data[] = new byte[1024];
int length = -1;
while ((length = stream.read(data)) != -1) {
o.write(data, 0, length);
}
o.flush();
//updateGallery(file.getAbsolutePath());//媒体库数据更新
return true;
} catch (FileNotFoundException e) {
throw new RuntimeException("FileNotFoundException occurred. ", e);
} catch (IOException e) {
throw new RuntimeException("IOException occurred. ", e);
} finally {
if (o != null) {
try {
o.close();
stream.close();
} catch (IOException e) {
throw new RuntimeException("IOException occurred. ", e);
}
}
}
}

public static boolean makeDirs(String filePath) {
String folderName = getFolderName(filePath);
if (StringUtils.isEmpty(folderName)) {
return false;
}

File folder = new File(folderName);
return (folder.exists() && folder.isDirectory()) ? true : folder.mkdirs();
}

public static String getFolderName(String filePath) {

if (StringUtils.isEmpty(filePath)) {
return filePath;
}

int filePosi = filePath.lastIndexOf(File.separator);
return (filePosi == -1) ? "" : filePath.substring(0, filePosi);
}

}

+ 58
- 0
app/src/main/java/com/yzx/webebook/utils/GsonHelper.java View File

@@ -0,0 +1,58 @@
package com.yzx.webebook.utils;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

import java.util.ArrayList;
import java.util.List;


/**
* Created by andrew on 2016/8/15 0015.
*/
public class GsonHelper {

public static String toJson(Object src){
try {
return new Gson().toJson(src);
} catch (Exception e){
e.printStackTrace();
}
return null;
}

public static <T> T fromJson(String json, Class<T> clazz) {
try {
return new Gson().fromJson(json, clazz);
} catch (Exception e){
e.printStackTrace();
}
return null;
}

public static <T> List<T> fromJsonArray(String json, Class<T> clazz) {
try {
List<T> lst = new ArrayList<T>();
JsonArray array = new JsonParser().parse(json).getAsJsonArray();
for(final JsonElement elem : array){
lst.add(new Gson().fromJson(elem, clazz));
}
return lst;
} catch (Exception e){
e.printStackTrace();
}
return null;
}

public static <T> T fromJsonObject(String json, Class<T> clazz) {
try {
JsonElement elem = new JsonParser().parse(json).getAsJsonObject();
return new Gson().fromJson(elem, clazz);
} catch (Exception e){
e.printStackTrace();
}
return null;
}
}

+ 204
- 0
app/src/main/java/com/yzx/webebook/utils/ListUtils.java View File

@@ -0,0 +1,204 @@
package com.yzx.webebook.utils;

import android.text.TextUtils;

import java.util.ArrayList;
import java.util.List;

/**
* List Utils
*
* @author andrew 2015-9-2
*/
public class ListUtils {

/** default join separator **/
public static final String DEFAULT_JOIN_SEPARATOR = ",";

private ListUtils() {
throw new AssertionError();
}

/**
* get size of list
*
* <pre>
* getSize(null) = 0;
* getSize({}) = 0;
* getSize({1}) = 1;
* </pre>
*
* @param <V>
* @param sourceList
* @return if list is null or empty, return 0, else return {@link List#size()}.
*/
public static <V> int getSize(List<V> sourceList) {
return sourceList == null ? 0 : sourceList.size();
}

/**
* is null or its size is 0
*
* <pre>
* isEmpty(null) = true;
* isEmpty({}) = true;
* isEmpty({1}) = false;
* </pre>
*
* @param <V>
* @param sourceList
* @return if list is null or its size is 0, return true, else return false.
*/
public static <V> boolean isEmpty(List<V> sourceList) {
return (sourceList == null || sourceList.size() == 0);
}

/**
* join list to string, separator is ","
*
* <pre>
* join(null) = "";
* join({}) = "";
* join({a,b}) = "a,b";
* </pre>
*
* @param list
* @return join list to string, separator is ",". if list is empty, return ""
*/
public static String join(List<String> list) {
return join(list, DEFAULT_JOIN_SEPARATOR);
}

/**
* join list to string
*
* <pre>
* join(null, '#') = "";
* join({}, '#') = "";
* join({a,b,c}, ' ') = "abc";
* join({a,b,c}, '#') = "a#b#c";
* </pre>
*
* @param list
* @param separator
* @return join list to string. if list is empty, return ""
*/
public static String join(List<String> list, char separator) {
return join(list, new String(new char[] {separator}));
}

/**
* join list to string. if separator is null, use {@link #DEFAULT_JOIN_SEPARATOR}
*
* <pre>
* join(null, "#") = "";
* join({}, "#$") = "";
* join({a,b,c}, null) = "a,b,c";
* join({a,b,c}, "") = "abc";
* join({a,b,c}, "#") = "a#b#c";
* join({a,b,c}, "#$") = "a#$b#$c";
* </pre>
*
* @param list
* @param separator
* @return join list to string with separator. if list is empty, return ""
*/
public static String join(List<String> list, String separator) {
return list == null ? "" : TextUtils.join(separator, list);
}

/**
* add distinct entry to list
*
* @param <V>
* @param sourceList
* @param entry
* @return if entry already exist in sourceList, return false, else add it and return true.
*/
public static <V> boolean addDistinctEntry(List<V> sourceList, V entry) {
return (sourceList != null && !sourceList.contains(entry)) ? sourceList.add(entry) : false;
}

/**
* add all distinct entry to list1 from list2
*
* @param <V>
* @param sourceList
* @param entryList
* @return the count of entries be added
*/
public static <V> int addDistinctList(List<V> sourceList, List<V> entryList) {
if (sourceList == null || isEmpty(entryList)) {
return 0;
}

int sourceCount = sourceList.size();
for (V entry : entryList) {
if (!sourceList.contains(entry)) {
sourceList.add(entry);
}
}
return sourceList.size() - sourceCount;
}

/**
* remove duplicate entries in list
*
* @param <V>
* @param sourceList
* @return the count of entries be removed
*/
public static <V> int distinctList(List<V> sourceList) {
if (isEmpty(sourceList)) {
return 0;
}

int sourceCount = sourceList.size();
int sourceListSize = sourceList.size();
for (int i = 0; i < sourceListSize; i++) {
for (int j = (i + 1); j < sourceListSize; j++) {
if (sourceList.get(i).equals(sourceList.get(j))) {
sourceList.remove(j);
sourceListSize = sourceList.size();
j--;
}
}
}
return sourceCount - sourceList.size();
}

/**
* add not null entry to list
*
* @param sourceList
* @param value
* @return <ul>
* <li>if sourceList is null, return false</li>
* <li>if value is null, return false</li>
* <li>return {@link List#add(Object)}</li>
* </ul>
*/
public static <V> boolean addListNotNullValue(List<V> sourceList, V value) {
return (sourceList != null && value != null) ? sourceList.add(value) : false;
}


/**
* invert list
*
* @param <V>
* @param sourceList
* @return
*/
public static <V> List<V> invertList(List<V> sourceList) {
if (isEmpty(sourceList)) {
return sourceList;
}

List<V> invertList = new ArrayList<V>(sourceList.size());
for (int i = sourceList.size() - 1; i >= 0; i--) {
invertList.add(sourceList.get(i));
}
return invertList;
}
}

+ 332
- 0
app/src/main/java/com/yzx/webebook/utils/StringUtils.java View File

@@ -0,0 +1,332 @@
package com.yzx.webebook.utils;

import android.text.TextUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* String Utils
*
* @author andrew 2015-9-2
*/
public class StringUtils {

private StringUtils() {
throw new AssertionError();
}

/**
* is null or its length is 0 or it is made by space【字符串为空、长度为0、一个空格】
*
* <pre>
* isBlank(null) = true;
* isBlank(&quot;&quot;) = true;
* isBlank(&quot; &quot;) = true;
* isBlank(&quot;a&quot;) = false;
* isBlank(&quot;a &quot;) = false;
* isBlank(&quot; a&quot;) = false;
* isBlank(&quot;a b&quot;) = false;
* </pre>
*
* @param str
* @return if string is null or its size is 0 or it is made by space, return true, else return false.
*/
public static boolean isBlank(String str) {
return (str == null || str.trim().length() == 0);
}

/**
* is null or its length is 0【字符串为空、长度为0】
*
* <pre>
* isEmpty(null) = true;
* isEmpty(&quot;&quot;) = true;
* isEmpty(&quot; &quot;) = false;
* </pre>
*
* @param str
* @return if string is null or its size is 0, return true, else return false.
*/
public static boolean isEmpty(CharSequence str) {
return (str == null || str.length() == 0);
}

public static boolean isEqual(String paramString1, String paramString2) {
return paramString1.equals(paramString2);
}

/**
* get length of CharSequence【字符串的长度】
*
* <pre>
* length(null) = 0;
* length(\"\") = 0;
* length(\"abc\") = 3;
* </pre>
*
* @param str
* @return if str is null or empty, return 0, else return {@link CharSequence#length()}.
*/
public static int length(CharSequence str) {
return str == null ? 0 : str.length();
}

/**
* null Object to empty string
*
* <pre>
* nullStrToEmpty(null) = &quot;&quot;;
* nullStrToEmpty(&quot;&quot;) = &quot;&quot;;
* nullStrToEmpty(&quot;aa&quot;) = &quot;aa&quot;;
* </pre>
*
* @param str
* @return
*/
public static String nullStrToEmpty(Object str) {
return (str == null ? "" : (str instanceof String ? (String)str : str.toString()));
}

/**
* capitalize first letter
*
* <pre>
* capitalizeFirstLetter(null) = null;
* capitalizeFirstLetter("") = "";
* capitalizeFirstLetter("2ab") = "2ab"
* capitalizeFirstLetter("a") = "A"
* capitalizeFirstLetter("ab") = "Ab"
* capitalizeFirstLetter("Abc") = "Abc"
* </pre>
*
* @param str
* @return
*/
public static String capitalizeFirstLetter(String str) {
if (isEmpty(str)) {
return str;
}

char c = str.charAt(0);
return (!Character.isLetter(c) || Character.isUpperCase(c)) ? str : new StringBuilder(str.length())
.append(Character.toUpperCase(c)).append(str.substring(1)).toString();
}

/**
* encoded in utf-8
*
* <pre>
* utf8Encode(null) = null
* utf8Encode("") = "";
* utf8Encode("aa") = "aa";
* utf8Encode("啊啊啊啊") = "%E5%95%8A%E5%95%8A%E5%95%8A%E5%95%8A";
* </pre>
*
* @param str
* @return
* @throws UnsupportedEncodingException if an error occurs
*/
public static String utf8Encode(String str) {
if (!isEmpty(str) && str.getBytes().length != str.length()) {
try {
return URLEncoder.encode(str, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("UnsupportedEncodingException occurred. ", e);
}
}
return str;
}

/**
* encoded in utf-8, if exception, return defultReturn
*
* @param str
* @param defultReturn
* @return
*/
public static String utf8Encode(String str, String defultReturn) {
if (!isEmpty(str) && str.getBytes().length != str.length()) {
try {
return URLEncoder.encode(str, "UTF-8");
} catch (UnsupportedEncodingException e) {
return defultReturn;
}
}
return str;
}

/**
* get innerHtml from href
*
* <pre>
* getHrefInnerHtml(null) = ""
* getHrefInnerHtml("") = ""
* getHrefInnerHtml("mp3") = "mp3";
* getHrefInnerHtml("&lt;a innerHtml&lt;/a&gt;") = "&lt;a innerHtml&lt;/a&gt;";
* getHrefInnerHtml("&lt;a&gt;innerHtml&lt;/a&gt;") = "innerHtml";
* getHrefInnerHtml("&lt;a&lt;a&gt;innerHtml&lt;/a&gt;") = "innerHtml";
* getHrefInnerHtml("&lt;a href="baidu.com"&gt;innerHtml&lt;/a&gt;") = "innerHtml";
* getHrefInnerHtml("&lt;a href="baidu.com" title="baidu"&gt;innerHtml&lt;/a&gt;") = "innerHtml";
* getHrefInnerHtml(" &lt;a&gt;innerHtml&lt;/a&gt; ") = "innerHtml";
* getHrefInnerHtml("&lt;a&gt;innerHtml&lt;/a&gt;&lt;/a&gt;") = "innerHtml";
* getHrefInnerHtml("jack&lt;a&gt;innerHtml&lt;/a&gt;&lt;/a&gt;") = "innerHtml";
* getHrefInnerHtml("&lt;a&gt;innerHtml1&lt;/a&gt;&lt;a&gt;innerHtml2&lt;/a&gt;") = "innerHtml2";
* </pre>
*
* @param href
* @return <ul>
* <li>if href is null, return ""</li>
* <li>if not match regx, return source</li>
* <li>return the last string that match regx</li>
* </ul>
*/
public static String getHrefInnerHtml(String href) {
if (isEmpty(href)) {
return "";
}

String hrefReg = ".*<[\\s]*a[\\s]*.*>(.+?)<[\\s]*/a[\\s]*>.*";
Pattern hrefPattern = Pattern.compile(hrefReg, Pattern.CASE_INSENSITIVE);
Matcher hrefMatcher = hrefPattern.matcher(href);
if (hrefMatcher.matches()) {
return hrefMatcher.group(1);
}
return href;
}

/**
* process special char in html
*
* <pre>
* htmlEscapeCharsToString(null) = null;
* htmlEscapeCharsToString("") = "";
* htmlEscapeCharsToString("mp3") = "mp3";
* htmlEscapeCharsToString("mp3&lt;") = "mp3<";
* htmlEscapeCharsToString("mp3&gt;") = "mp3\>";
* htmlEscapeCharsToString("mp3&amp;mp4") = "mp3&mp4";
* htmlEscapeCharsToString("mp3&quot;mp4") = "mp3\"mp4";
* htmlEscapeCharsToString("mp3&lt;&gt;&amp;&quot;mp4") = "mp3\<\>&\"mp4";
* </pre>
*
* @param source
* @return
*/
public static String htmlEscapeCharsToString(String source) {
return StringUtils.isEmpty(source) ? source : source.replaceAll("&lt;", "<").replaceAll("&gt;", ">")
.replaceAll("&amp;", "&").replaceAll("&quot;", "\"");
}

/**
* transform half width char to full width char
*
* <pre>
* fullWidthToHalfWidth(null) = null;
* fullWidthToHalfWidth("") = "";
* fullWidthToHalfWidth(new String(new char[] {12288})) = " ";
* fullWidthToHalfWidth("!"#$%&) = "!\"#$%&";
* </pre>
*
* @param s
* @return
*/
public static String fullWidthToHalfWidth(String s) {
if (isEmpty(s)) {
return s;
}

char[] source = s.toCharArray();
for (int i = 0; i < source.length; i++) {
if (source[i] == 12288) {
source[i] = ' ';
// } else if (source[i] == 12290) {
// source[i] = '.';
} else if (source[i] >= 65281 && source[i] <= 65374) {
source[i] = (char)(source[i] - 65248);
} else {
source[i] = source[i];
}
}
return new String(source);
}

/**
* transform full width char to half width char
*
* <pre>
* halfWidthToFullWidth(null) = null;
* halfWidthToFullWidth("") = "";
* halfWidthToFullWidth(" ") = new String(new char[] {12288});
* halfWidthToFullWidth("!\"#$%&) = "!"#$%&";
* </pre>
*
* @param s
* @return
*/
public static String halfWidthToFullWidth(String s) {
if (isEmpty(s)) {
return s;
}

char[] source = s.toCharArray();
for (int i = 0; i < source.length; i++) {
if (source[i] == ' ') {
source[i] = (char)12288;
// } else if (source[i] == '.') {
// source[i] = (char)12290;
} else if (source[i] >= 33 && source[i] <= 126) {
source[i] = (char)(source[i] + 65248);
} else {
source[i] = source[i];
}
}
return new String(source);
}

private static String bytesToHexString(byte[] paramArrayOfByte) {

StringBuilder localStringBuilder = new StringBuilder();
for (int i = 0; i < paramArrayOfByte.length; i++)
{
String str = Integer.toHexString(0xFF & paramArrayOfByte[i]);
if (str.length() == 1)
localStringBuilder.append('0');
localStringBuilder.append(str);
}
return localStringBuilder.toString();
}

public static String hashKey(String paramString) {
String localObject = "";
if (!TextUtils.isEmpty(paramString));
try
{
MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
localMessageDigest.update(paramString.getBytes());
String str = bytesToHexString(localMessageDigest.digest());
localObject = str;
return localObject;
}
catch (NoSuchAlgorithmException localNoSuchAlgorithmException)
{
}
return String.valueOf(paramString.hashCode());
}

public static String stripLeadingSlash(String paramString) {

if (TextUtils.isEmpty(paramString))
{
return paramString;
}
int i = 0;
while (paramString.charAt(i) == '/'){
i ++;
}
return paramString.substring(i);
}
}

+ 0
- 1
app/src/main/jniLibs/armeabi/libpaintworker.so View File

@@ -1 +0,0 @@
/system/lib/libpaintworker.so

+ 9
- 1
app/src/main/res/layout/activity_main.xml View File

@@ -83,7 +83,15 @@
android:id="@+id/btn5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="电子书页面(不带背景)"
android:text="电子书页面(笔记本)"
android:visibility="visible"
android:layout_marginTop="@dimen/d_20"/>

<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="电子书页面(测试)"
android:visibility="visible"
android:layout_marginTop="@dimen/d_20"/>



+ 120
- 0
app/src/main/res/layout/activity_main1.xml View File

@@ -0,0 +1,120 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffffff"
android:orientation="vertical">
<LinearLayout
android:id="@+id/bottom_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:orientation="horizontal"
android:paddingTop="4dp">

<Button
android:id="@+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_select"
android:text="删除" />
<Button
android:id="@+id/init"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_select"
android:text="背景0" />

<Button
android:id="@+id/clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_select"
android:text="清除" />

<Button
android:id="@+id/zoom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_select"
android:text="V1缩放"
android:visibility="gone" />
<Button
android:id="@+id/redo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_select"
android:text="ReDo" />
<Button
android:id="@+id/undo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_select"
android:text="UnDo" />

<Button
android:id="@+id/pen_width"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_select"
android:text="宽度3" />
<Button
android:id="@+id/eraser_width"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_select"
android:text="橡皮宽15" />

<Button
android:id="@+id/draw_circle"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:background="@drawable/btn_select"
android:text="曲线" />

<CheckBox
android:id="@+id/visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/btn_select"
android:text="V1隐藏"
android:visibility="gone" />
<Button
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_select"
android:text="退出" />


</LinearLayout>
<TextView
android:id="@+id/tv_line"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@+id/bottom_view"
android:background="#ff000000" />

<com.wetao.note.WeNoteView
android:id="@+id/note_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/tv_line"
android:background="@android:color/transparent" />

</RelativeLayout>

BIN
buildKey/wenote.jks View File


BIN
buildKey/wetao_app_key View File


Loading…
Cancel
Save