使用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); } } }