ptz 发布的文章

清除数据

lineChart.clear(); 用于清除所有数据。

参考: https://blog.csdn.net/qq_44720366/article/details/104816512

刷新 x 轴数据问题

参考: https://blog.csdn.net/qq_35071078/article/details/76082125

参考:

How to use LineChart in com.github.mikephil.charting.charts
https://www.tabnine.com/code/java/classes/com.github.mikephil.charting.charts.LineChart

Android详细介绍MPAndroidChart-LineChart
https://www.cnblogs.com/leshen/p/12606161.html

MPAndroidChart
https://github.com/PhilJay/MPAndroidChart

MPAndroidChart
https://weeklycoding.com/mpandroidchart/

MPAndroidChart LineChart X轴标签显示问题
https://www.freesion.com/article/6030644140/

MPAndroidChart折线图详细使用
https://www.jianshu.com/p/185e50a70aa7

Android图表控件MPAndroidChart——LineChart实现 XY轴、原点线的直尺刻度样式
https://blog.csdn.net/ww897532167/article/details/78520548

Android图表控件MPAndroidChart——曲线图LineChart的使用(财富收益图)
https://blog.csdn.net/ww897532167/article/details/74129478

参考

软件项目工作流程图
https://blog.csdn.net/danny35/article/details/41010721
程序流程图详解(六大部分)
https://zhuanlan.zhihu.com/p/364507517
如何正确的画出功能流程图?
https://zhuanlan.zhihu.com/p/30188796
如何绘画状态机来描述业务的变化
https://zhuanlan.zhihu.com/p/30303045
如何绘画状态机来描述业务的变化
http://www.woshipm.com/pd/594751.html
如何正确地画出页面流程图
https://zhuanlan.zhihu.com/p/30188186
如何正确的画出功能流程图?
http://www.woshipm.com/pmd/663549.html
善用Axure写PRD,移动PM需要梳理这些流程图
http://www.woshipm.com/rp/398610.html
如何正确地画出页面流程图
http://www.woshipm.com/rp/651734.html
UI图与原型图的区分
https://zhuanlan.zhihu.com/p/66540090

参考

用代码生成流程图,Markdown的使用方法
https://blog.csdn.net/u012388993/article/details/116704452
flowchart.js
http://flowchart.js.org/
用markdown来画流程图
https://www.jianshu.com/p/02a5a1bf1096
markdown 中流程图详解
https://blog.csdn.net/suoxd123/article/details/84992282
Markdown 进阶技能:用代码画流程图(编程零基础也适用)
https://zhuanlan.zhihu.com/p/69495726
Markdown 流程图
https://www.imooc.com/wiki/markdownlesson/markdownflowchart.html
typora制作流程图
https://www.typora.net/945.html
Markdown--绘制流程图(flowchart)
https://blog.csdn.net/baidu_38172402/article/details/88757379

背景

需要在指定列中搜索所有包含 "x", "y", "z" 的数据,和不包含他们的数据

实现

  • 不包含他们的数据:
String find = "SELECT " + "*" + " FROM " + "analysisInfo" + " WHERE " + "stripId" +
                        " not in ( ?, ?, ? )";
Cursor cursor = db.rawQuery(find, new String[]{"x", "y", "z"});
  • 包含他们的数据
    String find = "SELECT " + "*" + " FROM " + "analysisInfo" + " WHERE " + "stripId" +
                        " in ( ?, ?, ? )";
    Cursor cursor = db.rawQuery(find, new String[]{"x", "y", "z"});

参考:

SQLite | Where 子句
https://blog.csdn.net/weixin_45488228/article/details/104377915?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_paycolumn_v3&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_paycolumn_v3&utm_relevant_index=1

sqlite3学习之where子句&AND/OR 运算符&Like 子句&Glob 子句
https://blog.csdn.net/luyaran/article/details/86239843

这个问题一般是 release 版本的时候才会出现,解决这个问题的办法其实报错的提示里面已经说了:

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
    }
}

就是在 build.gradle 里面的 android 条目下面增加 lintOptions 即可 release 成功。

参考:

android/flutter 打包报错 ':app:lintVitalRelease'
https://zhuanlan.zhihu.com/p/80453995

目的

从机器中提取 boot.img, dtbo.img 进行备用。

