1. Demand:
After downloading and installing the apk, you want to click and slide to a specific location without manual manipulation.
There are several ways to achieve this requirement. The following is an attempt to use MotionEvent to simulate user Finger clicks and sliding screen events.
**
2. Ideas:
**
The main purpose is to use four common onTouch events:
1,ACTION_DOWN:
Indicates that the screen is pressed, and the first execution is also a necessary method.
2,ACTION_MOVE:
Represents a moving gesture that continues to execute until the touch stops.
3,ACTION_UP :
Represents leaving the screen and executing when the touch stops.
4,ACTION_CANCEL:
Indicates that the cancellation gesture is not generated by the user, but by the program.
One Action_DOWN, multiple ACTION_MOVEs, and one ACTION_UP constitute many events in Android.
The idea is simple:
1. Get the event object MotionEvent
MotionEvent eventUp = MotionEvent.obtain(System.currentTimeMillis(),
System.currentTimeMillis() + 100, MotionEvent.ACTION_UP, x, y, 0);
2. Distribute the event object
activity.dispatchTouchEvent(eventUp);
3. Code implementation:
Encapsulated as a tool class, the parameters passed in can be used directly:
/**
* Simulate tapping screen, sliding screen, etc.
* Created by Jim Bin on 2017/9/9.
*/
public class TouchEvent {
/**
* Simulate finger tap control events
* @param view control
* @param x X-coordinate of relative control
* @param y Y-coordinate of relative control
*/
private static void simulateClick(View view, float x, float y) {
long downTime = SystemClock.uptimeMillis();
final MotionEvent downEvent = MotionEvent.obtain(downTime, downTime,MotionEvent.ACTION_DOWN, x, y, 0);
downTime += 1000;
final MotionEvent upEvent = MotionEvent.obtain(downTime, downTime,MotionEvent.ACTION_UP, x, y, 0);
view.onTouchEvent(downEvent);
view.onTouchEvent(upEvent);
downEvent.recycle();
upEvent.recycle();
}
/**
* Simulate mobile click screen events
* @param x X coordinate
* @param y Y coordinate
* @param activity Incoming Activity Object
*/
public static void setFingerClick(int x, int y, Activity activity){
MotionEvent evenDownt = MotionEvent.obtain(System.currentTimeMillis(),
System.currentTimeMillis() + 100, MotionEvent.ACTION_DOWN, x, y, 0);
activity.dispatchTouchEvent(evenDownt);
MotionEvent eventUp = MotionEvent.obtain(System.currentTimeMillis(),
System.currentTimeMillis() + 100, MotionEvent.ACTION_UP, x, y, 0);
activity.dispatchTouchEvent(eventUp);
evenDownt.recycle();
eventUp.recycle();
Log.d(TAG, "setFingerClick: ");
}
/**
* Simulate Downward Slide Event
* @param distance Slide distance
* @param activity Incoming Activity Object
*/
public static void setMoveToBottom(int distance,Activity activity){
activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
MotionEvent.ACTION_DOWN, 400, 500, 0));
activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
MotionEvent.ACTION_MOVE, 400, 500-distance, 0));
activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
MotionEvent.ACTION_UP, 400, 500-distance, 0));
Log.d(TAG, "setMoveToBottom: ");
}
/**
* Simulate Slide Up Event
* @param distance Slide distance
* @param activity Incoming Activity Object
*/
public static void setMoveToTop(int distance,Activity activity){
activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
MotionEvent.ACTION_DOWN, 400, 500, 0));
activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
MotionEvent.ACTION_MOVE, 400, 500+distance, 0));
activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
MotionEvent.ACTION_UP, 400, 500+distance, 0));
Log.d(TAG, "setMoveToTop: ");
}
}
Of course, this method needs to get the coordinates of the phone screen. Here is a way to get coordinates. In fact, it is to get a custom view and get the coordinates of your finger by listening to touch events.
1. Customize TextView
/**
* Created by Jim Bin on 2017/9/9.
*/
public class CustomTextView extends android.support.v7.widget.AppCompatTextView{
private LogListener mLogListener;
public CustomTextView(Context context) {
super(context);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setLogListener(LogListener pListener) {
mLogListener = pListener;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_MOVE:
float rawX = event.getRawX();
float rawY = event.getRawY();
float x = event.getX();
float y = event.getY();
if (mLogListener != null) {
mLogListener.output("rawX = " + rawX
+ "\n rawY = " + rawY
+ "\n x = " + x
+ "\n Y = " + y);
}
break;
}
return true;
}
/**
* Used to output real-time Touch location information in Actvity
*/
public interface LogListener {
public void output(String pOutput);
}
}
2. Initialize this view in Activity and set up listening:
CustomTextView customTextView = (CustomTextView) findViewById(R.id.custom_textview);
customTextView.setLogListener((CustomTextView.LogListener) new CustomLogListener());
3. Display coordinates on textview when listening for changes
/**
* Used to get location information in TouchEvent
*/
private class CustomLogListener implements CustomTextView.LogListener {
@Override
public void output(String pOutput) {
tv.setText(pOutput);
}
}
4. Then set the custom view on the layout file.
<com.example.jim.motionevent.CustomTextView
android:id="@+id/custom_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:background="#666666"/>
**
4. Summary:
**
There's a**here
pit
**, I want to combine events, such as waiting a few seconds after clicking a button before swiping the screen.I started with the Thread.sleep() method, and seconds after calling the click method, sleep calls the sliding method again.
However, the effect I want is not what I want. The effect I want to show is the effect of sleep followed by click and slide.Guessing that it might be affected by the distribution mechanism of the event, after searching for reasons that were not found for a while, I decided to set aside and learn later. Big guys with that understanding could have a conversation.Later, I used a timer in java to perform a function operation at a few seconds interval so that the result would be satisfactory.
However...I find that this can only be done in demo to simulate clicks and slides, that is, when another program gets the focus and we run the logic of simulated clicks in this program, the code of simulated clicks is still implemented, but it does not point to the page where another program currently occupies the screen, but simulates clicks on its own program page.So it doesn't really meet my needs. The solution might be to find out if you can get active objects from other programs (which doesn't feel very feasible), or to consider using AccessibilityService to implement them.
5. Sources:
http://blog.sina.com.cn/s/blog_7256fe8f01016tyz.html
http://www.android-doc.com/guide/components/android7.0.html?q=AlarmManager#q=AlarmManager