版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
【移動應用開發(fā)技術】Android9.0如何靜默apk的代碼
在下給大家分享一下Android9.0如何靜默apk的代碼,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!網(wǎng)上基本都停在8.0就沒人開始分析Android9.0如何靜默apk的代碼,這是我自己之前研究9.0的framework整理出來的,真實源碼整理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
.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#
*
時間
:
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;
//這個暫時用不上
//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();
//這是卸載,不調用
//
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();
mit(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;
ent
=
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
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年消防器材智能化改造升級服務合同2篇
- 2024租賃合同簽訂程序及條件
- 2025年拓展訓練合同范本大全:企業(yè)團隊凝聚力提升計劃3篇
- 二零二四年度2024年三人健身產業(yè)合作合同6篇
- 2025年洗車場車輛停放管理及承包合同3篇
- 2025版航空航天專用鋁合金采購合同書4篇
- 二零二四年云服務器租賃與智能運維合同3篇
- 個人汽車租賃合同樣本 2024年版版B版
- 2025年度臨時臨時設施租賃合同標準范本4篇
- 2025年無償使用政府辦公樓場地舉辦會議合同范本3篇
- 非誠不找小品臺詞
- 2024年3月江蘇省考公務員面試題(B類)及參考答案
- 患者信息保密法律法規(guī)解讀
- 老年人護理風險防控PPT
- 充電樁采購安裝投標方案(技術方案)
- 醫(yī)院科室考勤表
- 鍍膜員工述職報告
- 春節(jié)期間化工企業(yè)安全生產注意安全生產
- 保險行業(yè)加強清廉文化建設
- Hive數(shù)據(jù)倉庫技術與應用
- 數(shù)字的秘密生活:最有趣的50個數(shù)學故事
評論
0/150
提交評論