当前位置: 代码迷 >> 综合 >> Android apk静默安装与卸载7.0 9.0
  详细解决方案

Android apk静默安装与卸载7.0 9.0

热度:37   发布时间:2024-02-12 20:18:34.0

7.0apk静默安装

将 源码frameworks\base\core\java\android\app\PackageInstallObserver.java拷贝到项目并放在android.app包下

/** Copyright (C) 2014 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** 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 android.app;import android.content.Intent;
import android.content.pm.IPackageInstallObserver2;
import android.os.Bundle;/** {@hide} */
public class PackageInstallObserver {private final IPackageInstallObserver2.Stub mBinder = new IPackageInstallObserver2.Stub() {@Overridepublic void onUserActionRequired(Intent intent) {PackageInstallObserver.this.onUserActionRequired(intent);}@Overridepublic void onPackageInstalled(String basePackageName, int returnCode,String msg, Bundle extras) {PackageInstallObserver.this.onPackageInstalled(basePackageName, returnCode, msg,extras);}};/** {@hide} */public IPackageInstallObserver2 getBinder() {return mBinder;}public void onUserActionRequired(Intent intent) {}/*** This method will be called to report the result of the package* installation attempt.** @param basePackageName Name of the package whose installation was* attempted* @param extras If non-null, this Bundle contains extras providing* additional information about an install failure. See* {@link android.content.pm.PackageManager} for documentation* about which extras apply to various failures; in particular* the strings named EXTRA_FAILURE_*.* @param returnCode The numeric success or failure code indicating the* basic outcome* @hide*/public void onPackageInstalled(String basePackageName, int returnCode, String msg,Bundle extras) {}
}

通过反射调用

PackageManager packageManager = getContext().getPackageManager();Class<?> pmClz = packageManager.getClass();try {Method method = pmClz.getDeclaredMethod("installPackage",Uri.class,Class.forName("android.app.PackageInstallObserver"),int.class, String.class);method.setAccessible(true);method.invoke(packageManager, Uri.fromFile(new File(apkPath)),new PackageInstallObserver() {@Overridepublic void onPackageInstalled(String basePackageName, int returnCode,String msg, Bundle extras) {Log.i(TAG, "onPackageInstalled:" + returnCode + ",msg:" + msg+ ",basePackageName:" + basePackageName);}}, 2, null);} catch (Exception e) {e.printStackTrace();}

7.0apk静默卸载

将 源码frameworks\base\core\java\android\content\pm\IPackageDeleteObserver.aidl拷贝到项目并放在android.content.pm包下

/*
**
** Copyright 2007, 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
**
**     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 android.content.pm;/*** API for deletion callbacks from the Package Manager.** {@hide}*/
oneway interface IPackageDeleteObserver {void packageDeleted(in String packageName, in int returnCode);
}

通过反射调用

try {Method method = mPackageManager.getClass().getMethod("deletePackage",String.class,Class.forName("android.content.pm.IPackageDeleteObserver"),int.class);method.setAccessible(true);method.invoke(mPackageManager, "packageName",new PackageDeleteObserver(), 0x00000002);/*** 0x00000002 to indicate that you want the package* deleted for all users.*/} catch (Exception e) {e.printStackTrace();}

添加卸载观察者

private class PackageDeleteObserver extends IPackageDeleteObserver.Stub {@Overridepublic void packageDeleted(String basePackageName, final int returnCode)throws RemoteException {Log.i(TAG, "package:" + basePackageName + ",code:" + returnCode+ ",msg:");}});}}

9.0apk静默安装

