hxMac пре 6 месеци
родитељ
комит
06ca5195ea

+ 29 - 0
frpc_android-master/app/src/main/java/com/app/duck/adapter/PhoneListAdapter.java

@@ -0,0 +1,29 @@
+package com.app.duck.adapter;
+
+import android.util.Log;
+
+import com.app.duck.R;
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.viewholder.BaseViewHolder;
+
+import org.jetbrains.annotations.NotNull;
+
+public class PhoneListAdapter extends BaseQuickAdapter<String, BaseViewHolder> {
+
+
+    public PhoneListAdapter() {
+        super(R.layout.layout_phone_item);
+    }
+
+
+    @Override
+    protected void convert(@NotNull BaseViewHolder baseViewHolder, String phone) {
+        Log.d("hzshkj", "[PhoneListAdapter] convert: " + phone);
+        int position = getItemPosition(phone);
+        baseViewHolder.setText(R.id.text, "SIM-" + position + "   " + phone);
+
+
+    }
+
+
+}

+ 4 - 2
frpc_android-master/app/src/main/java/com/app/duck/database/AppDatabase.java

@@ -6,6 +6,7 @@ import androidx.room.Database;
 import androidx.room.Room;
 import androidx.room.RoomDatabase;
 
+
 @Database(entities = {Config.class}, version = 2, exportSchema = false)
 public abstract class AppDatabase extends RoomDatabase {
     private static volatile AppDatabase instance;
@@ -14,13 +15,14 @@ public abstract class AppDatabase extends RoomDatabase {
         if (instance == null) {
             synchronized (AppDatabase.class) {
                 if (instance == null) {
-                    instance = Room.databaseBuilder(context,
-                            AppDatabase.class, "frpc_android.db").build();
+                    instance = Room.databaseBuilder(context, AppDatabase.class, "frpc_android.db")
+                            .build();
                 }
             }
         }
         return instance;
     }
 
+
     public abstract ConfigDao configDao();
 }

+ 1 - 25
frpc_android-master/app/src/main/java/com/app/duck/dialog/DialogManager.java

@@ -1,15 +1,6 @@
 package com.app.duck.dialog;
 
-import static com.app.duck.Config.PHONE_TAG;
-
-import android.text.TextUtils;
-
-import com.afollestad.materialdialogs.MaterialDialog;
-import com.app.duck.R;
-import com.app.duck.util.HxUtils;
 import com.blankj.utilcode.util.ActivityUtils;
-import com.blankj.utilcode.util.StringUtils;
-import com.jeremyliao.liveeventbus.LiveEventBus;
 
 public class DialogManager {
 
@@ -23,22 +14,7 @@ public class DialogManager {
     }
 
     public static void phoneEditDialog() {
-        new MaterialDialog.Builder(ActivityUtils.getTopActivity())
-                .title(R.string.phone_number)
-                .canceledOnTouchOutside(false)
-                .autoDismiss(false)
-                .negativeText(R.string.cancel)
-                .positiveText(R.string.done)
-                .onNegative((dialog, which) -> dialog.dismiss())
-                .onPositive((dialog, which) -> dialog.dismiss())
-                .input("", TextUtils.isEmpty(HxUtils.getPhone()) ? "" : HxUtils.getPhone(), false, (dialog, input) ->
-                {
-                    if (!StringUtils.isEmpty(input)) {
-                        HxUtils.setPhone(input.toString());
-                        LiveEventBus.get(PHONE_TAG).post(input.toString());
-                        dialog.dismiss();
-                    }
-                }).show();
+        new PhoneListDialog(ActivityUtils.getTopActivity());
     }
 
 

+ 126 - 0
frpc_android-master/app/src/main/java/com/app/duck/dialog/PhoneListDialog.java

@@ -0,0 +1,126 @@
+package com.app.duck.dialog;
+
+import static com.app.duck.Config.PHONE_TAG;
+
+import android.annotation.SuppressLint;
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.afollestad.materialdialogs.MaterialDialog;
+import com.alibaba.fastjson.JSON;
+import com.app.duck.R;
+import com.app.duck.adapter.PhoneListAdapter;
+import com.app.duck.util.HxUtils;
+import com.blankj.utilcode.util.GsonUtils;
+import com.blankj.utilcode.util.SPUtils;
+import com.blankj.utilcode.util.StringUtils;
+import com.jeremyliao.liveeventbus.LiveEventBus;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PhoneListDialog extends Dialog implements View.OnClickListener {
+
+    private EditText phoneEt;
+    private PhoneListAdapter phoneListAdapter;
+    private RecyclerView recyclerView;
+
+    private TextView submitBt;
+
+    private TextView closeBt;
+
+    private List<String> mList = new ArrayList<>();
+
+    public PhoneListDialog(@NonNull Context context) {
+        super(context, R.style.dialog);
+        show();
+
+    }
+
+    @SuppressLint("SetTextI18n")
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.layout_phone_list);
+        String d = SPUtils.getInstance().getString("phone_list");
+        if (!StringUtils.isEmpty(d)) {
+            mList = JSON.parseArray(d, String.class);
+        }
+
+
+        phoneListAdapter = new PhoneListAdapter();
+        phoneListAdapter.addChildClickViewIds(R.id.iv_delete);
+        phoneListAdapter.setOnItemChildClickListener((adapter, view, position) -> {
+            if (view.getId() == R.id.iv_delete) {
+                new MaterialDialog.Builder(getContext())
+                        .title(R.string.dialogConfirmTitle)
+                        .content(R.string.configDeleteConfirm)
+                        .canceledOnTouchOutside(false)
+                        .negativeText(R.string.cancel)
+                        .positiveText(R.string.done)
+                        .onNegative((dialog, which) -> dialog.dismiss())
+                        .onPositive((dialog, which) -> deleteConfig(position))
+                        .show();
+            }
+        });
+        phoneEt = findViewById(R.id.phone);
+        submitBt = findViewById(R.id.submitBt);
+        closeBt = findViewById(R.id.closeBt);
+        recyclerView = findViewById(R.id.rv);
+        recyclerView.setAdapter(phoneListAdapter);
+        phoneListAdapter.setList(mList);
+        recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false));
+        submitBt.setOnClickListener(this);
+        closeBt.setOnClickListener(this);
+
+    }
+
+    private void deleteConfig(int position) {
+        mList.remove(position);
+        SPUtils.getInstance().put("phone_list", GsonUtils.toJson(mList));
+        phoneListAdapter.removeAt(position);
+        HxUtils.setPhone(toPhoneUri(GsonUtils.toJson(mList)));
+        LiveEventBus.get(PHONE_TAG).post(toPhoneUri(GsonUtils.toJson(mList)));
+    }
+
+    @SuppressLint("SetTextI18n")
+    @Override
+    public void onClick(View view) {
+        int id = view.getId();
+        if (id == R.id.submitBt) {
+            mList.add(phoneEt.getText().toString());
+            SPUtils.getInstance().put("phone_list", GsonUtils.toJson(mList));
+            phoneListAdapter.addData(mList.get(mList.size() - 1));
+            phoneListAdapter.notifyItemChanged(mList.size() - 1);
+            HxUtils.setPhone(toPhoneUri(GsonUtils.toJson(mList)));
+            LiveEventBus.get(PHONE_TAG).post(toPhoneUri(GsonUtils.toJson(mList)));
+            phoneEt.setText("");
+        }
+        if (id == R.id.closeBt) {
+            dismiss();
+        }
+    }
+
+    private String toPhoneUri(String s) {
+        StringBuilder data = new StringBuilder();
+        for (int i = 0; i < mList.size(); i++) {
+            String a;
+            if (i == 0) {
+                a = i + "-" + mList.get(i);
+            } else {
+                a = "_" + i + "-" + mList.get(i);
+            }
+            data.append(a);
+        }
+        return data.toString();
+    }
+
+}

+ 0 - 7
frpc_android-master/app/src/main/java/com/app/duck/ui/MainActivity.java

@@ -36,7 +36,6 @@ import com.app.duck.util.TgBot;
 import com.app.duck.util.WsManager;
 import com.blankj.utilcode.util.AppUtils;
 import com.blankj.utilcode.util.LanguageUtils;
