使用AndroidStudio自带模拟器挂载串口不能接收超过8字节的数据
注:使用AndroidStudio自带的模拟器,发送8字节以内的数据是ok的,一旦超过8字节模拟器就会挂掉,后来使用了Genymotion模拟器,这个问题就没有了。
使用AndroidStudio自带模拟器挂载串口不能接收超过8字节的数据
注:使用AndroidStudio自带的模拟器,发送8字节以内的数据是ok的,一旦超过8字节模拟器就会挂掉,后来使用了Genymotion模拟器,这个问题就没有了。
1.下载工具包
2.解压工具包到D盘根目录
3.打开雷电模拟器,执行Shell命令
adb remount / adb push D:\xposed /system adb shell cd /system/xposed chmod 777 script.sh sh script.sh
4.安装成功
************************** Xposed framework installer ************************** - Checking environment Xposed version: 89 - Placing files cp: bad 'system/priv-app/XposedInstaller/XposedInstaller.apk': No such file or directory chmod: /system/priv-app/XposedInstaller/XposedInstaller.apk: No such file or directory chcon: /system/priv-app/XposedInstaller/XposedInstaller.apk: No such file or directory - Done ```
参考链接:
雷电模拟器4.0(android 7.1 x86_64) xposed安装
雷电安卓模拟器解决Could not load available ZIP files.Pull down to try again问题
转载自:android 分享文件功能实现
1.添加依赖
// Excel implementation 'org.apache.poi:poi:3.17' implementation 'org.apache.poi:poi-ooxml:3.17' implementation 'org.apache.xmlbeans:xmlbeans:3.1.0' implementation 'stax:stax:1.2.0' implementation 'com.alibaba:easyexcel:2.2.10'
2.实现一个简单的java.awt.Color类 继续阅读Android使用EasyExcel操作Excel
导出整个数据库
sqlite3 main.db .dump > main.sql
导出一张表
sqlite3 main.db ".dump table" > table.sql
导入
sqlite3 main.db < main.sql
原理:搞定Gson泛型封装
首先,推荐大家用一下 AndroidUtilCode,是一个很好用的工具类库。
如果你已经使用上面提到的工具类库,可以这样用:
import com.blankj.utilcode.util.GsonUtils; GsonUtils.getListType(clazz)
如果没使用的话,可以这样用:
import com.google.gson.reflect.TypeToken; TypeToken.getParameterized(List.class, clazz).getType();
import android.content.Context;
import android.os.storage.StorageManager;
import java.lang.reflect.Method;
public class USBUtil {
public static String getUSBPath(Context context) {
StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
try {
// 通过反射调用getVolumeList,获取所有挂载的设备(内部sd卡、外部sd卡、挂载的U盘)
Method getVolumeListMethod = StorageManager.class.getMethod("getVolumeList");
Object[] volumes = (Object[]) getVolumeListMethod.invoke(storageManager);
Class<?> storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
// 通过反射调用getPath、isRemovable
Method getPathMethod = storageVolumeClazz.getMethod("getPath");
Method isRemovableMethod = storageVolumeClazz.getMethod("isRemovable");
if (volumes != null && volumes.length > 0) {
for (Object volume : volumes) {
String path = (String) getPathMethod.invoke(volume); // 获取路径
boolean isRemovable = (boolean) isRemovableMethod.invoke(volume);// 是否可移除
if (isRemovable) {
return path;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return "/";
}
}
参考链接:
获取Android设备上的所有存储设备
首先,笔者的主Activity中包含了多个Fragment,通过show、hide来切换展示。当笔者切换到其他的APP,操作一段时间后,返回到当前APP,有很大几率会出现Fragment重叠现象。
首先,在Activity的生命周期中,当Activity不在前台展示时,如果此时其他的APP需要使用内存,系统会杀掉该APP的进程,当用户重新进入该APP时,系统会重新创建Activity。
Activity不在前台展示时会保存Fragment的状态,当系统重新创建Activity时会恢复之前保存的Fragment的状态。
方案一:在Activity的onCreate方法中判断savedInstanceState是否为空,不为空则使用系统保存的Fragment。
public class MainActivity extends AppCompatActivity {
Fragment fragment;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
fragment = getSupportFragmentManager().findFragmentByTag("fragment");
} else {
fragment = new Fragment();
getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, fragment, "fragment").commit();
}
}
}
方案二:在Activity的onCreate方法中,调用super方法时直接传null,不使用保存的状态。
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(null);
}
参考资料:
Android fragment 重叠问题——通过hide,show方式导致的解决方法
Android使用TouchDelegate增加View的触摸范围
ListView Tips & Tricks #5: Enlarged Touchable Areas
TouchDelegateGroup
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.TouchDelegate;
import android.view.View;
import androidx.annotation.NonNull;
import java.util.ArrayList;
public class TouchDelegateGroup extends TouchDelegate {
private ArrayList<TouchDelegate> mTouchDelegates = new ArrayList<>();
private TouchDelegate mCurrentTouchDelegate;
public TouchDelegateGroup(@NonNull Rect bounds, @NonNull View delegateView) {
super(bounds, delegateView);
mTouchDelegates.add(this);
}
public void addTouchDelegate(@NonNull TouchDelegate touchDelegate) {
mTouchDelegates.add(touchDelegate);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
TouchDelegate delegate = null;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
for (TouchDelegate touchDelegate : mTouchDelegates) {
if (onDelegateTouchEvent(touchDelegate, event)) {
mCurrentTouchDelegate = touchDelegate;
return true;
}
}
break;
case MotionEvent.ACTION_MOVE:
delegate = mCurrentTouchDelegate;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
delegate = mCurrentTouchDelegate;
mCurrentTouchDelegate = null;
break;
}
if (delegate != null) {
return onDelegateTouchEvent(delegate, event);
}
return false;
}
public boolean onSelfTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
public boolean onDelegateTouchEvent(TouchDelegate touchDelegate, MotionEvent event) {
if (touchDelegate instanceof TouchDelegateGroup) {
return ((TouchDelegateGroup) touchDelegate).onSelfTouchEvent(event);
} else {
return touchDelegate.onTouchEvent(event);
}
}
}