/*
* 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) {
}
}
/*
* 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:
*
*
*
* INSTALL_FAILED_DUPLICATE_PERMISSION
* 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.
*
*
*/
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();
}
/*
**
** 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:");
}
});
}
}
/**
* 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);
}
}
<receiver
android:name=".InstallResultReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.content.pm.extra.STATUS"/>
intent-filter>
receiver>
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());
同上安装广播
<receiver
android:name=".UnInstallResultReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.content.pm.extra.STATUS"/>
intent-filter>
receiver>