优化:新增帮助文档(跳转GitHub的wiki)

pull/86/head
pppscn 3 years ago
parent 5187b410de
commit aac73b17db

@ -3,6 +3,7 @@ package com.idormy.sms.forwarder;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@ -296,6 +297,12 @@ public class MainActivity extends AppCompatActivity implements RefreshListView.I
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) {
Intent intent = new Intent(this, RuleActivity.class);
startActivity(intent);
@ -352,6 +359,9 @@ public class MainActivity extends AppCompatActivity implements RefreshListView.I
case R.id.to_about:
toAbout();
return true;
case R.id.to_help:
toHelp();
return true;
default:
return super.onOptionsItemSelected(item);
}

@ -1,148 +1,146 @@
package com.idormy.sms.forwarder.sender;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import androidx.annotation.NonNull;
import com.alibaba.fastjson.JSON;
import com.idormy.sms.forwarder.utils.LogUtil;
import com.idormy.sms.forwarder.utils.SettingUtil;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableEmitter;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
@SuppressWarnings({"ResultOfMethodCallIgnored", "rawtypes", "unchecked", "deprecation"})
public class SenderDingdingMsg extends SenderBaseMsg {
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 {
Log.i(TAG, "sendMsg token:" + token + " secret:" + secret + " atMobiles:" + atMobiles + " atAll:" + atAll + " content:" + content);
if (token == null || token.isEmpty()) {
return;
}
if (secret != null && !secret.isEmpty()) {
Long timestamp = System.currentTimeMillis();
String stringToSign = timestamp + "\n" + secret;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
String sign = URLEncoder.encode(new String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8");
token += "&timestamp=" + timestamp + "&sign=" + sign;
Log.i(TAG, "token:" + token);
}
Map textMsgMap = new HashMap();
textMsgMap.put("msgtype", "text");
Map textText = new HashMap();
textText.put("content", content);
textMsgMap.put("text", textText);
if (atMobiles != null || atAll != null) {
Map AtMap = new HashMap();
if (atMobiles != null) {
String[] atMobilesArray = atMobiles.split(",");
List<String> atMobilesList = new ArrayList<>();
for (String atMobile : atMobilesArray
) {
if (TextUtils.isDigitsOnly(atMobile)) {
atMobilesList.add(atMobile);
}
}
if (!atMobilesList.isEmpty()) {
AtMap.put("atMobiles", atMobilesList);
}
}
AtMap.put("isAtAll", false);
if (atAll != null) {
AtMap.put("isAtAll", atAll);
}
textMsgMap.put("at", AtMap);
}
final String requestUrl = "https://oapi.dingtalk.com/robot/send?access_token=" + token;
Log.i(TAG, "requestUrl:" + requestUrl);
final String requestMsg = JSON.toJSONString(textMsgMap);
Log.i(TAG, "requestMsg:" + requestMsg);
Observable
.create((ObservableEmitter<Object> emitter) -> {
Toast(handError, TAG, "开始请求接口...");
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), requestMsg);
final Request request = new Request.Builder()
.url(requestUrl)
.addHeader("Content-Type", "application/json; charset=utf-8")
.post(requestBody)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull final IOException e) {
LogUtil.updateLog(logId, 0, e.getMessage());
Toast(handError, TAG, "发送失败:" + e.getMessage());
emitter.onError(new RuntimeException("请求接口异常..."));
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
final String responseStr = Objects.requireNonNull(response.body()).string();
Log.d(TAG, "Response" + response.code() + "" + responseStr);
Toast(handError, TAG, "发送状态:" + responseStr);
//TODO:粗略解析是否发送成功
if (responseStr.contains("\"errcode\":0")) {
LogUtil.updateLog(logId, 1, responseStr);
} else {
LogUtil.updateLog(logId, 0, responseStr);
}
}
});
}).retryWhen((Observable<Throwable> errorObservable) -> errorObservable
.zipWith(Observable.just(
SettingUtil.getRetryDelayTime(1),
SettingUtil.getRetryDelayTime(2),
SettingUtil.getRetryDelayTime(3),
SettingUtil.getRetryDelayTime(4),
SettingUtil.getRetryDelayTime(5)
), (Throwable e, Integer time) -> time)
.flatMap((Integer delay) -> {
Toast(handError, TAG, "请求接口异常," + delay + "秒后重试");
return Observable.timer(delay, TimeUnit.SECONDS);
}))
.subscribe(System.out::println);
}
}
package com.idormy.sms.forwarder.sender;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import androidx.annotation.NonNull;
import com.alibaba.fastjson.JSON;
import com.idormy.sms.forwarder.utils.LogUtil;
import com.idormy.sms.forwarder.utils.SettingUtil;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableEmitter;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
@SuppressWarnings({"ResultOfMethodCallIgnored", "rawtypes", "unchecked", "deprecation"})
public class SenderDingdingMsg extends SenderBaseMsg {
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 {
Log.i(TAG, "sendMsg token:" + token + " secret:" + secret + " atMobiles:" + atMobiles + " atAll:" + atAll + " content:" + content);
if (token == null || token.isEmpty()) {
return;
}
if (secret != null && !secret.isEmpty()) {
Long timestamp = System.currentTimeMillis();
String stringToSign = timestamp + "\n" + secret;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
String sign = URLEncoder.encode(new String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8");
token += "&timestamp=" + timestamp + "&sign=" + sign;
Log.i(TAG, "token:" + token);
}
Map textMsgMap = new HashMap();
textMsgMap.put("msgtype", "text");
Map textText = new HashMap();
textText.put("content", content);
textMsgMap.put("text", textText);
if (atMobiles != null || atAll != null) {
Map AtMap = new HashMap();
if (atMobiles != null) {
String[] atMobilesArray = atMobiles.split(",");
List<String> atMobilesList = new ArrayList<>();
for (String atMobile : atMobilesArray
) {
if (TextUtils.isDigitsOnly(atMobile)) {
atMobilesList.add(atMobile);
}
}
if (!atMobilesList.isEmpty()) {
AtMap.put("atMobiles", atMobilesList);
}
}
AtMap.put("isAtAll", false);
if (atAll != null) {
AtMap.put("isAtAll", atAll);
}
textMsgMap.put("at", AtMap);
}
final String requestUrl = "https://oapi.dingtalk.com/robot/send?access_token=" + token;
Log.i(TAG, "requestUrl:" + requestUrl);
final String requestMsg = JSON.toJSONString(textMsgMap);
Log.i(TAG, "requestMsg:" + requestMsg);
Observable
.create((ObservableEmitter<Object> emitter) -> {
Toast(handError, TAG, "开始请求接口...");
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), requestMsg);
final Request request = new Request.Builder()
.url(requestUrl)
.addHeader("Content-Type", "application/json; charset=utf-8")
.post(requestBody)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull final IOException e) {
LogUtil.updateLog(logId, 0, e.getMessage());
Toast(handError, TAG, "发送失败:" + e.getMessage());
emitter.onError(new RuntimeException("请求接口异常..."));
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
final String responseStr = Objects.requireNonNull(response.body()).string();
Log.d(TAG, "Response" + response.code() + "" + responseStr);
Toast(handError, TAG, "发送状态:" + responseStr);
//TODO:粗略解析是否发送成功
if (responseStr.contains("\"errcode\":0")) {
LogUtil.updateLog(logId, 1, responseStr);
} else {
LogUtil.updateLog(logId, 0, responseStr);
}
}
});
}).retryWhen((Observable<Throwable> errorObservable) -> errorObservable
.zipWith(Observable.just(
SettingUtil.getRetryDelayTime(1),
SettingUtil.getRetryDelayTime(2),
SettingUtil.getRetryDelayTime(3),
SettingUtil.getRetryDelayTime(4),
SettingUtil.getRetryDelayTime(5)
), (Throwable e, Integer time) -> time)
.flatMap((Integer delay) -> {
Toast(handError, TAG, "请求接口异常," + delay + "秒后重试");
return Observable.timer(delay, TimeUnit.SECONDS);
}))
.subscribe(System.out::println);
}
}

@ -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:icon="@drawable/ic_forwarder"
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>

@ -12,6 +12,7 @@
<string name="clone">Clone Settings</string>
<string name="setting">Settings</string>
<string name="about">About</string>
<string name="help">Help</string>
<string name="rule_setting">Rule Setting</string>
<string name="sender_setting">Sender Setting</string>
<string name="app_list">App List</string>

@ -12,6 +12,7 @@
<string name="clone">一键克隆</string>
<string name="setting">通用设置</string>
<string name="about">关于软件</string>
<string name="help">使用帮助</string>
<string name="rule_setting">转发规则</string>
<string name="sender_setting">发送通道</string>
<string name="app_list">应用列表</string>
@ -159,11 +160,11 @@
<string name="add_extra">转发时附加卡槽信息</string>
<string name="add_device_name">转发时附加设备名称</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_tips">总开关,请授予读取通话记录、联系人等权限,开启后需添加转发规则</string>
<string name="forward_missed_calls_tips">总开关,请授予读取通话记录、联系人等权限</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_tips">全局自定义模版,如果添加转发规则再次定义,则优先取转发规则的</string>
<string name="enable_exclude_from_recents">不在最近任务列表中显示</string>

Loading…
Cancel
Save