Android卸载反馈

UninstallFeedback, 卸载apk时显示反馈页面.zip UninstallFeedback, 卸载apk时显示反馈页面 UninstallFeedback既然 Java 实现不了,那就得考虑下其他的了,自然最先想到的就是 JNI 了,可惜 C的部分不懂,上网搜了很多资料和介绍,找得到可以通过一下方式实现: pid_t fpid = fork() 立即下载

Android卸载反馈

最初记得是在360安全卫士中出现的,在手机上卸载他的应用之后浏览器就会弹出一个反馈页面,让用户进行反馈,感觉这种功能对于产品改进特别有帮助。
但是仔细一想该怎么去实现却犯愁了,最开始想这也简单啊,不就是监听下自身被卸载就可以了,应该系统会有卸载的广播,可惜没有。甚至其他的一些
方法也是不行的,因为你程序都被卸载了,你的代码怎么会执行呢?皮之不存,毛将焉附。那360是怎样实现的呢?说句真心话360做的产品还是非常有创新
的,虽然有些时候他会损坏用户的利益,不过但从技术方面,着实让人信服。

既然Java实现不了,那就得考虑下其他的了,自然最先想到的就是JNI了,可惜C的部分不懂,上网搜了很多资料和介绍,找得到可以通过一下方式实现:
- 通过c中的fork方法来复制一个子进程。复制出来的子进程在父进程被销毁后,仍然可以存在。
pid_t fpid = fork()被调用前,就一个进程执行该段代码,这条语句执行之后,就会有两个进程执行该代码,两个进程执行没有固定先后顺序,只要看
系统调度策略,fork()函数的特别之处在于调用一次会返回两次结果:
- 返回值大于0,当前是父进程。
- 返回0,当前是子进程。
- 返回小于0的负值。(出错了,可能是内存不足或者是进程数已经达到系统最大值)

  • fork出子进程后让子进程一直去监听/data/data/packageName是否存在,如果不存在了,那就说明程序被卸载了,但是这样一直去轮训判断肯定会浪费
    系统资源的,当然也会更加费电,对用户来讲肯定是有损害的。所以这种技术最好也不好用,不然大家的手机以后还能了得。万恶的产品。

  • 得到程序被卸载之后弹出浏览器打开指定反馈页面。这就要用到am命令了,最早知道这个命令是在开发TV版的时候,遥控器找不到了,程序安装后无法
    打开了,用该命令就不怕了,哈哈。但是在c中怎么执行am命令呢?这就要用到execlp()函数,该函数就是c中执行系统命令的函数。

好了,主要的内容上面都分析完了,下面上代码。

  • Java层定义natvie方法。
public class MainActivity extends Activity {
    private static final String TAG = "@@@";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String packageDir = "/data/data/" + getPackageName();
        initUninstallFeedback(packageDir, Build.VERSION.SDK_INT);
    }

    private native void initUninstallFeedback(String packagePath, int sdkVersion);

    static {
        System.loadLibrary("uninstall_feedback");
    }
}
  • 创建jni目录,增加Android.mk以及uninstall_feedback.c文件。
    Android.mk的内容:
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := uninstall_feedback
LOCAL_SRC_FILES := uninstall_feedback.c

LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog

include $(BUILD_SHARED_LIBRARY)

uninstall_feedback.c的实现:

/**
 * 将Java中的String转换成c中的char字符串
 */
char* Jstring2CStr(JNIEnv* env, jstring jstr) {
    char* rtn = NULL;
    jclass clsstring = (*env)->FindClass(env, "java/lang/String"); //String
    jstring strencode = (*env)->NewStringUTF(env, "GB2312"); // 得到一个java字符串 "GB2312"
    jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes",
            "(Ljava/lang/String;)[B"); //[ String.getBytes("gb2312");
    jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid,
            strencode); // String .getByte("GB2312");
    jsize alen = (*env)->GetArrayLength(env, barr); // byte数组的长度
    jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
    if (alen > 0) {
        rtn = (char*) malloc(alen + 1); //""
        memcpy(rtn, ba, alen);
        rtn[alen] = 0;
    }
    (*env)->ReleaseByteArrayElements(env, barr, ba, 0); //
    return rtn;
}

