Android NDK Development (eight)--application monitoring itself uninstall, pop-up user feedback survey

Source: Internet
Author: User
Tags log log

Reprint Please specify source:http://blog.csdn.net/allen315410/article/details/42521251

Monitoring and unloading scenarios and principle analysis 1, situational analysis

In the previous blog I wrote about the NDK development practice project, the use of open source Lame library transcoding MP3, as the previous basic blog for the deepening understanding of use, but such projects are not useful, in addition to practicing the NDK Foundation. This blog, I will describe a very common application of a feature, is also based on the development of JNI Android app small demo, after reading this, not only can deepen the understanding of NDK development, and the demo can also be used in the actual development. Do not know when you use an Android app, when we uninstall the app, the device will pop up a "User Feedback survey" page, perhaps many people have not noticed or directly ignored, then from now on please note, you may wish to download the "Pea pod" "360" and other applications installed on And then uninstall, to see if there is no pop-up browser on the device, open "XXX user feedback" on the browser? There are some HTML forms on it that ask us "Do you want to uninstall such a good app for your hair?" "Where have we offended you?" "After uninstalling, do you still pretend not to?" ", hehe, open a joke, the actual effect such as:


Well, the picture above is feeling like it has been shown? So how does such a small function be implemented? Let's start with the Java layer and analyze it with all of our Android basics:

1, listen to the system's uninstall broadcast, but this can only listen to other applications of the uninstall broadcast action, by uninstalling the broadcast monitoring itself is not able to listen to: failure
2, the system configuration file, do a tag application whether uninstall, Judge Mark to show user feedback, obviously this is also unreasonable, because after the application uninstall, the configuration file is not.
3, silently installs another program, listens to own application to be uninstalled the action. The premise is to root, to achieve. But most phones in the market are not rooted by default.
4, service detection, can only be self-opened, when itself was uninstalled, the service was also killed.

The above points do not seem to be able to achieve this function, indeed ah, simple from the Java layer can not do this.


2, the analysis of the above scenario analysis shows that Java can not implement such a function, whether to consider the use of JNI, C at the bottom for us to implement such an open built-in browser to load user feedback Web page, before we know this method, we need to understand the following several points of knowledge.

1. Through C language, c process monitoring.

Since Java does not, we try to use the C language at the bottom of the implementation, let the C language call Android ADB command to open the built-in browser.

Determine if you are uninstalled
The Andoird program generates a directory/data/data/package name for the package name in the/data/data/directory when it is installed
Listen to whether the directory is still present, and if it does not exist, it proves that the application was uninstalled.


2.C code can copy a current process as its own son, when the parent process is destroyed, the child process also exists.

Fork () Function:

the fork () function creates a process that is almost identical to the original process through a system call, two processes can do the same thing, the equivalent of having a son, if the initial parameters or the parameters passed in different, two processes do things differently. After the current process calls the fork function, the system allocates resources to the current process and then copies the values of all the variables of the current process into the new process (only a few values are different), which is equivalent to cloning a self.

pid_t fpid = fork () is called before the code is executed on a process, after the execution of this statement, there will be two process execution code, two process execution without a fixed order, mainly see the system scheduling strategy, the fork function is called once, but can return two times, Even three kinds of results.
(1) Process ID (PID) of the child process returned in the parent process
(2) Return 0 in child process
(3) An error occurred and a negative value of less than 0 is returned
The cause of the error: (1) The number of processes has reached the system (2) Insufficient memory, this time to return


3. In the child process of C code, monitor whether the parent process is uninstalled, if uninstalled, notify the Android system to open a URL to uninstall the survey Web page.

AM command

The ADB tools provided by the Android system enable the ADB shell to execute shell commands directly on the Android system, based on ADB
AM Command: Launches an activity, Service, phone call, launch browser, and other Android commands on the Android system via the ADB shell.
The source of the AM command in Am.java, executing the AM command in the shell environment is actually starting a thread to execute the main function in Am.java (Main method), and the parameters followed by the AM command are passed to the main function as run-time parameters, mainly in the Am.java run method.
The AM command can be used with the START subcommand, and with the specified parameters, start is a subcommand, not a parameter
Common parameters:-A: Represents an action,-D: Represents the data being carried,-t: Indicates the type passed in,-N: The specified component name

