Android项目实战--手机卫士30--读取应用的权限以及自定义Toast

本文主要是介绍Android项目实战--手机卫士30--读取应用的权限以及自定义Toast,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



最新实战教程,让你了解Android自动化刷量、作弊与防作弊的那些事,案例:刷友盟统计、批量注册苹果帐号




昨天呢,我们就已经把杀死进程的功能给完成的啦,那么今天我们就来做这样一件事,那就是,当我们长按某一个条目的时候,我们就显示出这个条目对应的那个应用的权限

这个做起来就有点难度啦,因为Android没有公开这个api给我们,所以我们就要自己想办法的啦

但是,在做这个之前,我们先处理一些细节的东西先,第一个就是把我手机卫士,以及那些没有界面的一些进程做成不可选定,也就是不能被杀死,

第二个就是把我们的总内存也显示出来,第三个就是自定义Toast,下面看看我们的效果


大家可以看到,我们在上面显示的是我们自己定义的Toast,至于那个不能让用户杀死我们手机卫士的进程这个,我忘记了截图,其实就也是把我们的checkbox隐藏掉,然后再处理一下而已,很简单的,我们就先来完成它,其实就是在条目点击的时候,以及adapter的getView的时候加几行代码就可以的啦

在onItemClickListener里面

					// 设置成不能杀死自己的进程,还有一些系统进程if ("com.xiaobin.security".equals(taskInfo.getPackageName())|| "system".equals(taskInfo.getPackageName())|| "android.process.media".equals(taskInfo.getPackageName())){cb_process_state.setVisibility(View.INVISIBLE);return;}

在adapter的getView里面

			// 设置成不能杀死自己的进程,还有一些系统进程if ("com.xiaobin.security".equals(taskInfo.getPackageName())|| "system".equals(taskInfo.getPackageName())|| "android.process.media".equals(taskInfo.getPackageName())){views.cb_process_state.setVisibility(View.INVISIBLE);}else{views.cb_process_state.setVisibility(View.VISIBLE);}

其实上面的代码也是很简单的啦,主要就是进行包名的比较啦,其实可以在我们的com.xiaobin.security.engine.TaskInfoProvider读取那些进程的信息的时候,

遇到抛出异常的时候,我们就给这个对象加一个flag就可以的啦,这样子就可以在这里灵活的判断啦,而不是像我这样写死在这里面,这个细节的处理,大家可以回去自己完成,也不是很难。


那么,经过上面这两处修改,我们的一些重要进程,用户就无法杀死的啦,接下来,我们就把我们的总内存也显示出来的啦


之前,我已经和大家说过了,Android并没有提供给我们读取总内存的api,所以我们只能通过,累计所有进程占用的内存,再加上可用的内存来计算,但这样计算出来的值是不准确的。所以这个值是会有点怪的啦

