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!
首先 我们来定义一个特殊的服务:
- package com.example.administrator.powertest;
- import android.accessibilityservice.AccessibilityService;
- import android.view.accessibility.AccessibilityEvent;
- import android.view.accessibility.AccessibilityNodeInfo;
- import java.util.List;
- /**
- * 这个服务是不需要你在activity里去开启的,属于系统级别辅助服务 需要在设置里去手动开启 和我们平常app里
- * 经常使用的service 是有很大不同的 非常特殊
- * 你可以在 \sdk\samples\android-23\legacy\ApiDemos 这样的目录下 找到这个工程 这个工程下面有一个accessibility
- * 包 里面有关于这个服务的demo 当然他们那个demo 非常复杂,但是信息量很大,有兴趣深入研究的同学可以多看demo
- * 我这里只实现最基本的功能 且没有做冗余和异常处理,只包含基础功能,不能作为实际业务上线!
- */
- public class MyAccessibilityService extends AccessibilityService {
- public MyAccessibilityService() {
- }
- /**
- * AccessibilityService 这个服务可以关联很多属性,这些属性 一般可以通过代码在这个方法里进行设置,
- * 我这里偷懒 把这些设置属性的流程用xml 写好 放在manifest里,如果你们要使用的时候需要区分版本号
- * 做兼容,在老的版本里是无法通过xml进行引用的 只能在这个方法里手写那些属性 一定要注意.
- * 同时你的业务如果很复杂比如需要初始化广播啊之类的工作 都可以在这个方法里写。
- */
- @Override
- protected void onServiceConnected() {
- super.onServiceConnected();
- }
- /**
- * 当你这个服务正常开启的时候,就可以监听事件了,当然监听什么事件,监听到什么程度 都是由给这个服务的属性来决定的,
- * 我的那些属性写在xml里了。
- */
- @Override
- public void onAccessibilityEvent(AccessibilityEvent event) {
- /**
- * 事件是分很多种的,我这里是最简单的那种,只演示核心功能,如果要做成业务上线 这里推荐一个方法可以快速理解这里的type属性。
- * 把这个type的int 值取出来 并转成16进制,然后去AccessibilityEvent 源码里find。顺便看注释 ,这样是迅速理解type类型的方法
- */
- final int eventType = event.getEventType();
- switch (eventType) {
- case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
- //这个地方没什么好说的 你就理解成 找到当前界面 包含有安装 这个关键词的 所有节点就可以了。返回这些节点的list
- //注意这里的find 其实是contains的意思,比如你界面上有2个节点,一个节点内容是安装1 一个节点内容是安装2,那这2个节点是都会返回过来的
- //除了有根据Text找节点的方法 还有根据Id找节点的方法。考虑到众多手机rom都不一样,这里需要大家多测试一下,有的rom packageInstall
- //定制的比较深入,可能和官方rom里差的很远 这里就要做冗余处理,可以告诉大家一个小技巧 你就把这些rom的 安装器打开 然后
- //通过ddms里 看view结构的按钮 直接进去看就行了,可以直接看到那个界面属于哪个包名,也可以看到你要捕获的那个按钮的id是什么 很方便!
- List<AccessibilityNodeInfo> list = event.getSource().findAccessibilityNodeInfosByText("安装");
- if (null!=list){
- for (AccessibilityNodeInfo info : list) {
- if (info.getText().toString().equals("安装"))
- {
- //找到你的节点以后 就直接点击他就行了
- info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
- }
- }
- }
- break;
- default:
- break;
- }
- }
- @Override
- public void onInterrupt() {
- }
- }
服务定义好了 就要在配置文件里配置一下,看manifest的主要代码:
- <!-- label 这个就是在设置界面显示的label 应该比较好理解了-->
- <service
- android:name=".MyAccessibilityService"
- android:exported="true"
- android:label="女神的自动装"
- android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
- <intent-filter>
- <action android:name="android.accessibilityservice.AccessibilityService" />
- </intent-filter>
- <meta-data
- android:name="android.accessibilityservice"
- android:resource="@xml/taskbackconfig" />
- </service>
然后我们在res路径下 新建一个xml 文件夹 并在下面 新建一个xml文件取名为taskbackconfig.xml
- <?xml version="1.0" encoding="utf-8"?>
- <!--
- Copyright (C) 2011 The Android Open Source Project
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
- <!--
- 这个就是给我们的AccessibilityService 设置属性的,当然你也可以在代码里 的 connnect函数里 手动设置。可以向下兼容。
- accessibilityFeedbackType 这个属性如果不设置的话 我们那个onAccessibilityEvent 这个回调函数 根本回调不了 所以这里要注意
- packageNames 这个属性 就是捕获什么app的行为的,比如我这里写的包名是packageinstaller 那就肯定只能捕获安装器的 事件了
- 有的rom 安装器可能不是这个包名 那你就要进行特殊设置了,此外这个属性你如果什么都不写 就意味着 你可以捕获所有手机的动作
- 如果你要做流氓软件的话 可以packageNames 里面什么都不写。。。甚至可以操作支付宝 给你打钱。。。如果你知道用户密码的话。
- 当然你如果真这么做了 相信捕获一次用户输入密码的行为 也是很容易的。。细思极恐 我就不往下深入了。。。
- description 这个就是对你那个申请服务的时候说明了,可以写的煽情一点 让用户打开这个服务的可能性更高一点。。。
- -->
- <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
- android:accessibilityEventTypes="typeAllMask"
- android:notificationTimeout="100"
- android:packageNames="com.android.packageinstaller"
- android:accessibilityFeedbackType="feedbackSpoken"
- android:canRetrieveWindowContent="true"
- android:description="@string/hint" />
到此时就差不多了,我们再把activity的代码放上来:
- package com.example.administrator.powertest;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.net.Uri;
- import android.os.Bundle;
- import android.provider.Settings;
- import android.support.design.widget.FloatingActionButton;
- import android.support.design.widget.Snackbar;
- import android.support.v4.content.LocalBroadcastManager;
- import android.support.v7.app.AppCompatActivity;
- import android.support.v7.widget.Toolbar;
- import android.util.Log;
- import android.view.View;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.widget.TextView;
- import java.io.File;
- public class MainActivity extends AppCompatActivity {
- private TextView tv,installTv;
- /**
- * 你得引导用户去设置界面吗,你不能让用户自己去找吧。
- */
- private static final Intent sSettingsIntent =
- new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
- //这里就假设想要安装的apk 是扇贝网 并且在sd卡根目录下面
- private static final String FILE_PATH="/mnt/sdcard/shanbeidanci6.0.000.apk";
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
- FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
- fab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
- .setAction("Action", null).show();
- }
- });
- tv = (TextView) findViewById(R.id.tv);
- tv.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- startActivity(sSettingsIntent);
- }
- });
- installTv=(TextView)this.findViewById(R.id.tv2);
- installTv.setOnClickListener(new View.OnClickListener(){
- @Override
- public void onClick(View v) {
- //调用安装器去安装我们的apk 一键安装开始啦,如果用户把那个服务打开了的话。
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setDataAndType(Uri.fromFile(new File(FILE_PATH)), "application/vnd.android.package-archive");
- startActivity(intent);
- }
- });
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.menu_main, menu);
- return true;
- }
- private class ResponseReceiver extends BroadcastReceiver {
- public void onReceive(Context context, Intent intent) {
- tv.setText(intent.getStringExtra("msg"));
- }
- }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // Handle action bar item clicks here. The action bar will
- // automatically handle clicks on the Home/Up button, so long
- // as you specify a parent activity in AndroidManifest.xml.
- int id = item.getItemId();
- //noinspection SimplifiableIfStatement
- if (id == R.id.action_settings) {
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
- }
到此所有代码就结束了,如果你想做的好一点 ,请自己做冗余异常处理,我这里主要演示功能就不做的那么细致了,最后看下跑起来的效果吧:
Android 高仿豌豆荚 一键安装app 功能 实现的更多相关文章
- Android 高仿腾讯旗下app的 皮肤加载技术
http://www.cnblogs.com/punkisnotdead/p/4968851.html 以前写的这篇文章 可以高仿出 知乎 新浪微博等 绝大多数app的换肤技术,但是遗漏了腾讯的效果, ...
- (android高仿系列)今日头条 --新闻阅读器 (二)
高仿今日头条 --- 第一篇:(android高仿系列)今日头条 --新闻阅读器 (一) 上次,已经完毕了头部新闻分类栏目的拖动效果. 这篇文章是继续去完好APP 今日头条 这个新闻阅读器的其 ...
- Android 高仿QQ滑动弹出菜单标记已读、未读消息
在上一篇博客<Android 高仿微信(QQ)滑动弹出编辑.删除菜单效果,增加下拉刷新功能>里,已经带着大家学习如何使用SwipeMenuListView这一开源库实现滑动列表弹出菜单,接 ...
- android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码
Android精选源码 android模仿支付宝app"记账本"模块源码 android一个超轻量级剪贴板历史记录管理软件源码 android模仿QQ拖动红点消失动画效果源码 展示 ...
- android高仿抖音、点餐界面、天气项目、自定义view指示、爬取美女图片等源码
Android精选源码 一个爬取美女图片的app Android高仿抖音 android一个可以上拉下滑的Ui效果 android用shape方式实现样式源码 一款Android上的新浪微博第三方轻量 ...
- (android高仿系列)今日头条 --新闻阅读器 (三) 完结 、总结 篇
从写第一篇今日头条高仿系列开始,到现在已经过去了1个多月了,其实大体都做好了,就是迟迟没有放出来,因为我觉得,做这个东西也是有个过程的,我想把这个模仿中一步一步学习的过程,按照自己的思路写下来,在根据 ...
- Android 高仿 频道管理----网易、今日头条、腾讯视频 (可以拖动的GridView)附源码DEMO
距离上次发布(android高仿系列)今日头条 --新闻阅读器 (二) 相关的内容已经半个月了,最近利用空闲时间,把今日头条客户端完善了下.完善的功能一个一个全部实现后,就放整个源码.开发的进度就是按 ...
- Android 高仿QQ5.2双向側滑菜单DrawerLayout实现源代码
Android 高仿QQ5.2双向側滑菜单DrawerLayout实现源代码 左右側滑效果图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a ...
- Android 高仿 频道管理----网易、今日头条、腾讯视频 (能够拖动的GridView)附源代码DEMO
距离上次公布(android高仿系列)今日头条 --新闻阅读器 (二) 相关的内容已经半个月了.近期利用空暇时间,把今日头条client完好了下.完好的功能一个一个所有实现后.就放整个源代码.开发的进 ...
随机推荐
- 编程实现Linux下的ls -l
头文件 #ifndef __FUNC_H__ #define __FUNC_H__ #include <stdio.h> #include <stdlib.h> #includ ...
- http://blog.csdn.net/wxwzy738/article/details/16968767
http://blog.csdn.net/wxwzy738/article/details/16968767
- (.iso)光盘镜像文件的打开与安装
直接解压就可以打开,然后就可以安装.exe文件
- C++:delete和delete[]释放内存的区别
C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]. 关于 new[] 和 delete[], ...
- 整合Struts2+SiteMesh+Spring+MyFaces(JSF)+Freemarker的时候启动服务器报错ClassNotFoundException: org.apache.struts2.sitemesh.FreeMarkerPageFilter
我一琢磨,难道freemarker与struts2的整合也需要添加一个struts2-freemarker-plugin的jar包? 后来找了半天,确认不需要这个. 然后我就上网搜,这个FreeMar ...
- C# 值类型和引用类型的区别
C# 值类型和引用类型的区别 1. 值类型的数据存储在内存的栈中:引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的地址. 2. 值类型存取速度快,引用类型存取速度慢. 3. 值类型表示实 ...
- jsp+servlet+jquery 用jquery uploadify最新版本实现多文件上传
//这是script代码 <link rel="stylesheet" type="text/css" href="uploadify/uplo ...
- R之pryr
1. Pryr安装 由于项目pryr,还没有发布到CRAN,仅支持从github安装.要使用devtools包来通过github来安装,在https://github.com/hadley/pryr中 ...
- Objective-C编码规范:26个方面解决iOS开发问题
介绍 我们制定Objective-C编码规范的原因是我们能够在我们的书,教程和初学者工具包的代码保持优雅和一致.即使我们有很多不同的作者来完成不同的书籍. 这里编码规范有可能与你看到的其他Object ...
- HDU 4658 Integer Partition(整数拆分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4658 题意:给出n.k.求n的拆分方案数.要求拆分中每个数不超过k. i64 f[N]; void i ...