Android 監聽應用卸載

[cpp]  

最近再考慮一個問題,就是監聽應用卸載,在卸載360的時候彈出瞭一個360的網址,很好奇怎麼實現的試瞭好幾種方式再Service實時監聽log日志,廣播都不行,因為卸載瞭應用程序Service就被停止瞭。後來再Stackoverflow上面找到瞭答案,通過底層監聽應用目錄的變化來實現,下面說說具體得實現方式。  

[cpp]  

[cpp]  

/* 

 * Copyright (C) 2009 The Android Open Source Project 

 * 

 * Licensed under the Apache License, Version 2.0 (the "License"); 

 * you may not use this file except in compliance with the License. 

 * You may obtain a copy of the License at 

 * 

 *      https://www.apache.org/licenses/LICENSE-2.0 

 * 

 * Unless required by applicable law or agreed to in writing, software 

 * distributed under the License is distributed on an "AS IS" BASIS, 

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

 * See the License for the specific language governing permissions and 

 * limitations under the License. 

 * 

 */  

#include <string.h>  

#include <jni.h>  

  

#include <jni.h>  

#include <stdio.h>  

#include <stdlib.h>  

#include <string.h>  

#include <android/log.h>  

#include <unistd.h>  

#include <sys/inotify.h>  

  

/* 宏定義begin */  

//清0宏  

#define MEM_ZERO(pDest, destSize) memset(pDest, 0, destSize)  

  

//LOG宏定義  

#define LOG_INFO(tag, msg) __android_log_write(ANDROID_LOG_INFO, tag, msg)  

#define LOG_DEBUG(tag, msg) __android_log_write(ANDROID_LOG_DEBUG, tag, msg)  

#define LOG_WARN(tag, msg) __android_log_write(ANDROID_LOG_WARN, tag, msg)  

#define LOG_ERROR(tag, msg) __android_log_write(ANDROID_LOG_ERROR, tag, msg)  

  

  

/* 內全局變量begin */  

static char c_TAG[] = "onEvent";  

static jboolean b_IS_COPY = JNI_TRUE;  

  

jstring  

Java_com_example_untitled_MyActivity_init( JNIEnv* env,  

                                                 jobject thiz )  

{  

    jstring tag = (*env)->NewStringUTF(env, c_TAG);  

  

    //初始化log  

    LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY)  

            , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "init OK"), &b_IS_COPY));  

  

    //fork子進程,以執行輪詢任務  

    pid_t pid = fork();  

    if (pid < 0)  

    {  

        //出錯log  

        LOG_ERROR((*env)->GetStringUTFChars(env, tag, &b_IS_COPY)  

                , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "fork failed !!!"), &b_IS_COPY));  

    }  

    else if (pid == 0)  

    {  

        //子進程註冊"/data/data/pym.test.uninstalledobserver"目錄監聽器  

        int fileDescriptor = inotify_init();  

        if (fileDescriptor < 0)  

        {  

            LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY)  

                    , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "inotify_init failed !!!"), &b_IS_COPY));  

  

             exit(1);  

        }  

  

        int watchDescriptor;  

        watchDescriptor = inotify_add_watch(fileDescriptor, "/data/data/com.example.untitled", IN_DELETE);  

        if (watchDescriptor < 0)  

        {  

            LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY)  

                    , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "inotify_add_watch failed !!!"), &b_IS_COPY));  

  

            exit(1);  

        }  

  

        //分配緩存,以便讀取event,緩存大小=一個struct inotify_event的大小,這樣一次處理一個event  

        void *p_buf = malloc(sizeof(struct inotify_event));  

        if (p_buf == NULL)  

        {  

            LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY)  

                    , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "malloc failed !!!"), &b_IS_COPY));  

  

            exit(1);  

        }  

        //開始監聽  

        LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY)  

                    , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "start observer"), &b_IS_COPY));  

        size_t readBytes = read(fileDescriptor, p_buf, sizeof(struct inotify_event));  

  

        //read會阻塞進程,走到這裡說明收到目錄被刪除的事件,註銷監聽器  

        free(p_buf);  

        inotify_rm_watch(fileDescriptor, IN_DELETE);  

  

        //目錄不存在log  

        LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY)  

                    , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "uninstalled"), &b_IS_COPY));  

  

        //執行命令am start -a android.intent.action.VIEW -d https://shouji.360.cn/web/uninstall/uninstall.html  

       // execlp("am", "am", "start", "-a", "android.intent.action.VIEW", "-d", "https://shouji.360.cn/web/uninstall/uninstall.html", (char *)NULL);  

        //4.2以上的系統由於用戶權限管理更嚴格,需要加上 –user 0  

       execlp("am", "am", "start","–user", "0" ,"-a", "android.intent.action.VIEW", "-d", "https://www.google.com", (char *)NULL);  

  

    }  

    else  

    {  

        //父進程直接退出,使子進程被init進程領養,以避免子進程僵死  

    }  

  

    return (*env)->NewStringUTF(env, "Hello from JNI !");  

}  

下面是mk文件

[cpp]  

LOCAL_PATH := $(call my-dir)  

  

include $(CLEAR_VARS)  

  

LOCAL_MODULE    := hello-jni  

LOCAL_SRC_FILES := hello-jni.c  

[cpp]  

//因為加瞭Log日志  

LOCAL_C_INCLUDES := $(LOCAL_PATH)/include  

LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog  

  

include $(BUILD_SHARED_LIBRARY)  

編譯SO文件就不多說瞭,編譯成功後將編譯好的so文件放在libs目錄下

通過調用init方法就可以瞭

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *