今天个人几篇文章介绍了改安装应用的文章. 关联文章的地址

在android机上安装APK时一般都是借助PC端的91手机助手或者豌豆荚之类的工具;或者直接将APK下载到android机子上手动点击安装,手动安装时系统会弹出“是不是要安装该应用程序?”的对话框让你选择是不是安装,如果一次只安装一两个APK还可以在每次弹出对话框时选择“安装“,如果一次须要安装数十个时这是相称费劲而且容易遗漏APK没有安装的。

安装应用android批量安装APK_第1张图片

能不能自己写个应用来实现一次批量安装全部APK呢?谜底是肯定的,但是对于一个只熟悉android应用开发的人员是办不到的。因为google为了避免出于一些特殊目的的开发人员编写应用程序偷偷的在你的android机子上安装一些有特殊目的的APK,已将静默安装APK的API屏蔽了,在官方发布的SDK中是没有这样的API给你调用的。但是对于系统开发人员还是很容易开收回这样的应用的,因为我们可以在编译系统时去编译我们调用了google隐藏了的API的应用。

先上个我写的批量安装APK应用的界面和批量安装APK时的效果图,该应用实现的功能是先扫描外置SD、TF卡下的全部APK,点击”安装APK“按钮后即开始一次批量安装完扫描到的APK,不须要用户去干预。

安装应用android批量安装APK_第2张图片

安装应用android批量安装APK_第3张图片

该应用重要用到的是android.content.pm.PackageManager类下的installPackage方法来实现静默安装全部APK的。

工程文件列表:

updatepackage│  .classpath│  .project│  Android.mk│  AndroidManifest.xml│  MainActivity.apk│  ├─res│  ├─drawable│  │      back.jpg│  │      │  ├─drawable-hdpi│  │      ic_action_search.png│  │      ic_launcher.png│  │      │  ├─drawable-ldpi│  │      ic_launcher.png│  │      │  ├─drawable-mdpi│  │      ic_action_search.png│  │      ic_launcher.png│  │      │  ├─drawable-xhdpi│  │      ic_action_search.png│  │      ic_launcher.png│  │      │  ├─layout│  │      activity_main.xml│  │      │  ├─menu│  │      activity_main.xml│  │      │  ├─values│  │      dimens.xml│  │      strings.xml│  │      styles.xml│  │      │  └─values-large│          dimens.xml│          └─src    └─com        └─example            └─adnroid                └─updatepackage                        ApkFile.java                        ApkSearchUtils.java                        MainActivity.java                        UpdateBroadcastReceiver.java

android系统源代码下添加我们的updatepackage工程,工程下添加用于编译的Android.mk文件内容如下所示:

LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE_TAGS := optionalLOCAL_SRC_FILES := $(call all-subdir-java-files)LOCAL_PACKAGE_NAME := MainActivityLOCAL_DEX_PREOPT :=falseLOCAL_CERTIFICATE := platforminclude $(BUILD_PACKAGE)

布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"     >       <TextView        android:id="@+id/textView1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="10dip"        android:text="@string/textview1text"/>    <ProgressBar        android:id="@+id/progressBar1"        style="?android:attr/progressBarStyleHorizontal"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="10dip"        />    <TextView        android:id="@+id/textView2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="10dip"        android:text= "@string/textview2text"/>    <Button        android:id="@+id/button1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="10dip"        android:text="@string/button1text"/>  </LinearLayout>

AndroidManifest.xml文件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.adnroid.updatepackage"    android:versionCode="1"    android:versionName="1.0"     >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="8" />    <application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.example.adnroid.updatepackage.MainActivity"            android:label="@string/title_activity_main"             android:launchMode="singleTask">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.DEFAULT" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <receiver android:name="UpdateBroadcastReceiver" android:enabled="true">            <intent-filter >                <action android:name="com.example.adnroid.updatepackage.hello"/>            </intent-filter>        </receiver>    </application><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_PHONESTATE" /><uses-permission android:name="android.permission.INSTALL_PACKAGES" /><uses-permission android:name="android.permission.DELETE_PACKAGES" /><uses-permission android:name="android.permission.CLEAR_APP_CACHE" /><uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" /></manifest>

重要界面MainActivity.java代码:

