本文介绍两种提取完整apk(系统预装的和用户安装的)

一、通过adb提取(适合开发者)

1. adb shell pm list packages找到要提取apk的包名

F:\winadb>adb shell pm list packages
package:com.android.fmradio
package:com.mediatek.gba
package:com.mediatek.ims
package:com.android.cts.priv.ctsshim
package:com.google.android.youtube
package:org.simalliance.openmobileapi.uicc2terminal
package:com.google.android.ext.services
package:com.android.providers.telephony
...

2. adb shell pm path 定位apk所在系统路径

F:\winadb>adb shell pm path com.google.android.youtube
package:/system/app/YouTube/YouTube.apk

3. adb pull <remote> [<local>] 从手机把apk pull下来

F:\winadb>adb pull /system/app/YouTube/YouTube.apk
9745 KB/s (31047955 bytes in 3.111s)

这样三步就把想要的apk pull下来了,但是有个问题,执行第1步时,会dump很多包名,怎么确定那个包名是自己想要提取的apk吗?有些熟悉apk对应的包名一眼就认出来,但是对一个陌生的apk,是很难确定包名的。

二、app实现提取(适合大众)

比如坐高铁(或火车),看见隔壁的小伙伴玩的某款游戏,好像挺有意思,也想玩一下,好不容易向人家问到了,App名字,但是高速奔跑的高铁上没有WIFI,4G/3G网络(2G就不考虑了)又不好,怎么下载呢?如果能离线传输岂不更好?的确有,比如蓝牙、WIFI P2P(WIFI直连)都可以传输文件。这种情况还得apk在手机存储卡,否则也无法分享了。

下面就介绍通过app的方式将app(系统预装的和用户安装的)提取到手机存储(sdcard),实现的原理就像shell命令cp,java的实现是通过文件输入/输出流进行拷贝。(思路借鉴快牙app)

先上一张图,左边是快牙app,右边是本文说的demo

demo上面三个按钮用于过滤显示系统应用和用户自己安装的应用,每个item显示应用的图标、应用的名称、应用的包名、应用所在系统路径,一一对应,很容找到想要备份的apk了,长按弹出ContextMenu即可备份,代码比较简单,就一个类,直接贴出来了