void Java_com_charon_uninstallfeedback_MainActivity_initUninstallFeedback(
        JNIEnv* env, jobject thiz, jstring packageDir, jint sdkVersion) {

    char * pd = Jstring2CStr(env, packageDir);

    //fork子进程,以执行轮询任务
    pid_t pid = fork();

    if (pid < 0) {
        // fork失败了
    } else if (pid == 0) {
        // 可以一直采用一直判断文件是否存在的方式去判断,但是这样效率稍低,下面使用监听的方式,死循环,每个一秒判断一次,这样太浪费资源了。
        int check = 1;
        while (check) {
            FILE* file = fopen(pd, "rt");
            if (file == NULL) {
                if (sdkVersion >= 17) {
                    // Android4.2系统之后支持多用户操作,所以得指定用户
                    execlp("am", "am", "start", "--user", "0", "-a",
                            "android.intent.action.VIEW", "-d",
                            "http://shouji.360.cn/web/uninstall/uninstall.html",
                            (char*) NULL);
                } else {
                    // Android4.2以前的版本无需指定用户
                    execlp("am", "am", "start", "-a",
                        "android.intent.action.VIEW", "-d",
                            "http://shouji.360.cn/web/uninstall/uninstall.html",
                            (char*) NULL);
                }
                check = 0;
            } else {
            }
            sleep(1);
        }
    } else {
    }
}
  • 编译so文件。Windows下要用cygwin来操作。
    上面的介绍是在Eclipse中进行的,用ndk-build命令来编译so。具体请看之前写的JNI基础这篇文章。

源码请见Github

有关如何在Android Stuido中进行ndk开发请看另一篇文章。


android-uninstall-feedback:当Android的APP被卸载的时候打开浏览器或者发送一个其他的Action来进行反馈 android-uninstall-feedback 当Android的APP被卸载的时候打开浏览器或者发送一个其他的Action来进行反馈 立即下载

相关推荐

Android-uninstall-feedback:卸载APK,跳转到反馈页面

uninstallFeedback 卸载APK,跳转到反馈页面。 原理:在c层fork一个进程,监听data/data/包名/lib目录。 注:在华为机型上,如果在java端中直接fork这个c进程,且java端退出调用了system.exit方法,则会出现黑屏崩溃问题。 所以,把这个native调用放在remote service中。在需要监听的项目中,启动一个远程服务,这个远程服务只做一个任务:调用c层代码来fork监听进程。 在C层写了一个Kill方法,在JAVA层调用,可以用来结束C层的监听进程,实现原理:将fork出来的监听进程的pid存在data/data/包名/files/中的uninstall文件中, 当需要结束C层监听进程的时候,读取该文件,获取到pid值,再调用linux中的kill函数结束进程。 ####2015-03-05新增 #####1.增加防止误操作处理 ##

IDEA2017.2.6卸载方法(其它版本类似)

1.找到要卸载的IDEA的快捷键,右键---打开文件位置,此时打开IDEA的bin目录,往下翻找到Uninstall文件,双击,即可打开卸载界面。 2.选择是否删除原有配置。建议保留,这样新版本就可以导入旧版本配置。(Unistall Feedback:卸载反馈) 3.等待卸载完成。 4.卸载完毕,完成卸载。 ...

优快云_LeBin的博客 9840

android卸载弹出反馈界面

该资源包含了一个实现了android app卸载以后弹出反馈界面给用户,具体的可以参考博客http://blog.youkuaiyun.com/mockingbirds/article/details/46594107

Android卸载程序之后跳转到指定的反馈页面

今天去面试,一面还可以,到了第二面的时候也差不多吧,最后来了一题,说那个360被卸载之后会跳转到指定的反馈页面,是怎么弄的?这个之前没有研究过,但是这个效果是见过的。当时想到了,Android中卸载应用的时候会发送一个广播,我们可以接收到这个广播,然后处理一下。结果他来个反问句:这样可以吗?然后仔细想想,既然他这么问了,应该是有问题,在想想,发现的确是有问题,当应用被卸载了,那个接收到广播处理之后...

modabobo 278

Android App监听自身卸载反馈统计

作者venshine,源码AppUninstall,方案监听系统卸载广播:只能监听到其他应用的卸载广播,无法监听到自己是否被卸载。读取系统 log:第三方软件卸载无法得知。静默安装另一个程序,监听自己是否被卸载:需要 root 权限。Java 线程轮询,监听/data/data/{package-name}目录是否存在:卸载 app,进程退出,线程也被销毁。C 进程轮询,监听/data/data/{package-name}目录是否存在:目前业界普遍采用的方案。原理从前四种方案可以看到,单纯的 Java 层代码是无法监听自身卸载的。既然 Java 层无法实现,我们试着使用 C 语言在底层实现。借助 Linux 进程 fork 出来的 C 进程在应用被卸载后不会被销毁,监听/data/data/{package-name}目录是否存在,如果不存在,就证明应用被卸载了。本程序采用第 5 种解决方案,对其进行优化,通过 linux 中的inotify机制来监听应用的卸载。实现fork()子进程创建监听文件初始化 inotify 实例注册监听事件调用 read 函数开始监听卸载反馈统计场景正常卸载断网卸载清除数据(5.0 以上不支持)kill 进程(5.0 以上不支持)插拔 USB 线覆盖安装内部存储移到 SD 卡开机监听(官方不推荐)打开浏览器(5.0 以上部分机型无法开启)