每日一道理
无知者为梦想中的虚幻而苦苦等待,换回的不是所求的,而是岁月在脸上留下的印痕,一事无成的人一生便是虚度。生活中,与其花时间去等待,不如加快步伐去追寻理想,试着与时间赛跑,也许身躯、心理会感到劳累,但这样的生活毕竟是充实的。
package com.example.adnroid.updatepackage;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.app.Activity;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Button;import android.widget.ProgressBar;import android.widget.TextView;import android.content.Intent;import android.net.Uri;import java.io.File;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.content.pm.PackageManager.NameNotFoundException;import android.content.pm.IPackageInstallObserver;public class MainActivity extends Activity {int count,i;ApkSearchUtils apksearchutils;private static final int  UPDATE = 0;ProgressBar progressbar1;Button button1;TextView textview1;TextView textview2;private final int INSTALL_COMPLETE = 1;boolean threadrun=true;boolean installcomplete=false;private final int INSTALL_COMPLETED = 1;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        button1=(Button)findViewById(R.id.button1);        progressbar1=(ProgressBar)findViewById(R.id.progressBar1);        textview1=(TextView)findViewById(R.id.textView1);        textview2=(TextView)findViewById(R.id.textView2);        progressbar1.setMax(100);        apksearchutils=new ApkSearchUtils(this);        apksearchutils.FindAllAPKFile(new File("/mnt/sdcard/"));            count=apksearchutils.getMyFiles().size();i=0;Log.e("zkliu","count:"+String.valueOf(count)+","+"i:"+String.valueOf(i));        button1.setOnClickListener(new Button.OnClickListener() {@Overridepublic void onClick(View arg0) {        new Thread(new Runnable() {        @Overridepublic void run() {threadrun=true;installcomplete=true;while(threadrun){try{if(!installcomplete){Thread.sleep(10);}else{installcomplete=false;Message msg=new Message();msg.what=UPDATE;myhandler.sendMessage(msg);    }}catch(Exception e){e.printStackTrace();}}button1.setEnabled(true);}}).start();}});            }    Handler myhandler=new Handler(){    public void handleMessage(android.os.Message msg) {    switch(msg.what){    case UPDATE:if(i<count){button1.setEnabled(false);    progressbar1.setProgress((int)((double)(i+1)/(double)count*100));    textview1.setText("安装进度:"+String.valueOf((int)((double)(i+1)/(double)count*100))+"%");    textview2.setText("当前安装文件为:"+apksearchutils.getMyFiles().get(i).getFilePath());    Log.e("zkliu",R.string.textview2text+apksearchutils.getMyFiles().get(i).getFilePath());Uri uri = Uri.fromFile(new File(apksearchutils.getMyFiles().get(i).getFilePath()));int installFlags = 0;PackageManager pm = getPackageManager();try {PackageInfo pi = pm.getPackageInfo(apksearchutils.getMyFiles().get(i).getPackageName(),PackageManager.GET_UNINSTALLED_PACKAGES);if(pi != null) {    installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;}} catch (NameNotFoundException e) {}   PackageInstallObserver observer = new PackageInstallObserver();pm.installPackage(uri, observer, installFlags,apksearchutils.getMyFiles().get(i).getPackageName());    i++;}else{threadrun=false;button1.setEnabled(true);}    break;case INSTALL_COMPLETED:installcomplete=true;break;    }    }    };    class PackageInstallObserver extends IPackageInstallObserver.Stub {        public void packageInstalled(String packageName, int returnCode) {            Message msg = myhandler.obtainMessage(INSTALL_COMPLETED);            msg.arg1 = returnCode;            myhandler.sendMessage(msg);        }    };    @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.activity_main, menu);        return true;    }    }

在编译android系统时编译该应用的指令如下所示:

root@l-desktop:~/A13/android4.0# source build/envsetup.shincluding device/samsung/maguro/vendorsetup.shincluding device/samsung/tuna/vendorsetup.shincluding device/softwinner/common/vendorsetup.shincluding device/softwinner/nuclear-evb_mmc/vendorsetup.shincluding device/softwinner/nuclear-evb/vendorsetup.shincluding device/softwinner/nuclear-mini/vendorsetup.shincluding device/ti/panda/vendorsetup.shincluding sdk/bash_completion/adb.bashroot@l-desktop:~/A13/android4.0# cd device/softwinner/common/packages/updatepackage/root@l-desktop:~/A13/android4.0/device/softwinner/common/packages/updatepackage# mmm ./find: `device/softwinner/nuclear-evb/apkwithlib': 没有那个文件或目录find: `device/softwinner/nuclear-evb/apkwithlib/lib': 没有那个文件或目录============================================PLATFORM_VERSION_CODENAME=RELPLATFORM_VERSION=4.0.4TARGET_PRODUCT=fullTARGET_BUILD_VARIANT=engTARGET_BUILD_TYPE=releaseTARGET_BUILD_APPS=TARGET_ARCH=armTARGET_ARCH_VARIANT=armv7-aHOST_ARCH=x86HOST_OS=linuxHOST_BUILD_TYPE=releaseBUILD_ID=IMM76D============================================make:进入目录'/root/A13/android4.0'target R.java/Manifest.java: MainActivity (out/target/common/obj/APPS/MainActivity_intermediates/src/R.stamp)Warning: AndroidManifest.xml already defines versionCode (in http://schemas.android.com/apk/res/android); using existing value in manifest.Warning: AndroidManifest.xml already defines versionName (in http://schemas.android.com/apk/res/android); using existing value in manifest.Warning: AndroidManifest.xml already defines minSdkVersion (in http://schemas.android.com/apk/res/android); using existing value in manifest.Warning: AndroidManifest.xml already defines targetSdkVersion (in http://schemas.android.com/apk/res/android); using existing value in manifest.target Java: MainActivity (out/target/common/obj/APPS/MainActivity_intermediates/classes)Copying: out/target/common/obj/APPS/MainActivity_intermediates/classes-jarjar.jarCopying: out/target/common/obj/APPS/MainActivity_intermediates/emma_out/lib/classes-jarjar.jarCopying: out/target/common/obj/APPS/MainActivity_intermediates/classes.jarCopying: out/target/common/obj/APPS/MainActivity_intermediates/noproguard.classes.jartarget Dex: MainActivityCopying: out/target/common/obj/APPS/MainActivity_intermediates/noproguard.classes.dextarget Package: MainActivity (out/target/product/generic/obj/APPS/MainActivity_intermediates/package.apk)Warning: AndroidManifest.xml already defines versionCode (in http://schemas.android.com/apk/res/android); using existing value in manifest.Warning: AndroidManifest.xml already defines versionName (in http://schemas.android.com/apk/res/android); using existing value in manifest.Warning: AndroidManifest.xml already defines minSdkVersion (in http://schemas.android.com/apk/res/android); using existing value in manifest.Warning: AndroidManifest.xml already defines targetSdkVersion (in http://schemas.android.com/apk/res/android); using existing value in manifest. 'out/target/common/obj/APPS/MainActivity_intermediates/classes.dex' as 'classes.dex'...Install: out/target/product/generic/system/app/MainActivity.apkmake:离开目录“/root/A13/android4.0”