方法

  1. 打开 /dev/block/platform/soc/7824900.sdhci/by-name ,然后 ls -l,就可以看到所有分区的具体指向,比如 lrwxrwxrwx 1 root root 21 1970-01-03 23:21 boot -> /dev/block/mmcblk0p32, lrwxrwxrwx 1 root root 21 1970-01-03 23:21 dtbo -> /dev/block/mmcblk0p28
  2. sdcard /storage/emulated/0 /storage/self/primary 指向的是同一个地方,打开这个位置
  3. dd if=/dev/block/mmcblk0p32 of=/storage/self/primary/Download/boot.img 备份 boot.img
  4. dd if=/dev/block/mmcblk0p28 of=/storage/self/primary/Download/dtbo.img 备份 dtbo.img
  5. adb pull /storage/self/primary/Download/boot.img, adb pull /storage/self/primary/Download/dtbo.img 提取出 boot.imgdtbo.img.

参考

从手机中提取boot.img
https://www.cnblogs.com/xirtam/p/10782679.html

背景

插 SIM 卡的产品需要获取 ICCID,IMEI 等数据,方便管理。

准备

  1. computer management 中,查看 modems 下面有没有相应的高通产品,类似 Qualcomm HS-USB Modem 90B8
  2. 双击上面这个条目,或者右键属性,打开这个条目详细信息
  3. 点击 Modem 选项卡,查看 Port 绑定的串口号,和 Speed 指定的波特率数值。

读取

  1. 打开相应的串口助手,选择对应的串口号和波特率,然后勾选上流控,RTSDTR,勾选上加回车换行。
  2. 输入 ATI 可以看到一些 模块的基本信息。
  3. 输入 AT+ICCID 获取到 ICCID 的值。
  4. 输入 AT+CIMI 获取到 IMSI 的值。
  5. 输入 AT+EGMR 获取到 MEID 的值。

把程序文件下的数据库文件复制到其他目录,需要用到文件复制。

/**
 * @author ptz
 * @date 2022/02/05
 * @description
 */
public class CopyFile {
    private static final String TAG = "CopyFile";
    /**
     * 根据文件路径拷贝文件
     * @param srcPath 源文件
     * @param destDir 目标文件路径
     * @param fileName 目标文件名
     * @return boolean 成功true、失败false
     */
    public static boolean copyFile(String srcPath, String destDir, String fileName) {
        boolean result = false;

        DLog.w(TAG, "copyFile: src: " + srcPath + ", dest: " + destDir + fileName);

        File src = new File(srcPath);
        if ((src == null) || (destDir== null)) {
            return false;
        }

        File dir = new File(destDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        File dest= new File(destDir + fileName);
        if (dest!= null && dest.exists()) {
            boolean ret = dest.delete(); // delete file
            DLog.d(TAG, "copyFile: delete dest result: " + ret);
        }

        try {
            boolean ret = dest.createNewFile();
            DLog.d(TAG, "copyFile: create dest result: " + ret);
        } catch (IOException e) {
            //e.printStackTrace();
            DLog.d(TAG, Log.getStackTraceString(e));
        }

        FileChannel srcChannel = null;
        FileChannel dstChannel = null;

        try {
            srcChannel = new FileInputStream(src).getChannel();
            dstChannel = new FileOutputStream(dest).getChannel();
            srcChannel.transferTo(0, srcChannel.size(), dstChannel);
            result = true;
        } catch (FileNotFoundException e) {
            //e.printStackTrace();
            DLog.d(TAG, Log.getStackTraceString(e));
        } catch (IOException e) {
            //e.printStackTrace();
            DLog.d(TAG, Log.getStackTraceString(e));
        }

        try {
            srcChannel.close();
            dstChannel.close();
        } catch (Exception e) {
            //e.printStackTrace();
            DLog.d(TAG, Log.getStackTraceString(e));
        }

        return result;
    }
}
/**
 * @author ptz
 * @date 2022/02/05
 * @description
 */
public class FileName {
    /**
     * 仅保留文件名不保留后缀
     */
    public static String getFileName(String path) {
        int start = path.lastIndexOf("/");
        int end = path.lastIndexOf(".");
        if (start != -1 && end != -1) {
            return path.substring(start + 1, end);
        } else {
            return null;
        }
    }