For example, we are now entering the ADB shell under command-line mode, using this command to open a Web page


These are the same commands:

Dial number
Command: AM START-A android.intent.action.call-d Tel: Phone number
Example: AM start-a android.intent.action.call-d tel:10086

Open a Web page
Command: AM start-a android.intent.action.view-d URL
Example: AM start-a android.intent.action.view-d http://www.baidu.com

Start a service

Command: AM StartService < service name >
Example: AM startservice-n com.android.music/com.android.music.mediaplaybackservice


EXECLP () function

The EXECLP function is simply a function of executing system commands in the C language.
EXECLP () looks for the file name in the directory referred to by the PATH environment variable, executes the file after it is found, and then takes the second later parameter as the file's argv[0], argv[1], ..., and the last argument must end with a null pointer (NULL).
Android development, EXECLP function corresponding to the path path of Android system/bin/directory

Call Format:

EXECLP ("AM", "AM", "Start", "--user", "0", "-a", "Android.intent.action.VIEW", "-D", "http://shouji.360.cn/web/ Uninstall/uninstall.html ", (char*) NULL);

=============================================================================================================== ====


Write code to implement 1,java layer definition native method

Defines a native method in the Java layer that provides calls on the Java side and the C-side

public native void Uninstall (String packagedir, int sdkversion);

This method needs to pass the installation directory of the application and the version number of the current device, get it in Java code, and pass it to C code processing.


2, using the Javah command to generate the method signature header file

/* Don't EDIT this file-it are machine generated */#include <jni.h>/* Header for class Com_example_appuninstall_ma Inactivity */#ifndef _included_com_example_appuninstall_mainactivity#define _included_com_example_appuninstall_ Mainactivity#ifdef __cplusplusextern "C" {#endif/* * Class:     com_example_appuninstall_mainactivity * Method:    Uninstall * Signature: (ljava/lang/string;) V */jniexport void Jnicall java_com_example_appuninstall_mainactivity_ Uninstall  (jnienv *, Jobject, jstring); #ifdef __cplusplus} #endif #endif

After the method signature is generated, right-click Android Tools--and ADD Native support in the Pop-up dialog box, enter the file name of the editor/C + +, OK, Files that find the CPP suffix name in the automatically generated JNI directory of the project are modified to a. c suffix file because this case is implemented based on the C language and then similarly modifies the local_src_ in the Android.mk file Files is a C file for. C, and the resulting good. h method signature file is then copied to the JNI directory.


3, write the C language code

As the above analysis of the principle, we implement such a function in Java is not possible, only in C to clone a child process of the current app, let this sub-process to listen to the application itself uninstall. So what steps do we need to implement such a feature? Here is the idea of writing code:

1. Convert the package name of the passed-in Java to the C string
2, create the clone process for the current process
3, do different actions depending on the return value
4, monitor the/data/data/package name in the sub-process directory
5, directory is deleted, description is uninstalled, execute open User Feedback page

