android textview 靠右对齐
参考:
android中 有textview在布局中居右展示以及文本靠右对齐
https://blog.csdn.net/emmmsuperdan/article/details/85047770
如何使文本在 Android TextView 向右对齐
https://blog.csdn.net/qq_35114086/article/details/52398962
android中 有textview在布局中居右展示以及文本靠右对齐
https://blog.csdn.net/emmmsuperdan/article/details/85047770
如何使文本在 Android TextView 向右对齐
https://blog.csdn.net/qq_35114086/article/details/52398962
libaums https://github.com/magnusja/libaums
Android-USB-OTG-读写U盘文件
https://www.jianshu.com/p/a32e376ea70e
文件流之文件输出流FileOutputStream
https://blog.csdn.net/chengqiuming/article/details/78795960
禁用Android底部虚拟按键
https://blog.csdn.net/cao861544325/article/details/81748095
android 系统隐藏和显示虚拟按键的几种方法
https://blog.csdn.net/xct841990555/article/details/102810360
Android 隐藏底部虚拟键的两种方法
https://cloud.tencent.com/developer/article/1741856
android:backgroundDimEnabled的作用
https://blog.csdn.net/chuyouyinghe/article/details/73468648
java 的 ymodem 可以使用 github 上面的 YModemForAndroid
,链接是 https://github.com/LeonXtp/YModemForAndroid
直接使用 YModemForAndroid
有以下几个问题
当Android BLE遇上YModem
https://www.jianshu.com/p/d37eb7fa1d6e
【安卓相关】蓝牙基于Ymodem协议发送bin文件,对硬件设备进行升级。
https://www.jianshu.com/p/85784aa3143b
YMODEM协议简介
https://zhuanlan.zhihu.com/p/81133050
stm32 Bootloader设计(YModem协议)
https://www.amobbs.com/thread-5559677-1-1.html
Ymodem协议详解
https://blog.csdn.net/lcmsir/article/details/80550821/
Ymodem 协议详解
https://blog.csdn.net/huangdenan/article/details/103611081
BGAUpdate-Android
https://github.com/bingoogolapple/BGAUpdate-Android
YModemForAndroid
https://github.com/LeonXtp/YModemForAndroid
YModemlib_Android
https://github.com/ArdWang/YModemlib_Android
anroid ymodem 实现单片机固件升级
https://www.jianshu.com/p/c36e0d0211e4
MCUUpdate
https://github.com/h4de5ing/MCUUpdate
SerialPortLib
https://github.com/h4de5ing/SerialPortLib
lineChart.clear();
用于清除所有数据。
参考: https://blog.csdn.net/qq_44720366/article/details/104816512
参考: 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
需要在指定列中搜索所有包含 "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"});
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
/**
* @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
遇到的坑:
先看效果图:
<?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>
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(getApplicationContext());
}
}
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));//模拟数组越界
}
});
}
}
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);
}
}
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;
}
}
在 app/build.gradle
的 android
闭包之外增加:
def generateTime() {
return new Date().format("yyyy_MM_dd_HH_mm_ss")
}
在 app/build.gradle
的 android
包中增加:
android {
defaultConfig {
...
}
// 自定义打包名称
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${applicationId}_${buildType.name}_v${versionName}_${generateTime()}.apk"
}
}
buildTypes {
...
}
源码里面如果需要用到app/build.gradle
的版本号,可以使用下面这个:
public static final String VERSION = BuildConfig.VERSION_NAME;
Android Studio 打包APK(详细版)
https://blog.csdn.net/qq_38436214/article/details/112288954