    /**
     * 保留文件名及后缀
     */
    public static String getFileNameWithSuffix(String path) {
        int start = path.lastIndexOf("/");
        if (start != -1 ) {
            return path.substring(start + 1);
        } else {
            return null;
        }
    }

    /**
     * 仅保留目录名
     */
    public static String getDirName(String path) {
        int start = 0;
        int end = path.lastIndexOf("/");
        if (start != end && end != -1) {
            return path.substring(start, end + 1);
        } else {
            return null;
        }
    }
}

参考

可能是最完美的Android复制拷贝文件的实例(Java NIO速度快)
https://blog.csdn.net/mvpstevenlin/article/details/54090722
java如何操作字符串取得绝对路径中的文件名及文件夹名
https://blog.csdn.net/weiqiang_1989/article/details/50987852

转自: https://blog.csdn.net/cf8833/article/details/92662279

遇到的坑:

  1. 这个东西只能保存崩溃的错误日志,有点局限性
  2. 文件权限申请,文件权限申请,文件权限申请,重要的事情讲三遍,
  3. 这个生成之后的文件,一定要用手机去看,千万不要用电脑,别问题为什么,因为电脑看的那个文件夹没刷新,不显示,还有我们存储路径的wangrusheg 这个东西是可变化的,是你的项目名称,千万不要傻愣愣的一直去找这个文件夹 这个是项目名称,项目名称,项目名称!!!!切记

先看效果图:

1.权限,文件的读写,在清单文件里面,注意,我这里为了方便,没做动态权限申请,你们使用的时候,记得把权限开起来,还有,我们的用到了application,记得在清单文件添加

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.administrator.testz">

        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

        <application
            android:name=".App"
            android:allowBackup="true"
            android:icon="@mipmap/icona"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />

                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>

        </application>

    </manifest>

2.创建App文件

    public class App extends Application {
        @Override
        public void onCreate() {
            super.onCreate();
            CrashHandler crashHandler = CrashHandler.getInstance();
            crashHandler.init(getApplicationContext());
        }
    }

3.MainActivity ,只要是模拟一下报错,你们也可以模拟别的错误,界面我就不贴了,就一个button,自己添加

    package com.example.administrator.testz;

    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;

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

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

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            final Button button2 = (Button) findViewById(R.id.bug);

            button2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    List<String> list = new ArrayList<>();

                    String[] strings = CrashHandler.getCrashReportFiles(MainActivity.this);//获取异常文件路径
                    for (int i = 0; i < strings.length; i++) {
                        Log.e(TAG, "onCreate: " + strings[i]);
                    }

                    Log.e(TAG, "onCreate: " + list.get(1));//模拟数组越界
                }
            });

        }
    }

4.日志类

    package com.example.administrator.testz;

    import android.util.Log;

    /**
     * @author DeMon
     * @date 2018/8/14
     * @description
     */
    public class DLog {
        /*m默认不打印Log,如果要打印,置为true*/
        private static boolean enableLog = BuildConfig.DEBUG;

        public static void e(String tag, String msg) {
            if (enableLog)
                Log.e(tag, msg);

        }

        public static void d(String tag, String msg) {
            if (enableLog)
                Log.d(tag, msg);

        }

        public static void i(String tag, String msg) {
            if (enableLog)
                Log.i(tag, msg);

        }

        public static void v(String tag, String msg) {
            if (enableLog)
                Log.v(tag, msg);

        }

        public static void w(String tag, String msg) {
            if (enableLog)
                Log.w(tag, msg);

        }

    }

