Created
March 12, 2014 05:05
-
-
Save dagezi/9501179 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.quipper.appdater; | |
import java.lang.reflect.InvocationTargetException; | |
import java.lang.reflect.Method; | |
import android.content.Context; | |
import android.content.pm.IPackageInstallObserver; | |
import android.content.pm.PackageManager; | |
import android.net.Uri; | |
import android.os.RemoteException; | |
// Fake Package Manager | |
// @see http://paulononaka.wordpress.com/2011/07/02/how-to-install-a-application-in-background-on-android/ | |
public class FakePackageManager { | |
// Following constants are copied from android/content/pm/PackageManager.java | |
/** | |
* Flag parameter for {@link #installPackage(android.net.Uri, int)} to | |
* indicate that this package should be installed as forward locked, i.e. only the app itself | |
* should have access to its code and non-resource assets. | |
*/ | |
public static final int INSTALL_FORWARD_LOCK = 0x00000001; | |
/** | |
* Flag parameter for {@link #installPackage} to indicate that you want to replace an already | |
* installed package, if one exists. | |
*/ | |
public static final int INSTALL_REPLACE_EXISTING = 0x00000002; | |
/** | |
* Flag parameter for {@link #installPackage} to indicate that you want to | |
* allow test packages (those that have set android:testOnly in their | |
* manifest) to be installed. | |
*/ | |
public static final int INSTALL_ALLOW_TEST = 0x00000004; | |
/** | |
* Flag parameter for {@link #installPackage} to indicate that this | |
* package has to be installed on the sdcard. | |
*/ | |
public static final int INSTALL_EXTERNAL = 0x00000008; | |
/** | |
* Flag parameter for {@link #installPackage} to indicate that this package | |
* has to be installed on the sdcard. | |
*/ | |
public static final int INSTALL_INTERNAL = 0x00000010; | |
/** | |
* Flag parameter for {@link #installPackage} to indicate that this install | |
* was initiated via ADB. | |
* | |
*/ | |
public static final int INSTALL_FROM_ADB = 0x00000020; | |
/** | |
* Flag parameter for {@link #installPackage} to indicate that this install | |
* should immediately be visible to all users. | |
* | |
*/ | |
public static final int INSTALL_ALL_USERS = 0x00000040; | |
/** | |
* Flag parameter for {@link #installPackage} to indicate that it is okay | |
* to install an update to an app where the newly installed app has a lower | |
* version code than the currently installed app. | |
* | |
*/ | |
public static final int INSTALL_ALLOW_DOWNGRADE = 0x00000080; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} on success. | |
*/ | |
public static final int INSTALL_SUCCEEDED = 1; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if the package is | |
* already installed. | |
*/ | |
public static final int INSTALL_FAILED_ALREADY_EXISTS = -1; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if the package archive | |
* file is invalid. | |
*/ | |
public static final int INSTALL_FAILED_INVALID_APK = -2; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if the URI passed in | |
* is invalid. | |
*/ | |
public static final int INSTALL_FAILED_INVALID_URI = -3; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if the package manager | |
* service found that the device didn't have enough storage space to install the app. | |
*/ | |
public static final int INSTALL_FAILED_INSUFFICIENT_STORAGE = -4; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if a | |
* package is already installed with the same name. | |
*/ | |
public static final int INSTALL_FAILED_DUPLICATE_PACKAGE = -5; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the requested shared user does not exist. | |
*/ | |
public static final int INSTALL_FAILED_NO_SHARED_USER = -6; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* a previously installed package of the same name has a different signature | |
* than the new package (and the old package's data was not removed). | |
*/ | |
public static final int INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package is requested a shared user which is already installed on the | |
* device and does not have matching signature. | |
*/ | |
public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package uses a shared library that is not available. | |
*/ | |
public static final int INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package uses a shared library that is not available. | |
*/ | |
public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package failed while optimizing and validating its dex files, | |
* either because there was not enough storage or the validation failed. | |
*/ | |
public static final int INSTALL_FAILED_DEXOPT = -11; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package failed because the current SDK version is older than | |
* that required by the package. | |
*/ | |
public static final int INSTALL_FAILED_OLDER_SDK = -12; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package failed because it contains a content provider with the | |
* same authority as a provider already installed in the system. | |
*/ | |
public static final int INSTALL_FAILED_CONFLICTING_PROVIDER = -13; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package failed because the current SDK version is newer than | |
* that required by the package. | |
*/ | |
public static final int INSTALL_FAILED_NEWER_SDK = -14; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package failed because it has specified that it is a test-only | |
* package and the caller has not supplied the {@link #INSTALL_ALLOW_TEST} | |
* flag. | |
*/ | |
public static final int INSTALL_FAILED_TEST_ONLY = -15; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the package being installed contains native code, but none that is | |
* compatible with the the device's CPU_ABI. | |
*/ | |
public static final int INSTALL_FAILED_CPU_ABI_INCOMPATIBLE = -16; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package uses a feature that is not available. | |
*/ | |
public static final int INSTALL_FAILED_MISSING_FEATURE = -17; | |
// ------ Errors related to sdcard | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* a secure container mount point couldn't be accessed on external media. | |
*/ | |
public static final int INSTALL_FAILED_CONTAINER_ERROR = -18; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package couldn't be installed in the specified install | |
* location. | |
*/ | |
public static final int INSTALL_FAILED_INVALID_INSTALL_LOCATION = -19; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package couldn't be installed in the specified install | |
* location because the media is not available. | |
*/ | |
public static final int INSTALL_FAILED_MEDIA_UNAVAILABLE = -20; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package couldn't be installed because the verification timed out. | |
*/ | |
public static final int INSTALL_FAILED_VERIFICATION_TIMEOUT = -21; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package couldn't be installed because the verification did not succeed. | |
*/ | |
public static final int INSTALL_FAILED_VERIFICATION_FAILURE = -22; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the package changed from what the calling program expected. | |
*/ | |
public static final int INSTALL_FAILED_PACKAGE_CHANGED = -23; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package is assigned a different UID than it previously held. | |
*/ | |
public static final int INSTALL_FAILED_UID_CHANGED = -24; | |
/** | |
* Installation return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} if | |
* the new package has an older version code than the currently installed package. | |
*/ | |
public static final int INSTALL_FAILED_VERSION_DOWNGRADE = -25; | |
/** | |
* Installation parse return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} | |
* if the parser was given a path that is not a file, or does not end with the expected | |
* '.apk' extension. | |
*/ | |
public static final int INSTALL_PARSE_FAILED_NOT_APK = -100; | |
/** | |
* Installation parse return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} | |
* if the parser was unable to retrieve the AndroidManifest.xml file. | |
*/ | |
public static final int INSTALL_PARSE_FAILED_BAD_MANIFEST = -101; | |
/** | |
* Installation parse return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} | |
* if the parser encountered an unexpected exception. | |
*/ | |
public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102; | |
/** | |
* Installation parse return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} | |
* if the parser did not find any certificates in the .apk. | |
*/ | |
public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103; | |
/** | |
* Installation parse return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} | |
* if the parser found inconsistent certificates on the files in the .apk. | |
*/ | |
public static final int INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES = -104; | |
/** | |
* Installation parse return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} | |
* if the parser encountered a CertificateEncodingException in one of the | |
* files in the .apk. | |
*/ | |
public static final int INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING = -105; | |
/** | |
* Installation parse return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} | |
* if the parser encountered a bad or missing package name in the manifest. | |
*/ | |
public static final int INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106; | |
/** | |
* Installation parse return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} | |
* if the parser encountered a bad shared user id name in the manifest. | |
*/ | |
public static final int INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID = -107; | |
/** | |
* Installation parse return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} | |
* if the parser encountered some structural problem in the manifest. | |
*/ | |
public static final int INSTALL_PARSE_FAILED_MANIFEST_MALFORMED = -108; | |
/** | |
* Installation parse return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} | |
* if the parser did not find any actionable tags (instrumentation or application) | |
* in the manifest. | |
*/ | |
public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109; | |
/** | |
* Installation failed return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} | |
* if the system failed to install the package because of system issues. | |
*/ | |
public static final int INSTALL_FAILED_INTERNAL_ERROR = -110; | |
/** | |
* Installation failed return code: this is passed to the {@link OnPackageInstalledListener} by | |
* {@link #installPackage(android.net.Uri, int)} | |
* if the system failed to install the package because the user is restricted from installing | |
* apps. | |
*/ | |
public static final int INSTALL_FAILED_USER_RESTRICTED = -111; | |
// The constants above are copied from android/content/pm/PackageManager.java | |
public interface OnPackageInstalledListener { | |
void onPackageInstalled(String packageName, int returnCode); | |
} | |
private PackageInstallObserver observer; | |
private PackageManager pm; | |
private Method method; | |
private OnPackageInstalledListener listener; | |
class PackageInstallObserver extends IPackageInstallObserver.Stub { | |
public void packageInstalled(String packageName, int returnCode) throws RemoteException { | |
if (listener != null) { | |
listener.onPackageInstalled(packageName, returnCode); | |
} | |
} | |
} | |
public FakePackageManager(Context context) throws SecurityException, NoSuchMethodException { | |
observer = new PackageInstallObserver(); | |
pm = context.getPackageManager(); | |
Class<?>[] types = | |
new Class[] {Uri.class, IPackageInstallObserver.class, int.class, String.class}; | |
method = pm.getClass().getMethod("installPackage", types); | |
} | |
public void setOnPackageInstalledListener(OnPackageInstalledListener listener) { | |
this.listener = listener; | |
} | |
public void installPackage(Uri apkFile, int flags) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { | |
method.invoke(pm, new Object[] {apkFile, observer, flags, null}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment