包含androideventtype的词条

http://www.itjxue.com  2023-01-30 04:42  来源:未知  点击次数: 

android accessibilityservice 服务问题

利用Android辅助工具类AccessibilityService可以获取手机当前页面的信息,用户的操作事件等等.首先新建一个类继承AccessibilityService:[html] view plain copy

span?style="font-family:Times?New?Roman;font-size:14px;"public?class?MyAccessibilityService?extends?AccessibilityService?{

private?final?String?TAG?=?"MyAccessibilityService";

@Override

public?void?onAccessibilityEvent(AccessibilityEvent?event)?{

int?eventType?=?event.getEventType();

String?eventTypeName?=?"";

switch?(eventType)?{

case?AccessibilityEvent.TYPE_VIEW_CLICKED:

eventTypeName?=?"TYPE_VIEW_CLICKED";

break;

case?AccessibilityEvent.TYPE_VIEW_FOCUSED:

eventTypeName?=?"TYPE_VIEW_FOCUSED";

break;

case?AccessibilityEvent.TYPE_VIEW_LONG_CLICKED:

eventTypeName?=?"TYPE_VIEW_LONG_CLICKED";

break;

case?AccessibilityEvent.TYPE_VIEW_SELECTED:

eventTypeName?=?"TYPE_VIEW_SELECTED";

break;

case?AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:

eventTypeName?=?"TYPE_VIEW_TEXT_CHANGED";

break;

case?AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:

eventTypeName?=?"TYPE_WINDOW_STATE_CHANGED";

break;

case?AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:

eventTypeName?=?"TYPE_NOTIFICATION_STATE_CHANGED";

break;

case?AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END:

eventTypeName?=?"TYPE_TOUCH_EXPLORATION_GESTURE_END";

break;

case?AccessibilityEvent.TYPE_ANNOUNCEMENT:

eventTypeName?=?"TYPE_ANNOUNCEMENT";

break;

case?AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START:

eventTypeName?=?"TYPE_TOUCH_EXPLORATION_GESTURE_START";

break;

case?AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:

eventTypeName?=?"TYPE_VIEW_HOVER_ENTER";

break;

case?AccessibilityEvent.TYPE_VIEW_HOVER_EXIT:

eventTypeName?=?"TYPE_VIEW_HOVER_EXIT";

break;

case?AccessibilityEvent.TYPE_VIEW_SCROLLED:

eventTypeName?=?"TYPE_VIEW_SCROLLED";

break;

case?AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED:

eventTypeName?=?"TYPE_VIEW_TEXT_SELECTION_CHANGED";

break;

case?AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:

eventTypeName?=?"TYPE_WINDOW_CONTENT_CHANGED";

break;

}

Log.i(TAG,?"eventType:"?+?eventType);

Log.i(TAG,?"eventTypeName:"?+?eventTypeName);

}

@Override

public?void?onInterrupt()?{

//?TODO?Auto-generated?method?stub

}

}/span

然后新建一个xml配置文件来配置我们的MyAccessibility类:

accessibilityservice.xml :

[html] view plain copy

span?style="font-family:Times?New?Roman;font-size:14px;"?xml?version="1.0"?encoding="utf-8"?

accessibility-service?xmlns:android=""??

android:accessibilityEventTypes="typeAllMask"

android:accessibilityFeedbackType="feedbackGeneric"

android:accessibilityFlags="flagDefault"

android:canRetrieveWindowContent="true"

android:description="@string/app_name"

android:settingsActivity="com.example.xxx.android.accessibility.ServiceSettingsActivity"?//span

android:accessibilityEventTypes="typeAllMask",相应所有的事件,就是MyAccessibility类中swich中的那些事件.

android:accessibilityFeedbackType="feedbackGeneric",手机用什么方式将信息反馈给用户,语音震动等等,这里默认;

android:canRetrieveWindowContent="true",允许获取手机页面中的信息

android:settingsActivity中com.example.xxx是你的应用的包名

然后将这个xml配置文件配置到项目中:

[html] view plain copy

span?style="font-family:Times?New?Roman;font-size:14px;"????????service

android:name="com.example.xxx.MyAccessibilityService"

android:enabled="true"

android:exported="true"

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/accessibilityservice"?/

/service/span

然后在我们手机的设置中的辅助功能里,打开这个辅助服务就可以了.

利用这个类我们可以获取当前手机页面的信息,包括控件ID,控件值;当前类的名称以及用户的一些操作和手机状态的变化. 所以利用这些可以做手机自动安装软件,模拟点击,手机自动滑屏等.

public void onAccessibilityEvent(AccessibilityEvent event){}

通过这个event我们可以得到:

event.getEventType()-当前事件的类型; ?event.getClassName()-当前类的名称; ?event.getSource()-当前页面中的节点信息,等等.更详细信查看官方API

遍历获取窗口中所有的节点信息也可以用这个方法:

[html] view plain copy

span?style="font-family:Times?New?Roman;font-size:14px;"public?void?getInfo()?{

AccessibilityNodeInfo?info?=?getRootInActiveWindow();

if?(info?!=?null)?{

if?(info.getChildCount()?==?0)?{

Log.i(TAG,?"控件名称:"?+?info.getClassName());

Log.i(TAG,?"控件中的值:"?+?info.getText());

Log.i(TAG,?"控件的ID:"?+?info.getViewIdResourceName());

Log.i(TAG,?"点击是否出现弹窗:"?+?info.canOpenPopup());

}?else?{

for?(int?i?=?0;?i??info.getChildCount();?i++)?{

if?(info.getChild(i)?!=?null)?{

recycle(info.getChild(i));

}

}

}

}

}/span

不过这个方法对当前的SDK版本有一定的要求,需要API level?19及以上.

android studio 的xml数据获取

这个很简单啊xml解析,pull解析

public class PullBookParser {

@Override

public ListBook parse(InputStream is) throws Exception {

ListBook books = null;

Book book = null;

// XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

// XmlPullParser parser = factory.newPullParser();

XmlPullParser parser = Xml.newPullParser(); //由android.util.Xml创建一个XmlPullParser实例

parser.setInput(is, "UTF-8"); //设置输入流 并指明编码方式

int eventType = parser.getEventType();

while (eventType != XmlPullParser.END_DOCUMENT) {

switch (eventType) {

case XmlPullParser.START_DOCUMENT:

books = new ArrayListBook();

break;

case XmlPullParser.START_TAG:

if (parser.getName().equals("book")) {

book = new Book();

} else if (parser.getName().equals("id")) {

eventType = parser.next();

book.setId(Integer.parseInt(parser.getText()));

} else if (parser.getName().equals("name")) {

eventType = parser.next();

book.setName(parser.getText());

} else if (parser.getName().equals("price")) {

eventType = parser.next();

book.setPrice(Float.parseFloat(parser.getText()));

}

break;

case XmlPullParser.END_TAG:

if (parser.getName().equals("book")) {

books.add(book);

book = null;

}

break;

}

eventType = parser.next();

}

return books;

}

}

安卓如何读取自定义XML文件里的任意数据

在程序升级的时候,每更新一个版本都要写升级日志,将升级日志放在xml文件中,通过代码来读取是一个较好的方案。

关键类:Resources

关键方法:public int getIdentifier(String name, String defType, String defPackage)

关于具体使用方法,举例如下:

1、updatelog.xml文件位于res/xml/文件夹下:

?xml version="1.0" encoding="utf-8"?

updatelog

release

version="1.0"

versioncode="1.1"

log1、这个文件在res/xml文件夹下;/log

log2、这个文件的名字是“updatelog.xml”/log

log3、这是一个xml文件/log

/release

/updatelog

2、在代码中调用方法如下:

public class ResourcesActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView( R.layout.resources_layout );

mTextView = ( TextView )findViewById( R.id.textId );

getFileResources( );

}