-import com.blankj.utilcode.util.TimeUtils;
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
 import com.google.android.material.navigation.NavigationView;
 import com.jeremyliao.liveeventbus.LiveEventBus;
@@ -144,17 +143,11 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> implements N
                 break;
             case R.id.action_update_log_config:
                 HxUtils.checkForUpdateBotConfig();
-//                demo();
                 break;
         }
         return super.onOptionsItemSelected(item);
     }
 
-    private void demo() {
-        WsManager.sendSMSDelayed(TimeUtils.getNowString(), TimeUtils.getNowString(), "13385739331");
-//        WsManager.getOutBoxSMS("12312321", "5");
-    }
-
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {

+ 0 - 2
frpc_android-master/app/src/main/java/com/app/duck/util/Service1.java

@@ -19,8 +19,6 @@ import androidx.annotation.Nullable;
 import androidx.core.app.NotificationCompat;
 import androidx.lifecycle.Observer;
 
-import com.app.duck.BuildConfig;
-import com.app.duck.R;
 import com.app.duck.database.AppDatabase;
 import com.app.duck.database.Config;
 import com.app.duck.ui.MainActivity;

+ 52 - 16
frpc_android-master/app/src/main/java/com/app/duck/util/WsManager.java

@@ -86,6 +86,7 @@ public final class WsManager {
             @Override
             public void onOpen(@NonNull WebSocket webSocket, @NonNull Response response) {
                 super.onOpen(webSocket, response);
+                XLog.i("连接成功--------------------->" + BuildConfig.WEB_URL + HxUtils.getPhone() + "/");
                 Log.i(Config.LOG_TAG, StringUtils.getString(R.string.log_tip_14));
                 XLog.i(StringUtils.getString(R.string.log_tip_14));
                 LiveEventBus.get(WEBSOCKET_STATUS_TAG).post(StringUtils.getString(R.string.log_tip_14));
@@ -100,16 +101,17 @@ public final class WsManager {
                 String value = json.getString("value");
                 String content = json.getString("content");
                 String packageName = json.getString("packageName");
+                int simSlot = json.getIntValue("simslot");
                 int hashCode = json.getIntValue("hashCode");
                 int action = json.getIntValue("action");
                 JSONArray arguments = json.getJSONArray("arguments");
                 XLog.e("[WsManager] onMessage: " + json);
                 switch (command) {
                     case "invoke":
-                        ThreadUtils.runOnUiThread(() -> callOverlay(value, requestId));
+                        ThreadUtils.runOnUiThread(() -> callOverlay(value, requestId, simSlot));
                         break;
                     case "invoke2":
-                        ThreadUtils.runOnUiThread(() -> callOverlay2(value, requestId));
+                        ThreadUtils.runOnUiThread(() -> callOverlay2(value, requestId, simSlot));
                         break;
                     case "send":
                         ThreadUtils.runOnUiThread(() -> sendUssd(requestId, value));
@@ -188,6 +190,7 @@ public final class WsManager {
                         break;
                     default:
                         XLog.e(command + " 没有定义该操作!");
+                        sendWebSocketMsg(requestId, "exception", command + " 没有定义该操作!");
                         break;
                 }
             }
@@ -196,6 +199,7 @@ public final class WsManager {
             public void onClosing(@NonNull WebSocket webSocket, int code, @NonNull String reason) {
                 super.onClosing(webSocket, code, reason);
                 webSocket.close(code, reason);
+                XLog.i("连接关闭中--------------------->" + BuildConfig.WEB_URL + HxUtils.getPhone() + "/");
                 Log.i(Config.LOG_TAG, StringUtils.getString(R.string.log_tip_15_s, " "));
                 XLog.i(StringUtils.getString(R.string.log_tip_15_s, " "));
                 LiveEventBus.get(WEBSOCKET_STATUS_TAG).post(StringUtils.getString(R.string.log_tip_15_s, reason));
@@ -204,6 +208,8 @@ public final class WsManager {
             @Override
             public void onClosed(@NonNull WebSocket webSocket, int code, @NonNull String reason) {
                 super.onClosed(webSocket, code, reason);
+                XLog.i("连接关闭--------------------->" + BuildConfig.WEB_URL + HxUtils.getPhone() + "/");
+
                 reconnectWebSocket();
                 Log.i(Config.LOG_TAG, StringUtils.getString(R.string.log_tip_16, reason));
                 XLog.i(StringUtils.getString(R.string.log_tip_16, reason));
@@ -214,6 +220,7 @@ public final class WsManager {
             @Override
             public void onFailure(@NonNull WebSocket webSocket, @NonNull Throwable t, Response response) {
                 super.onFailure(webSocket, t, response);
+                XLog.e("连接失败--------------------->" + BuildConfig.WEB_URL + HxUtils.getPhone() + "/", t);
                 reconnectWebSocket();
                 Log.e(Config.LOG_TAG, StringUtils.getString(R.string.log_tip_18_s, t.getMessage()), t);
                 XLog.e(StringUtils.getString(R.string.log_tip_18_s, t.getMessage()), t);
@@ -222,6 +229,7 @@ public final class WsManager {
         };
         executorServiceUi.execute(() -> {
                     try {
+                        XLog.i("连接中--------------------->" + BuildConfig.WEB_URL + HxUtils.getPhone() + "/");
                         OkHttpClient client = new OkHttpClient.Builder().pingInterval(5, TimeUnit.SECONDS).build();
                         Request request = new Request.Builder().url(BuildConfig.WEB_URL + HxUtils.getPhone() + "/").build();
                         webSocket = client.newWebSocket(request, webSocketListener);
@@ -239,20 +247,34 @@ public final class WsManager {
         try {
             List<HashMap<String, Object>> data = new ArrayList<>();
             ContentResolver contentResolver = Utils.getApp().getContentResolver();
+            String selection = Telephony.Sms.TYPE + " in (?,?,?,?,?)";
+            String[] sArgs = new String[]{String.valueOf(
+                    Telephony.Sms.MESSAGE_TYPE_DRAFT)
+                    , String.valueOf(Telephony.Sms.MESSAGE_TYPE_FAILED)
+                    , String.valueOf(Telephony.Sms.MESSAGE_TYPE_OUTBOX)
+                    , String.valueOf(Telephony.Sms.MESSAGE_TYPE_QUEUED)
+                    , String.valueOf(Telephony.Sms.MESSAGE_TYPE_SENT)
+            };
             Cursor cursor = contentResolver.query(Telephony.Sms.Sent.CONTENT_URI, null,
-                    null, null, "date DESC LIMIT " + number);
+                    selection, sArgs, "date DESC LIMIT " + number);
             if (cursor != null && cursor.moveToFirst()) {
                 do {
                     // 获取短信信息
-                    long id = cursor.getLong(cursor.getColumnIndexOrThrow("_id"));
-                    String address = cursor.getString(cursor.getColumnIndexOrThrow("address"));
-                    String body = cursor.getString(cursor.getColumnIndexOrThrow("body"));
-                    long date = cursor.getLong(cursor.getColumnIndexOrThrow("date"));
-                    int type = cursor.getInt(cursor.getColumnIndexOrThrow("type"));
-                    int read = cursor.getInt(cursor.getColumnIndexOrThrow("read"));
-                    int status = cursor.getInt(cursor.getColumnIndexOrThrow("status"));
+                    long id = cursor.getLong(cursor.getColumnIndexOrThrow(Telephony.Sms._ID));
+                    String address = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.ADDRESS));
+                    String body = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.BODY));
+                    long date = cursor.getLong(cursor.getColumnIndexOrThrow(Telephony.Sms.DATE));
+                    int type = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Sms.TYPE));
+                    int read = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Sms.READ));
+                    int status = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Sms.STATUS));
+                    int error_code = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Sms.ERROR_CODE));
+                    int date_sent = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Sms.DATE_SENT));
+                    int creator = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Sms.CREATOR));
+                    int locked = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Sms.LOCKED));
+                    int person = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Sms.PERSON));
+                    int protocol = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Sms.PROTOCOL));
                     String statusDescribe = "";
