Android silent mode for in-depth analysis of batch installation and uninstallation of applications

Source: Internet
Author: User

Some time ago I made a small application for batch installation and uninstallation of applications. Because some APIs for installing and uninstalling applications are hidden, the Android system source code must be downloaded under ubuntu, after compilation, use the MM command to compile and generate the APK file, which is also difficult.

The idea is that there is a PackageInstaller application under the XX/packages/apps directory, and installation and uninstallation on the Android machine is completed by this application. However, it does not support batch installation and uninstallation. If you want to add the batch installation and uninstallation functions to your application, it is actually very simple, you only need to refer to the installation and uninstallation code in PakcageInstaller and add a loop. However, during compilation, you must copy the Android. mk file in PackageInstaller and change the file to the project directory name.
Okay, let's stop talking nonsense. The following is the key code.
1. Android. mk File
Copy codeThe Code is as follows: LOCAL_PATH :=$ (call my-dir)
Include $ (CLEAR_VARS)

LOCAL_MODULE_TAGS: = optional

LOCAL_SRC_FILES: = $ (call all-subdir-java-files)

LOCAL_PACKAGE_NAME: = PackageInstaller
LOCAL_CERTIFICATE: = platform

Include $ (BUILD_PACKAGE)

Copy codeThe Code is as follows: LOCAL_PATH :=$ (call my-dir)
Include $ (CLEAR_VARS)

LOCAL_MODULE_TAGS: = optional

LOCAL_SRC_FILES: = $ (call all-subdir-java-files)

LOCAL_PACKAGE_NAME: = PackageInstaller
LOCAL_CERTIFICATE: = platform

Include $ (BUILD_PACKAGE)

2. PakcageInstaller. java file (key code)
Copy codeThe Code is as follows: package cn.ceadic.apk mgr;

Import java. io. File;
Import java. io. FileNotFoundException;
Import java. io. FileOutputStream;
Import java. io. IOException;

Import android. content. Context;
Import android. content. Intent;
Import android. content. pm. PackageInfo;
Import android. content. pm. PackageManager;
Import android. content. pm. PackageManager. NameNotFoundException;
Import android.net. Uri;
Import android. util. Log;

Import android. content. pm. IPackageInstallObserver;
Import android. content. pm. IPackageDeleteObserver;
Import android. OS. FileUtils;

Public class PackageInstaller {

Private File mTmpFile;
Private final String TMP_FILE_NAME = "tmpCopy.apk ";

Private final static String TAG = "PackInstaller ";
Private Context mContext;

Public PackageInstaller (Context context ){
MContext = context;
}

Public void install (String path, String packageName ){
Intent intent = new Intent (Intent. ACTION_VIEW );
Intent. setDataAndType (Uri. fromFile (new File (path )),
"Application/vnd. android. package-archive ");
MContext. startActivity (intent );
}

Public void instatllBatch (String path, String packageName ){

Log. I (TAG, "path =" + path );
Int installFlags = 0;
PackageManager pm = mContext. getPackageManager ();
Try {
PackageInfo pi = pm. getPackageInfo (packageName,
PackageManager. GET_UNINSTALLED_PACKAGES );
If (pi! = Null ){
InstallFlags | = PackageManager. INSTALL_REPLACE_EXISTING;
}
} Catch (NameNotFoundException e ){
}
If (installFlags & PackageManager. INSTALL_REPLACE_EXISTING )! = 0 ){
Log. w (TAG, "Replacing package:" + packageName );
}

// Create temp file before invoking install api
MTmpFile = createTempPackageFile (path );
If (mTmpFile = null ){
// Message msg = mHandler. obtainMessage (INSTALL_COMPLETE );
// Msg. arg1 = PackageManager. INSTALL_FAILED_INSUFFICIENT_STORAGE;
// MHandler. sendMessage (msg );
Return;
}
Uri mPackageURI = Uri. parse ("file: //" + mTmpFile. getPath ());
String installerPackageName = mContext. getIntent (). getStringExtra (
Intent. EXTRA_INSTALLER_PACKAGE_NAME );

PackageInstallObserver observer = new PackageInstallObserver ();
Pm. installPackage (mPackageURI, observer, installFlags,
InstallerPackageName );
}

