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
Android 倒计时CountDownTimer
https://www.jianshu.com/p/b91ac97930db
android之几种定时器实现
https://blog.csdn.net/generallizhong/article/details/100662373
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
在 AndroidManifest.xml
中如下增加 android:sharedUserId="android.uid.system
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.example"
android:sharedUserId="android.uid.system">
注意编译后,会报错提示不能安装,这个没关系。系统 app 是需要后来放到 aosp 中去的。 具体方法,见读取 imei 的文章。
Android普通应用升级为系统应用,获取系统权限
https://blog.csdn.net/weixin_42484608/article/details/83028528
android 系统级别应用
https://blog.csdn.net/jinmv/article/details/44646277
修改安卓系统应用,将自己的app变成系统应用
https://blog.csdn.net/u012930316/article/details/100740399
秒懂Android开发之权限总结
https://zhuanlan.zhihu.com/p/158899172
Android app获取系统权限
https://blog.csdn.net/VSRfind/article/details/79648281
硬件电路里面按键时高电平有效,从 getevent -l
这边看,kernel 上报时没有问题的,只是up 和 down 反过来而已,有一下,就发一条信息。但是在 app 里面就不一样了,每当 app 的界面出现前后台切换的时候,会对所有的按键进行刷新,导致出现一直刷新按键事件的情况。
直接修改按键本身比较困难,最简单方法是新建一个驱动文件,专门针对这个高电平有效按键即可。
//#define DEBUG
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/err.h>
#include <linux/sched.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/pinctrl/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/power_supply.h>
#include <linux/uaccess.h>
#include <linux/kdev_t.h>
#include <linux/device.h>
#include <linux/wait.h>
static struct class *gpio_reverse_key_class;
struct gpio_reverse_key_detect {
struct device *dev;
struct input_dev *p_inputdev;
unsigned int gpio_reverse_key_gpio;
unsigned int gpio_reverse_key_irq_num;
struct workqueue_struct *gpio_reverse_key_detect_wq;
struct delayed_work gpio_work;
atomic_t state;
unsigned int code;
};
static int reverse_key_count = 0;
static void gpio_reverse_key_detect_work_func(struct work_struct *work){
struct gpio_reverse_key_detect *dev_struct;
int old_state, new_state;
printk("gpio_reverse_key_detect in work func\n");
dev_struct = container_of(work, struct gpio_reverse_key_detect, gpio_work.work);
reverse_key_count = 0;
old_state = atomic_read(&dev_struct->state);
new_state = gpio_get_value(dev_struct->gpio_reverse_key_gpio);
if (new_state < 0) {
dev_err(dev_struct->dev,
"failed to get qrcode-gpio state: %d\n", new_state);
return;
}
if(new_state != old_state){
dev_err(dev_struct->dev, "qrcode_detect update state %d", new_state);
atomic_set(&dev_struct->state, new_state);
input_report_key(dev_struct->p_inputdev, dev_struct->code, new_state);
input_sync(dev_struct->p_inputdev);
}
printk("gpio_reverse_key_detect repot the key %d, value %d\n", dev_struct->code, new_state);
enable_irq(dev_struct->gpio_reverse_key_irq_num);
printk("gpio_reverse_key_detect enable irq");
}
static irqreturn_t gpio_reverse_key_detect_func(int irq, void *dev_id){
struct gpio_reverse_key_detect * dev_struct = dev_id;
printk("gpio_reverse_key_detect in irq func\n");
disable_irq_nosync(dev_struct->gpio_reverse_key_irq_num);
//printk("gpio_reverse_key_detect disable irq\n");
if(!reverse_key_count){
schedule_delayed_work(&dev_struct->gpio_work,msecs_to_jiffies(20));
reverse_key_count = 1;
}else{
cancel_delayed_work(&dev_struct->gpio_work);
schedule_delayed_work(&dev_struct->gpio_work,msecs_to_jiffies(20));
//queue_work(dev_struct->gpio_reverse_key_detect_wq, &dev_struct->work);
//printk("gpio_reverse_key_detect queue work ok\n");
}
return IRQ_HANDLED;
}
static int gpio_reverse_key_detect_input_set(struct gpio_reverse_key_detect *dev_struct){
int ret;
printk("gpio_reverse_key_detect input set begin\n");
dev_struct->p_inputdev = input_allocate_device();
if (dev_struct->p_inputdev == NULL) {
printk("Failed to allocate input device.\n");
return -1;
}
__set_bit(EV_KEY, dev_struct->p_inputdev->evbit);
dev_struct->p_inputdev->name = "gpio_reverse_key_detect_input";
//__set_bit(KEY_VOLUMEDOWN, dev_struct->p_inputdev->keybit);
__set_bit(dev_struct->code, dev_struct->p_inputdev->keybit);
printk("gpio_reverse_key_detect input set bit %d\n", dev_struct->code);
input_set_drvdata(dev_struct->p_inputdev, dev_struct);
ret = input_register_device(dev_struct->p_inputdev);
if (ret) {
printk( "Register %s input device failed.\n",dev_struct->p_inputdev->name);
// goto exit_free_inputdev;
}
printk("gpio_reverse_key_detect input set successd \n");
return 0;
}
static int gpio_reverse_key_detect_probe(struct platform_device *pdev){
struct gpio_reverse_key_detect *dev_struct;
int ret;
int state;
printk("gpio_reverse_key_detect probe begin\n");
dev_struct = devm_kzalloc(&pdev->dev,sizeof(struct gpio_reverse_key_detect) , GFP_KERNEL);
dev_struct->dev = &pdev->dev;
dev_struct->gpio_reverse_key_gpio = of_get_named_gpio(dev_struct->dev->of_node, "gpio_reverse_key_gpio", 0);
gpio_request(dev_struct->gpio_reverse_key_gpio, "gpio_reverse_key_gpio");
dev_struct->gpio_reverse_key_irq_num = gpio_to_irq(dev_struct->gpio_reverse_key_gpio);
gpio_direction_input(dev_struct->gpio_reverse_key_gpio);
if(of_property_read_u32(dev_struct->dev->of_node, "linux,code", &dev_struct->code)) {
dev_err(dev_struct->dev, "fail to get linux code\n");
return (-EINVAL);
}
printk("gpio_reverse_key_detect probe get key code %d\n", dev_struct->code);
gpio_reverse_key_detect_input_set(dev_struct);
dev_struct->gpio_reverse_key_detect_wq = create_singlethread_workqueue("gpio_reverse_key_detect_wq");
INIT_DELAYED_WORK(&dev_struct->gpio_work, gpio_reverse_key_detect_work_func);
state = gpio_get_value(dev_struct->gpio_reverse_key_gpio);
if(state < 0) {
dev_err(dev_struct->dev, "fail to init base_detect state %d\n", state);
return (-EINVAL);
}
atomic_set(&dev_struct->state, state);
ret = devm_request_threaded_irq(&pdev->dev, dev_struct->gpio_reverse_key_irq_num, (irq_handler_t)gpio_reverse_key_detect_func, NULL, IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING | IRQF_ONESHOT, "gpio_reverse_key_detect", dev_struct);
if (ret) {
printk("quectel sc20 %s create gpio_reverse_key_class err\n", __func__);
return ret;
}
printk("gpio_reverse_key_detect probe end\n");
return 0;
}
static struct of_device_id of_device_sc20_gpio_match_table[] =
{
{.compatible = "quectel,gpio_reverse_key_detect"},
{},
};
int gpio_reverse_key_detect_remove(struct platform_device *pdev)
{
int ret = 0;
// struct = NULL;
// sc20_gpio_dev = (struct sc20_gpio_device *)dev_get_drvdata(&pdev->dev);
// if(sc20_gpio_dev)
// kfree(sc20_gpio_dev);
printk("quectel sc20 %s enter\n", __func__);
return ret;
}
static struct platform_driver gpio_reverse_key_platform_driver =
{
.probe = gpio_reverse_key_detect_probe,
.remove = gpio_reverse_key_detect_remove,
.driver =
{
.name = "GPIO_REVERSE_KEY",
.owner = THIS_MODULE,
.of_match_table = of_device_sc20_gpio_match_table,
}
};
static int __init gpio_reverse_key_detect_init(void)
{
int ret = 0;
printk("quectel sc20 %s enter\n", __func__);
gpio_reverse_key_class = class_create(THIS_MODULE, "gpio_reverse_key_detect");
if (IS_ERR(gpio_reverse_key_class))
{
printk("quectel sc20 %s create gpio_reverse_key_class err\n", __func__);
return PTR_ERR(gpio_reverse_key_class);
}
// sc20_gpio_class->dev_attrs = sc20_gpio_class_attrs;
printk("quectel sc20 %s create gpio_reverse_key_class success\n", __func__);
ret = platform_driver_register(&gpio_reverse_key_platform_driver);
return ret;
}
module_init(gpio_reverse_key_detect_init);
static void __exit gpio_reverse_key_detect_exit(void)
{
printk("quectel sc20 %s enter\n", __func__);
}
module_exit(gpio_reverse_key_detect_exit);
mODULE_DESCRIPTION("QUCTEL sc20 GPIOS_REVERSE_KEY");
mODULE_LICENSE("GPL v2");
按键响应onKeyDown,onKeyLongPress,onKeyUp
https://www.jianshu.com/p/83a1dd9db896
onKeyPress Vs. onKeyUp and onKeyDown
https://stackoverflow.com/questions/3396754/onkeypress-vs-onkeyup-and-onkeydown#:~:text=The%20onKeyDown%20event%20is%20triggered%20when%20the%20user,%26%20releases%20a%20key%20%28onKeyDown%20followed%20by%20onKeyUp%29.
onkeyup、onkeydown和onkeypress的区别
https://blog.csdn.net/czh500/article/details/80330207
安卓onkeyup onkeydown事件小记
https://blog.csdn.net/sjpz0124/article/details/50619524#:~:text=android%20Activity%E7%B1%BB%20onKeyUp%20%28%29%2C%20onKeyDown,%E7%95%A5%E8%AF%BB%20Activity.%20onKeyDown%20%28%29%3B%20%E5%BD%93%E6%9F%90%E4%B8%AA%E9%94%AE%E8%A2%AB%E6%8C%89%E4%B8%8B%E6%97%B6%E4%BC%9A%E8%A7%A6%E5%8F%91%EF%BC%8C%E4%BD%86%E4%B8%8D%E4%BC%9A%E8%A2%AB%E4%BB%BB%E4%BD%95%E7%9A%84%E8%AF%A5Activity%E5%86%85%E7%9A%84%E4%BB%BB%E4%BD%95view%E5%A4%84%E7%90%86%E3%80%82
Android使用adb抓完整Log
https://blog.csdn.net/wzy_1988/article/details/42233611
adb logcat说明
https://blog.csdn.net/jasonactions/article/details/108683379
Android使用adb抓完整Log
https://blog.csdn.net/wzy_1988/article/details/42233611
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
需要在 xml 文件中增加 system 相关设置,编译的时候,会有红字提示不能安装,这个提示不用管。
\项目名\app\build\outputs\apk\debug\app_debug.apk
packages/apps/
下新建一个文件夹 GetImei
android.mk
拷入as 编译的 app_debug.apk
,改名为 GetImei.apk
\device\qcom\common\base.mk
中添加一行 PRODUCT_PACKAGES += GetImei
source build/envsetup.sh
lunch
(选择项目)
mmm packages/apps/GetImei/
拿到 \out\target\product\msm8937_32\system\app\GetImei\GetImei.apk
root remount
:adb root
adb disable-verity
adb reboot
adb root
adb remount
adb shell
#mkdir system/app/GetImei
#chmod 777 system/app/GetImei
#exit
adb push D:\GetImei.apk system/app/GetImei/
adb shell
#chmod 777 system/app/GetImei/GetImei.apk
#reboot
RK3399 Android7.1系统 自定义号码CMEI信息写入vendor_storage
https://blog.csdn.net/yafeixi/article/details/95626903
[RK3399][Android7.1] Vendor Storage区域知识及探讨
https://blog.csdn.net/kris_fei/article/details/79580845
quickstep
或者 其他想要的 app.launcher
.这个网上有很多,修改 xml 文件。
Launcher安卓手机桌面怎么切换 Launcher手机桌面切换方法
https://product.pconline.com.cn/itbk/sjtx/sjwt/1711/10278395.html
Android 6.0替换原系统Launcher傻瓜教程
https://blog.csdn.net/kkle1994/article/details/85338328