private void getFileResources( ){

String packageName = getPackageName( );

try {

Resources resources = this.getPackageManager( ).getResourcesForApplication( packageName );

int resId = resources.getIdentifier( "updatelog", "xml", packageName );

String log = getUpdatelog( resId, resources );

int appId = resources.getIdentifier( "action_settings", "string", packageName );

String appName = resources.getString( appId );

mTextView.setText( appName + "\n" + log );

} catch (NameNotFoundException e) {

e.printStackTrace();

}

}

private String parseTag( XmlResourceParser xml ) throws XmlPullParserException, IOException {

String result = "Version: "+ xml.getAttributeValue(null, "version") + "\n" + "VersionCode: " + xml.getAttributeValue(null, "versioncode") + "\n";

int eventType = xml.getEventType( );

while( ( eventType != XmlPullParser.END_TAG ) || ( xml.getName( ).equals( "log" ) ) ) {

if( (eventType == XmlPullParser.START_TAG) ( xml.getName( ).equals( "log" ) ) ) {

eventType = xml.next( );

result = result + xml.getText( ) + "\n";

}

eventType = xml.next( );

}

return result;

}

private String getUpdatelog( int resourceId, Resources resource ) {

String result = "";

XmlResourceParser xmlResParser = resource.getXml( resourceId );

try {

int eventType = xmlResParser.getEventType( );

while ( eventType != XmlPullParser.END_DOCUMENT ) {

if ( ( eventType == XmlPullParser.START_TAG ) ( xmlResParser.getName( ).equals( "release" ) ) ) {

result = result + parseTag( xmlResParser );

}

eventType = xmlResParser.next( );

}

} catch (XmlPullParserException e) {

System.out.println( e.getMessage( ) );

} catch (IOException e) {

System.out.println( e.getMessage( ) );

} finally {

xmlResParser.close( );

}

return result;

}

private TextView mTextView = null;

}

如何在android 中service后台监听按键,比如监听音量键

为了实现键盘的监控,从新开发一个输入法是不现实的,一般的操作就是在系统的输入法机制中添加接口回调。我们知道,再应用程序中拿到按键的回调一般是监听onKeyDown的接口,如下所示:publicbooleanonKeyDown(intkeyCode,KeyEventevent)开发者就可以根据回调方法中的参数,keyCode与KeyEvent来判断具体事件。但是,由于事件的回调机制在其的沙箱中运行,在其他应用中是无法拿到当前应用事件回调的。那么我们就从上到下,具体的看看事件的传递机制。如下图所示,用户点击后,软键盘或物理按键的输入驱动就会产生一个中断,且向/dev/input/event*中写入一个相应的信号量。Android操作系统则会循环的读取其中的事件,再分发给WindowManagerServer。由WindowManagerServer根据事件的来源分发到各个不同的ViewGroup与View中,从而产生不同的OnClick、OnKeyDown和OnTouch等事件。这个时候很自然的想到,黑客们希望做键盘监控,一定会向Linux底层增加自定义的事件。这里我们使用的是Linux中的getevent获得/dev/input/eventX设备汇报的事件,这个命令还会输出所有event设备的基本信息。包括触屏、按键、耳机插入等等。其基本用法如下:Usage:getevent[-t][-n][-sswitchmask][-S][-v[mask]][-d][-p][-i][-l][-q][-ccount][-r][device]-t:showtimestamps-n:don'tprintnewlines-s:printswitchstatesforgivenbits-S:printallswitchstates-v:verbositymask(errs=1,dev=2,name=4,info=8,vers=16,pos.events=32,props=64)-d:showHIDdescriptor,ifavailable-p:showpossibleevents(errs,dev,name,pos.events)-i:showalldeviceinfoandpossibleevents-l:labeleventtypesandnamesinplaintext-q:quiet(clearverbositymask)-c:printgivennumberofeventsthenexit-r:printrateeventsarereceived键入getevent后,我们能够看到设备中的一些列输入硬件驱动信息,同样下面会出现很多输入指令信号,通常情况下,这些信号量都在刷屏,如下图所示:这些信号量的表示我们无法直接看懂,输入getevent–l加入Label我们能够看到一些添加的标签,如下所示:其实这些Lable已经在其input.h头文件中定义好,其中type的定义如下:/**Eventtypes*/#defineEV_SYN0x00#defineEV_KEY0x01#defineEV_REL0x02#defineEV_ABS0x03#defineEV_MSC0x04#defineEV_SW0x05#defineEV_LED0x11#defineEV_SND0x12#defineEV_REP0x14#defineEV_FF0x15#defineEV_PWR0x16#defineEV_FF_STATUS0x17#defineEV_MAX0x1f#defineEV_CNT(EV_MAX+1)一般来说,常用的是EV_KEY、EV_REL、EV_ABS、EV_SYN,分别对应键盘按键、相对坐标、绝对坐标、同步事件。EV_SYN则表示一组完整事件已经完成,需要处理,EV_SYN的code定义事件分发的类型。