详解Android App卸载后跳转到指定的反馈页面的方法

主要介绍了Android App卸载后跳转到指定的反馈页面的方法,关键点是相关线程要判断在目录被消除以前作出响应,需要的朋友可以参考下

Android应用如何监听自己是否被卸载及卸载反馈功能的实现

1、Android应用如何监听自己是否被卸载及卸载反馈功能的实现   一个应用被用户卸载肯定是有理由的,而开发者却未必能得知这一重要的理由,毕竟用户很少会主动反馈建议,多半就是用得不爽就卸,如果能在被卸载后获取到用户的一些反馈,那对开发者进一步改进应用是非常有利的。目前据我所知,国内的Android应用中实现这一功能的只有360手机卫士、360平板卫士,那么如何实现这一功能的?  

键盘的起始页 1787

Shader之——花草动画shader

今天 ,接到了个需求,花草的动画。谈到花草动画,立马就想到顶点动画,让顶点动起来就可以实现了。但是有个问题,所有的草都往一个方向运动,这个就麻烦了。因为在shader里没有随机这种概念,提到最多的是用一张噪声图来模拟。在网上搜索了一下,发现有更好的办法,就是用每个顶点到一个点的距离来控制动画的开始,毕竟每个顶点到同一个点的距离很少是一样的。 float dis = distance ...

baicaishisan的博客 2186

Android 如何实现应用卸载反馈,卸载监控

市面上有很多Android 的App在卸载之后会弹出一个反馈页面,让用户填写卸载原因,收集用户的卸载反馈。这是怎么实现的呢?应用自身已经被卸载了,怎么还能弹出一个反馈页面呢 ? 首先,可以排除的是BroadCastReceiver,因为应用已经被卸载了,BroadCastReceiver是不可能有机会接收到卸载消息的。 所以肯定是有一个后台在监控,那么会是android service吗?肯定

我的专栏 6021

CentOS 7环境下GLPI与OCS Inventory资产管理系统集成部署指南

本文详细介绍了在CentOS 7环境下,如何将GLPI与OCS Inventory两大开源工具进行集成部署,构建自动化资产管理系统。指南涵盖环境准备、核心服务安装、Web界面初始化、OCS插件配置及资产同步实战,帮助运维人员实现IT资产的自动发现、统一管理与可视化,大幅提升资产管理效率。

weixin_29274337的博客 329

第一章 初识SpringBoot

提供大量的自动配置Spring和第三方库,开发者可以根据项目需求选择相关的starters依赖,而无需手动配置大量的Spring配置文件,开箱即用,无需配置XML,无代码生成。Spring Boot与Spring Cloud等框架集成,为构建微服务提供了强大的支持,并通过Spring Cloud实现服务注册、负载均衡、熔断等功能。本质上讲,Spring Boot就是Spring,它做了那些本应我们去做的Spring Bean配置等工作。以上就是一个简单的Spring Boot应用的创建和运行过程。

Calvin的博客 1581

android 卸载弹出窗口,android app卸载以后弹出用户反馈界面

在android app开发中,有的时候会有这样的需求,就是当用户卸载了我们的app的时候,如果可以搜集用户的反馈信息,那样是极好的,今天带大家手把手实现这样的功能,先说下原理:我们的app在安装的时候会在/data/data/报名,下生成这样的文件夹,一旦我们的应用被卸载,那么该文件夹同样会被移除,因此,我们可以通过利用底层c代码不断地查询该文件夹是否来存在,来判断app是否被卸载。声明nati...

weixin_39795116的博客 633

从数据集到产品:聊聊Room-to-Room (R2R) 如何影响扫地机器人、AR导航的未来

本文探讨了Room-to-Room (R2R) 数据集如何推动视觉与语言导航(VLN)技术的发展,并重塑扫地机器人和AR导航的未来。通过分析R2R基于Matterport3D的设计及其在真实场景中的应用,揭示了其在提升智能导航精度和自然语言交互能力方面的潜力。文章还讨论了从实验室到产品化的关键技术挑战与解决方案。

weixin_29084231的博客 143

android app卸载以后弹出用户反馈界面

