| @@ -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 { | |||
| @@ -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,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") | |||
| @@ -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); | |||
| // } | |||
| } | |||
| }; | |||
| @@ -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); | |||
| } | |||
| } | |||
| @@ -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]) | |||
| } | |||
| //从笔记文件夹中读取当前笔记的页面信息 | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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("") = true; | |||
| * isBlank(" ") = true; | |||
| * isBlank("a") = false; | |||
| * isBlank("a ") = false; | |||
| * isBlank(" a") = false; | |||
| * isBlank("a b") = 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("") = true; | |||
| * isEmpty(" ") = 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) = ""; | |||
| * nullStrToEmpty("") = ""; | |||
| * nullStrToEmpty("aa") = "aa"; | |||
| * </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("<a innerHtml</a>") = "<a innerHtml</a>"; | |||
| * getHrefInnerHtml("<a>innerHtml</a>") = "innerHtml"; | |||
| * getHrefInnerHtml("<a<a>innerHtml</a>") = "innerHtml"; | |||
| * getHrefInnerHtml("<a href="baidu.com">innerHtml</a>") = "innerHtml"; | |||
| * getHrefInnerHtml("<a href="baidu.com" title="baidu">innerHtml</a>") = "innerHtml"; | |||
| * getHrefInnerHtml(" <a>innerHtml</a> ") = "innerHtml"; | |||
| * getHrefInnerHtml("<a>innerHtml</a></a>") = "innerHtml"; | |||
| * getHrefInnerHtml("jack<a>innerHtml</a></a>") = "innerHtml"; | |||
| * getHrefInnerHtml("<a>innerHtml1</a><a>innerHtml2</a>") = "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<") = "mp3<"; | |||
| * htmlEscapeCharsToString("mp3>") = "mp3\>"; | |||
| * htmlEscapeCharsToString("mp3&mp4") = "mp3&mp4"; | |||
| * htmlEscapeCharsToString("mp3"mp4") = "mp3\"mp4"; | |||
| * htmlEscapeCharsToString("mp3<>&"mp4") = "mp3\<\>&\"mp4"; | |||
| * </pre> | |||
| * | |||
| * @param source | |||
| * @return | |||
| */ | |||
| public static String htmlEscapeCharsToString(String source) { | |||
| return StringUtils.isEmpty(source) ? source : source.replaceAll("<", "<").replaceAll(">", ">") | |||
| .replaceAll("&", "&").replaceAll(""", "\""); | |||
| } | |||
| /** | |||
| * 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); | |||
| } | |||
| } | |||
| @@ -1 +0,0 @@ | |||
| /system/lib/libpaintworker.so | |||
| @@ -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"/> | |||
| @@ -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> | |||