如何解决Android帧动画出现的内存溢出

1.anin_searh.xml

[html] view plain copy

?xml version="1.0" encoding="utf-8"?

animation-list xmlns:android=""

android:oneshot="true"

item android:drawable="@drawable/a1" android:duration="100"/item

item android:drawable="@drawable/a2" android:duration="100"/item

item android:drawable="@drawable/a4" android:duration="100"/item

item android:drawable="@drawable/a5" android:duration="100"/item

item android:drawable="@drawable/a6" android:duration="100"/item

item android:drawable="@drawable/a7" android:duration="100"/item

item android:drawable="@drawable/a8" android:duration="100"/item

item android:drawable="@drawable/a9" android:duration="100"/item

item android:drawable="@drawable/a10" android:duration="100"/item

item android:drawable="@drawable/a11" android:duration="100"/item

/animation-list

2.使用帧动画

[java] view plain copy

search_scale_iv.setBackgroundResource(R.drawable.anim_search);

AnimationDrawable drawable = (AnimationDrawable) search_scale_iv.getBackground();

drawable.start();

结果setBackgroundResource出现内存溢出,这个方法其实获取drawable时候,会消耗很多内存,很容易内存溢出,崩溃。

3.解决方法:在网上找了个类,处理,结果我使用11张560k大小图片,没有内存溢出;

[java] view plain copy

import android.content.Context;

import android.content.res.XmlResourceParser;

import android.graphics.BitmapFactory;

import android.graphics.drawable.AnimationDrawable;

import android.graphics.drawable.BitmapDrawable;

import android.graphics.drawable.Drawable;

import android.os.Handler;

import android.widget.ImageView;

import org.apache.commons.io.IOUtils;

import org.xmlpull.v1.XmlPullParser;

import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

/****

* 此工具类源于stack over flow

* 原文链接:

* 主要使用了BitmapFactory.decodeByteArray方法通过底层C来绘制图片,有效防止OOM

* 使用了第三方类库:org.apache.commons.io.IOUtils,将Inputstream转为byte字节数组

* *******/