如果须要完整工程,可以发邮件到:229425962@qq.com索取。

文章结束给大家分享下程序员的一些笑话语录: 话剧:程序员过沟
  本剧内容纯属虚构,如有雷同……HEHE……俺也没办法了。
  话说某市街道改建,某某软件公司门口横七竖八挖了几条大沟。一群程序员(SDK程序员赵某,VB程序员钱某,VC程序员孙某,DELPHI程序员李某)下班从公司里出来,看到门前的几条沟,于是各显神通……门前第一条沟也就半米来宽,SDK程序员赵某二话没说,轻轻一跃跳了过去,看到其它人纷纷把随身携带的公文包(类库)横在沟上踩着过沟,不屑地说,这么小一条沟,犯得着小题大做用那个吗?看我多么轻松多么洒脱多么……多么……(众人皆怒目横视之……)
  接着第二条沟有点宽度。SDK程序员赵某还是还是一马当先,飞跃而起……不好,还差一点才到……幸好凭着多年的(跳远?编程?)经验,单手抓住沟沿,颤巍巍地爬了上来,嘴里还念念有词“高手就是高手啊,虽然差一点就……不过毕竟……HEHE……跳远是过沟的基础嘛,有基础(SDK)就有一切的说……”(众人作瞠目结舌状……)看到别人跳过去了,可自己又跳不了那么远,只好再想办法了……VB程序员钱某,DELPHI程序员李某打开手提,连上手机,开始上网找可供过沟的控件……VC程序员孙某却不慌不忙,打开公文包,把几块衬板拆了下来,然后三下五除二拼成一个简易木桥……“虽然这几个板子(类)做得不怎么样,不过先把这个项目应付过去,有时间我自己做一个好了……”于是踩着板子过了沟。
  这时钱某和李某也分别找到了合适的东东。钱某找到的是“钢丝绳.ocx”,安装简单,使用方便,拉出一头,对孙某说“大虾,顺手拉兄弟一把……”,于是把绳子系在沟两边的绿化树木上,踩着钢丝就过了沟。刚刚站稳就四方作揖,“小生这里有礼了”。这时一戴着黄袖圈的老太太跳了出来,抓住钱某,“破坏绿化树木,罚款XXXX元,交钱,交钱,交钱!”(老人家作双枪老太婆怒视伪军状
……钱某被逼无奈,只好边掏钱,边对着后台叫道“导演,我这可是因公牺牲,不给个烈士称号也得报销”,后台一个臭鸡蛋飞出,“叫什么叫,我这个月的粮饷还不知哪里去领呢,都什么时代了,你不下岗都不错了……”)
  李某看着刚刚好不容易从台湾拖回来的“铝条.ZIP”

--------------------------------- 原创文章 By 安装和应用 ---------------------------------

更多相关文章

  1. Android中解析与创建XML文件
  2. Android中读取properties文件2
  3. Android下载 文件(APP) 并且静默安装
  4. Android文件读写权限
  5. android 文件选择
  6. Android 实现文件的下载
  7. 《android的SQLite与文件下载》
  8. Android Studio 与git 添加忽略文件

随机推荐

  1. Android开发 FAQ
  2. React Native 适配Android物理返回键,实现
  3. Android作业:一个3D相册源码
  4. unity3d开发一:入门知识+导入模型+旋转脚
  5. android 系统架构介绍
  6. Ubuntu上搭建Android编译环境(1)
  7. Android程序结构
  8. Android免root查看数据库内容
  9. android frameworks 源码介绍
  10. Google解密携手宏达电:确保Android一炮打