【Android】android静默安装/卸载
目的:实现利用隐藏api静默安装/卸载apk条件:必须有 root权限/当前系统签名 之一
工具:android studio/eclipse + adt
文档结构:
D:\PROGRAM FILES\ECLIPSE\INSTALLINBACKGROUNDSAMPLE\SRC
├─android
│└─content
│ └─pm
│ IPackageDeleteObserver.java
│ IPackageInstallObserver.java
│
└─com
└─paulononaka
│InstallInBackgroundSample.java
│
└─apihelper
ApplicationManager.java
OnDeletedPackaged.java
OnInstalledPackaged.java
代码:
package android.content.pm;
import android.content.Intent;
public interface IPackageDeleteObserverextends android.os.IInterface {
public abstract static class Stub extends android.os.Binder implements android.content.pm.IPackageDeleteObserver {
public Stub() {
throw new RuntimeException("Stub!");
}
public static android.content.pm.IPackageInstallObserver asInterface(android.os.IBinder obj) {
throw new RuntimeException("Stub!");
}
public android.os.IBinder asBinder() {
throw new RuntimeException("Stub!");
}
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)
throws android.os.RemoteException {
throw new RuntimeException("Stub!");
}
}
public abstract void packageDeleted(String packageName, int returnCode, String msg)
throws android.os.RemoteException;
}
package android.content.pm;
import android.content.Intent;
public interface IPackageInstallObserver extends android.os.IInterface {
public abstract static class Stub extends android.os.Binder implements android.content.pm.IPackageInstallObserver {
public Stub() {
throw new RuntimeException("Stub!");
}
public static android.content.pm.IPackageInstallObserver asInterface(android.os.IBinder obj) {
throw new RuntimeException("Stub!");
}
public android.os.IBinder asBinder() {
throw new RuntimeException("Stub!");
}
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)
throws android.os.RemoteException {
throw new RuntimeException("Stub!");
}
}
public abstract void packageInstalled(java.lang.String packageName, int returnCode)
throws android.os.RemoteException;
}package com.paulononaka;
import com.paulononaka.apihelper.ApplicationManager;
import com.paulononaka.apihelper.OnInstalledPackaged;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class InstallInBackgroundSample extends Activity {
public static final String TAG = "InstallInBackgroundSample";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
final ApplicationManager am = new ApplicationManager(InstallInBackgroundSample.this);
am.setOnInstalledPackaged(new OnInstalledPackaged() {
public void packageInstalled(String packageName, int returnCode) {
if (returnCode == ApplicationManager.INSTALL_SUCCEEDED) {
Log.d(TAG, "Install succeeded");
} else {
Log.d(TAG, "Install failed: " + returnCode);
}
}
});
final TextView txtApkFilePath = (TextView) findViewById(R.id.txtApkFilePath);
Button btnInstall = (Button) findViewById(R.id.btnInstall);
btnInstall.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
try {
am.uninstallPackage("com.immomo.momo");
//am.installPackage(txtApkFilePath.getText().toString());
} catch (Exception e) {
logError(e);
}
}
});
} catch (Exception e) {
logError(e);
}
}
private void logError(Exception e) {
e.printStackTrace();
Toast.makeText(InstallInBackgroundSample.this, R.string.error, Toast.LENGTH_LONG).show();
}
}package com.paulononaka.apihelper;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.content.Context;
import android.content.Intent;
import android.content.pm.IPackageInstallObserver;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.RemoteException;
public class ApplicationManager {
public final int INSTALL_REPLACE_EXISTING = 2;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} on success.
* @hide
*/
public static final int INSTALL_SUCCEEDED = 1;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package is
* already installed.
* @hide
*/
public static final int INSTALL_FAILED_ALREADY_EXISTS = -1;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package archive
* file is invalid.
* @hide
*/
public static final int INSTALL_FAILED_INVALID_APK = -2;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the URI passed in
* is invalid.
* @hide
*/
public static final int INSTALL_FAILED_INVALID_URI = -3;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package manager
* service found that the device didn't have enough storage space to install the app.
* @hide
*/
public static final int INSTALL_FAILED_INSUFFICIENT_STORAGE = -4;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if a
* package is already installed with the same name.
* @hide
*/
public static final int INSTALL_FAILED_DUPLICATE_PACKAGE = -5;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* the requested shared user does not exist.
* @hide
*/
public static final int INSTALL_FAILED_NO_SHARED_USER = -6;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* a previously installed package of the same name has a different signature
* than the new package (and the old package's data was not removed).
* @hide
*/
public static final int INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* the new package is requested a shared user which is already installed on the
* device and does not have matching signature.
* @hide
*/
public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* the new package uses a shared library that is not available.
* @hide
*/
public static final int INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* the new package uses a shared library that is not available.
* @hide
*/
public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* the new package failed while optimizing and validating its dex files,
* either because there was not enough storage or the validation failed.
* @hide
*/
public static final int INSTALL_FAILED_DEXOPT = -11;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* the new package failed because the current SDK version is older than
* that required by the package.
* @hide
*/
public static final int INSTALL_FAILED_OLDER_SDK = -12;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* the new package failed because it contains a content provider with the
* same authority as a provider already installed in the system.
* @hide
*/
public static final int INSTALL_FAILED_CONFLICTING_PROVIDER = -13;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* the new package failed because the current SDK version is newer than
* that required by the package.
* @hide
*/
public static final int INSTALL_FAILED_NEWER_SDK = -14;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* the new package failed because it has specified that it is a test-only
* package and the caller has not supplied the {@link #INSTALL_ALLOW_TEST}
* flag.
* @hide
*/
public static final int INSTALL_FAILED_TEST_ONLY = -15;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* the package being installed contains native code, but none that is
* compatible with the the device's CPU_ABI.
* @hide
*/
public static final int INSTALL_FAILED_CPU_ABI_INCOMPATIBLE = -16;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* the new package uses a feature that is not available.
* @hide
*/
public static final int INSTALL_FAILED_MISSING_FEATURE = -17;
// ------ Errors related to sdcard
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* a secure container mount point couldn't be accessed on external media.
* @hide
*/
public static final int INSTALL_FAILED_CONTAINER_ERROR = -18;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* the new package couldn't be installed in the specified install
* location.
* @hide
*/
public static final int INSTALL_FAILED_INVALID_INSTALL_LOCATION = -19;
/**
* Installation return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
* the new package couldn't be installed in the specified install
* location because the media is not available.
* @hide
*/
public static final int INSTALL_FAILED_MEDIA_UNAVAILABLE = -20;
/**
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the parser was given a path that is not a file, or does not end with the expected
* '.apk' extension.
* @hide
*/
public static final int INSTALL_PARSE_FAILED_NOT_APK = -100;
/**
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the parser was unable to retrieve the AndroidManifest.xml file.
* @hide
*/
public static final int INSTALL_PARSE_FAILED_BAD_MANIFEST = -101;
/**
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the parser encountered an unexpected exception.
* @hide
*/
public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102;
/**
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the parser did not find any certificates in the .apk.
* @hide
*/
public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103;
/**
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the parser found inconsistent certificates on the files in the .apk.
* @hide
*/
public static final int INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES = -104;
/**
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the parser encountered a CertificateEncodingException in one of the
* files in the .apk.
* @hide
*/
public static final int INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING = -105;
/**
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the parser encountered a bad or missing package name in the manifest.
* @hide
*/
public static final int INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106;
/**
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the parser encountered a bad shared user id name in the manifest.
* @hide
*/
public static final int INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID = -107;
/**
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the parser encountered some structural problem in the manifest.
* @hide
*/
public static final int INSTALL_PARSE_FAILED_MANIFEST_MALFORMED = -108;
/**
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the parser did not find any actionable tags (instrumentation or application)
* in the manifest.
* @hide
*/
public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109;
/**
* Installation failed return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the system failed to install the package because of system issues.
* @hide
*/
public static final int INSTALL_FAILED_INTERNAL_ERROR = -110;
private PackageInstallObserver installobserver;
private PackageDeleteObserver uninstallobserver;
private PackageManager pm;
private Method installmethod;
private Method uninstallmethod;
private OnInstalledPackaged onInstalledPackaged;
private OnDeletedPackaged onDeletedPackaged;
class PackageInstallObserver extends IPackageInstallObserver.Stub {
@Override
public void packageInstalled(String packageName, int returnCode) throws RemoteException {
if (onInstalledPackaged != null) {
onInstalledPackaged.packageInstalled(packageName, returnCode);
}
}
}
class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
@Override
public void packageDeleted(String packageName, int returnCode, String msg) throws RemoteException {
if (onDeletedPackaged != null) {
onDeletedPackaged.packageDeleted(packageName, returnCode, msg);
}
}
}
public ApplicationManager(Context context) throws SecurityException, NoSuchMethodException {
installobserver = new PackageInstallObserver();
uninstallobserver = new PackageDeleteObserver();
pm = context.getPackageManager();
Class<?>[] installtypes = new Class[] {Uri.class, IPackageInstallObserver.class, int.class, String.class};
Class<?>[] uninstalltypes = new Class[] {String.class, IPackageDeleteObserver.class, int.class};
installmethod = pm.getClass().getMethod("installPackage", installtypes);
uninstallmethod = pm.getClass().getMethod("deletePackage", uninstalltypes);
}
public void setOnInstalledPackaged(OnInstalledPackaged onInstalledPackaged) {
this.onInstalledPackaged = onInstalledPackaged;
}
public void installPackage(String apkFile) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
installPackage(new File(apkFile));
}
public void installPackage(File apkFile) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
if (!apkFile.exists()) throw new IllegalArgumentException();
Uri packageURI = Uri.fromFile(apkFile);
installPackage(packageURI);
}
public void installPackage(Uri apkFile) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
installmethod.invoke(pm, new Object[] {apkFile, installobserver, INSTALL_REPLACE_EXISTING, null});
}
public void uninstallPackage(String packageName) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
uninstallmethod.invoke(pm, new Object[] {packageName, uninstallobserver, 0});
}
}package com.paulononaka.apihelper;
public interface OnDeletedPackaged {
public void packageDeleted(String packageName, int returnCode, String msg);
}package com.paulononaka.apihelper;
public interface OnInstalledPackaged {
public void packageInstalled(String packageName, int returnCode);
}androidmanifest.xml<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.paulononaka"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="android.uid.system">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".InstallInBackgroundSample"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
</manifest>这里利用反射机制访问隐藏api,原本卸载的过程是,通过intent跳转到系统卸载activity中,经过用户确认才可以卸载,而直接在apk中执行系统activity的操作需要系统权限,
因此需要root过或者用特定android系统签名过,才可以当作系统app安装。root法比较通用,而签名法,由于大多数手机厂商都会修改android因此签名文件都不是原生android的,签名文件本身不会给你,因此只能在模拟器里耍耍,在自己手机里大部分是玩不转的。
签名命令:java -jar signapk.jar platform.x509.pemplatform.pk8input.apk output.apk
signapk.jar可以在android改之理这个软件中获取
platform.x509.pemplatform.pk8这2各是签名文件,在android源码目录\build\target\product\security\中可以找到
另附android源码下载大法——windows:
(需要python,需要代理或翻墙)
①安装git http://rj.baidu.com/soft/detail/30195.html?ald
②安装tortoisegit http://www.baidu.com/link?url=87PgszcFBx5ca3Q3yUCh71fQC53NodwETkJcCzsDS9nH4GF-jRo81vNzzoyh_F0s&wd=&eqid=d545d79a000265f60000000356739d84
③(设置代理啥的就不说了)git clone https://android.googlesource.com/platform/manifest.git 得到manifest文件夹
④manifest文件夹中,右键git bash here,命令git tag得到分支:
lichao26@B00000039559AB MINGW64 /e/1/manifest1/manifest (master)
$ git tag
adt_23.0.3
android-1.6_r1.1_
android-1.6_r1.2_
android-1.6_r1.3_
android-1.6_r1.4_
android-1.6_r1.5_
android-1.6_r1_
android-1.6_r2_
android-2.0.1_r1_
android-2.0_r1_
android-2.1_r1_
android-2.1_r2.1p2_
android-2.1_r2.1p_
android-2.1_r2.1s_
android-2.1_r2_
android-2.2.1_r1_
android-2.2.1_r2_
android-2.2.2_r1_
android-2.2.3_r1
android-2.2.3_r2
android-2.2.3_r2.1
android-2.2_r1.1_
android-2.2_r1.2_
android-2.2_r1.3_
android-2.2_r1_
android-2.3.1_r1_
android-2.3.2_r1_
android-2.3.3_r1.1_
android-2.3.3_r1_
android-2.3.4_r0.9_
android-2.3.4_r1_
android-2.3.5_r1_
android-2.3.6_r0.9
android-2.3.6_r1
android-2.3.7_r1
android-2.3_r1_
android-4.0.1_r1
android-4.0.1_r1.1
android-4.0.1_r1.2
android-4.0.2_r1
android-4.0.3_r1
android-4.0.3_r1.1
android-4.0.4_r1
android-4.0.4_r1.1
android-4.0.4_r1.2
android-4.0.4_r2
android-4.0.4_r2.1
android-4.1.1_r1
android-4.1.1_r1.1
android-4.1.1_r1_
android-4.1.1_r2
android-4.1.1_r3
android-4.1.1_r4
android-4.1.1_r5
android-4.1.1_r6
android-4.1.1_r6.1
android-4.1.2_r1
android-4.1.2_r2
android-4.1.2_r2.1
android-4.2.1_r1.1
android-4.2.1_r1.2
android-4.2.1_r1__
android-4.2.2_r1.1
android-4.2.2_r1.2
android-4.2.2_r1_
android-4.2_r1___
android-4.3.1_r1
android-4.3_r0.9
android-4.3_r0.9.1
android-4.3_r0.9.1_
android-4.3_r0.9_
android-4.3_r1
android-4.3_r1.1
android-4.3_r1_
android-4.3_r2
android-4.3_r2.1_
android-4.3_r2.1__
android-4.3_r2.2
android-4.3_r2.3
android-4.3_r2_
android-4.3_r3
android-4.3_r3.1
android-4.4.1_r1
android-4.4.1_r1.0.1
android-4.4.2_r1
android-4.4.2_r1.0.1
android-4.4.2_r2
android-4.4.2_r2.0.1
android-4.4.3_r1
android-4.4.3_r1.0.1
android-4.4.3_r1.1
android-4.4.3_r1.1.0.1
android-4.4.4_r1
android-4.4.4_r1.0.1
android-4.4.4_r2
android-4.4.4_r2.0.1
android-4.4_r1
android-4.4_r1.0.1
android-4.4_r1.1
android-4.4_r1.1.0.1
android-4.4_r1.2
android-4.4_r1.2.0.1
android-4.4w_r1
android-5.0.0_r1
android-5.0.0_r1.0.1
android-5.0.0_r2
android-5.0.0_r2.0.1
android-5.0.0_r3
android-5.0.0_r3.0.1
android-5.0.0_r4
android-5.0.0_r4.0.1
android-5.0.0_r5
android-5.0.0_r5.0.1
android-5.0.0_r5.1
android-5.0.0_r5.1.0.1
android-5.0.0_r6
android-5.0.0_r6.0.1
android-5.0.0_r7
android-5.0.0_r7.0.1
android-5.0.1_r1
android-5.0.2_r1
android-5.0.2_r3
android-5.1.0_r1
android-5.1.0_r3
android-5.1.0_r4
android-5.1.0_r5
android-5.1.1_r1
android-5.1.1_r10
android-5.1.1_r12
android-5.1.1_r13
android-5.1.1_r14
android-5.1.1_r15
android-5.1.1_r16
android-5.1.1_r17
android-5.1.1_r18
android-5.1.1_r19
android-5.1.1_r2
android-5.1.1_r20
android-5.1.1_r22
android-5.1.1_r23
android-5.1.1_r24
android-5.1.1_r25
android-5.1.1_r26
android-5.1.1_r28
android-5.1.1_r29
android-5.1.1_r3
android-5.1.1_r30
android-5.1.1_r4
android-5.1.1_r5
android-5.1.1_r6
android-5.1.1_r7
android-5.1.1_r8
android-5.1.1_r9
android-6.0.0_r1
android-6.0.0_r11
android-6.0.0_r12
android-6.0.0_r13
android-6.0.0_r2
android-6.0.0_r23
android-6.0.0_r24
android-6.0.0_r25
android-6.0.0_r26
android-6.0.0_r3
android-6.0.0_r4
android-6.0.0_r41
android-6.0.0_r5
android-6.0.0_r6
android-6.0.0_r7
android-6.0.1_r1
android-6.0.1_r3
android-cts-2.2_r8
android-cts-2.3_r10
android-cts-2.3_r11
android-cts-2.3_r12
android-cts-4.0.3_r1
android-cts-4.0.3_r2
android-cts-4.0_r1
android-cts-4.1_r1
android-cts-4.1_r2
android-cts-4.1_r4
android-cts-4.2_r2
android-cts-4.4_r1
android-cts-4.4_r4
android-cts-5.0_r2
android-cts-5.0_r3
android-cts-5.1_r1
android-cts-5.1_r2
android-cts-5.1_r3
android-cts-6.0_r1
android-cts-6.0_r2
android-cts-verifier-4.0.3_r1
android-cts-verifier-4.0_r1
android-l-preview_r2
android-m-preview
android-m-preview-1
android-m-preview-2
android-sdk-4.0.3-tools_r1
android-sdk-4.0.3_r1
android-sdk-4.4.2_r1
android-sdk-4.4.2_r1.0.1
android-sdk-adt_r16.0.1
android-sdk-adt_r20
android-sdk-support_r11
android-tsl-2.0
android-tsl-3.0
android-tsl-4.0
android-wear-5.0.0_r1
android-wear-5.1.0_r1
android-wear-5.1.1_r1
gradle_0.12.2
gradle_0.13.0
gradle_0.13.1
gradle_0.13.2
gradle_0.13.3
gradle_0.14.0
gradle_0.14.1
gradle_0.14.2
gradle_0.14.3
gradle_0.14.4
gradle_1.0.0
gradle_1.0.0-rc1
gradle_1.0.0-rc2
gradle_1.0.0-rc3
gradle_1.0.0-rc4
gradle_1.0.1
gradle_1.1.0
gradle_1.1.0-rc1
gradle_1.1.0-rc2
gradle_1.1.0-rc3
gradle_1.1.1
gradle_1.1.2
gradle_1.1.3
gradle_1.2.0
gradle_1.2.0-beta1
gradle_1.2.0-rc1
gradle_1.2.1
gradle_1.2.2
gradle_1.2.3
gradle_1.3.0-beta1
gradle_1.3.0-beta2
gradle_1.3.0-beta3
gradle_1.3.0-beta4
gradle_1.3.1
studio-1.4
studio-1.5
studio_0.8.6
studio_1.0.0
studio_1.0.1
ub-jack-arzon-mr2
webview-m40_r1
webview-m40_r2
webview-m40_r3
webview-m40_r4
⑤输入git checkout 分支名,获取想要分支的配置信息default.xml
lichao26@B00000039559AB MINGW64 /e/1/manifest1/manifest (master)
$ git checkout android-1.6_r1.1_
Note: checking out 'android-1.6_r1.1_'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch-name>
HEAD is now at 93b16e4... Manufest for android-1.6_r1.1
⑥编写python脚本下载downloadsource.py
import xml.dom.minidom
import os
from subprocess import call
#downloaded source path
rootdir = "e:/android-4.4.4_r2.0.1"
#git program path
git = "C:/Program Files/Git/bin/git.exe"
dom = xml.dom.minidom.parse("E:/1/manifest/default.xml")
root = dom.documentElement
prefix = git + " clone https://android.googlesource.com/"
suffix = ".git"
if not os.path.exists(rootdir):
os.mkdir(rootdir)
for node in root.getElementsByTagName("project"):
os.chdir(rootdir)
d = node.getAttribute("path")
last = d.rfind("/")
if last != -1:
d = rootdir + "/" + d[:last]
if not os.path.exists(d):
os.makedirs(d)
os.chdir(d)
cmd = prefix + node.getAttribute("name") + suffix
call(cmd)
按自己情况改写rootdirgit和xml路径
按需要删减default.xmlo
运行downloadsource.py即可!
android6.0源码约40+G
查阅android源码的最佳方式:android studio直接打开工程根目录即可
配置了提示的选项后,可以跳转和引用了 ctrl+左键 顶chao哥~:lol 谢谢分享,来一个试试。。。
页:
[1]