欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Android apk静默安装与卸载7.0 9.0

程序员文章站 2022-06-18 13:56:21
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 fil...

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() {
        @Override
        public void onUserActionRequired(Intent intent) {
            PackageInstallObserver.this.onUserActionRequired(intent);
        }

        @Override
        public 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) {
    }
}

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

/*
 * 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.content.pm;

import android.content.Intent;
import android.os.Bundle;

/**
 * API for installation callbacks from the Package Manager.  In certain result cases
 * additional information will be provided.
 * @hide
 */
oneway interface IPackageInstallObserver2 {
    void onUserActionRequired(in Intent intent);

    /**
     * The install operation has completed.  {@code returnCode} holds a numeric code
     * indicating success or failure.  In certain cases the {@code extras} Bundle will
     * contain additional details:
     *
     * <p><table>
     * <tr>
     *   <td>INSTALL_FAILED_DUPLICATE_PERMISSION</td>
     *   <td>Two strings are provided in the extras bundle: EXTRA_EXISTING_PERMISSION
     *       is the name of the permission that the app is attempting to define, and
     *       EXTRA_EXISTING_PACKAGE is the package name of the app which has already
     *       defined the permission.</td>
     * </tr>
     * </table>
     */
    void onPackageInstalled(String basePackageName, int returnCode, String msg, in 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() {

		@Override
		public 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 {

		@Override
		public 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() {

			@Override
			public 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() {

								@Override
								public 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<>();

	@Override
	public 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) {
				// success
				Log.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>() {

			@Override
			public void accept(InstallResultObserver t) {
				t.onResult(statusCode, message);
			}

			@Override
			public Consumer<InstallResultObserver> andThen(
					Consumer<? super InstallResultObserver> after) {
				// TODO Auto-generated method stub
				return 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添加安装广播接收者

        <receiver
            android: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() {

								@Override
								public 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添加卸载广播接收者

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

本文地址:https://blog.csdn.net/chen1103978255/article/details/108122246