5.日志写入错误信息类

    package com.example.administrator.testz;

    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.os.Build;
    import android.os.Environment;
    import android.util.Log;

    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.io.StringWriter;
    import java.io.Writer;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;

    /**
     * @author DeMon
     * @date 2018/8/14
     * @description
     */
    public class CrashHandler implements Thread.UncaughtExceptionHandler {

        private static final String TAG = "CrashHandler";
        /**
         * 系统默认的UncaughtException处理类
         */
        private Thread.UncaughtExceptionHandler mDefaultHandler;
        /**
         * 程序的Context对象
         */
        private Context mContext;
        /**
         * 错误报告文件的扩展名
         */
        private static final String CRASH_REPORTER_EXTENSION = ".txt";

        /**
         * CrashHandler实例
         */
        private static CrashHandler INSTANCE;

        /**
         * 保证只有一个CrashHandler实例
         */
        private CrashHandler() {
        }

        /**
         * 获取CrashHandler实例 ,单例模式
         */
        public static CrashHandler getInstance() {
            if (INSTANCE == null) {
                synchronized (CrashHandler.class) {
                    if (INSTANCE == null) {
                        INSTANCE = new CrashHandler();
                    }
                }
            }
            return INSTANCE;
        }

        /**
         * 初始化,注册Context对象,
         * 获取系统默认的UncaughtException处理器,
         * 设置该CrashHandler为程序的默认处理器
         *
         * @param ctx
         */
        public void init(Context ctx) {
            mContext = ctx;
            mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
            Thread.setDefaultUncaughtExceptionHandler(this);
        }

        /**
         * 当UncaughtException发生时会转入该函数来处理
         */
        @Override
        public void uncaughtException(Thread thread, Throwable ex) {
            handleException(ex);
            if (mDefaultHandler != null) {
                //收集完信息后,交给系统自己处理崩溃
                mDefaultHandler.uncaughtException(thread, ex);
            }
        }

        /**
         * 自定义错误处理,收集错误信息
         * 发送错误报告等操作均在此完成.
         * 开发者可以根据自己的情况来自定义异常处理逻辑
         */
        private void handleException(Throwable ex) {
            if (ex == null) {
                Log.w(TAG, "handleException--- ex==null");
                return;
            }
            String msg = ex.getLocalizedMessage();
            if (msg == null) {
                return;
            }
            //收集设备信息
            //保存错误报告文件
            saveCrashInfoToFile(ex);
        }

        /**
         * 获取错误报告文件路径
         *
         * @param ctx
         * @return
         */
        public static String[] getCrashReportFiles(Context ctx) {
            File filesDir = new File(getCrashFilePath(ctx));
            String[] fileNames = filesDir.list();
            int length = fileNames.length;
            String[] filePaths = new String[length];
            for (int i = 0; i < length; i++) {
                filePaths[i] = getCrashFilePath(ctx) + fileNames[i];
            }
            return filePaths;
        }

        /**
         * 保存错误信息到文件中
         *
         * @param ex
         * @return
         */
        private void saveCrashInfoToFile(Throwable ex) {
            Writer info = new StringWriter();
            PrintWriter printWriter = new PrintWriter(info);
            ex.printStackTrace(printWriter);
            Throwable cause = ex.getCause();
            while (cause != null) {
                cause.printStackTrace(printWriter);
                cause = cause.getCause();
            }
            String result = info.toString();
            printWriter.close();
            StringBuilder sb = new StringBuilder();
            @SuppressLint("SimpleDateFormat") SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
            String now = sdf.format(new Date());
            sb.append("TIME:").append(now);//崩溃时间
            //程序信息
            sb.append("\nAPPLICATION_ID:").append(BuildConfig.APPLICATION_ID);//软件APPLICATION_ID
            sb.append("\nVERSION_CODE:").append(BuildConfig.VERSION_CODE);//软件版本号
            sb.append("\nVERSION_NAME:").append(BuildConfig.VERSION_NAME);//VERSION_NAME
            sb.append("\nBUILD_TYPE:").append(BuildConfig.BUILD_TYPE);//是否是DEBUG版本
            //设备信息
            sb.append("\nMODEL:").append(android.os.Build.MODEL);
            sb.append("\nRELEASE:").append(Build.VERSION.RELEASE);
            sb.append("\nSDK:").append(Build.VERSION.SDK_INT);
            sb.append("\nEXCEPTION:").append(ex.getLocalizedMessage());
            sb.append("\nSTACK_TRACE:").append(result);
            try {
                FileWriter writer = new FileWriter(getCrashFilePath(mContext) + now + CRASH_REPORTER_EXTENSION);
                writer.write(sb.toString());
                writer.flush();
                writer.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * 获取文件夹路径
         *
         * @param context
         * @return
         */
        private static String getCrashFilePath(Context context) {
            String path = null;
            try {
                path = Environment.getExternalStorageDirectory().getCanonicalPath() + "/"
                        + context.getResources().getString(R.string.app_name) + "/Crash/";
                File file = new File(path);
                if (!file.exists()) {
                    file.mkdirs();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            Log.e(TAG, "getCrashFilePath: " + path);
            return path;
        }
    }