Private File createTempPackageFile (String filePath ){
File tmpPackageFile = mContext. getFileStreamPath (TMP_FILE_NAME );
If (tmpPackageFile = null ){
Log. w (TAG, "Failed to create temp file ");
Return null;
}
If (tmpPackageFile. exists ()){
TmpPackageFile. delete ();
}
// Open file to make it world readable
FileOutputStream fos;
Try {
Fos = openFileOutput (TMP_FILE_NAME, MODE_WORLD_READABLE );
} Catch (FileNotFoundException e1 ){
Log. e (TAG, "Error opening file" + TMP_FILE_NAME );
Return null;
}
Try {
Fos. close ();
} Catch (IOException e ){
Log. e (TAG, "Error opening file" + TMP_FILE_NAME );
Return null;
}

File srcPackageFile = new File (filePath );
If (! FileUtils. copyFile (srcPackageFile, tmpPackageFile )){
Log. w (TAG, "Failed to make copy of file:" + srcPackageFile );
Return null;
}
Return tmpPackageFile;
}

Private class PackageInstallObserver extends IPackageInstallObserver. Stub {
Public void packageInstalled (String packageName, int returnCode ){
// Message msg = mHandler. obtainMessage (INSTALL_COMPLETE );
// Msg. arg1 = returnCode;
// MHandler. sendMessage (msg );
Log. I (TAG, "=== INSTALL_COMPLETE ");
}
}

Private class PackageDeleteObserver extends IPackageDeleteObserver. Stub {
Public void packageDeleted (boolean succeeded ){
// Message msg = mHandler. obtainMessage (UNINSTALL_COMPLETE );
// Msg. arg1 = succeeded? SUCCEEDED: FAILED;
// MHandler. sendMessage (msg );
Log. I (TAG, "=== UNINSTALL_COMPLETE ");
}
}

Public void uninstall (String packageName ){
Uri packageURI = Uri. parse ("package:" + packageName );
Intent uninstallIntent = new Intent (Intent. ACTION_DELETE,
PackageURI );
MContext. startActivity (uninstallIntent );
}

Public void uninstallBatch (String packageName ){
PackageDeleteObserver observer = new PackageDeleteObserver ();
MContext. getPackageManager (). deletePackage (packageName, observer, 0 );

}
}

Copy codeThe Code is as follows: package cn.ceadic.apk mgr;

Import java. io. File;
Import java. io. FileNotFoundException;
Import java. io. FileOutputStream;
Import java. io. IOException;

Import android. content. Context;
Import android. content. Intent;
Import android. content. pm. PackageInfo;
Import android. content. pm. PackageManager;
Import android. content. pm. PackageManager. NameNotFoundException;
Import android.net. Uri;
Import android. util. Log;

Import android. content. pm. IPackageInstallObserver;
Import android. content. pm. IPackageDeleteObserver;
Import android. OS. FileUtils;

Public class PackageInstaller {

Private File mTmpFile;
Private final String TMP_FILE_NAME = "tmpCopy.apk ";

Private final static String TAG = "PackInstaller ";
Private Context mContext;

Public PackageInstaller (Context context ){
MContext = context;
}

Public void install (String path, String packageName ){
Intent intent = new Intent (Intent. ACTION_VIEW );
Intent. setDataAndType (Uri. fromFile (new File (path )),
"Application/vnd. android. package-archive ");
MContext. startActivity (intent );
}

Public void instatllBatch (String path, String packageName ){

Log. I (TAG, "path =" + path );
Int installFlags = 0;
PackageManager pm = mContext. getPackageManager ();
Try {
PackageInfo pi = pm. getPackageInfo (packageName,
PackageManager. GET_UNINSTALLED_PACKAGES );
If (pi! = Null ){
InstallFlags | = PackageManager. INSTALL_REPLACE_EXISTING;
}
} Catch (NameNotFoundException e ){
}
If (installFlags & PackageManager. INSTALL_REPLACE_EXISTING )! = 0 ){
Log. w (TAG, "Replacing package:" + packageName );
}

// Create temp file before invoking install api
MTmpFile = createTempPackageFile (path );
If (mTmpFile = null ){
// Message msg = mHandler. obtainMessage (INSTALL_COMPLETE );
// Msg. arg1 = PackageManager. INSTALL_FAILED_INSUFFICIENT_STORAGE;
// MHandler. sendMessage (msg );
Return;
}
Uri mPackageURI = Uri. parse ("file: //" + mTmpFile. getPath ());
String installerPackageName = mContext. getIntent (). getStringExtra (
Intent. EXTRA_INSTALLER_PACKAGE_NAME );

PackageInstallObserver observer = new PackageInstallObserver ();
Pm. installPackage (mPackageURI, observer, installFlags,
InstallerPackageName );
}