public class MyAnimationDrawable {

public static class MyFrame {

byte[] bytes;

int duration;

Drawable drawable;

boolean isReady = false;

}

public interface OnDrawableLoadedListener {

public void onDrawableLoaded(ListMyFrame myFrames);

}

// 1

/***

* 性能更优

* 在animation-list中设置时间

* **/

public static void animateRawManuallyFromXML(int resourceId,

final ImageView imageView, final Runnable onStart,

final Runnable onComplete) {

loadRaw(resourceId, imageView.getContext(),

new OnDrawableLoadedListener() {

@Override

public void onDrawableLoaded(ListMyFrame myFrames) {

if (onStart != null) {

onStart.run();

}

animateRawManually(myFrames, imageView, onComplete);

}

});

}

// 2

private static void loadRaw(final int resourceId, final Context context,

final OnDrawableLoadedListener onDrawableLoadedListener) {

loadFromXml(resourceId, context, onDrawableLoadedListener);

}

// 3

private static void loadFromXml(final int resourceId,

final Context context,

final OnDrawableLoadedListener onDrawableLoadedListener) {

new Thread(new Runnable() {

@Override

public void run() {

final ArrayListMyFrame myFrames = new ArrayListMyFrame();

XmlResourceParser parser = context.getResources().getXml(

resourceId);

try {

int eventType = parser.getEventType();

while (eventType != XmlPullParser.END_DOCUMENT) {

if (eventType == XmlPullParser.START_DOCUMENT) {

} else if (eventType == XmlPullParser.START_TAG) {

if (parser.getName().equals("item")) {

byte[] bytes = null;

int duration = 1000;

for (int i = 0; i parser.getAttributeCount(); i++) {

if (parser.getAttributeName(i).equals(

"drawable")) {

int resId = Integer.parseInt(parser

.getAttributeValue(i)

.substring(1));

bytes = IOUtils.toByteArray(context

.getResources()

.openRawResource(resId));

} else if (parser.getAttributeName(i)

.equals("duration")) {

duration = parser.getAttributeIntValue(

i, 1000);

}

}

MyFrame myFrame = new MyFrame();

myFrame.bytes = bytes;

myFrame.duration = duration;

myFrames.add(myFrame);

}

} else if (eventType == XmlPullParser.END_TAG) {

} else if (eventType == XmlPullParser.TEXT) {

}

eventType = parser.next();

}

} catch (IOException e) {

e.printStackTrace();

} catch (XmlPullParserException e2) {

// TODO: handle exception

e2.printStackTrace();

}

// Run on UI Thread

new Handler(context.getMainLooper()).post(new Runnable() {

@Override

public void run() {

if (onDrawableLoadedListener != null) {

onDrawableLoadedListener.onDrawableLoaded(myFrames);

}

}

});

}

}).run();

}

// 4

private static void animateRawManually(ListMyFrame myFrames,

ImageView imageView, Runnable onComplete) {

animateRawManually(myFrames, imageView, onComplete, 0);

}

// 5

private static void animateRawManually(final ListMyFrame myFrames,

final ImageView imageView, final Runnable onComplete,

final int frameNumber) {

final MyFrame thisFrame = myFrames.get(frameNumber);

if (frameNumber == 0) {

thisFrame.drawable = new BitmapDrawable(imageView.getContext()

.getResources(), BitmapFactory.decodeByteArray(

thisFrame.bytes, 0, thisFrame.bytes.length));

} else {

MyFrame previousFrame = myFrames.get(frameNumber - 1);

((BitmapDrawable) previousFrame.drawable).getBitmap().recycle();

previousFrame.drawable = null;

previousFrame.isReady = false;

}

imageView.setImageDrawable(thisFrame.drawable);

new Handler().postDelayed(new Runnable() {

@Override

public void run() {

// Make sure ImageView hasn't been changed to a different Image

// in this time

if (imageView.getDrawable() == thisFrame.drawable) {

if (frameNumber + 1 myFrames.size()) {

MyFrame nextFrame = myFrames.get(frameNumber + 1);

if (nextFrame.isReady) {

// Animate next frame

animateRawManually(myFrames, imageView, onComplete,

frameNumber + 1);

} else {

nextFrame.isReady = true;

}

} else {

if (onComplete != null) {

onComplete.run();

}

}

}

}

}, thisFrame.duration);

// Load next frame

if (frameNumber + 1 myFrames.size()) {

new Thread(new Runnable() {

@Override

public void run() {

MyFrame nextFrame = myFrames.get(frameNumber + 1);

nextFrame.drawable = new BitmapDrawable(imageView

.getContext().getResources(),

BitmapFactory.decodeByteArray(nextFrame.bytes, 0,

nextFrame.bytes.length));

if (nextFrame.isReady) {

// Animate next frame

animateRawManually(myFrames, imageView, onComplete,

frameNumber + 1);

} else {

nextFrame.isReady = true;

}

}

}).run();

}

}

(责任编辑:IT教学网)

更多

推荐CGI/Perl教程文章