#include <stdio.h> #include <jni.h> #include <malloc.h> #include <string.h> #include < strings.h> #include <stdlib.h> #include <unistd.h> #include "com_example_appuninstall_mainactivity.h" #include <android/log.h> #define LOG_TAG "system.out.c" #define LOGD (...) __android_log_print (android_log_debug , Log_tag, __va_args__) #define Logi (...) __android_log_print (Android_log_info, Log_tag, __va_args__)/** * return value char* This represents the first address of the char array * JSTRING2CSTR converts the type of jstring in Java into a char string in the C language */char* jstring2cstr (jnienv* env, jstring jstr) {char* RTN = Null;jclass clsstring = (*env)->findclass (env, "java/lang/string"); Stringjstring Strencode = (*env)->newstringutf (env, "GB2312"); Get a Java string "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); The length of the byte array 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;} Jniexport void Jnicall Java_com_example_appuninstall_mainactivity_uninstall (jnienv * env, jobject obj, jstring Packagedir, Jint sdkversion) {///1, converts the package name of the passed-in Java to the C string char * PD = JSTRING2CSTR (env, packagedir);//2, creating the clone process of the current process pid_t pi d = fork ();//3, depending on the return value, do different operations, &LT;0,&GT;0,=0IF (PID < 0) {//indicates that the cloning process failed logd ("Current crate process Failure");} else if ( PID > 0) {//Indicates the cloning process was successful, and the code runs in the parent process LOGD ("Crate process success,current Parent PID =%d", pid);} else {//Indicates the cloning process was successful and the code runs  In the subprocess logd ("Crate process success,current child pid =%d", pid);//4, monitor the/data/data/package name in the child process this directory while (jni_true) {file* FILE = fopen (PD, "RT"), if (file = = NULL) {//The application is uninstalled, the notification system opens the user feedback page logd ("app uninstall,current sdkversion =%d", sdkversion); if (s Dkversion >=) {//Android4.2 system supports multi-user operation, so specify user EXECLP ("AM", "AM", "Start", "--user", "0", "-a", "Android.intent.action.VIEW ","-D "," http://www.baidu.com ", (char*) NULL);} else {//Android4.2 Previous versions do not need to specify user EXECLP ("AM", "AM", "Start", "-a", "Android.intent.action.VIEW", "-D", "/http Www.baidu.com ", (char*) NULL);}} else {//app not uninstalled logd ("app run Normal");} Sleep (1);}}
The above code is like the above steps, with C code implementation, the first thing to note is the Android version of the problem, it is known that Android is a very good Linux-based operating system, And after the Android4.2 version of the support for multi-user operation, but this also gives us this small project inconvenience, because in the multi-user situation when the AM command force to specify a user and a number, before the Android4.2 version of these parameters is not necessary, so we write C code, we need to To differentiate the Android version, execute the corresponding AM command separately, about getting the Android system version can be implemented in the Java layer, and then pass it as a parameter to the C code, C code according to the Android version to determine the conditions to execute the AM command.

Note: For the sake of brevity, I use a while (true) dead loop when the C code monitors the application is unloaded, and monitor detection every 1 milliseconds, so that the code is "eco-friendly", so the result is that the program is kept running, the log is continuously printed, It is unavoidable to waste and consume CPU computing resources. The best solution is to use Android to provide us with the Fileobserve file Viewer, fileobserve using the Linux system under the inotify process, to monitor the changes in the file directory, in this case, if need to optimize the use of this API, But the need for more knowledge, I now for the sake of simple demonstration, temporarily used while (true) dead loop, about the later version of the optimization, and so I write it out, and then publish!


4, compiling. So dynamic library

As the previous blog wrote, after we have written the C source code, we need to use the Ndk-build command to compile the. So file, the specific compilation process is very simple, in eclipse to switch to the editor's C + + editors, find the "small Hammer" button, click on the start of compiling, If the code is not in an error condition, the result of the compilation is this:



5, write Java code, pass the data, load the link library

The above work is done, and the rest is to load the link library in Java, and call this local method. First, to get the directory/data/data/package name for this app installation, then get the version number of the current device, pass it to the local method, and finally call this method.

public class Mainactivity extends Activity {static {system.loadlibrary ("Uninstall");} public native void Uninstall (String packagedir, int sdkversion), @Overrideprotected void OnCreate (Bundle Savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); String Packagedir = "/data/data/" + getpackagename (); int sdkversion = Android.os.build.version.sdk_int;uninstall ( Packagedir, sdkversion);}}
6, Test

OK, the application is done, we clean the project, and then start an arm-based simulator, run the program, go back to the desktop, click on the application image-Uninstall the application, to see the effect:


Well, we look at the effect, actually open the Web page should be the User feedback survey page, because I temporarily do not have a server, so the URL is directed to the Baidu home page, we in the development of the time, you can EXECLP function in the parameters of the URL into its own server URL, so it's done. Check the output of the log log:


See, log input logs and code flow is consistent, well, the source in the following link, interested friends can download research, you are welcome to give me valuable advice, we learn together progress!


Please download the source code here


Android NDK Development (eight)--application monitoring itself uninstall, pop-up user feedback survey

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.