Private File createTempPackageFile (String filePath ){
File tmpPackageFile = mContext. getFileStreamPath (TMP_FILE_NAME );
If (tmpPackageFile = null ){
Log. w (TAG, "Failed to create temp file ");
Return null;
}
If (tmpPackageFile. exists ()){
TmpPackageFile. delete ();
}
// Open file to make it world readable
FileOutputStream fos;
Try {
Fos = openFileOutput (TMP_FILE_NAME, MODE_WORLD_READABLE );
} Catch (FileNotFoundException e1 ){
Log. e (TAG, "Error opening file" + TMP_FILE_NAME );
Return null;
}
Try {
Fos. close ();
} Catch (IOException e ){
Log. e (TAG, "Error opening file" + TMP_FILE_NAME );
Return null;
}

File srcPackageFile = new File (filePath );
If (! FileUtils. copyFile (srcPackageFile, tmpPackageFile )){
Log. w (TAG, "Failed to make copy of file:" + srcPackageFile );
Return null;
}
Return tmpPackageFile;
}

Private class PackageInstallObserver extends IPackageInstallObserver. Stub {
Public void packageInstalled (String packageName, int returnCode ){
// Message msg = mHandler. obtainMessage (INSTALL_COMPLETE );
// Msg. arg1 = returnCode;
// MHandler. sendMessage (msg );
Log. I (TAG, "=== INSTALL_COMPLETE ");
}
}

Private class PackageDeleteObserver extends IPackageDeleteObserver. Stub {
Public void packageDeleted (boolean succeeded ){
// Message msg = mHandler. obtainMessage (UNINSTALL_COMPLETE );
// Msg. arg1 = succeeded? SUCCEEDED: FAILED;
// MHandler. sendMessage (msg );
Log. I (TAG, "=== UNINSTALL_COMPLETE ");
}
}

Public void uninstall (String packageName ){
Uri packageURI = Uri. parse ("package:" + packageName );
Intent uninstallIntent = new Intent (Intent. ACTION_DELETE,
PackageURI );
MContext. startActivity (uninstallIntent );
}

Public void uninstallBatch (String packageName ){
PackageDeleteObserver observer = new PackageDeleteObserver ();
MContext. getPackageManager (). deletePackage (packageName, observer, 0 );

}
}

3. Do not forget to add permissions
Copy codeThe Code is as follows: <uses-permission android: name = "android. permission. WRITE_EXTERNAL_STORAGE"/>
<Uses-permission android: name = "android. permission. INSTALL_PACKAGES"/>
<Uses-permission android: name = "android. permission. DELETE_PACKAGES"/>
<Uses-permission android: name = "android. permission. CLEAR_APP_CACHE"/>
<Uses-permission android: name = "android. permission. READ_PHONE_STATE"/>
<Uses-permission android: name = "android. permission. CLEAR_APP_USER_DATA"/>

Copy codeThe Code is as follows: <uses-permission android: name = "android. permission. WRITE_EXTERNAL_STORAGE"/>
<Uses-permission android: name = "android. permission. INSTALL_PACKAGES"/>
<Uses-permission android: name = "android. permission. DELETE_PACKAGES"/>
<Uses-permission android: name = "android. permission. CLEAR_APP_CACHE"/>
<Uses-permission android: name = "android. permission. READ_PHONE_STATE"/>
<Uses-permission android: name = "android. permission. CLEAR_APP_USER_DATA"/>

The above code is compiled in the SDK of Android2.1 and correctly installed and uninstalled in batches.

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.