package com.android.backupapp;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;import com.android.backupapp.R.string;import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.UserHandle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;public class MainActivity extends Activity implementsOnCreateContextMenuListener, OnClickListener {private PackageManager mPackageManager;private Button mBtnAllApps;private Button mBtnSystemApps;private Button mBtnDataApps;private ListView mListView;private AppListAdapter mAdapter;public int MID;private static final String BACKUP_PATH = "/sdcard/Backup/";private static final String APK = ".apk";private static final String ODEX = ".odex";private static final String OAT32 = "oat/arm";private static final String OAT64 = "oat/arm64";public static enum AppType {SYSTEM, DATA, ALL}private static final int EVENT_COMPLETE = 1;private Handler mH = new Handler() {public void handleMessage(Message msg) {switch (msg.what) {case EVENT_COMPLETE:Toast.makeText(MainActivity.this, (String) msg.obj,Toast.LENGTH_SHORT).show();break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mListView = (ListView) findViewById(R.id.listview);mListView.setOnCreateContextMenuListener(this);mBtnAllApps = (Button) findViewById(R.id.all_apps);mBtnSystemApps = (Button) findViewById(R.id.system_apps);mBtnDataApps = (Button) findViewById(R.id.data_apps);mBtnAllApps.setOnClickListener(this);mBtnSystemApps.setOnClickListener(this);mBtnDataApps.setOnClickListener(this);mPackageManager = getPackageManager();List<PackageInfo> lists = mPackageManager.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);Collections.sort(lists, new DisplayNameComparator(mPackageManager));mAdapter = new AppListAdapter(this, lists);mListView.setAdapter(mAdapter);}@Overridepublic void onClick(View view) {// TODO Auto-generated method stubif (view == mBtnAllApps) {if (mAdapter.getAppType() != AppType.ALL) {mAdapter.setAppType(AppType.ALL);mAdapter.notifyDataSetChanged();}} else if (view == mBtnSystemApps) {if (mAdapter.getAppType() != AppType.SYSTEM) {mAdapter.setAppType(AppType.SYSTEM);mAdapter.notifyDataSetChanged();}} else if (view == mBtnDataApps) {if (mAdapter.getAppType() != AppType.DATA) {mAdapter.setAppType(AppType.DATA);mAdapter.notifyDataSetChanged();}}}@Overridepublic void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {// TODO Auto-generated method stubMenuInflater inflater = new MenuInflater(this);inflater.inflate(R.menu.context_menu, menu);super.onCreateContextMenu(menu, v, menuInfo);}@Overridepublic boolean onContextItemSelected(MenuItem item) {// TODO Auto-generated method stubAdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();MID = (int) info.id;PackageInfo pi = mAdapter.getItem(MID);switch (item.getItemId()) {case R.id.backup:backupApp(pi);return true;}return super.onContextItemSelected(item);}private Drawable getAppIcon(PackageInfo packageInfo) {return packageInfo.applicationInfo.loadIcon(mPackageManager);}private String getAppName(PackageInfo packageInfo) {return packageInfo.applicationInfo.loadLabel(mPackageManager).toString();}private String getAppPackageName(PackageInfo packageInfo) {return packageInfo.packageName;}private String getAppSourceDir(PackageInfo packageInfo) {return packageInfo.applicationInfo.sourceDir;}private void backupApp(PackageInfo packageInfo) {String source = getAppSourceDir(packageInfo);if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {String key = getAppName(packageInfo);String dest = BACKUP_PATH + key + APK;Toast.makeText(this, R.string.backup_start, Toast.LENGTH_SHORT).show();new Thread(new CopyRunnable(source, dest, key)).start();} else {String path = new File(source).getParent();String name = new File(source).getName();name = name.substring(0, name.indexOf(APK));String kitKat = new File(path).getParent() + File.separator + name+ ODEX;String oat32 = path + File.separator + OAT32 + File.separator+ name + ODEX;String oat64 = path + File.separator + OAT64 + File.separator+ name + ODEX;if (!new File(kitKat).exists() && !new File(oat32).exists()&& !new File(oat64).exists()) {String key = getAppName(packageInfo);if (getAppIcon(packageInfo).equals(getAppPackageName(packageInfo))) {key = name;}String dest = BACKUP_PATH + key + APK;Toast.makeText(this, R.string.backup_start, Toast.LENGTH_SHORT).show();new Thread(new CopyRunnable(source, dest, key)).start();} else {Toast.makeText(this, R.string.apk_has_oat, Toast.LENGTH_SHORT).show();}}}private class CopyRunnable implements Runnable {private String source;private String dest;private String key;public CopyRunnable(String source, String dest, String key) {this.source = source;this.dest = dest;this.key = key;}@Overridepublic void run() {// TODO Auto-generated method stubtry {int length = 1024 * 1024;if (!new File(BACKUP_PATH).exists()) {new File(BACKUP_PATH).mkdirs();}File fDest = new File(dest);if (fDest.exists()) {fDest.delete();}fDest.createNewFile();FileInputStream in = new FileInputStream(new File(source));FileOutputStream out = new FileOutputStream(fDest);FileChannel inC = in.getChannel();FileChannel outC = out.getChannel();int i = 0;while (true) {if (inC.position() == inC.size()) {inC.close();outC.close();Message message = mH.obtainMessage(EVENT_COMPLETE);message.obj = MainActivity.this.getString(R.string.backup_success, key, dest);mH.sendMessage(message);break;}if ((inC.size() - inC.position()) < 1024 * 1024) {length = (int) (inC.size() - inC.position());} else {length = 1024 * 1024;}inC.transferTo(inC.position(), length, outC);inC.position(inC.position() + length);i++;}} catch (Exception e) {// TODO: handle exceptionLog.e("zhouyj", e.toString());}}}private class AppListAdapter extends BaseAdapter {private Context context;private List<PackageInfo> lists;private AppType appType = AppType.DATA;public AppListAdapter(Context context, List<PackageInfo> lists) {this.context = context;this.lists = lists;}public AppType getAppType() {return appType;}public void setAppType(AppType appType) {this.appType = appType;}private List<PackageInfo> getDataList(AppType appType) {List<PackageInfo> l = new ArrayList<PackageInfo>();switch (appType) {case SYSTEM:for (PackageInfo pi : lists) {if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {l.add(pi);}}break;case DATA:for (PackageInfo pi : lists) {if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {l.add(pi);}}break;case ALL:return lists;}return l;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn getDataList(getAppType()).size();}@Overridepublic PackageInfo getItem(int position) {// TODO Auto-generated method stubreturn getDataList(getAppType()).get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubPackageInfo pi = getItem(position);ViewHolder viewHolder = null;if (convertView == null) {viewHolder = new ViewHolder();LayoutInflater mInflater = LayoutInflater.from(context);convertView = mInflater.inflate(R.layout.layout_item, null);viewHolder.imageView = (ImageView) convertView.findViewById(R.id.drawable);viewHolder.tvAppName = (TextView) convertView.findViewById(R.id.app_name);viewHolder.tvPackageName = (TextView) convertView.findViewById(R.id.package_name);viewHolder.tvPath = (TextView) convertView.findViewById(R.id.app_path);convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}viewHolder.imageView.setImageDrawable(getAppIcon(pi));viewHolder.tvAppName.setText(getAppName(pi));viewHolder.tvPackageName.setText(getAppPackageName(pi));viewHolder.tvPath.setText(getAppSourceDir(pi));return convertView;}}private static class ViewHolder {ImageView imageView;TextView tvAppName;TextView tvPackageName;TextView tvPath;}public static class DisplayNameComparator implementsComparator<PackageInfo> {public DisplayNameComparator(PackageManager pm) {mPM = pm;mCollator.setStrength(Collator.PRIMARY);}public final int compare(PackageInfo a, PackageInfo b) {// We want to put the one targeted to another user at the end of the// dialog.CharSequence sa = a.applicationInfo.loadLabel(mPM);if (sa == null)sa = a.packageName;CharSequence sb = b.applicationInfo.loadLabel(mPM);if (sb == null)sb = b.packageName;return mCollator.compare(sa.toString(), sb.toString());}private final Collator mCollator = Collator.getInstance();private PackageManager mPM;}}

Demo完整下载

Android 备份(提取)apk相关推荐

  1. android 备份管理器,最佳Android备份提取器和备份解决方案

    第1部分:如何进行ADB备份 可以使用Android备份提取器轻松备份其数据.如果您的设备安装了Android 4.0及更高版本,则可以轻松执行这些简单的步骤.虽然,它也适用于其他版本,但方法可能会有 ...

  2. 【Android 逆向】APK 文件格式 ( Android 应用安装 | Zip 文件格式 | 使用 Python 代码提取 APK 文件 )

    文章目录 一.Android 应用安装 二.APK 文件格式 三.使用 Python 提取 APK 文件 一.Android 应用安装 APK 是 Android 应用的安装文件 , 现在也有 AAB ...

  3. php获取apk中文应用名,php提取apk包信息 - 搜知道网 - 搜知道社区,C, iOS,Android,golang 等的知识....

    最近在项目中需要使用 php 提取 apk 包的主要信息如包名.应用名称.版本号.入口地址和应用 Icon 等.安卓 apk 的大部分信息都保存在包内的 AndroidManifest.xml 文件中 ...

  4. 【Android】提取Android中已安装app的apk

    提取Android中已安装的apk,这个需求很多时候都会遇到.比如从google play上安装过apk后,如何提取出来给别人用? 本文1. 先介绍转载的apk提取方法并 2. 验证提取出来的apk和 ...

  5. android服务下载apk,Android 一个简单的版本更新下载apk小示例

    一.简介: 1.运用 okhttp + notification 通知栏带进度的下载apk,下载完毕后并自动安装,如果用户取消可在通知栏点击安装,点击一次通知栏移除,同时支持自动静默下载(后台默默下载 ...

  6. [免费专栏] Android安全之APK逆向入门介绍

    也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 Android安全付费专栏长期更新,本篇最新内容请前往: [ ...

  7. php apk包信息,php提取apk包信息

    最近在项目中需要使用 php 提取 apk 包的主要信息如包名.应用名称.版本号.入口地址和应用 Icon 等.安卓 apk 的大部分信息都保存在包内的 AndroidManifest.xml 文件中 ...

  8. 使用 Android 备份和恢复功能留住用户

    随着移动设备厂商不断推出新的型号,用户更换设备的频率也越来越频繁.替换新机时,最让用户头疼的问题之一就是数据迁移了.那么不完善的数据迁移会给用户带来哪些糟糕体验呢?我们从下面的案例来看看用户的烦恼. ...

  9. 钛备份-Android备份神器

    有时候想要获取Android手机里面APK文件,但是市场上又下不到APK源文件,比如Google Play上的应用,你只能下载安装,得不到APK.这时候,钛备份就派上用场了,具体用法这里就不讲了,备份 ...

最新文章

  1. Samtools(CentOS Linux)安装及常用命令详解
  2. linux aptana,Ubuntu 下Aptana Studio 3安装使用
  3. matlab dsp工具箱_GPU中的并行运算,加速你的Matlab程序
  4. oracle的listagg函数
  5. java的队列_java实现队列
  6. Hyperledger Fabric 智能合约实战 (6) 访问链码接口
  7. ssis导入xml_使用XML文件配置SSIS包
  8. 局域网怎么查看单位摄像头_一行代码,实现多平台文件查看传输!
  9. java课程设计实验报告_《java课程设计实验报告.doc
  10. python并发编程gevent模块以及猴子补丁学习
  11. 非法使用爬虫,一互联网公司被端,警方上门,23人被带走…
  12. 在同一局域网连接其他电脑的MySQL数据库
  13. 嗨起来,让你在社交圈里有聊不完的话题
  14. Vue+Springboot项目练手(主要是后端)
  15. ASEMI整流模块MSAD165-16参数,MSAD165-16规格
  16. Redis集群为什么至少需要三个master节点,并且推荐节点数为奇数?
  17. 衡水中学计算机老师,衡水中学资深老师:电脑阅卷本就是一种淘汰机制,学生都不以为然...
  18. 13星座性格购买iphone6s的搞笑反映
  19. 悲观锁、乐观锁和自旋锁
  20. nfc充值java_实测北京公交一卡通NFC手机充值

热门文章

  1. PHP微信开发素材管理,PHP微信开发包,微信开发SDK
  2. python求级数的值_python中的级数和
  3. 如何购买一台腾讯云服务器
  4. 【数据集转换】VOC数据集转COCO数据集·代码实现+操作步骤
  5. Unity的图片轮播
  6. 【计算机二级Python】Python全部内置函数解析与使用
  7. 大疆A型板使用经验分享(八)——FreeRTOS操作系统的使用
  8. 认识Access中的MDE文件
  9. DM数据库配置开机自启动
  10. C++ 缺省参数 详解