那么,现在我们就来做一下,要累计所有进程占用的内存,那么,我们就在所有进程加载出来的时候,算一下就可以啦,那么我们就在加载完成的时候,处理一下啦

	private void initData(){// 因为这个title是要显示当前进程数目和可用内存的,所以我们每次在这里都调用一下,以更新数据initTitle();ll_process_load.setVisibility(View.VISIBLE);new Thread(new Runnable(){@Overridepublic void run(){taskInfoProvider = new TaskInfoProvider(ProcessManagerActivity.this);taskInfos = taskInfoProvider.getAllTask(runningAppProcessInfos);// 计算总内存大小,因为不可以直接获取到总内存的,所以只能计算// 计算方法就是,全部进程占用的内存,再加上可用的内存,但这样计算是不准确的long total = 0;for (TaskInfo taskInfo : taskInfos){total += taskInfo.getMemory();}// new一个内存的对象MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();// 拿到现在系统里面的内存信息activityManager.getMemoryInfo(memoryInfo);// 拿到有效的内存空间long size = memoryInfo.availMem;// 因为我们拿到的进程占用的内存是以KB为单位的,所以这里要乘以1024,也就是左移10位啦total = total << 10;// 加上可用的内存,就可以得到总内存啦total += size;totalMemory = TextFormater.dataSizeFormat(total);Message msg = new Message();msg.what = LOAD_FINISH;handler.sendMessage(msg);}}).start();}

计算完成之后,我们就在Handler里面把这个值设置到TextView里面就可以啦

	private Handler handler = new Handler(){public void handleMessage(Message msg){switch (msg.what){case LOAD_FINISH:ll_process_load.setVisibility(View.INVISIBLE);adapter = new TaskInfoAdapter();lv_process_list.setAdapter(adapter);tv_process_memory.setText(availMemory + "/" + totalMemory);break;default:break;}}};

就这样,我们的总内存,也显示在title上啦


那么,接下来,我们就来做一下我们的自定义Toast,其实也很简单啦

我们先来写一个布局文件,就是我们的Toast要显示成的而已,这里,我们比较简单啦,只是用一个TextView,然后在它的左边加了一个图标而已

mytoast.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/title_background"android:orientation="horizontal" ><TextView android:id="@+id/tv_toast_msg"android:layout_width="wrap_content"android:layout_height="wrap_content"android:maxWidth="200dip"android:drawableLeft="@drawable/notification"android:drawablePadding="8dip"android:textColor="@android:color/white"android:text="@string/hello_world"/></LinearLayout>

布局文件写好了之后,我们就来写一个类

com.xiaobin.security.ui.view.MyToast

package com.xiaobin.security.ui.view;import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;import com.xiaobin.security.R;public class MyToast
{//自定义Toastpublic static void showToast(Context context, int id, String text){View view = View.inflate(context, R.layout.mytoast, null);TextView tv_toast_msg = (TextView) view.findViewById(R.id.tv_toast_msg);Drawable drawable = context.getResources().getDrawable(id);//在左边设置一张图片,对应android:drawableLeft这个属性tv_toast_msg.setCompoundDrawables(drawable, null, null, null);tv_toast_msg.setText(text);Toast toast = new Toast(context);toast.setDuration(0);toast.setView(view);toast.show();}}

上面的代码都是很容易看明白的啦,所以我就不写注释了,如果有不明白的,可以问一下

就这样子,我们自己定义的Toast就完成的啦,当然你还可以设置多一些属性,以及把那个显示的样式做得更好看,这里是为了演示,所以比较简陋的啦

写好了我们的Toast,那我们就要用我们的Toast来显示那些信息的啦

		// 显示成我们自己定义的ToastMyToast.showToast(this, R.drawable.notification, "已经杀死了" + total+ "个进程!释放了" + TextFormater.getSizeFromKB(memorySize) + "空间");

就这样,我们就用我们自己定义的的Toast啦


好啦,这些小问题,我们都讲完啦,那么,接下来,我们就要讲我们今天的重点啦,那就是读取对应进程的权限,先来看一下我们要做成的效果


大家可以看到,当我们长按某一个条目的时候,就会弹出上面的那个Activity的啦,上面显示的就是这个应用对应的权限啦

因为我们弹出来的是activity,那么我们就要在AndroidMainfest里面声明的时候,指定一下它的style为Theme.Dialog,但是一般的dialog是有title的,我们这个是没有的

那么,我们就要自己定义一个没有title的dialog啦,如果有不明白怎样自定义对话框的,可以看一下我们之前的文章(自定义对话框)


首先,我们在style里面写这样一个style

    <style name="NoTitleDialog" parent="@android:style/Theme.Dialog"><item name="android:windowNoTitle">true</item></style>

然后就在AndroidMainfest里面使用这个style就行的啦

        <activity android:theme="@style/NoTitleDialog"android:name="com.xiaobin.security.ui.AppDetialActivity"></activity>


就这样,我们的一个对话框形式的,没有title的activity就声明成功的啦

那么,接下来,我们就写一下它的布局文件啦

app_detail.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><LinearLayout android:layout_width="match_parent"android:layout_height="40dip"android:gravity="center_vertical|center_horizontal"android:background="@drawable/title_background"android:orientation="vertical"><TextView android:id="@+id/tv_app_detail_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@android:color/white"android:textSize="22sp"android:text="@string/app_manager"/></LinearLayout><TextView android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="5dip"android:layout_marginBottom="5dip"android:text="@string/security_desc"/><ScrollView android:id="@+id/sv_app_detail_desc"android:layout_width="match_parent"android:layout_height="200dip"></ScrollView></LinearLayout>

这个界面也是非常的简单啦,大家也可以看明白的啦


好啦,界面做好了之后呢,我们就要进入最重要的逻辑啦,其实呢Android里面有一个类,叫AppSecurityPermissions,它里面有一个方法叫getPermissionsView

它拿到的就是应用的权限啦,它返回的就是一个view对象,但是Android并没有公开这个类,所以我们是无法通过导入的方式,引入这个类的,那么怎么办呢

我们就要通过反射来调用这个方法啦

com.xiaobin.security.ui.AppDetialActivity

package com.xiaobin.security.ui;import java.lang.reflect.Constructor;
import java.lang.reflect.Method;import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.ScrollView;
import android.widget.TextView;import com.xiaobin.security.MyApplication;
import com.xiaobin.security.R;
import com.xiaobin.security.domain.TaskInfo;public class AppDetialActivity extends Activity
{private TextView tv_app_detail_name;private ScrollView sv_app_detail_desc;@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.app_detail);tv_app_detail_name = (TextView) findViewById(R.id.tv_app_detail_name);sv_app_detail_desc = (ScrollView) findViewById(R.id.sv_app_detail_desc);// 拿到自己定义的application对象,然后再拿到设置在里面的taskinfo对象MyApplication myApplication = (MyApplication) getApplication();TaskInfo taskInfo = myApplication.getTaskInfo();if (taskInfo != null){tv_app_detail_name.setText(taskInfo.getName());try{/*** 因为我们获取那个权限列表这个功能,Android是不对外开放的, 但是我们可以通过反射来进程获取* 其实Android的内部已经帮我们写好了这个类的啦,* 它就是android.widget.AppSecurityPermissions* 它里面有一个方法getPermissionsView* 返回的就是一个权限列表的view对象,所以我们只要通过反射,调用一下这个方法就可以的啦*/// 拿到这个类的对象Class<?> clazz = getClass().getClassLoader().loadClass("android.widget.AppSecurityPermissions");// 拿到它的构造方法,它的构造方法里面有两个参数,一个是Context,一个是String类型的包名Constructor<?> constructor = clazz.getConstructor(new Class[] {Context.class, String.class });//通过构造方法的对象,new一个对象出来,记得要把context和包名这两个参数传递进去Object object = constructor.newInstance(new Object[] { this,taskInfo.getPackageName() });//拿到我们的想要调用的方法getPermissionsView,这个方法是没有参数的,所以我们new一个空的数组Method method = clazz.getDeclaredMethod("getPermissionsView",new Class[] {});//调用这个方法,返回一个view对象啦View view = (View) method.invoke(object, new Object[] {});//然后就把返回的view对象设置进去就可以的啦sv_app_detail_desc.addView(view);}catch (Exception e){e.printStackTrace();}}}}

大家可以看到,核心的部分,就是try里面的几行代码啦,主要就是反射的一些操作啦,

至于我为什么会知道有这样一个类呢,那就是因为,我们Android系统的设置里面,就有这样的一个功能的,我反编译看到有这样一个类和方法,所有才会用反射来调用的,大家也可以反编译来看看


好啦,现在,我们就完成最后一步,就是给那些条目加一个长点击的事件

		lv_process_list.setOnItemLongClickListener(new OnItemLongClickListener(){@Overridepublic boolean onItemLongClick(AdapterView<?> parent, View view,int position, long id){// adapter里面的getItem返回的值Object obj = lv_process_list.getItemAtPosition(position);if (obj instanceof TaskInfo){TaskInfo taskInfo = (TaskInfo) obj;//拿到我们自己定义的application对象MyApplication myApplication = (MyApplication) getApplication();//把TaskInfo对象设置进去myApplication.setTaskInfo(taskInfo);Intent intent = new Intent(ProcessManagerActivity.this, AppDetialActivity.class);startActivity(intent);}return false;}});}

对啊,还忘记说一个东西了,就是,我们启动查看权限的这个activity的时候,要拿到一个TaskInfo对象的,那么,我们怎样传递过去呢,有两种方法,一种就是非常常用的啦

就是用Bundle来传递啦,但是,用Bundle来传递一个自己写的对象的时候,我们就要进行序列化的,不然,我们是无法传递的,序列化有两种方式,一种就是Android自带的Parcelable接口,一种就是java自带的Serializable接口,这两种序列化方式都可以,但是要说一下,Android的Parcelable是序列化到内存里面的,所以比较快,java的Serializable是序列化到硬盘上的,所以会比较慢

第二种方式呢,就是我们要讲的,把一些常用的对象,放到我们整个应用的容器里面,也就是Application里面,要这样做,我们就要自己写一个Application然后继承系统的Applicaiton

com.xiaobin.security.MyApplication

package com.xiaobin.security;import android.app.Application;import com.xiaobin.security.domain.TaskInfo;public class MyApplication extends Application
{private TaskInfo taskInfo;public TaskInfo getTaskInfo(){return taskInfo;}public void setTaskInfo(TaskInfo taskInfo){this.taskInfo = taskInfo;}}

当然,这样做还不行,我们还要通知应用,我们用的Application是我们自己写的,所以就要在AndroidMainfest里面注册一下啦

    <applicationandroid:allowBackup="true"android:icon="@drawable/app"android:label="@string/app_name"android:theme="@style/AppTheme"android:name="com.xiaobin.security.MyApplication" >

在application节点里面增加一个name就行的啦

就这样子,我们就可以通过getApplication来拿到我们自己的Application类的对象啦,然后就可以拿到存放在里面的一些常用的对象啦


好啦,今天的知识点有点多,大家可以多看看,有什么不明白的,可以提出来,今天就先到这里啦


最后,和大家说一下

为了方便大家的交流,我创建了一个群,这样子大家有什么疑问也可以在群上交流

群号是298440981





今天源码下载



这篇关于Android项目实战--手机卫士30--读取应用的权限以及自定义Toast的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1045611

相关文章

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

Pandas使用SQLite3实战

《Pandas使用SQLite3实战》本文主要介绍了Pandas使用SQLite3实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1 环境准备2 从 SQLite3VlfrWQzgt 读取数据到 DataFrame基础用法:读

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

一文教你如何将maven项目转成web项目

《一文教你如何将maven项目转成web项目》在软件开发过程中,有时我们需要将一个普通的Maven项目转换为Web项目,以便能够部署到Web容器中运行,本文将详细介绍如何通过简单的步骤完成这一转换过程... 目录准备工作步骤一:修改​​pom.XML​​1.1 添加​​packaging​​标签1.2 添加

tomcat多实例部署的项目实践

《tomcat多实例部署的项目实践》Tomcat多实例是指在一台设备上运行多个Tomcat服务,这些Tomcat相互独立,本文主要介绍了tomcat多实例部署的项目实践,具有一定的参考价值,感兴趣的可... 目录1.创建项目目录,测试文China编程件2js.创建实例的安装目录3.准备实例的配置文件4.编辑实例的

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Python实现自动化接收与处理手机验证码

《Python实现自动化接收与处理手机验证码》在移动互联网时代,短信验证码已成为身份验证、账号注册等环节的重要安全手段,本文将介绍如何利用Python实现验证码的自动接收,识别与转发,需要的可以参考下... 目录引言一、准备工作1.1 硬件与软件需求1.2 环境配置二、核心功能实现2.1 短信监听与获取2.

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda