小編給大家分享一下Android9.0如何靜默apk的代碼,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、文山州ssl等。為成百上千家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的文山州網(wǎng)站制作公司
網(wǎng)上基本都停在8.0就沒(méi)人開(kāi)始分析Android9.0如何靜默apk的代碼,這是我自己之前研究9.0的framework整理出來(lái)的,真實(shí)源碼整理
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
/**
* 作者 :
* 郵箱 : 709847739#qq.com
* 時(shí)間 : 2019/2/21-9:21
* desc :
* version: 1.0
*/
public class PackageManagerCompatP {
private final static String TAG = PackageManagerCompatP.class.getSimpleName();
public static final long MAX_WAIT_TIME = 25 * 1000;
public static final long WAIT_TIME_INCR = 5 * 1000;
private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec";
private Context mContext;
public PackageManagerCompatQ(Context context) {
this.mContext = context;
}
private static class LocalIntentReceiver {
private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>();
private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
@Override
public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
try {
mResult.offer(intent, 5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
public IntentSender getIntentSender() {
Class<?> aClass = null;
try {
aClass = Class.forName("android.content.IntentSender");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (aClass == null) {
return null;
}
try {
Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
Log.i(TAG, "declaredConstructor.toString():" + declaredConstructor.toString());
Log.i(TAG, "declaredConstructor.getName():" + declaredConstructor.getName());
Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();
for (Class<?> parameterType : parameterTypes) {
Class aClass1 = parameterType.getClass();
Log.i(TAG, "parameterTypes...aClass1:" + aClass1.getName());
}
}
} catch (Exception e) {
e.printStackTrace();
}
Constructor constructor = null;
try {
constructor = aClass.getDeclaredConstructor(IIntentSender.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
if (constructor == null) {
return null;
}
Object o = null;
try {
o = constructor.newInstance((IIntentSender) mLocalSender);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return (IntentSender) o;
// new IntentSender((IIntentSender) mLocalSender)
}
public Intent getResult() {
try {
return mResult.take();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
private PackageManager getPm() {
return mContext.getPackageManager();
}
private PackageInstaller getPi() {
return getPm().getPackageInstaller();
}
private void writeSplitToInstallSession(PackageInstaller.Session session, String inPath,
String splitName) throws RemoteException {
long sizeBytes = 0;
final File file = new File(inPath);
if (file.isFile()) {
sizeBytes = file.length();
} else {
return;
}
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(inPath);
out = session.openWrite(splitName, 0, sizeBytes);
int total = 0;
byte[] buffer = new byte[65536];
int c;
while ((c = in.read(buffer)) != -1) {
total += c;
out.write(buffer, 0, c);
}
session.fsync(out);
} catch (IOException e) {
e.printStackTrace();
} finally {
IoUtils.closeQuietly(out);
IoUtils.closeQuietly(in);
IoUtils.closeQuietly(session);
}
}
/**
* 入口方法
* String apkPackageName = ""; //填寫安裝的包名
* String apkPath = "";//填寫安裝的路徑
**/
public void testReplaceFlagSdcardInternal(String apkPackageName, String apkPath) throws Exception {
// Do not run on devices with emulated external storage.
if (Environment.isExternalStorageEmulated()) {
return;
}
int iFlags = 0x00000008;// PackageManager.INSTALL_EXTERNAL 0x00000008
int rFlags = 0;
//這個(gè)暫時(shí)用不上
//InstallParams ip = sampleInstallFromRawResource(iFlags, false);
Uri uri = Uri.fromFile(new File(apkPath));
GenericReceiver receiver = new ReplaceReceiver(apkPackageName);
int replaceFlags = rFlags | 0x00000002;//PackageManager.INSTALL_REPLACE_EXISTING 0x00000002
try {
invokeInstallPackage(uri, replaceFlags, receiver, true);
//assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
} catch (Exception e) {
Log.e(TAG, "Failed with exception : " + e);
} finally {
// cleanUpInstall(ip);
}
}
// class InstallParams {
// Uri packageURI;
//
// PackageParser.Package pkg;
//
// InstallParams(String outFileName, int rawResId) throws PackageParserException {
// this.pkg = getParsedPackage(outFileName, rawResId);
// this.packageURI = Uri.fromFile(new File(pkg.codePath));
// }
//
// InstallParams(PackageParser.Package pkg) {
// this.packageURI = Uri.fromFile(new File(pkg.codePath));
// this.pkg = pkg;
// }
//
// long getApkSize() {
// File file = new File(pkg.codePath);
// return file.length();
// }
// }
//
// private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp)
// throws Exception {
// return installFromRawResource("install.apk", android.R.raw.install, flags, cleanUp, false, -1,
// PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
// }
// private void cleanUpInstall(InstallParams ip) {
//
// }
private void cleanUpInstall(String pkgName) throws Exception {
if (pkgName == null) {
return;
}
Log.i(TAG, "Deleting package : " + pkgName);
try {
final ApplicationInfo info = getPm().getApplicationInfo(pkgName,
PackageManager.MATCH_UNINSTALLED_PACKAGES);
if (info != null) {
//PackageManager.DELETE_ALL_USERS
final LocalIntentReceiver localReceiver = new LocalIntentReceiver();
//這是卸載,不調(diào)用
// getPi().uninstall(pkgName,
// 0x00000002,
// localReceiver.getIntentSender());
localReceiver.getResult();
assertUninstalled(info);
}
} catch (IllegalArgumentException | PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
private static void assertUninstalled(ApplicationInfo info) throws Exception {
File nativeLibraryFile = new File(info.nativeLibraryDir);
Log.e(TAG, "Native library directory " + info.nativeLibraryDir
+ " should be erased" + nativeLibraryFile.exists());
}
private void invokeInstallPackage(Uri packageUri, int flags, GenericReceiver receiver,
boolean shouldSucceed) {
mContext.registerReceiver(receiver, receiver.filter);
synchronized (receiver) {
final String inPath = packageUri.getPath();
PackageInstaller.Session session = null;
try {
final PackageInstaller.SessionParams sessionParams =
new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
try {
//sessionParams.installFlags = flags;
Field installFlags = sessionParams.getClass().getDeclaredField("installFlags");
installFlags.set(sessionParams, flags);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
final int sessionId = getPi().createSession(sessionParams);
session = getPi().openSession(sessionId);
writeSplitToInstallSession(session, inPath, "base.apk");
final LocalIntentReceiver localReceiver = new LocalIntentReceiver();
session.commit(localReceiver.getIntentSender());
final Intent result = localReceiver.getResult();
final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
PackageInstaller.STATUS_FAILURE);
if (shouldSucceed) {
if (status != PackageInstaller.STATUS_SUCCESS) {
Log.e(TAG, "Installation should have succeeded, but got code " + status);
}
} else {
if (status == PackageInstaller.STATUS_SUCCESS) {
Log.e(TAG, "Installation should have failed");
}
// We'll never get a broadcast since the package failed to install
return;
}
// Verify we received the broadcast
long waitTime = 0;
while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
try {
receiver.wait(WAIT_TIME_INCR);
waitTime += WAIT_TIME_INCR;
} catch (InterruptedException e) {
Log.i(TAG, "Interrupted during sleep", e);
}
}
if (!receiver.isDone()) {
Log.e(TAG, "Timed out waiting for PACKAGE_ADDED notification");
}
} catch (IllegalArgumentException | IOException | RemoteException e) {
Log.e(TAG, "Failed to install package; path=" + inPath, e);
} finally {
IoUtils.closeQuietly(session);
mContext.unregisterReceiver(receiver);
}
}
}
private abstract static class GenericReceiver extends BroadcastReceiver {
private boolean doneFlag = false;
boolean received = false;
Intent intent;
IntentFilter filter;
abstract boolean notifyNow(Intent intent);
@Override
public void onReceive(Context context, Intent intent) {
if (notifyNow(intent)) {
synchronized (this) {
received = true;
doneFlag = true;
this.intent = intent;
notifyAll();
}
}
}
public boolean isDone() {
return doneFlag;
}
public void setFilter(IntentFilter filter) {
this.filter = filter;
}
}
class ReplaceReceiver extends GenericReceiver {
String pkgName;
final static int INVALID = -1;
final static int REMOVED = 1;
final static int ADDED = 2;
final static int REPLACED = 3;
int removed = INVALID;
// for updated system apps only
boolean update = false;
ReplaceReceiver(String pkgName) {
this.pkgName = pkgName;
filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
if (update) {
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
}
filter.addDataScheme("package");
super.setFilter(filter);
}
public boolean notifyNow(Intent intent) {
String action = intent.getAction();
Uri data = intent.getData();
String installedPkg = data.getEncodedSchemeSpecificPart();
if (pkgName == null || !pkgName.equals(installedPkg)) {
return false;
}
if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
removed = REMOVED;
} else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
if (removed != REMOVED) {
return false;
}
boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
if (!replacing) {
return false;
}
removed = ADDED;
if (!update) {
return true;
}
} else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
if (removed != ADDED) {
return false;
}
removed = REPLACED;
return true;
}
return false;
}
}
}就這一個(gè)類的封裝,我也是看framework扣出來(lái)的
以上是“Android9.0如何靜默apk的代碼”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
當(dāng)前文章:Android9.0如何靜默apk的代碼
網(wǎng)站路徑:http://chinadenli.net/article6/ppscig.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、自適應(yīng)網(wǎng)站、全網(wǎng)營(yíng)銷推廣、企業(yè)建站、定制網(wǎng)站、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)