安卓按键辅助(类似按键精灵)
无障碍 和截图 功能 root的手机就不说了
无障碍:
package com.yangdc.auto.games.stzb; import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.GestureDescription; import android.accessibilityservice.GestureDescription.StrokeDescription; import android.graphics.Path; import android.os.Build; import android.util.Log; import android.view.accessibility.AccessibilityEvent; import androidx.annotation.RequiresApi; import com.blankj.utilcode.util.ToastUtils; public class MyAccessibilityService extends AccessibilityService { final String TAG = "Ydc"; public static MyAccessibilityService mService; public static boolean isStart() { return mService != null; } @Override public void onInterrupt() { } @Override public void onServiceConnected() { mService = this; //初始化 super.onServiceConnected(); ToastUtils.showShort("无障碍已开启"); } @Override public void onAccessibilityEvent(AccessibilityEvent event) { mService = this; } public Boolean keyevent(int action) { Log.d(TAG, "按下:" + action); return this.performGlobalAction(action); } @RequiresApi(api = Build.VERSION_CODES.N) public void dispatchGestureClick(int x, int y){ Path path=new Path(); path.moveTo(x, y); GestureDescription.Builder builder = new GestureDescription.Builder(); builder.addStroke(new StrokeDescription(path, 10, 100)); GestureDescription gestureDescription = builder.build(); dispatchGesture(gestureDescription,null,null); Log.d(TAG,"点击坐标 " + x + " " + y); } public void swipe(int x1,int y1,int x2,int y2,int time){ Path path=new Path(); path.moveTo(x1, y1); path.lineTo(x2,y2); GestureDescription.Builder builder = new GestureDescription.Builder(); builder.addStroke(new StrokeDescription(path, 10, time)); GestureDescription gestureDescription = builder.build(); dispatchGesture(gestureDescription,null,null); Log.d(TAG,"滑动 " + x1 + " " + y1 + " " + x2 + " "+ y2); } }
截图:
package com.yangdc.auto.games.stzb; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.Service; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.PixelFormat; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.media.Image; import android.media.ImageReader; import android.media.projection.MediaProjection; import android.media.projection.MediaProjectionManager; import android.os.Build; import android.os.IBinder; import android.os.SystemClock; import android.util.DisplayMetrics; import android.util.Log; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import com.blankj.utilcode.util.ImageUtils; import java.nio.ByteBuffer; import static android.media.ImageReader.*; public class ImageReaderService extends Service { public static ImageReaderService service; @Nullable @Override public IBinder onBind(Intent intent) { return null; } int width; int height; int dpi; ImageReader imageReader; MediaProjection mediaProjection; MediaProjectionManager projectionManager; @Override public int onStartCommand(Intent intent, int flags, int startId) { service = this; Log.d(TAG, "onStartCommand()"); setForeground(); DisplayMetrics metric = new DisplayMetrics(); MainActivity.Main.getWindowManager().getDefaultDisplay().getMetrics(metric); width = metric.widthPixels; height = metric.heightPixels + MainActivity.Main.getStatusBarHeight(); dpi = metric.densityDpi; int resultCode = intent.getIntExtra("code", -1); Intent data = intent.getParcelableExtra("data"); projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE); mediaProjection = projectionManager.getMediaProjection(resultCode,data); return super.onStartCommand(intent,flags,startId); } private static final String TAG="MyService"; private static final String ID="channel_1"; private static final String NAME="前台服务"; boolean isOk = false; public void setForeground(){ if (isOk){ return; } isOk = true; if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) { return; } NotificationManager manager=(NotificationManager)getSystemService (NOTIFICATION_SERVICE); NotificationChannel channel= null; channel = new NotificationChannel(ID,NAME, NotificationManager.IMPORTANCE_HIGH); assert manager != null; manager.createNotificationChannel (channel); Notification notification= null; notification = new Notification.Builder (this,ID) .setContentTitle ("收到一条重要通知") .setContentText ("这是重要通知") .setSmallIcon (R.mipmap.ic_launcher) .setLargeIcon (BitmapFactory.decodeResource (getResources (),R.mipmap.ic_launcher)) .build (); startForeground (1,notification); } public static Bitmap ScreenShot() { if (service != null){ return service.startCapture(); } Log.e(TAG, "没启动服务"); return null; } private synchronized Bitmap startCapture() { if (imageReader != null){ return null; } VirtualDisplay virtualDisplay = null; Bitmap bitmap = null; imageReader = newInstance(width, height, PixelFormat.RGBA_8888, 1); Log.d(TAG,"dpi" + dpi); virtualDisplay = mediaProjection.createVirtualDisplay("ScreenShout", width,height,dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, imageReader.getSurface(),null,null); try { Image image = null; int times = 0; do { times++; SystemClock.sleep(100); image = imageReader.acquireNextImage(); if (image != null){ break; } }while (times < 2000); if (image != null){ Log.d(TAG,"新图片"); int width = image.getWidth(); int height = image.getHeight(); final Image.Plane[] planes = image.getPlanes(); final ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(); int rowStride = planes[0].getRowStride(); int rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); Bitmap bitmap1 = Bitmap.createBitmap(bitmap, 0, 0,width, height); bitmap = bitmap1; Log.d(TAG,bitmap.getByteCount()+"bitmap.getByteCount()" + "rowPadding / pixelStride" + (rowPadding / pixelStride)); }else{ Log.d(TAG,"图片 为空"); } if (image != null) { image.close(); } }catch (Exception ignored){ }finally { if (imageReader != null) { imageReader.discardFreeBuffers(); } imageReader.close(); imageReader = null; if (virtualDisplay != null){ virtualDisplay.release(); virtualDisplay = null; } } return bitmap; } }
然后是C# adb 已经算是root了 所以也没啥可说的
完整代码可以看
https://gitee.com/yangdc/AutoAndroid
高版本坑还是很多的 码云项目没整理是 开发学习过程
项目实现了不少自用功能.....很实用 但是不大众化 使用起来 需要一定的理解才行不是傻瓜式的