Android 高仿豌豆荚 一键安装app 功能 实现

以往我们那些应用市场 帮我们安装app的时候  我们都得点确定,当然你如果 root 以后 不用点确定 也能自动安装了,后来豌豆荚 推出了一个功能 非root的手机也能不点确定 直接帮你安装好。(如果不理解我这段话意思的同学 赶紧试用豌豆荚就知道了)

实际上 这个功能还是蛮重要的,比如我们的app 如果需要强制升级 什么的,用户下载好 你启动installer 然后还要用户点确定才能安装,你看这就是用户体验不好吗 对吧,学会这个可以帮我们做很多事。

当然了 首先要感谢豌豆荚团队 在csdn做的采访,这是这篇文章的基础 http://www.csdn.net/article/1970-01-01/2824737 他透露了这个功能点的point。

好废话不多说 我们直接上代码吧,因为这个功能所涉及到的api 比较小众,我就不过多介绍了,有需要的同学可以参考 官方文档的这个training http://developer.android.com/intl/zh-cn/training/accessibility/service.html

我着重提一下,千万不要用这种方式去实现 流氓软件的流氓功能,作为android 开发,一个好的生态圈是要我们自己去维护的,不要学 百度 那种流氓apk!

首先 我们来定义一个特殊的服务:

 1 package com.example.administrator.powertest;
 2
 3 import android.accessibilityservice.AccessibilityService;
 4 import android.view.accessibility.AccessibilityEvent;
 5 import android.view.accessibility.AccessibilityNodeInfo;
 6
 7 import java.util.List;
 8
 9 /**
10  * 这个服务是不需要你在activity里去开启的,属于系统级别辅助服务 需要在设置里去手动开启 和我们平常app里
11  * 经常使用的service 是有很大不同的 非常特殊
12  * 你可以在 \sdk\samples\android-23\legacy\ApiDemos 这样的目录下 找到这个工程 这个工程下面有一个accessibility
13  * 包 里面有关于这个服务的demo 当然他们那个demo 非常复杂,但是信息量很大,有兴趣深入研究的同学可以多看demo
14  * 我这里只实现最基本的功能 且没有做冗余和异常处理,只包含基础功能,不能作为实际业务上线!
15  */
16 public class MyAccessibilityService extends AccessibilityService {
17     public MyAccessibilityService() {
18     }
19
20     /**
21      * AccessibilityService 这个服务可以关联很多属性,这些属性 一般可以通过代码在这个方法里进行设置,
22      * 我这里偷懒 把这些设置属性的流程用xml 写好 放在manifest里,如果你们要使用的时候需要区分版本号
23      * 做兼容,在老的版本里是无法通过xml进行引用的 只能在这个方法里手写那些属性 一定要注意.
24      * 同时你的业务如果很复杂比如需要初始化广播啊之类的工作 都可以在这个方法里写。
25      */
26     @Override
27     protected void onServiceConnected() {
28         super.onServiceConnected();
29     }
30
31     /**
32      * 当你这个服务正常开启的时候,就可以监听事件了,当然监听什么事件,监听到什么程度 都是由给这个服务的属性来决定的,
33      * 我的那些属性写在xml里了。
34      */
35     @Override
36     public void onAccessibilityEvent(AccessibilityEvent event) {
37         /**
38          * 事件是分很多种的,我这里是最简单的那种,只演示核心功能,如果要做成业务上线 这里推荐一个方法可以快速理解这里的type属性。
39          * 把这个type的int 值取出来 并转成16进制,然后去AccessibilityEvent 源码里find。顺便看注释 ,这样是迅速理解type类型的方法
40          */
41         final int eventType = event.getEventType();
42         switch (eventType) {
43             case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
44                 //这个地方没什么好说的 你就理解成 找到当前界面 包含有安装 这个关键词的 所有节点就可以了。返回这些节点的list
45                 //注意这里的find 其实是contains的意思,比如你界面上有2个节点,一个节点内容是安装1 一个节点内容是安装2,那这2个节点是都会返回过来的
46                 //除了有根据Text找节点的方法 还有根据Id找节点的方法。考虑到众多手机rom都不一样,这里需要大家多测试一下,有的rom packageInstall
47                 //定制的比较深入,可能和官方rom里差的很远 这里就要做冗余处理,可以告诉大家一个小技巧 你就把这些rom的 安装器打开 然后
48                 //通过ddms里 看view结构的按钮 直接进去看就行了,可以直接看到那个界面属于哪个包名,也可以看到你要捕获的那个按钮的id是什么 很方便!
49                 List<AccessibilityNodeInfo> list = event.getSource().findAccessibilityNodeInfosByText("安装");
50                 if (null!=list){
51                     for (AccessibilityNodeInfo info : list) {
52                         if (info.getText().toString().equals("安装"))
53                         {
54                             //找到你的节点以后 就直接点击他就行了
55                             info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
56                         }
57                     }
58                 }
59                 break;
60             default:
61                 break;
62         }
63     }
64     @Override
65     public void onInterrupt() {
66
67     }
68 }

