app/src/main/java/com/auto/lyric/MainActivity.java | ●●●●● patch | view | raw | blame | history | |
app/src/main/java/com/auto/lyric/retrofit/Interceptor/EncryptInterceptor.java | ●●●●● patch | view | raw | blame | history | |
app/src/main/java/com/auto/lyric/retrofit/Interceptor/HttpLoggingInterceptor.java | ●●●●● patch | view | raw | blame | history | |
app/src/main/java/com/auto/lyric/retrofit/observable/HttpObserver.java | ●●●●● patch | view | raw | blame | history | |
app/src/main/java/com/auto/lyric/retrofit/utils/HttpPrintUtils.java | ●●●●● patch | view | raw | blame | history | |
app/src/main/java/com/auto/lyric/retrofit/utils/RetrofitUtils.java | ●●●●● patch | view | raw | blame | history | |
app/src/main/java/com/auto/lyric/service/AutoInputService.java | ●●●●● patch | view | raw | blame | history | |
app/src/main/java/com/auto/lyric/util/MyLog.java | ●●●●● patch | view | raw | blame | history | |
app/src/main/java/com/auto/lyric/vm/MainViewModel.java | ●●●●● patch | view | raw | blame | history |
app/src/main/java/com/auto/lyric/MainActivity.java
@@ -1,14 +1,86 @@ package com.auto.lyric; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import android.os.Bundle; import com.auto.lyric.base.activities.BaseActivity; import com.auto.lyric.databinding.ActivityMainBinding; import com.auto.lyric.service.AutoInputService; import com.auto.lyric.vm.MainViewModel; public class MainActivity extends AppCompatActivity { public class MainActivity extends BaseActivity<ActivityMainBinding, MainViewModel> { Intent service = new Intent(getApplicationContext(), AutoInputService.class); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); public void initViews() { } @Override protected void onResume() { super.onResume(); //申请权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //开启悬浮窗 if(!Settings.canDrawOverlays(getApplicationContext())) { //启动Activity让用户授权 Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); intent.setData(Uri.parse("package:" + getPackageName())); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK ); startActivity(intent); }else if(!isAccessibilitySettingsOn()){//辅助权限 Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK ); startActivity(intent); }else{//开启监听服务 startService(service); } } } public boolean isAccessibilitySettingsOn() { int accessibilityEnabled = 0; final String service = getPackageName() + "/" + AutoInputService.class.getCanonicalName(); try { accessibilityEnabled = Settings.Secure.getInt( this.getApplicationContext().getContentResolver(), android.provider.Settings.Secure.ACCESSIBILITY_ENABLED); Log.v(TAG, "accessibilityEnabled = " + accessibilityEnabled); } catch (Settings.SettingNotFoundException e) { Log.e(TAG, "Error finding setting, default accessibility to not found: " + e.getMessage()); } TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':'); if (accessibilityEnabled == 1) { Log.v(TAG, "***ACCESSIBILITY IS ENABLED*** -----------------"); String settingValue = Settings.Secure.getString( getApplicationContext().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); if (settingValue != null) { mStringColonSplitter.setString(settingValue); while (mStringColonSplitter.hasNext()) { String accessibilityService = mStringColonSplitter.next(); Log.v(TAG, "-------------- > accessibilityService :: " + accessibilityService + " " + service); if (accessibilityService.equalsIgnoreCase(service)) { Log.v(TAG, "We've found the correct setting - accessibility is switched on!"); return true; } } } } else { Log.v(TAG, "***ACCESSIBILITY IS DISABLED***"); } return false; } } app/src/main/java/com/auto/lyric/retrofit/Interceptor/EncryptInterceptor.java
@@ -1,7 +1,7 @@ package com.auto.lyric.retrofit.Interceptor; import com.runt.open.mvvm.retrofit.utils.RSAUtils; import com.auto.lyric.retrofit.utils.RSAUtils; import org.json.JSONObject; app/src/main/java/com/auto/lyric/retrofit/Interceptor/HttpLoggingInterceptor.java
@@ -2,10 +2,10 @@ import android.util.Log; import com.runt.open.mvvm.retrofit.net.NetWorkCost; import com.runt.open.mvvm.retrofit.net.NetWorkListenear; import com.runt.open.mvvm.retrofit.utils.HttpPrintUtils; import com.runt.open.mvvm.util.GsonUtils; import com.auto.lyric.retrofit.net.NetWorkCost; import com.auto.lyric.retrofit.net.NetWorkListenear; import com.auto.lyric.retrofit.utils.HttpPrintUtils; import com.auto.lyric.util.GsonUtils; import org.json.JSONObject; app/src/main/java/com/auto/lyric/retrofit/observable/HttpObserver.java
@@ -4,7 +4,7 @@ import androidx.lifecycle.MutableLiveData; import com.runt.open.mvvm.data.BaseApiResult; import com.auto.lyric.data.BaseApiResult; import java.lang.reflect.ParameterizedType; import java.net.SocketTimeoutException; app/src/main/java/com/auto/lyric/retrofit/utils/HttpPrintUtils.java
@@ -1,8 +1,9 @@ package com.auto.lyric.retrofit.utils; import com.runt.open.mvvm.BuildConfig; import com.runt.open.mvvm.util.GsonUtils; import com.runt.open.mvvm.util.MyLog; import com.auto.lyric.BuildConfig; import com.auto.lyric.util.GsonUtils; import com.auto.lyric.util.MyLog; import java.io.EOFException; import java.util.ArrayList; app/src/main/java/com/auto/lyric/retrofit/utils/RetrofitUtils.java
@@ -1,12 +1,12 @@ package com.auto.lyric.retrofit.utils; import com.runt.open.mvvm.BuildConfig; import com.runt.open.mvvm.retrofit.Interceptor.EncryptInterceptor; import com.runt.open.mvvm.retrofit.Interceptor.HttpLoggingInterceptor; import com.runt.open.mvvm.retrofit.api.CommonApiCenter; import com.runt.open.mvvm.retrofit.converter.DecryptGsonConverterFactory; import com.runt.open.mvvm.retrofit.net.NetWorkListenear; import com.auto.lyric.BuildConfig; import com.auto.lyric.retrofit.Interceptor.EncryptInterceptor; import com.auto.lyric.retrofit.Interceptor.HttpLoggingInterceptor; import com.auto.lyric.retrofit.api.CommonApiCenter; import com.auto.lyric.retrofit.converter.DecryptGsonConverterFactory; import com.auto.lyric.retrofit.net.NetWorkListenear; import java.util.Collections; import java.util.concurrent.TimeUnit; @@ -108,7 +108,7 @@ //设置OKHttpClient .client(client) //设置baseUrl,注意,baseUrl必须后缀"/" .baseUrl(BuildConfig.ENVIRONMENT.equals("develop")?HOST_IP_ADDR:BuildConfig.HOST_IP_ADDR) //.baseUrl(BuildConfig.ENVIRONMENT.equals("develop")?HOST_IP_ADDR:BuildConfig.HOST_IP_ADDR) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); } app/src/main/java/com/auto/lyric/service/AutoInputService.java
New file @@ -0,0 +1,210 @@ package com.auto.lyric.service; import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityServiceInfo; import android.annotation.SuppressLint; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Build; import android.util.Log; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityWindowInfo; import android.widget.Toast; import java.util.List; /** * Created by Runt (qingingrunt2010@qq.com) on 2022/3/20. */ public class AutoInputService extends AccessibilityService { final String TAG = "AutoInputService"; public static final int ACTION_SEND = 1001,//发送 ACTION_PASTE = 1002;//粘贴 BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { int action = intent.getIntExtra("action", 0); Log.e(TAG, "onReceive action: " + action); switch (action){ case ACTION_SEND: //List<AccessibilityNodeInfo> nodeInfos = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("com.ss.android.ugc.aweme:id/llp"); AccessibilityNodeInfo sendNode = getViewByDesc(getRootInActiveWindow(),"发送"); Log.e(TAG, "ACTION_SEND nodeInfos: " + sendNode); if(sendNode != null){ Log.e(TAG, "ACTION_SEND nodeInfos: " + sendNode.getClassName()); sendNode.performAction(AccessibilityNodeInfo.ACTION_CLICK); }else{ printView(getRootInActiveWindow()," "); Toast.makeText(getBaseContext(),"未找到控件",Toast.LENGTH_SHORT).show(); } break; case ACTION_PASTE: List<AccessibilityNodeInfo> list = getRootInActiveWindow().findAccessibilityNodeInfosByText("说点什么..."); Log.e(TAG, "ACTION_PASTE nodeInfos: " + list.size()); printView(getRootInActiveWindow()," "); AccessibilityNodeInfo editNode = getView(getRootInActiveWindow(),"android.widget.EditText"); if(editNode != null){ Log.e(TAG, "ACTION_PASTE nodeInfos: " + editNode.getClassName()); editNode.performAction(AccessibilityNodeInfo.ACTION_PASTE); }else{ Toast.makeText(getBaseContext(),"未找到控件",Toast.LENGTH_SHORT).show(); } break; } } }; static boolean flag = false , isFront; @Override public void onAccessibilityEvent(AccessibilityEvent event) { int eventType = event.getEventType(); Log.d(TAG," text:" + event.getText()+" class:"+event.getClassName() +" action:" + event.getAction() +" windowId:"+ event.getWindowId()); Log.d(TAG,"event:"+event ); Log.d(TAG,"ParcelableData:"+event.getParcelableData() ); AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); AccessibilityNodeInfo source = event.getSource();//当前界面的可访问节点信息 if(source != null){ //printView(source,"source == "); } Log.d(TAG,"source:"+(source == null? null : source.getClassName()) ); Log.d(TAG,"nodeInfo:"+ (nodeInfo == null? null : nodeInfo.getClassName()) ); switch (eventType) { case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED://界面变化事件 Log.e(TAG, "TYPE_WINDOW_CONTENT_CHANGED " ); break; case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED://界面变化事件 Log.e(TAG, "TYPE_WINDOW_STATE_CHANGED " ); if(source != null && event.getClassName().toString().equals("com.ss.android.ugc.aweme.live.LivePlayActivity")){ List<AccessibilityNodeInfo> list = getRootInActiveWindow().findAccessibilityNodeInfosByText("说点什么..."); Log.e(TAG,"获取到控件 "+list.size()); if (list != null && list.size() > 0 && flag) { //模拟第三方点击事件 //找到你的节点以后 就直接点击他就行了 //AccessibilityNodeInfo node = list.get(0); list.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { Log.e(TAG,"执行点击 "+list.get(0).getPaneTitle()); } }else if(flag){ Toast.makeText(getBaseContext(),"未找到控件",Toast.LENGTH_SHORT).show(); } } if(event.getText().contains("更多选项") ){ //printView(nodeInfo," "); //performGlobalAction(GLOBAL_ACTION_RECENTS); // 任务管理器 //performGlobalAction(GLOBAL_ACTION_BACK); // 返回安装页面 } break; case AccessibilityEvent.TYPE_VIEW_FOCUSED://焦点变更 Log.e(TAG, "TYPE_VIEW_FOCUSED ResourceName:" +( source == null ? null : source.getParent())); if(event.getClassName().equals("android.widget.EditText") && source != null){ //source.performAction(AccessibilityNodeInfo.ACTION_LONG_CLICK); //source.performAction(AccessibilityNodeInfo.ACTION_PASTE);//粘贴 } break; case AccessibilityEvent.TYPE_VIEW_LONG_CLICKED: Log.e(TAG, "TYPE_VIEW_LONG_CLICKED ResourceName:" +( source == null ? null : source.getParent())); break; case AccessibilityEvent.TYPE_VIEW_CLICKED: Log.e(TAG, "TYPE_VIEW_CLICKED " ); if(nodeInfo != null) { Log.e(TAG, "TYPE_VIEW_CLICKED source:" + nodeInfo.getText() + " " + nodeInfo.getClass()); } /**/ //界面点击 break; case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED: //界面文字改动 Log.e(TAG, "TYPE_VIEW_TEXT_CHANGED " ); break; } } @SuppressLint("NewApi") private void printView(AccessibilityNodeInfo node, String space){ Log.e(TAG,space +node+" id:"+node.getViewIdResourceName() +" class:"+node.getClassName()+" text:"+node.getText()+" "+node.getPaneTitle()); if(node.getChildCount() > 0){ for(int i = 0 ; i < node.getChildCount() ; i ++){ if(node.getChild(i) != null) { printView(node.getChild(i), space + " \t"); } } } } @SuppressLint("NewApi") private AccessibilityNodeInfo getView(AccessibilityNodeInfo node, String className){ Log.e(TAG,className +" id:"+node.getViewIdResourceName() +" class:"+node.getClassName()+" text:"+node.getText()+" "+node.getPaneTitle()); if(node.getChildCount() > 0){ for(int i = 0 ; i < node.getChildCount() ; i ++){ if(node.getChild(i) != null) { AccessibilityNodeInfo nodeInfo = getView(node.getChild(i), className); if(nodeInfo != null){ return nodeInfo; } } } }else if(node.getClassName().equals(className)){ return node; } return null; } @SuppressLint("NewApi") private AccessibilityNodeInfo getViewByDesc(AccessibilityNodeInfo node, String desc){ Log.e(TAG,desc +" getViewByDesc id:"+node.getViewIdResourceName() +" class:"+node.getClassName()+" text:"+node.getText()+" "+node.getContentDescription()); Log.e(TAG,"getViewByDesc node:"+node); if(node.getChildCount() > 0){ for(int i = 0 ; i < node.getChildCount() ; i ++){ if(node.getChild(i) != null) { AccessibilityNodeInfo nodeInfo = getViewByDesc(node.getChild(i), desc); if(nodeInfo != null){ return nodeInfo; } } } }else if(node != null && node.getContentDescription() != null && node.getContentDescription().equals(desc)){ return node; } return null; } private void printWindow(AccessibilityWindowInfo window, String space){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { Log.e(TAG,space +" id:"+window.getId() +" class:"+window.getClass().getName()+" text:"+window.getTitle()+" "+window.getRoot()); printView(window.getRoot()," window node "); } if(window.getChildCount() > 0){ for(int i = 0 ; i < window.getChildCount() ; i ++){ if(window.getChild(i) != null) { printWindow(window.getChild(i),space + " \t"); } } } } @Override public void onInterrupt() { unregisterReceiver(receiver); } @Override protected void onServiceConnected() { AccessibilityServiceInfo serviceInfo = new AccessibilityServiceInfo(); serviceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; serviceInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC; serviceInfo.packageNames = new String[]{/*"com.tencent.mm",*/"com.ss.android.ugc.aweme"/*,"com.runt.autotext"*/}; serviceInfo.notificationTimeout=100; serviceInfo.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS; setServiceInfo(serviceInfo); IntentFilter filter = new IntentFilter(); filter.addAction(AutoInputService.class.getName()); registerReceiver(receiver,filter); } } app/src/main/java/com/auto/lyric/util/MyLog.java
@@ -2,7 +2,7 @@ import android.util.Log; import com.runt.open.mvvm.BuildConfig; import com.auto.lyric.BuildConfig; /** app/src/main/java/com/auto/lyric/vm/MainViewModel.java
New file @@ -0,0 +1,9 @@ package com.auto.lyric.vm; import com.auto.lyric.base.model.BaseViewModel; /** * Created by Runt (qingingrunt2010@qq.com) on 2022/3/20. */ public class MainViewModel extends BaseViewModel { }