From c91b1bff52b9bc9344e04f731dd13e11295dbdbd Mon Sep 17 00:00:00 2001 From: "ray.ma" Date: Tue, 24 Jun 2025 23:26:35 +0800 Subject: [PATCH] init --- .gitignore | 4 + app/build.gradle | 24 ++ app/src/main/AndroidManifest.xml | 30 +++ .../com/ruler/smsforwarder/MainActivity.java | 83 ++++++ .../com/ruler/smsforwarder/NetworkUtil.java | 33 +++ .../com/ruler/smsforwarder/SmsReceiver.java | 47 ++++ app/src/main/res/drawable/ic_logo.xml | 16 ++ app/src/main/res/layout/activity_main.xml | 30 +++ app/src/main/res/values/strings.xml | 3 + build.gradle | 21 ++ gradle.properties | 2 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 251 ++++++++++++++++++ gradlew.bat | 94 +++++++ local.properties | 8 + settings.gradle | 2 + 17 files changed, 655 insertions(+) create mode 100644 .gitignore create mode 100644 app/build.gradle create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/ruler/smsforwarder/MainActivity.java create mode 100644 app/src/main/java/com/ruler/smsforwarder/NetworkUtil.java create mode 100644 app/src/main/java/com/ruler/smsforwarder/SmsReceiver.java create mode 100644 app/src/main/res/drawable/ic_logo.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 local.properties create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..22c674d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +.gradle +.idea +build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..b8945e9 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,24 @@ +apply plugin: 'com.android.application' + +android { + namespace 'com.ruler.smsforwarder' + compileSdkVersion 34 + defaultConfig { + applicationId "com.ruler.smsforwarder" + minSdkVersion 26 + targetSdkVersion 34 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.squareup.okhttp3:okhttp:4.9.3' +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..9c9d938 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/ruler/smsforwarder/MainActivity.java b/app/src/main/java/com/ruler/smsforwarder/MainActivity.java new file mode 100644 index 0000000..cd5e66f --- /dev/null +++ b/app/src/main/java/com/ruler/smsforwarder/MainActivity.java @@ -0,0 +1,83 @@ +package com.ruler.smsforwarder; + +import android.Manifest; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +public class MainActivity extends AppCompatActivity { + private static final int PERMISSION_REQUEST_CODE = 1001; + private EditText apiEditText; + private Button saveButton; + private SharedPreferences preferences; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + apiEditText = findViewById(R.id.edit_api_url); + saveButton = findViewById(R.id.btn_save); + preferences = getSharedPreferences("config", Context.MODE_PRIVATE); + + String apiUrl = preferences.getString("api_url", ""); + apiEditText.setText(apiUrl); + + saveButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String url = apiEditText.getText().toString().trim(); + if (TextUtils.isEmpty(url)) { + Toast.makeText(MainActivity.this, "API地址不能为空", Toast.LENGTH_SHORT).show(); + return; + } + preferences.edit().putString("api_url", url).apply(); + Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_SHORT).show(); + } + }); + + checkAndRequestPermissions(); + } + + private void checkAndRequestPermissions() { + String[] permissions = { + Manifest.permission.RECEIVE_SMS, + Manifest.permission.READ_SMS, + Manifest.permission.INTERNET + }; + boolean needRequest = false; + for (String perm : permissions) { + if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) { + needRequest = true; + break; + } + } + if (needRequest) { + ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (requestCode == PERMISSION_REQUEST_CODE) { + for (int result : grantResults) { + if (result != PackageManager.PERMISSION_GRANTED) { + Toast.makeText(this, "请授予所有权限以保证功能正常", Toast.LENGTH_LONG).show(); + return; + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ruler/smsforwarder/NetworkUtil.java b/app/src/main/java/com/ruler/smsforwarder/NetworkUtil.java new file mode 100644 index 0000000..ce8adc2 --- /dev/null +++ b/app/src/main/java/com/ruler/smsforwarder/NetworkUtil.java @@ -0,0 +1,33 @@ +package com.ruler.smsforwarder; + +import android.util.Log; + +import java.io.IOException; + +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +public class NetworkUtil { + private static final OkHttpClient client = new OkHttpClient(); + private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + + public static void postJson(String url, String json) { + new Thread(() -> { + RequestBody body = RequestBody.create(JSON, json); + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + try (Response response = client.newCall(request).execute()) { + if (!response.isSuccessful()) { + Log.e("NetworkUtil", "请求失败: " + response); + } + } catch (IOException e) { + Log.e("NetworkUtil", "网络异常", e); + } + }).start(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ruler/smsforwarder/SmsReceiver.java b/app/src/main/java/com/ruler/smsforwarder/SmsReceiver.java new file mode 100644 index 0000000..3f438d1 --- /dev/null +++ b/app/src/main/java/com/ruler/smsforwarder/SmsReceiver.java @@ -0,0 +1,47 @@ +package com.ruler.smsforwarder; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.telephony.SmsMessage; +import android.util.Log; + +import org.json.JSONObject; + +public class SmsReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction() != null && intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) { + Bundle bundle = intent.getExtras(); + if (bundle != null) { + Object[] pdus = (Object[]) bundle.get("pdus"); + if (pdus != null) { + StringBuilder content = new StringBuilder(); + for (Object pdu : pdus) { + SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdu); + content.append(sms.getMessageBody()); + } + sendToApi(context, content.toString()); + } + } + } + } + + private void sendToApi(Context context, String smsContent) { + SharedPreferences preferences = context.getSharedPreferences("config", Context.MODE_PRIVATE); + String apiUrl = preferences.getString("api_url", ""); + if (apiUrl == null || apiUrl.isEmpty()) { + Log.e("SmsReceiver", "API地址未设置"); + return; + } + try { + JSONObject json = new JSONObject(); + json.put("content", smsContent); + NetworkUtil.postJson(apiUrl, json.toString()); + } catch (Exception e) { + Log.e("SmsReceiver", "发送API失败", e); + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_logo.xml b/app/src/main/res/drawable/ic_logo.xml new file mode 100644 index 0000000..a37865e --- /dev/null +++ b/app/src/main/res/drawable/ic_logo.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..26a0c21 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,30 @@ + + + + + + + +