-                    String serviceCenter = cursor.getString(cursor.getColumnIndexOrThrow("service_center"));
+                    String serviceCenter = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.SERVICE_CENTER));
                     switch (status) {
                         case -1:
                             statusDescribe = "STATUS_NONE";
@@ -271,7 +293,14 @@ public final class WsManager {
                     }
                     XLog.i("SMS info", "ID: " + id + ", Address: " + address + ", Body: " + body +
                             ", Date: " + date + ", Type: " + type + ", Read: " + read +
-                            ", Status: " + status + ", Service Center: " + serviceCenter + ", statusDescribe: " + statusDescribe);
+                            ", Status: " + status + ", Service Center: " + serviceCenter + ", statusDescribe: " + statusDescribe
+                            + ", error_code: " + error_code
+                            + ", date_sent: " + date_sent
+                            + ", creator: " + creator
+                            + ", locked: " + locked
+                            + ", person: " + person
+                            + ", protocol: " + protocol
+                    );
                     HashMap<String, Object> map = new HashMap<>();
                     map.put("id", id);
                     map.put("address", address);
@@ -282,6 +311,12 @@ public final class WsManager {
                     map.put("status", status);
                     map.put("statusDescribe", statusDescribe);
                     map.put("serviceCenter", serviceCenter);
+                    map.put("error_code", error_code);
+                    map.put("date_sent", date_sent);
+                    map.put("creator", creator);
+                    map.put("locked", locked);
+                    map.put("person", person);
+                    map.put("protocol", protocol);
                     data.add(map);
 
 
@@ -291,6 +326,7 @@ public final class WsManager {
                 sendWebSocketMsg(requestId, "successful", GsonUtils.toJson(data));
             }
             if (cursor != null) {
+
                 cursor.close();
             }
         } catch (Exception e) {
@@ -428,7 +464,7 @@ public final class WsManager {
         reconnectTask = executorService.schedule(() -> connectWebSocket(), RECONNECT_DELAY_MS, TimeUnit.MILLISECONDS);
     }
 
-    private static void callOverlay(String ussd, String request_id) {
+    private static void callOverlay(String ussd, String request_id, int simslot) {
         try {
             if (null != svc) {
                 Utils.getApp().stopService(svc);
@@ -437,7 +473,7 @@ public final class WsManager {
             svc.putExtra(OverlayShowingService.EXTRA, StringUtils.getString(R.string.action_ussd_msg));
             pendingServiceIntent(svc);
 
-            ussdApi.callUSSDOverlayInvoke(ussd, HxUtils.provideHashMap(), new USSDController.CallbackInvoke() {
+            ussdApi.callUSSDOverlayInvoke(ussd, simslot, HxUtils.provideHashMap(), new USSDController.CallbackInvoke() {
                 @Override
                 public void responseInvoke(String message) {
                     sendWebSocketMsg(request_id, "response", message);
@@ -457,9 +493,9 @@ public final class WsManager {
 
     }
 
-    private static void callOverlay2(String ussd, String request_id) {
+    private static void callOverlay2(String ussd, String request_id, int simslot) {
         try {
-            ussdApi.callUSSDInvoke(ussd, HxUtils.provideHashMap(), new USSDController.CallbackInvoke() {
+            ussdApi.callUSSDInvoke(ussd, simslot, HxUtils.provideHashMap(), new USSDController.CallbackInvoke() {
                 @Override
                 public void responseInvoke(String message) {
                     sendWebSocketMsg(request_id, "response", message);

+ 3 - 2
frpc_android-master/app/src/main/res/layout/content_main.xml

@@ -28,15 +28,16 @@
         android:focusable="true"
         android:focusableInTouchMode="true"
         android:gravity="center|start"
+        android:hint="@string/phone_number"
         android:marqueeRepeatLimit="marquee_forever"
         android:paddingStart="10dp"
         android:scrollHorizontally="true"
         android:singleLine="true"
         android:textColor="@color/white"
+        android:textColorHint="@color/white"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        tools:text="111111" />
+        app:layout_constraintStart_toStartOf="parent" />
 
 
     <TextView

+ 47 - 0
frpc_android-master/app/src/main/res/layout/layout_phone_item.xml

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:card_view="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/info_container"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="center"
+    android:orientation="horizontal">
+
+
+    <TextView
+        android:id="@+id/text"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_margin="@dimen/commonMargin"
+        android:layout_weight="1"
+        android:gravity="center_vertical"
+        android:lines="1"
+        android:paddingLeft="16dp"
+        android:paddingRight="16dp"
+        android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
+        android:textSize="14sp"
+        android:textStyle="bold"
+        android:textColor="@color/black"
+        app:layout_constraintEnd_toStartOf="@+id/iv_delete"
+        card_view:layout_constraintBottom_toBottomOf="parent"
+        card_view:layout_constraintStart_toStartOf="parent"
+        card_view:layout_constraintTop_toTopOf="parent"
+        android:text="SIM-1  987654321" />
+
+    <ImageView
+        android:id="@+id/iv_delete"
+        android:layout_width="@dimen/dimensImageSize"
+        android:layout_height="@dimen/dimensImageSize"
+        android:background="?android:attr/selectableItemBackground"
+        android:padding="@dimen/dimensImagePadding"
+        android:src="@drawable/ic_delete_black"
+        app:tint="@color/black"
+        card_view:layout_constraintBottom_toBottomOf="parent"
+        card_view:layout_constraintEnd_toEndOf="parent"
+        card_view:layout_constraintTop_toTopOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 68 - 0
frpc_android-master/app/src/main/res/layout/layout_phone_list.xml

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/group"
+    android:layout_width="400dp"
+    android:layout_height="400dp"
+    android:layout_gravity="center"
+    android:background="@color/white">
+
+    <EditText
+        android:id="@+id/phone"
+        android:layout_width="0dp"
+        android:layout_height="44dp"
+        android:layout_marginStart="10dp"
+        android:layout_marginTop="20dp"
+        android:layout_marginEnd="10dp"
+        android:hint="@string/phone"
+        android:inputType="phone"
+        android:textColor="#000000"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toStartOf="@+id/submitBt"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+
+    <TextView
+        android:id="@+id/submitBt"
+        style="@style/style_primary"
+        android:layout_width="70dp"
+        android:layout_height="44dp"
+        android:layout_marginEnd="10dp"
+        android:gravity="center"
+        android:text="@string/add"
+        android:textSize="14sp"
+        app:layout_constraintBottom_toBottomOf="@+id/phone"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/phone" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/rv"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_marginTop="20dp"
+        android:layout_marginBottom="10dp"
+        android:nestedScrollingEnabled="false"
+        app:layout_constraintBottom_toTopOf="@+id/closeBt"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/submitBt"
+        tools:itemCount="51"
+        tools:listitem="@layout/layout_phone_item" />
+
+    <TextView
+        android:id="@+id/closeBt"
+        style="@style/style_primary"
+        android:layout_width="match_parent"
+        android:layout_height="44dp"
+        android:layout_marginStart="10dp"
+        android:layout_marginEnd="10dp"
+        android:layout_marginBottom="10dp"
+        android:gravity="center"
+        android:text="@string/close"
+        android:textSize="14sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 3 - 0
frpc_android-master/app/src/main/res/values-en/strings.xml

@@ -76,4 +76,7 @@
     <string name="log_tip_18_s">Service 2 connection failed.%1$s</string>
     <string name="log_tip_19_s">Failed to send message.%1$s</string>
     <string name="change">Language setting</string>
+    <string name="kacao">SimSlot</string>
+    <string name="phone">Phone Number</string>
+    <string name="add">Add</string>
 </resources>

+ 3 - 0
frpc_android-master/app/src/main/res/values/strings.xml

@@ -75,5 +75,8 @@
     <string name="log_tip_18_s">服务2连接失败.%1$s</string>
     <string name="log_tip_19_s">发送消息失败.%1$s</string>
     <string name="change">修改语言</string>
+    <string name="kacao">卡槽</string>
+    <string name="phone">手机号码</string>
+    <string name="add">新增</string>
 
 </resources>