/*** android 9.0* * @param apkFilePath*/public void installApk(final String apkFilePath) {mService.execute(new Runnable() {@Overridepublic void run() {mInstallState = INSTALLING;File file = new File(apkFilePath);final PackageInfo packageInfo = getContext().getPackageManager().getPackageArchiveInfo(apkFilePath,PackageManager.GET_ACTIVITIES| PackageManager.GET_SERVICES);PackageInstaller packageInstaller = getContext().getPackageManager().getPackageInstaller();PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);params.setSize(file.length());int mSessionId = -1;PackageInstaller.Session session = null;try {mSessionId = packageInstaller.createSession(params);session = getContext().getPackageManager().getPackageInstaller().openSession(mSessionId);} catch (IOException e) {e.printStackTrace();}try {try (InputStream in = new FileInputStream(file)) {long sizeBytes = file.length();try (OutputStream out = session.openWrite("PackageInstaller", 0, sizeBytes)) {byte[] buffer = new byte[1024 * 1024];while (true) {int numRead = in.read(buffer);if (numRead == -1) {session.fsync(out);break;}out.write(buffer, 0, numRead);if (sizeBytes > 0) {float fraction = ((float) numRead / (float) sizeBytes);Log.i(TAG, "fraction:" + fraction);}}}}InstallResultReceiver.addObserver(new InstallResultObserver() {@Overridepublic void onResult(int statusCode,String message) {Log.i(TAG, "code:" + statusCode+ ",message:" + message);}});// session = getContext().getPackageManager()// .getPackageInstaller().openSession(mSessionId);Intent intent = new Intent(getContext(),InstallResultReceiver.class);PendingIntent pendingIntent = PendingIntent.getBroadcast(getContext(), 1, intent,PendingIntent.FLAG_UPDATE_CURRENT);session.commit(pendingIntent.getIntentSender());Log.i(TAG, "write package success");// installSuccessed(packageInfo.packageName);} catch (IOException | SecurityException e) {Log.e(TAG, "Could not write package", e);session.close();}}});}

通过广播接收安装信息


public abstract class AbsAppReceiver extends BroadcastReceiver {private static final Set<InstallResultObserver> mObservers = new HashSet<>();@Overridepublic void onReceive(Context context, Intent intent) {if (intent != null) {final int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS,PackageInstaller.STATUS_FAILURE);String msg = null;if (status == PackageInstaller.STATUS_SUCCESS) {// successLog.d("$$AbsAppReceiver$$", " Success!");} else {msg = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE);Log.e("$$AbsAppReceiver$$","AbsAppReceiver FAILURE status_massage" + msg);}update(status, TextUtils.isEmpty(msg) ? getMessage() : msg);}}@SuppressLint("NewApi")private void update(final int statusCode, final String message) {mObservers.forEach(new Consumer<InstallResultObserver>() {@Overridepublic void accept(InstallResultObserver t) {t.onResult(statusCode, message);}@Overridepublic Consumer<InstallResultObserver> andThen(Consumer<? super InstallResultObserver> after) {// TODO Auto-generated method stubreturn null;}});}public abstract String getMessage();public static void removeObserver(InstallResultObserver observer) {mObservers.remove(observer);}public static void addObserver(InstallResultObserver observer) {mObservers.add(observer);}public interface InstallResultObserver {void onResult(int statusCode, String message);}}

在AndroidManifest.xml添加安装广播接收者

        <receiverandroid:name=".InstallResultReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="android.content.pm.extra.STATUS"/></intent-filter></receiver>

9.0apk静默卸载

UnInstallResultReceiver.addObserver(new InstallResultObserver() {@Overridepublic void onResult(int statusCode,String message) {Log.i(TAG, "statusCode" + statusCode+ ",message:" + message);}});Intent broadcastIntent = new Intent(getActivity(),UnInstallResultReceiver.class);PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1, broadcastIntent,PendingIntent.FLAG_UPDATE_CURRENT);PackageInstaller packageInstaller = mPackageManager.getPackageInstaller();packageInstaller.uninstall(lnkInfo.getUri(),pendingIntent.getIntentSender());

通过广播接收卸载信息

同上安装广播

在AndroidManifest.xml添加卸载广播接收者

  <receiverandroid:name=".UnInstallResultReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="android.content.pm.extra.STATUS"/></intent-filter></receiver>
  相关解决方案