服务定义好了 就要在配置文件里配置一下,看manifest的主要代码:

 1 <!-- label 这个就是在设置界面显示的label 应该比较好理解了-->
 2         <service
 3             android:name=".MyAccessibilityService"
 4             android:exported="true"
 5             android:label="女神的自动装"
 6             android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
 7             <intent-filter>
 8                 <action android:name="android.accessibilityservice.AccessibilityService" />
 9             </intent-filter>
10             <meta-data
11                 android:name="android.accessibilityservice"
12                 android:resource="@xml/taskbackconfig" />
13         </service>

然后我们在res路径下 新建一个xml 文件夹 并在下面 新建一个xml文件取名为taskbackconfig.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!--
 3   Copyright (C) 2011 The Android Open Source Project
 4
 5   Licensed under the Apache License, Version 2.0 (the "License");
 6   you may not use this file except in compliance with the License.
 7   You may obtain a copy of the License at
 8
 9        http://www.apache.org/licenses/LICENSE-2.0
10
11   Unless required by applicable law or agreed to in writing, software
12   distributed under the License is distributed on an "AS IS" BASIS,
13   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   See the License for the specific language governing permissions and
15   limitations under the License.
16  -->
17 <!--
18 这个就是给我们的AccessibilityService 设置属性的,当然你也可以在代码里 的 connnect函数里 手动设置。可以向下兼容。
19 accessibilityFeedbackType 这个属性如果不设置的话 我们那个onAccessibilityEvent 这个回调函数 根本回调不了 所以这里要注意
20 packageNames 这个属性 就是捕获什么app的行为的,比如我这里写的包名是packageinstaller 那就肯定只能捕获安装器的 事件了
21 有的rom 安装器可能不是这个包名 那你就要进行特殊设置了,此外这个属性你如果什么都不写 就意味着 你可以捕获所有手机的动作
22 如果你要做流氓软件的话 可以packageNames 里面什么都不写。。。甚至可以操作支付宝 给你打钱。。。如果你知道用户密码的话。
23 当然你如果真这么做了 相信捕获一次用户输入密码的行为 也是很容易的。。细思极恐 我就不往下深入了。。。
24
25 description 这个就是对你那个申请服务的时候说明了,可以写的煽情一点 让用户打开这个服务的可能性更高一点。。。
26 -->
27 <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
28     android:accessibilityEventTypes="typeAllMask"
29     android:notificationTimeout="100"
30     android:packageNames="com.android.packageinstaller"
31     android:accessibilityFeedbackType="feedbackSpoken"
32     android:canRetrieveWindowContent="true"
33     android:description="@string/hint" />

