Android 一行代码搞定将错误日志放入到sd卡中且不需要任何权限,适配到android7.0
Android 一行代码搞定将错误日志放入到sd卡中且不需要任何权限,适配到android7.0
之前所有的项目都有一个将崩溃日志写入到sd卡的工具类,然后每次项目新建都从老项目copy过来,后来慢慢发现这样也挺累的。就吧工具类封装到了一个lib库里面,后来android6.0出了权限需要动态申请,然后又把日志写入到getExternalFilesDir()里面去。后来把他上传到jcenter里面去了,更方便了,就分享给大家。
github地址:https://github.com/dreamlivemeng/Clog
Clog
这是一个将android 崩溃日志写入到sd卡得工具类。
This is a tool that write the Android crash log to the sd card.
最低版本android2.2(8),已经适配到android7.0。
目前对应Clog版本0.0.1
.
导入方法
Android Studio
compile 'com.dreamlive.cn.clog:ClogLibrary:0.0.1'
使用方法1
***强烈建议****
使用方法1,因为不需要权限。
在application的oncreate()配置
//android6.0也不需要动态sd权限, //将错误日志写入到sd卡,默认为Android/data/包名/files/logs下面放这个目录下主要是为了不需要权限 CollectLog clog = CollectLog.getInstance(); clog.init(this); [object Object] //一行代码就是CollectLog.getInstance().init(this);
使用方法2
自定义日志存放路径 在application的oncreate()配置
//自定义日志存放路径, //这儿示例就只传了sd根目录下的dreamlivemeng(/storage/emulated/0/dreamlivemeng),把错误日志写到这个目录下 CollectLog clog = CollectLog.getInstance(); clog.init(this, Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "dreamlivemeng");
混淆
#Clog-dontwarn com.dreamlive.cn.**-keep classcom.dreamlive.cn.**{*;}
使用方法说完了,来说说具体是怎么实现的。
主要用到了一个类UncaughtExceptionHandler。
//初始化,2个init是因为一个是将日志存到默认路径下,另外一个是自定义保存路径。
/** * initialization * * @param context context */ public void init(Context context) { mContext = context; //Gets the system's default UncaughtException handler mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); //Set the CrashHandler as the default handler for the program Thread.setDefaultUncaughtExceptionHandler(this); } /** * initialization ,Can custom the path * * @param context context * @param path custom the path */ public void init(Context context, String path) { init(context); filePath = path; }
//收集设备基本信息
/** * Collect device parameter information * * @param ctx context */ public void collectDeviceInfo(Context ctx) { try { PackageManager pm = ctx.getPackageManager(); PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES); if (pi != null) { String versionName = pi.versionName == null ? "null" : pi.versionName; String versionCode = pi.versionCode + ""; infos.put("versionName", versionName); infos.put("versionCode", versionCode); } } catch (NameNotFoundException e) {// Log.e(TAG, "an error occured when collect package info", e); } Field[] fields = Build.class.getDeclaredFields(); for (Field field : fields) { try { field.setAccessible(true); infos.put(field.getName(), field.get(null).toString());// Log.d(TAG, field.getName() + " : " + field.get(null)); } catch (Exception e) {// Log.e(TAG, "an error occured when collect crash info", e); } } }
//收集错误日志
/** * Gets the string of the caught exception * * @param tr throwable * @return the string of the caught exception */ public static String getStackTraceString(Throwable tr) { try { if (tr == null) { return ""; } Throwable t = tr; while (t != null) { if (t instanceof UnknownHostException) { return ""; } t = t.getCause(); } StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); tr.printStackTrace(pw); return sw.toString(); } catch (Exception e) { return ""; } }
//将错误日志和设备信息写入到sd卡
/** * Save the error message to a file * * @param ex Throwable * @return Returns the name of the file to facilitate transfer of the file to the server */ private String saveCrashInfo2File(Throwable ex) { StringBuffer sb = new StringBuffer(); for (Map.Entryentry : infos.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); sb.append("[" + key + ", " + value + "]n"); } sb.append("n" + getStackTraceString(ex)); try { String time = formatter.format(new Date()); String fileName = "CRS_" + time + ".txt"; File sdDir = null; sdDir = mContext.getExternalFilesDir("logs").getAbsoluteFile(); File file = null; if (!TextUtils.isEmpty(filePath)) { File files = new File(filePath); if (!files.exists()) { //Create a directory files.mkdirs(); } file = new File(filePath + File.separator + fileName); } else { file = new File(sdDir + File.separator + fileName); } if (file == null) { file = new File(sdDir + File.separator + fileName); } FileOutputStream fos = new FileOutputStream(file); fos.write(sb.toString().getBytes()); fos.close(); return fileName; } catch (Exception e) { } return null; }
最后厚脸求star和fork,如有错误可以直接提issues。
github地址:https://github.com/dreamlivemeng/Clog
Android 一行代码搞定将错误日志放入到sd卡中且不需要任何权限,适配到android7.0相关推荐
- 自定义注解妙用,一行代码搞定用户操作日志记录,你学会了吗?
来源:https://blog.csdn.net/yjt520557/article/details/85099115 | 简介 我在使用spring完成项目的时候需要完成记录日志,我开始以为Spri ...
- 自定义注解妙用,一行代码搞定用户操作日志记录
1.简介 在使用spring完成项目的时候需要完成记录日志,开始以为Spring 的AOP功能,就可以轻松解决,半个小时都不用,可是经过一番了解过后,发现一般的日志记录,只能记录一些简单的操作,例如表 ...
- android加载网页pdf,android 一行代码搞定加载网络 pdf 文件
之前写过一篇Android打开本地pdf文件的文章,最后总结的时候说,后面一定要拓展库,让其也能打开网络的的pdf文件.今天终于可以兑现承诺了.frok一份代码github.com/JoanZapat ...
- 安卓视频播放器 一行代码快速实现视频播放,Android视频播放,AndroidMP3播放,安卓视频播放一行代码搞定,仿今日头条 Android视频播放器
一行代码快速实现视频播放,Android视频播放,AndroidMP3播放,安卓视频播放一行代码搞定,真正实现Android的全屏功能 github地址:https://github.com/qius ...
- 一行代码搞定android全屏适配
一行代码搞定安卓全屏幕适配--简单粗暴-低入侵,无继承,简单高效 话不多说,先上解决方案 方案一(推荐) ##### 1.引用工具类 DensityHelper.java ##### 2.在自定义的 ...
- thinkjdbc 关闭_ThinkJD: ThinkJD,又名ThinkJDBC,一个强大的开源JDBC/ORM操作库,让你尽可能简洁地用一行代码搞定数据库操作。...
1 简介 ThinkJD,又名ThinkJDBC,一个简洁而强大的开源JDBC操作库.你可以使用Java像ThinkPHP框架的M方法一样,一行代码搞定数据库操作.ThinkJD会自动管理数据库连接, ...
- table中加表单元素每行怎么验证_Validform 一行代码搞定整站的表单验证 - 文章
Validform 一行代码搞定整站的表单验证,为什么能如此方便?插件的核心思想就是把所有的验证条件及验证提示信息绑定到每个表单元素,让验证代码在执行时只是核对表单下各元素的值是否跟绑定的验证条件相符 ...
- WPF使用Linq 一行代码搞定数据绑定
首先设置好DataGrid控件的相关属性,注意XAML代码文件中的列绑定要和源数据的列名一致,如: Binding="{Binding No}" 详细设置如下: this.data ...
- 开源作品ThinkJDBC—一行代码搞定数据库操作
1 简介 ThinkJD,又名ThinkJDBC,一个简洁而强大的开源JDBC操作库.你可以使用Java像ThinkPHP框架的M方法一样,一行代码搞定数据库操作.ThinkJD会自动管理数据库连接, ...
最新文章
- redis之 centos 6.7 下安装 redis-3.2.5
- python _、__和__xx__的区别
- Mysql迁移到Postgresql
- 面向对象简述--对象、引用、指针
- android弹出输入框不影响布局,android 输入法弹出后,不影响activity原有布局
- 用定时中断来接收红外遥控信号
- java if else过多_Spring Boot中如何干掉过多的if else!
- Team photo的新api
- android签名忘记密码,修改Android签名证书keystore的密码、别名alias以及别名密码
- RedHat系列软件管理(第二版) --二进制软件包管理
- 写给小白的机器学习之数据表示与特征工程详解(附实战代码)
- 今日恐慌与贪婪指数为40 恐慌程度有所上升
- 2020-09-30
- Pygame教程系列三:绘制文本篇
- 数据抽取的常见理论方法
- 2016.12.30非线性优化计算方法1
- Bootstrap如何设置table样式
- 微信视频提取及接收文件路径
- 木马开发的基本理论基础(四)
- 阿里CEO张勇:“亲亲节”预示未来年轻人生活方式
热门文章
- error: Microsoft Visual C++ 14.0 or greater is required. Get it with “Micros 问题解决记录
- 自定义View(二-番外4-drawBitmapMesh)
- cisco(思科)两个不同网段相连接
- APS系统在企业生产中的场景应用
- 迅雷不能下载download.php,迅雷无法下载磁力链接文件?一招解决问题
- vim 指令 删除所有内容
- 工信部:全国规划在建大型以上数据中心平均设计PUE降到1.3以下​
- 用python写一个简答的英文文章分析程序
- WebRTC的音频编码(转)
- Spring Boot项目打war包(idea:多种方式)