Skip to content

Commit

Permalink
v2
Browse files Browse the repository at this point in the history
  • Loading branch information
lalakii committed Dec 7, 2024
1 parent 6a48f60 commit f7024c3
Show file tree
Hide file tree
Showing 14 changed files with 182 additions and 129 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Android GetEvent
# Android GetEvent V2

[English](README_en.md) | [中文](README.md)

**通过Shizuku权限,读取触摸屏事件示例** [下载演示APP](https://github.com/lalakii/get_event/releases/)

读取到的数据还需要解析,我只实现到这一步,有功能需求自行完善。

<img src="./video/demo.gif" width="300"/>
<img src="./video/demo_v2.gif" width="300"/>

## By lalaki.cn
4 changes: 2 additions & 2 deletions README_en.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Android GetEvent
# Android GetEvent V2

[中文](README.md) | [English](README_en.md)

**Example of reading touch screen events with Shizuku privileges** [Download Sample App](https://github.com/lalakii/get_event/releases/)

The read data still need to be parsed, I have only completed to this point, there are functional requirements to improve their own.

<img src="./video/demo.gif" width="300"/>
<img src="./video/demo_v2.gif" width="300"/>

## By lalaki.cn
18 changes: 7 additions & 11 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
plugins {
id 'com.android.application'
}

android {
namespace 'cn.lalaki.touch_event'
compileSdk 34

compileSdk 35
defaultConfig {
applicationId "cn.lalaki.touch_event"
minSdk 24
//noinspection EditedTargetSdkVersion
targetSdk 34
versionCode 1
versionName "1.0"
targetSdk 35
versionCode 2
versionName "2.0"
}

buildTypes {
release {
}
buildFeatures {
aidl true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
Expand All @@ -26,8 +22,8 @@ android {
}

dependencies {
implementation "androidx.annotation:annotation:1.9.1"
def shizuku_version = "13.1.5"
implementation "dev.rikka.shizuku:api:$shizuku_version"
implementation "dev.rikka.shizuku:provider:$shizuku_version"
implementation "com.google.guava:guava:33.0.0-android"
}
13 changes: 5 additions & 8 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:icon="@android:drawable/sym_def_app_icon"
android:label="@string/app_name"
android:largeHeap="true"
android:theme="@android:style/Theme.DeviceDefault">
android:theme="@android:style/Theme.Material.NoActionBar">

<activity
android:name=".MainActivity"
android:screenOrientation="portrait"
android:exported="true"
tools:ignore="LockedOrientationActivity">
android:launchMode="singleInstance">

<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand All @@ -27,8 +26,6 @@
android:exported="true"
android:multiprocess="false"
android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />

<!-- android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" is to protect this provider from accessing by normal apps -->
</application>

</manifest>
5 changes: 5 additions & 0 deletions app/src/main/aidl/cn/lalaki/touch_event/IGetEventService.aidl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package cn.lalaki.touch_event;
interface IGetEventService {
void destroy() = 16777114;
void getEvent(int port) = 2;
}
23 changes: 0 additions & 23 deletions app/src/main/assets/rish

This file was deleted.

Binary file removed app/src/main/assets/rish_shizuku.dex
Binary file not shown.
47 changes: 47 additions & 0 deletions app/src/main/java/cn/lalaki/touch_event/GetEventService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package cn.lalaki.touch_event;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

public class GetEventService extends IGetEventService.Stub implements Runnable {
private boolean isServiceRunning = true;
private final ProcessBuilder builder = new ProcessBuilder();
private int port;

@Override
public void destroy() {
isServiceRunning = false;
}

@Override
public void getEvent(int port) {
this.port = port;
new Thread(this).start();
}

/**
* @noinspection BusyWait
*/
@Override
public void run() {
while (isServiceRunning) {
try (Socket socket = new Socket(InetAddress.getLocalHost(), port)) {
String[] cmdline = {"getevent", "-t"};
InputStream in = builder.command(cmdline).start().getInputStream();
OutputStream out = socket.getOutputStream();
int ch;
while (isServiceRunning) {
ch = in.read();
if (ch == -1) {
Thread.sleep(1);
} else {
out.write(ch);
}
}
} catch (IOException | InterruptedException ignored) {
}
}
}
}
150 changes: 80 additions & 70 deletions app/src/main/java/cn/lalaki/touch_event/MainActivity.java
Original file line number Diff line number Diff line change
@@ -1,64 +1,64 @@
package cn.lalaki.touch_event;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import com.google.common.io.ByteStreams;
import java.io.File;
import java.io.FileOutputStream;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;

import rikka.shizuku.Shizuku;
import rikka.shizuku.ShizukuProvider;

public class MainActivity extends Activity implements View.OnClickListener, Shizuku.OnRequestPermissionResultListener {
private boolean permissionIsGranted = false;
private TextView te_data;
private File rish;
public class MainActivity extends Activity implements Runnable, View.OnClickListener, Shizuku.OnRequestPermissionResultListener, ServiceConnection {
private ScrollView sc;
private TextView showData;
private Intent shizukuIntent;
private boolean isRunning = false;
private boolean permissionIsGranted = false;
private Shizuku.UserServiceArgs mUserServiceArgs;
private final int port = 34567;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sc = findViewById(R.id.scroll);
te_data = findViewById(R.id.touch_data);
File external = getFilesDir();
if (external != null) {
String path = external.getAbsolutePath() + "/private/";
if (new File(path).mkdirs()) {
Toast.makeText(this, "create private dir is done.", Toast.LENGTH_SHORT).show();
}
rish = new File(path + "rish");
if (!rish.exists()) {
String[] files = {"rish_shizuku.dex", "rish"};
for (String name : files) {
try (InputStream rish_dex = getAssets().open(name)) {
try (FileOutputStream out = new FileOutputStream(path + name)) {
ByteStreams.copy(rish_dex, out);
}
} catch (IOException ignored) {
}
}
}
}
showData = findViewById(R.id.touch_data);
shizukuIntent = getPackageManager().getLaunchIntentForPackage(ShizukuProvider.MANAGER_APPLICATION_ID);
mUserServiceArgs = new Shizuku.UserServiceArgs(new ComponentName(getPackageName(), GetEventService.class.getName()))
.daemon(false)
.debuggable(false)
.processNameSuffix("lalaki_getevent")
.version(1);
}

@Override
public void onRequestPermissionResult(int requestCode, int grantResult) {
permissionIsGranted = grantResult == 0;
}

@Override
protected void onResume() {
Intent shizukuIntent = getPackageManager().getLaunchIntentForPackage("moe.shizuku.privileged.api");
if (shizukuIntent != null) {
if (Shizuku.pingBinder()) {
permissionIsGranted = Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED;
if (permissionIsGranted) {
findViewById(R.id.tips).setAlpha(0F);
Shizuku.removeRequestPermissionResultListener(this);
} else {
Shizuku.addRequestPermissionResultListener(this);
Shizuku.requestPermission(0);
Expand All @@ -68,55 +68,65 @@ protected void onResume() {
super.onResume();
}

@Override
public void onRequestPermissionResult(int requestCode, int grantResult) {
permissionIsGranted = grantResult == 0;
}
private boolean isRunning = false;
private final ProcessBuilder builder = new ProcessBuilder();
@Override
public void onClick(View view) {
if (!permissionIsGranted) return;
if (isRunning || !((Switch) view).isChecked()) {
if (isRunning) {
Toast.makeText(this, R.string.end, Toast.LENGTH_SHORT).show();
finish();
System.exit(0);
return;
}
if (rish.exists()) {
isRunning = !isRunning;
Toast.makeText(this, R.string.touch_tips, Toast.LENGTH_SHORT).show();
new Thread(() -> {
try {
String[] cmdline = {"sh", rish.getAbsolutePath(), "-c", "getevent -t"};
builder.environment().put("RISH_APPLICATION_ID", getPackageName());
InputStream in = builder.command(cmdline).start().getInputStream();
StringBuilder sb = new StringBuilder();
byte[] data = new byte[64];
while (isRunning) {
try {
ByteStreams.readFully(in, data);
onData(sb, data);
} catch (IOException e) {
runOnUiThread(() -> te_data.setText(e.getLocalizedMessage()));
}
if (!permissionIsGranted) return;
isRunning = true;
new Thread(this).start();
Shizuku.bindUserService(mUserServiceArgs, this);
((Button) view).setText(R.string.stop);
Toast.makeText(this, R.string.touch_tips, Toast.LENGTH_SHORT).show();
}

// 进程间通信,如果不理解此处为什么要用到socket,请百度
@Override
public void run() {
try (ServerSocket server = new ServerSocket(port)) {
while (isRunning) {
BufferedReader reader = new BufferedReader(new InputStreamReader(server.accept().getInputStream()));
StringBuilder sb = new StringBuilder();
while (isRunning) {
String line = reader.readLine();
sb.append(line).append('\n');
if (sb.length() > 4096) {
sb.delete(0, 1024);
runOnUiThread(() -> {
showData.setText(sb);
sc.fullScroll(View.FOCUS_DOWN);
});
}
} catch (IOException e) {
runOnUiThread(() -> te_data.setText(e.getLocalizedMessage()));
Log.d(getPackageName(), line);
}
}).start();
}
} catch (IOException ignored) {
}
}

@SuppressLint("SetTextI18n")
public void onData(StringBuilder sb, byte[] data) {
sb.append(new String(data));
int len = sb.length();
if (len > 2048) {
sb.delete(0, 1024);
runOnUiThread(() -> {
te_data.setText(sb + "\n\n\n\n\n\n");
sc.fullScroll(View.FOCUS_DOWN);
});
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (service != null && service.pingBinder()) {
IGetEventService iUserService = IGetEventService.Stub.asInterface(service);
// getevent 进程
try {
iUserService.getEvent(port);
} catch (RemoteException ignored) {
}
}
}

@Override
protected void onDestroy() {
isRunning = false;
Shizuku.unbindUserService(mUserServiceArgs, this, true);
super.onDestroy();
}

@Override
public void onServiceDisconnected(ComponentName name) {
}
}
Loading

0 comments on commit f7024c3

Please sign in to comment.