Java tutorial
/* * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you 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 * * http://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. */ package org.wso2.emm.system.service.utils; import android.app.PackageInstallObserver; import android.content.Context; import android.content.pm.IPackageDeleteObserver; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import org.json.JSONException; import org.json.JSONObject; import static android.content.pm.PackageManager.*; /** * Utility class to hold app operations. */ public class AppUtils { private static final String TAG = "AppUtils"; private static final int DELETE_ALL_USERS = 0x00000002; private static final int INSTALL_ALL_USERS = 0x00000040; private static final int INSTALL_ALLOW_DOWNGRADE = 0x00000080; private static final int INSTALL_REPLACE_EXISTING = 0x00000002; public static final int INSTALL_SUCCEEDED = 1; private static final int DEFAULT_STATE_INFO_CODE = 0; private static final String INSTALL_FAILED_STATUS = "INSTALL_FAILED"; private static final String INSTALL_SUCCESS_STATUS = "INSTALLED"; private static final String PACKAGE_PREFIX = "package:"; /** * Silently installs the app resides in the provided URI. * @param context - Application context. * @param packageUri - App package URI. */ public static void silentInstallApp(final Context context, Uri packageUri) { PackageManager pm = context.getPackageManager(); PackageInstallObserver observer = new PackageInstallObserver() { @Override public void onPackageInstalled(String basePackageName, int returnCode, String msg, Bundle extras) { if (INSTALL_SUCCEEDED == returnCode) { Log.d(TAG, "Installation succeeded!"); publishAppInstallStatus(context, INSTALL_SUCCESS_STATUS, null); } else { if (msg == null || msg.isEmpty()) { switch (returnCode) { case INSTALL_FAILED_ALREADY_EXISTS: msg = "INSTALL_FAILED_ALREADY_EXISTS"; break; case INSTALL_FAILED_INVALID_APK: msg = "INSTALL_FAILED_INVALID_APK"; break; case INSTALL_FAILED_INVALID_URI: msg = "INSTALL_FAILED_INVALID_URI"; break; case INSTALL_FAILED_INSUFFICIENT_STORAGE: msg = "INSTALL_FAILED_INSUFFICIENT_STORAGE"; break; case INSTALL_FAILED_DUPLICATE_PACKAGE: msg = "INSTALL_FAILED_DUPLICATE_PACKAGE"; break; case INSTALL_FAILED_NO_SHARED_USER: msg = "INSTALL_FAILED_NO_SHARED_USER"; break; case INSTALL_FAILED_UPDATE_INCOMPATIBLE: msg = "INSTALL_FAILED_UPDATE_INCOMPATIBLE"; break; case INSTALL_FAILED_SHARED_USER_INCOMPATIBLE: msg = "INSTALL_FAILED_SHARED_USER_INCOMPATIBLE"; break; case INSTALL_FAILED_MISSING_SHARED_LIBRARY: msg = "INSTALL_FAILED_MISSING_SHARED_LIBRARY"; break; case INSTALL_FAILED_REPLACE_COULDNT_DELETE: msg = "INSTALL_FAILED_REPLACE_COULDNT_DELETE"; break; case INSTALL_FAILED_DEXOPT: msg = "INSTALL_FAILED_DEXOPT"; break; case INSTALL_FAILED_OLDER_SDK: msg = "INSTALL_FAILED_OLDER_SDK"; break; case INSTALL_FAILED_CONFLICTING_PROVIDER: msg = "INSTALL_FAILED_CONFLICTING_PROVIDER"; break; case INSTALL_FAILED_NEWER_SDK: msg = "INSTALL_FAILED_NEWER_SDK"; break; case INSTALL_FAILED_TEST_ONLY: msg = "INSTALL_FAILED_TEST_ONLY"; break; case INSTALL_FAILED_CPU_ABI_INCOMPATIBLE: msg = "INSTALL_FAILED_CPU_ABI_INCOMPATIBLE"; break; case INSTALL_FAILED_MISSING_FEATURE: msg = "INSTALL_FAILED_MISSING_FEATURE"; break; case INSTALL_FAILED_CONTAINER_ERROR: msg = "INSTALL_FAILED_CONTAINER_ERROR"; break; case INSTALL_FAILED_INVALID_INSTALL_LOCATION: msg = "INSTALL_FAILED_INVALID_INSTALL_LOCATION"; break; case INSTALL_FAILED_MEDIA_UNAVAILABLE: msg = "INSTALL_FAILED_MEDIA_UNAVAILABLE"; break; case INSTALL_FAILED_VERIFICATION_TIMEOUT: msg = "INSTALL_FAILED_VERIFICATION_TIMEOUT"; break; case INSTALL_FAILED_VERIFICATION_FAILURE: msg = "INSTALL_FAILED_VERIFICATION_FAILURE"; break; case INSTALL_FAILED_PACKAGE_CHANGED: msg = "INSTALL_FAILED_PACKAGE_CHANGED"; break; case INSTALL_FAILED_UID_CHANGED: msg = "INSTALL_FAILED_UID_CHANGED"; break; case INSTALL_FAILED_VERSION_DOWNGRADE: msg = "INSTALL_FAILED_VERSION_DOWNGRADE"; break; case INSTALL_PARSE_FAILED_NOT_APK: msg = "INSTALL_PARSE_FAILED_NOT_APK"; break; case INSTALL_PARSE_FAILED_BAD_MANIFEST: msg = "INSTALL_PARSE_FAILED_BAD_MANIFEST"; break; case INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION: msg = "INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION"; break; case INSTALL_PARSE_FAILED_NO_CERTIFICATES: msg = "INSTALL_PARSE_FAILED_NO_CERTIFICATES"; break; case INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES: msg = "INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES"; break; case INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING: msg = "INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING"; break; case INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME: msg = "INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME"; break; case INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID: msg = "INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID"; break; case INSTALL_PARSE_FAILED_MANIFEST_MALFORMED: msg = "INSTALL_PARSE_FAILED_MANIFEST_MALFORMED"; break; case INSTALL_PARSE_FAILED_MANIFEST_EMPTY: msg = "INSTALL_PARSE_FAILED_MANIFEST_EMPTY"; break; case INSTALL_FAILED_INTERNAL_ERROR: msg = "INSTALL_FAILED_INTERNAL_ERROR"; break; case INSTALL_FAILED_USER_RESTRICTED: msg = "INSTALL_FAILED_USER_RESTRICTED"; break; case INSTALL_FAILED_DUPLICATE_PERMISSION: msg = "INSTALL_FAILED_DUPLICATE_PERMISSION"; break; case INSTALL_FAILED_NO_MATCHING_ABIS: msg = "INSTALL_FAILED_NO_MATCHING_ABIS"; break; case NO_NATIVE_LIBRARIES: msg = "NO_NATIVE_LIBRARIES"; break; case INSTALL_FAILED_ABORTED: msg = "INSTALL_FAILED_ABORTED"; break; case INSTALL_FAILED_THEME_AAPT_ERROR: msg = "INSTALL_FAILED_THEME_AAPT_ERROR"; break; case INSTALL_FAILED_THEME_IDMAP_ERROR: msg = "INSTALL_FAILED_THEME_IDMAP_ERROR"; break; case INSTALL_FAILED_THEME_UNKNOWN_ERROR: msg = "INSTALL_FAILED_THEME_UNKNOWN_ERROR"; break; } } String error = "Package installation failed due to an internal error with code: " + returnCode + " and message: " + msg; Log.e(TAG, error); publishAppInstallStatus(context, INSTALL_FAILED_STATUS, error); } } }; pm.installPackage(packageUri, observer, INSTALL_ALL_USERS | INSTALL_ALLOW_DOWNGRADE | INSTALL_REPLACE_EXISTING, null); } /** * Silently uninstalls the app resides in the provided URI. * @param context - Application context. * @param packageName - App package name. */ public static void silentUninstallApp(Context context, String packageName) { if (packageName != null && packageName.contains(PACKAGE_PREFIX)) { packageName = packageName.replace(PACKAGE_PREFIX, ""); } final String _packageName = packageName; PackageManager pm = context.getPackageManager(); IPackageDeleteObserver observer = new IPackageDeleteObserver() { @Override public void packageDeleted(String s, int i) throws RemoteException { Log.d(TAG, _packageName + " deleted successfully."); } @Override public IBinder asBinder() { return null; } }; pm.deletePackage(packageName, observer, DELETE_ALL_USERS); } private static void publishAppInstallStatus(Context context, String status, String error) { JSONObject result = new JSONObject(); try { result.put("appInstallStatus", status); if (error != null) { result.put("appInstallFailedMessage", error); CommonUtils.sendBroadcast(context, Constants.Operation.SILENT_INSTALL_APPLICATION, Constants.Code.FAILURE, Constants.Status.INTERNAL_ERROR, result.toString()); } else { CommonUtils.sendBroadcast(context, Constants.Operation.SILENT_INSTALL_APPLICATION, Constants.Code.SUCCESS, Constants.Status.SUCCESSFUL, result.toString()); } } catch (JSONException e) { Log.e(TAG, "Failed to create JSON object when publishing App install status."); CommonUtils.sendBroadcast(context, Constants.Operation.SILENT_INSTALL_APPLICATION, Constants.Code.FAILURE, Constants.Status.INTERNAL_ERROR, String.valueOf(DEFAULT_STATE_INFO_CODE)); } } }