mirror of
https://github.com/pppscn/SmsForwarder
synced 2025-08-03 17:37:40 +08:00
优化:新增帮助文档(跳转GitHub的wiki)
This commit is contained in:
parent
5187b410de
commit
aac73b17db
@ -3,6 +3,7 @@ package com.idormy.sms.forwarder;
|
|||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@ -296,6 +297,12 @@ public class MainActivity extends AppCompatActivity implements RefreshListView.I
|
|||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void toHelp() {
|
||||||
|
Uri uri = Uri.parse("https://github.com/pppscn/SmsForwarder/wiki");
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
public void toRuleSetting(View view) {
|
public void toRuleSetting(View view) {
|
||||||
Intent intent = new Intent(this, RuleActivity.class);
|
Intent intent = new Intent(this, RuleActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
@ -352,6 +359,9 @@ public class MainActivity extends AppCompatActivity implements RefreshListView.I
|
|||||||
case R.id.to_about:
|
case R.id.to_about:
|
||||||
toAbout();
|
toAbout();
|
||||||
return true;
|
return true;
|
||||||
|
case R.id.to_help:
|
||||||
|
toHelp();
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
@ -1,148 +1,146 @@
|
|||||||
package com.idormy.sms.forwarder.sender;
|
package com.idormy.sms.forwarder.sender;
|
||||||
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.idormy.sms.forwarder.utils.LogUtil;
|
import com.idormy.sms.forwarder.utils.LogUtil;
|
||||||
import com.idormy.sms.forwarder.utils.SettingUtil;
|
import com.idormy.sms.forwarder.utils.SettingUtil;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.crypto.Mac;
|
import javax.crypto.Mac;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
import io.reactivex.rxjava3.core.Observable;
|
import io.reactivex.rxjava3.core.Observable;
|
||||||
import io.reactivex.rxjava3.core.ObservableEmitter;
|
import io.reactivex.rxjava3.core.ObservableEmitter;
|
||||||
import okhttp3.Call;
|
import okhttp3.Call;
|
||||||
import okhttp3.Callback;
|
import okhttp3.Callback;
|
||||||
import okhttp3.MediaType;
|
import okhttp3.MediaType;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.RequestBody;
|
import okhttp3.RequestBody;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
|
||||||
@SuppressWarnings({"ResultOfMethodCallIgnored", "rawtypes", "unchecked", "deprecation"})
|
@SuppressWarnings({"ResultOfMethodCallIgnored", "rawtypes", "unchecked", "deprecation"})
|
||||||
public class SenderDingdingMsg extends SenderBaseMsg {
|
public class SenderDingdingMsg extends SenderBaseMsg {
|
||||||
|
|
||||||
static final String TAG = "SenderDingdingMsg";
|
static final String TAG = "SenderDingdingMsg";
|
||||||
|
|
||||||
public static void sendMsg(final long logId, final Handler handError, String token, String secret, String atMobiles, Boolean atAll, String content) throws Exception {
|
public static void sendMsg(final long logId, final Handler handError, String token, String secret, String atMobiles, Boolean atAll, String content) throws Exception {
|
||||||
Log.i(TAG, "sendMsg token:" + token + " secret:" + secret + " atMobiles:" + atMobiles + " atAll:" + atAll + " content:" + content);
|
Log.i(TAG, "sendMsg token:" + token + " secret:" + secret + " atMobiles:" + atMobiles + " atAll:" + atAll + " content:" + content);
|
||||||
|
|
||||||
if (token == null || token.isEmpty()) {
|
if (token == null || token.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (secret != null && !secret.isEmpty()) {
|
if (secret != null && !secret.isEmpty()) {
|
||||||
Long timestamp = System.currentTimeMillis();
|
Long timestamp = System.currentTimeMillis();
|
||||||
String stringToSign = timestamp + "\n" + secret;
|
String stringToSign = timestamp + "\n" + secret;
|
||||||
Mac mac = Mac.getInstance("HmacSHA256");
|
Mac mac = Mac.getInstance("HmacSHA256");
|
||||||
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
|
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
|
||||||
byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
|
byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
|
||||||
String sign = URLEncoder.encode(new String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8");
|
String sign = URLEncoder.encode(new String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8");
|
||||||
token += "×tamp=" + timestamp + "&sign=" + sign;
|
token += "×tamp=" + timestamp + "&sign=" + sign;
|
||||||
Log.i(TAG, "token:" + token);
|
Log.i(TAG, "token:" + token);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map textMsgMap = new HashMap();
|
Map textMsgMap = new HashMap();
|
||||||
textMsgMap.put("msgtype", "text");
|
textMsgMap.put("msgtype", "text");
|
||||||
Map textText = new HashMap();
|
Map textText = new HashMap();
|
||||||
textText.put("content", content);
|
textText.put("content", content);
|
||||||
textMsgMap.put("text", textText);
|
textMsgMap.put("text", textText);
|
||||||
if (atMobiles != null || atAll != null) {
|
if (atMobiles != null || atAll != null) {
|
||||||
Map AtMap = new HashMap();
|
Map AtMap = new HashMap();
|
||||||
if (atMobiles != null) {
|
if (atMobiles != null) {
|
||||||
String[] atMobilesArray = atMobiles.split(",");
|
String[] atMobilesArray = atMobiles.split(",");
|
||||||
List<String> atMobilesList = new ArrayList<>();
|
List<String> atMobilesList = new ArrayList<>();
|
||||||
for (String atMobile : atMobilesArray
|
for (String atMobile : atMobilesArray
|
||||||
) {
|
) {
|
||||||
if (TextUtils.isDigitsOnly(atMobile)) {
|
if (TextUtils.isDigitsOnly(atMobile)) {
|
||||||
atMobilesList.add(atMobile);
|
atMobilesList.add(atMobile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!atMobilesList.isEmpty()) {
|
if (!atMobilesList.isEmpty()) {
|
||||||
AtMap.put("atMobiles", atMobilesList);
|
AtMap.put("atMobiles", atMobilesList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
AtMap.put("isAtAll", false);
|
||||||
AtMap.put("isAtAll", false);
|
if (atAll != null) {
|
||||||
if (atAll != null) {
|
AtMap.put("isAtAll", atAll);
|
||||||
AtMap.put("isAtAll", atAll);
|
}
|
||||||
|
|
||||||
}
|
textMsgMap.put("at", AtMap);
|
||||||
|
}
|
||||||
textMsgMap.put("at", AtMap);
|
|
||||||
}
|
final String requestUrl = "https://oapi.dingtalk.com/robot/send?access_token=" + token;
|
||||||
|
Log.i(TAG, "requestUrl:" + requestUrl);
|
||||||
final String requestUrl = "https://oapi.dingtalk.com/robot/send?access_token=" + token;
|
final String requestMsg = JSON.toJSONString(textMsgMap);
|
||||||
Log.i(TAG, "requestUrl:" + requestUrl);
|
Log.i(TAG, "requestMsg:" + requestMsg);
|
||||||
final String requestMsg = JSON.toJSONString(textMsgMap);
|
|
||||||
Log.i(TAG, "requestMsg:" + requestMsg);
|
Observable
|
||||||
|
.create((ObservableEmitter<Object> emitter) -> {
|
||||||
Observable
|
Toast(handError, TAG, "开始请求接口...");
|
||||||
.create((ObservableEmitter<Object> emitter) -> {
|
|
||||||
Toast(handError, TAG, "开始请求接口...");
|
OkHttpClient client = new OkHttpClient();
|
||||||
|
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), requestMsg);
|
||||||
OkHttpClient client = new OkHttpClient();
|
|
||||||
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), requestMsg);
|
final Request request = new Request.Builder()
|
||||||
|
.url(requestUrl)
|
||||||
final Request request = new Request.Builder()
|
.addHeader("Content-Type", "application/json; charset=utf-8")
|
||||||
.url(requestUrl)
|
.post(requestBody)
|
||||||
.addHeader("Content-Type", "application/json; charset=utf-8")
|
.build();
|
||||||
.post(requestBody)
|
Call call = client.newCall(request);
|
||||||
.build();
|
call.enqueue(new Callback() {
|
||||||
Call call = client.newCall(request);
|
@Override
|
||||||
call.enqueue(new Callback() {
|
public void onFailure(@NonNull Call call, @NonNull final IOException e) {
|
||||||
@Override
|
LogUtil.updateLog(logId, 0, e.getMessage());
|
||||||
public void onFailure(@NonNull Call call, @NonNull final IOException e) {
|
Toast(handError, TAG, "发送失败:" + e.getMessage());
|
||||||
LogUtil.updateLog(logId, 0, e.getMessage());
|
emitter.onError(new RuntimeException("请求接口异常..."));
|
||||||
Toast(handError, TAG, "发送失败:" + e.getMessage());
|
}
|
||||||
emitter.onError(new RuntimeException("请求接口异常..."));
|
|
||||||
}
|
@Override
|
||||||
|
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
|
||||||
@Override
|
final String responseStr = Objects.requireNonNull(response.body()).string();
|
||||||
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
|
Log.d(TAG, "Response:" + response.code() + "," + responseStr);
|
||||||
final String responseStr = Objects.requireNonNull(response.body()).string();
|
Toast(handError, TAG, "发送状态:" + responseStr);
|
||||||
Log.d(TAG, "Response:" + response.code() + "," + responseStr);
|
|
||||||
Toast(handError, TAG, "发送状态:" + responseStr);
|
//TODO:粗略解析是否发送成功
|
||||||
|
if (responseStr.contains("\"errcode\":0")) {
|
||||||
//TODO:粗略解析是否发送成功
|
LogUtil.updateLog(logId, 1, responseStr);
|
||||||
if (responseStr.contains("\"errcode\":0")) {
|
} else {
|
||||||
LogUtil.updateLog(logId, 1, responseStr);
|
LogUtil.updateLog(logId, 0, responseStr);
|
||||||
} else {
|
}
|
||||||
LogUtil.updateLog(logId, 0, responseStr);
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
});
|
}).retryWhen((Observable<Throwable> errorObservable) -> errorObservable
|
||||||
|
.zipWith(Observable.just(
|
||||||
}).retryWhen((Observable<Throwable> errorObservable) -> errorObservable
|
SettingUtil.getRetryDelayTime(1),
|
||||||
.zipWith(Observable.just(
|
SettingUtil.getRetryDelayTime(2),
|
||||||
SettingUtil.getRetryDelayTime(1),
|
SettingUtil.getRetryDelayTime(3),
|
||||||
SettingUtil.getRetryDelayTime(2),
|
SettingUtil.getRetryDelayTime(4),
|
||||||
SettingUtil.getRetryDelayTime(3),
|
SettingUtil.getRetryDelayTime(5)
|
||||||
SettingUtil.getRetryDelayTime(4),
|
), (Throwable e, Integer time) -> time)
|
||||||
SettingUtil.getRetryDelayTime(5)
|
.flatMap((Integer delay) -> {
|
||||||
), (Throwable e, Integer time) -> time)
|
Toast(handError, TAG, "请求接口异常," + delay + "秒后重试");
|
||||||
.flatMap((Integer delay) -> {
|
return Observable.timer(delay, TimeUnit.SECONDS);
|
||||||
Toast(handError, TAG, "请求接口异常," + delay + "秒后重试");
|
}))
|
||||||
return Observable.timer(delay, TimeUnit.SECONDS);
|
.subscribe(System.out::println);
|
||||||
}))
|
}
|
||||||
.subscribe(System.out::println);
|
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
10
app/src/main/res/drawable/ic_help.xml
Normal file
10
app/src/main/res/drawable/ic_help.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M11,18h2v-2h-2v2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM12,6c-2.21,0 -4,1.79 -4,4h2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2c0,2 -3,1.75 -3,5h2c0,-2.25 3,-2.5 3,-5 0,-2.21 -1.79,-4 -4,-4z"/>
|
||||||
|
</vector>
|
@ -27,4 +27,10 @@
|
|||||||
android:title="@string/about"
|
android:title="@string/about"
|
||||||
android:icon="@drawable/ic_forwarder"
|
android:icon="@drawable/ic_forwarder"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/to_help"
|
||||||
|
android:orderInCategory="100"
|
||||||
|
android:title="@string/help"
|
||||||
|
android:icon="@drawable/ic_help"
|
||||||
|
app:showAsAction="never" />
|
||||||
</menu>
|
</menu>
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
<string name="clone">Clone Settings</string>
|
<string name="clone">Clone Settings</string>
|
||||||
<string name="setting">Settings</string>
|
<string name="setting">Settings</string>
|
||||||
<string name="about">About</string>
|
<string name="about">About</string>
|
||||||
|
<string name="help">Help</string>
|
||||||
<string name="rule_setting">Rule Setting</string>
|
<string name="rule_setting">Rule Setting</string>
|
||||||
<string name="sender_setting">Sender Setting</string>
|
<string name="sender_setting">Sender Setting</string>
|
||||||
<string name="app_list">App List</string>
|
<string name="app_list">App List</string>
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
<string name="clone">一键克隆</string>
|
<string name="clone">一键克隆</string>
|
||||||
<string name="setting">通用设置</string>
|
<string name="setting">通用设置</string>
|
||||||
<string name="about">关于软件</string>
|
<string name="about">关于软件</string>
|
||||||
|
<string name="help">使用帮助</string>
|
||||||
<string name="rule_setting">转发规则</string>
|
<string name="rule_setting">转发规则</string>
|
||||||
<string name="sender_setting">发送通道</string>
|
<string name="sender_setting">发送通道</string>
|
||||||
<string name="app_list">应用列表</string>
|
<string name="app_list">应用列表</string>
|
||||||
@ -159,11 +160,11 @@
|
|||||||
<string name="add_extra">转发时附加卡槽信息</string>
|
<string name="add_extra">转发时附加卡槽信息</string>
|
||||||
<string name="add_device_name">转发时附加设备名称</string>
|
<string name="add_device_name">转发时附加设备名称</string>
|
||||||
<string name="forward_sms">转发短信广播</string>
|
<string name="forward_sms">转发短信广播</string>
|
||||||
<string name="forward_sms_tips">总开关,请授予读取短信、通知类短信、发送短信等权限,开启后需添加转发规则</string>
|
<string name="forward_sms_tips">总开关,请授予读取短信、通知类短信、发送短信等权限</string>
|
||||||
<string name="forward_missed_calls">转发未接来电</string>
|
<string name="forward_missed_calls">转发未接来电</string>
|
||||||
<string name="forward_missed_calls_tips">总开关,请授予读取通话记录、联系人等权限,开启后需添加转发规则</string>
|
<string name="forward_missed_calls_tips">总开关,请授予读取通话记录、联系人等权限</string>
|
||||||
<string name="forward_app_notify">转发应用通知</string>
|
<string name="forward_app_notify">转发应用通知</string>
|
||||||
<string name="forward_app_notify_tips">总开关,请先授予通知使用权,开启后需添加转发规则</string>
|
<string name="forward_app_notify_tips">总开关,请先授予通知使用权</string>
|
||||||
<string name="enable_custom_templates">启用自定义模版</string>
|
<string name="enable_custom_templates">启用自定义模版</string>
|
||||||
<string name="enable_custom_templates_tips">全局自定义模版,如果添加转发规则再次定义,则优先取转发规则的</string>
|
<string name="enable_custom_templates_tips">全局自定义模版,如果添加转发规则再次定义,则优先取转发规则的</string>
|
||||||
<string name="enable_exclude_from_recents">不在最近任务列表中显示</string>
|
<string name="enable_exclude_from_recents">不在最近任务列表中显示</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user