安卓5.0以后getRunningTasks不在好用,但我们还想获得应用包名和topActivity,所以我就想了个办法
先说思路:
利用 AccessibilityService获得的event得到包名和类名
利用WindowManager显示在桌面上
要写一个类继承于 AccessibilityService
并实现必须实现的两个方法
@Override
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
}
@Override
public void onInterrupt() {
}
这里我们多重写一个方法 onServiceConnected(),在系统会在成功连接上你的服务的时候调用这个方法,我们用来创建WindowManager。
@Override
protected void onServiceConnected() {
super.onServiceConnected();
//创建一个windowManager
windowManager=(WindowManager)getSystemService(Context.WINDOW_SERVICE);
//初始化一个桌面悬浮窗的布局
View v= LayoutInflater.from(this).inflate(R.layout.fudong_layout,null);
textView = (TextView)v.findViewById(R.id.txt1);
//这里把WindowManager的type设置成TYPE_TOAST的好处是不需要权限
WindowManager.LayoutParams windowManagerParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_TOAST,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
windowManagerParams.width= ViewGroup.LayoutParams.WRAP_CONTENT;
windowManagerParams.height=ViewGroup.LayoutParams.WRAP_CONTENT;
//设置一下对齐方式
windowManagerParams.gravity=Gravity.LEFT|Gravity.TOP;
windowManager.addView(v,windowManagerParams);
}
我们看下浮动窗的布局,很简单
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/small_window_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:background="#78000000"
android:id="@+id/txt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#ffffff"
/>
</LinearLayout>
就是一个textview,所以上面的onServiceConnected() 中也可以采用动态创建textview的方法
onAccessibilityEvent中我们来获得包名和类名,以及textview的显示
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
//获取包名
String packages=event.getPackageName().toString();
//获取类名
String name= event.getClassName().toString();
//过滤
if(name.contains("com."))
{
if(name.contains(packages))
{
name=name.replace(packages,"");
name=name.replace("..","");
if(name.charAt(0)=='.')
name=name.substring(1);
}
//设置文本
textView.setText("包名"+packages+"\n"+"类名"+name);
}
}
onInterrupt(),这里我们不需要重写这个方法,让他为空就可以了。
AccessibilityService需要在AndroidManifest.xml里注册
<service android:name="你的服务名"
//显示在辅助服务里的名称
android:label="@string/app_label"
android:exported="true"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
//利用系统进程保活
android:process="system">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
//配置文件
android:resource="@xml/accessibility_config"/>
</service>
配置文件
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackGeneric"
android:canRetrieveWindowContent="true"
//关于这项辅助服务的描述
android:description="@string/app_desc"
android:notificationTimeout="100" />
多说一句,如果要隐藏app的图标和启动activity,只需要设置隐式启动就可以了
<activity
android:name=".MainActivity"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<data
//设置隐式启动
android:scheme="com.mafanwei.lalala"/>
</intent-filter>
</activity>
效果图:
补充
提供一种adb命令来查看当前Activity
adb shell "dumpsys window | grep mCurrentFocus"