到此时就差不多了,我们再把activity的代码放上来:

  1 package com.example.administrator.powertest;
  2
  3 import android.content.BroadcastReceiver;
  4 import android.content.Context;
  5 import android.content.Intent;
  6 import android.content.IntentFilter;
  7 import android.net.Uri;
  8 import android.os.Bundle;
  9 import android.provider.Settings;
 10 import android.support.design.widget.FloatingActionButton;
 11 import android.support.design.widget.Snackbar;
 12 import android.support.v4.content.LocalBroadcastManager;
 13 import android.support.v7.app.AppCompatActivity;
 14 import android.support.v7.widget.Toolbar;
 15 import android.util.Log;
 16 import android.view.View;
 17 import android.view.Menu;
 18 import android.view.MenuItem;
 19 import android.widget.TextView;
 20
 21 import java.io.File;
 22
 23 public class MainActivity extends AppCompatActivity {
 24
 25     private TextView tv,installTv;
 26     /**
 27      * 你得引导用户去设置界面吗,你不能让用户自己去找吧。
 28      */
 29     private static final Intent sSettingsIntent =
 30             new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
 31     //这里就假设想要安装的apk 是扇贝网 并且在sd卡根目录下面
 32     private static final String FILE_PATH="/mnt/sdcard/shanbeidanci6.0.000.apk";
 33
 34
 35     @Override
 36     protected void onCreate(Bundle savedInstanceState) {
 37         super.onCreate(savedInstanceState);
 38         setContentView(R.layout.activity_main);
 39         Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
 40         setSupportActionBar(toolbar);
 41
 42         FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
 43         fab.setOnClickListener(new View.OnClickListener() {
 44             @Override
 45             public void onClick(View view) {
 46                 Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
 47                         .setAction("Action", null).show();
 48             }
 49         });
 50
 51         tv = (TextView) findViewById(R.id.tv);
 52         tv.setOnClickListener(new View.OnClickListener() {
 53
 54             @Override
 55             public void onClick(View v) {
 56                 startActivity(sSettingsIntent);
 57             }
 58         });
 59         installTv=(TextView)this.findViewById(R.id.tv2);
 60         installTv.setOnClickListener(new View.OnClickListener(){
 61
 62             @Override
 63             public void onClick(View v) {
 64                 //调用安装器去安装我们的apk 一键安装开始啦,如果用户把那个服务打开了的话。
 65                 Intent intent = new Intent(Intent.ACTION_VIEW);
 66                 intent.setDataAndType(Uri.fromFile(new File(FILE_PATH)), "application/vnd.android.package-archive");
 67                 startActivity(intent);
 68             }
 69         });
 70     }
 71
 72     @Override
 73     public boolean onCreateOptionsMenu(Menu menu) {
 74         // Inflate the menu; this adds items to the action bar if it is present.
 75         getMenuInflater().inflate(R.menu.menu_main, menu);
 76         return true;
 77     }
 78
 79     private class ResponseReceiver extends BroadcastReceiver {
 80
 81         public void onReceive(Context context, Intent intent) {
 82
 83             tv.setText(intent.getStringExtra("msg"));
 84         }
 85     }
 86
 87     @Override
 88     public boolean onOptionsItemSelected(MenuItem item) {
 89         // Handle action bar item clicks here. The action bar will
 90         // automatically handle clicks on the Home/Up button, so long
 91         // as you specify a parent activity in AndroidManifest.xml.
 92         int id = item.getItemId();
 93
 94         //noinspection SimplifiableIfStatement
 95         if (id == R.id.action_settings) {
 96             return true;
 97         }
 98
 99         return super.onOptionsItemSelected(item);
100     }
101 }

到此所有代码就结束了,如果你想做的好一点 ,请自己做冗余异常处理,我这里主要演示功能就不做的那么细致了,最后看下跑起来的效果吧:

时间: 2024-11-04 11:12:52

Android 高仿豌豆荚 一键安装app 功能 实现的相关文章

Android高仿QQ消息滑动删除(附源码)

大家都应该使用过QQ吧,他的消息中可以滑动删除功能,我觉得比较有意思,所以模仿写了一个,并且修改了其滑动算法.我先贴几个简单示范图吧 其实主要用的是算法以及对ListView的把控. 一下是适配器的类 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

(android高仿系列)今日头条 --新闻阅读器 (三) 完结 、总结 篇

从写第一篇今日头条高仿系列开始,到现在已经过去了1个多月了,其实大体都做好了,就是迟迟没有放出来,因为我觉得,做这个东西也是有个过程的,我想把这个模仿中一步一步学习的过程,按照自己的思路写下来,在根据碰到的知识点和问题,并且罗列出这些东西的知识点和使用方法.如果你单纯的把做好的一个DEMO拿去改改用用,那样,你永远不知道里面用到的内容是涉及到什么知识点,用什么方法实现,那样就没有多少提升价值而言了. 近期都是在通过开发文档把以前的一些东西重新过一遍,看好多网友都催促想要新版本的,那我就在这里先把

Android 高仿 频道管理----网易、今日头条、腾讯视频 (可以拖动的GridView)附源码DEMO