在android app开发中,有的时候会有这样的需求,就是当用户卸载了我们的app的时候,如果可以搜集用户的反馈信息,那样是极好的,今天带大家手把手实现这样的功能,先说下原理:我们的app在安装的时候会在/data/data/报名,下生成这样的文件夹,一旦我们的应用被卸载,那么该文件夹同样会被移除,因此,我们可以通过利用底层c代码不断地查询该文件夹是否来存在,来判断app是否被卸载。声明nativ

mockingbirds的专栏 4329

UG NX二次开发(C#)-读取PMI对象的名称

摘要:本文介绍了在UG NX中通过NXOpen获取PMI对象名称的方法。首先说明PMI对象初始无名称,可通过重命名或属性设置名称。然后提供C#代码示例,展示如何遍历PMI集合获取对象名称,并显示名称和类型信息。适用于需要操作PMI对象的开发人员,欢迎加入技术交流QQ群749492565。(99字)

GimiGimmy 592

171、运动控制中的标定:摩擦力与死区补偿标定

摘要(149字) 运动控制系统中的摩擦力与死区补偿是提升精度的关键。摩擦力分为静摩擦、库仑摩擦和粘滞摩擦,其中Stribeck效应是低速抖动的主因;死区则表现为控制信号的无效区间。有效标定方法包括恒速测试(摩擦力)和斜坡响应法(死区)。补偿策略需采用分段前馈和动态调整,避免过度补偿导致振荡。实践中要注意机械状态检查、补偿量限幅,并定期重新标定。硬件升级配合算法补偿才能实现最优控制,标定工作应优先于PID参数调整。

m0_50546716的博客 231

《利用UninstallFeedback提升Android应用卸载反馈效率》

《利用UninstallFeedback提升Android应用卸载反馈效率》 UninstallFeedbackShow feedback page when the apk is uninstalled.项目地址:https://gitcode.com/gh_mirrors/un/UninstallFeedback 在软件开发中,尤其是对于Android应用开发者而言,了解用户为何卸载应用是优...

gitblog_00061的博客 550

DeepSeek 赋能招投标全流程智能化:多模态解析、知识图谱与投标文件自动生成实战指南(附完整代码与行业案例)

摘要:本文深入探讨DeepSeek技术在招投标领域的全流程智能化应用,通过整合自然语言处理(NLP)、多模态解析、知识图谱等核心技术,实现招标文件智能解析与投标文件自动生成。文中详细解析DeepSeek-R1模型的多模态处理机制、动态知识图谱构建方法及智能模板填充算法,通过完整代码实现展示技术细节。结合广某资源交易平台、山西XX"XX云"等典型案例,验证技术方案在提升招投标效率、降低人为错误方面的显著效果。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1464

Android使用分叉子进程来实现卸载后打开反馈网页

前言 我们的app有的时候难免会有很多问题,导致用户卸载掉我们的app。而我们作为开发者需要采集用户卸载的原因,来更好的完善我们的app,所以需要在用户卸载后弹出我们的反馈页面,让用户把自己不满意的地方反馈给我们。 本文为ndk学习文章,经本人对4.4,5.1,6.0,7.1的版本测试,该功能仅适用于低版本的Android设备,高版本中子进程会连带父进程一起被杀死,所以仅供学习。 效果 原理解析...

Ricador_Tuan的博客 321

Java 大视界 -- 基于 Java+Flink 构建实时电商交易风控系统实战(436)

本文介绍基于Java+Flink构建实时电商交易风控系统的实战经验。系统采用分层架构设计,包含数据采集层、实时计算层、规则引擎层、数据存储层和应用服务层,实现毫秒级风险识别与拦截。核心组件包括Flink 1.17处理交易数据流、Drools规则引擎动态匹配风险规则、Redis缓存热点数据等。文章详细提供了开发环境配置清单和Maven依赖说明,确保系统具备低延迟(≤200ms)、高吞吐(10万TPS)和高可用性(99.99%)特性。该方案已通过生产环境验证,可有效应对恶意刷单、盗刷支付等电商交易风险。

【青云交】华为云云享专家 | 阿里云开发者社区专家博主 技术圈个人影响力前 9 | 博客之星 TOP12 优快云 首位四榜(原力榜 / 作者周榜 / 领军人物 / 综合热榜)榜首,破平台纪录! 苏州地区全榜霸榜,感恩全网十多万粉丝同行! 3943

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Android监听自身被卸载与反馈

使用

ljtyzhr的专栏 1002

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

上一篇: ListView实现分析
下一篇: AndroidStudio使用教程(第七弹)
CharonChui
博客等级 码龄12年 66粉丝 134原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值