距离上次发布(android高仿系列)今日头条 --新闻阅读器 (二) 相关的内容已经半个月了,最近利用空闲时间,把今日头条客户端完善了下.完善的功能一个一个全部实现后,就放整个源码.开发的进度就是按照一个一个功能的思路走的,所以开发一个小的功能,如果有用,就写一个专门的博客以便有人用到独立的功能可以方便使用. 这次实现的功能是很多新闻阅读器(网易,今日头条,360新闻等)以及腾讯视频等里面都会出现的频道管理功能. 下面先上这次实现功能的效果图:(注:这个效果图没有拖拽的时候移动动画,DEMO里

Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭【学习鸿洋_视频博客笔记总结】

学习鸿洋博客:http://blog.csdn.net/lmj623565791/article/details/39257409 学习鸿洋视频:慕课网视频 看看Android 高仿 QQ5.0 侧滑菜单效果 自定义控件实现效果: 技术上,继承HorizontalScrollView 加上自定义ViewGroup来实现: 1.onMeasure:决定内部View(子View)的宽和高,以及自己的宽和高 2.onLayout:决定子View的放置位置 3.onTouchEvent[监听动作] 自定

android高仿微信拍照、多选、预览、删除(去除相片)相册功能

先声明授人与鱼不如授人与渔,只能提供一个思路,当然需要源码的同学可以私下有偿问我要源码:QQ:508181017 工作了将近三年时间了,一直没正儿八经的研究系统自带的相册和拍照,这回来个高仿微信的拍照.多选.预览.删除(去除相片)相册功能,之前开发的所有应用都带有这需求,但是一直都不实用!废话就不多说了,先来捋一下思路: 1.拍照能实时保存到本地并实时查询(不必用广播或者服务) 2.拍照保存到到自定义路径并根据不同文件夹显示文件夹下的相片 3.多选规定张数图片 4.用到的集合有: (1).所有相

Android 高仿微信实时聊天 基于百度云推送

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38799363 ,本文出自:[张鸿洋的博客] 一直在仿微信界面,今天终于有幸利用百度云推送仿一仿微信聊天了~~~ 首先特别感谢:weidi1989分享的Android之基于百度云推送IM ,大家可以直接下载:省了很多事哈,本例中也使用了weidi的部分代码,凡是@author way的就是weidi1989的代码~~ 1.效果图 核心功能也就上面的两张图了~~~我拿着手机和模拟器

Android高仿微信头像裁剪

最近公司的APP很多用户反应无法上传头像,于是打算修改原来头像裁剪的代码.参考微信.QQ.唱吧头像裁剪的操作,决定就仿微信头像裁剪来上传用户头像,在Android大神鸿洋的一篇高仿微信头像的博客(博客地址结尾会贴出来)的基础上加了一些代码,加的代码主要增加如下的功能: 1.增加对大图的处理,缩放到我们裁剪框的大小. 2.裁剪后的图片保存到临时文件里,把临时文件的路径返回到需要处理的界面,因为在三星S4传byte数组返回数据时会闪退,传路径则正常. 3.对有些系统返回旋转过的图片进行处理. 这个功

Android 高仿微信头像截取 打造不一样的自定义控件

转载请表明出处:http://blog.csdn.net/lmj623565791/article/details/39761281,本文出自:[张鸿洋的博客] 1.概述 前面已经写了关于检测手势识别的文章,如果不了解可以参考:Android 手势检测实战 打造支持缩放平移的图片预览效果(下).首先本篇文章,将对之前博客的ZoomImageView代码进行些许的修改与改善,然后用到我们的本篇博客中去,实现仿微信的头像截取功能,当然了,个人觉得微信的截取头像功能貌似做得不太好,本篇博客准备去其糟粕

Android 高仿微信头像截取 打造不一样的自己定义控件

转载请表明出处:http://blog.csdn.net/lmj623565791/article/details/39761281,本文出自:[张鸿洋的博客] 1.概述 前面已经写了关于检測手势识别的文章.假设不了解能够參考:Android 手势检測实战 打造支持缩放平移的图片预览效果(下).首先本篇文章,将对之前博客的ZoomImageView代码进行些许的改动与改善,然后用到我们的本篇博客中去,实现仿微信的头像截取功能.当然了.个人觉得微信的截取头像功能貌似做得不太好.本篇博客准备去其糟粕