Merge branch 'main' into dev

This commit is contained in:
pppscn 2022-01-14 16:15:10 +08:00 committed by GitHub
commit 2204f4fb56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 731 additions and 293 deletions

View File

@ -170,4 +170,4 @@ dependencies {
//jetty
implementation "org.eclipse.jetty:jetty-server:$jetty_version"
implementation "org.eclipse.jetty:jetty-servlet:$jetty_version"
}
}

View File

@ -21,6 +21,10 @@
#-renamesourcefileattribute SourceFile
-keep class com.idormy.sms.forwarder.model.**{*;}
-keep public class com.idormy.sms.forwarder.R$*{
public static final int *;
}
-keep class com.umeng.** {*;}
-keepclassmembers class * {
public <init> (org.json.JSONObject);

View File

@ -52,7 +52,12 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
android:usesCleartextTraffic="true"
tools:targetApi="m">
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
<meta-data
android:name="UPDATE_APP_KEY"
@ -66,6 +71,7 @@
<activity
android:name=".MainActivity"
android:exported="true"
tools:ignore="IntentFilterExportedReceiver">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -74,6 +80,7 @@
</activity>
<activity
android:name=".AboutActivity"
android:exported="true"
android:label="@string/about"
tools:ignore="IntentFilterExportedReceiver">
<intent-filter>
@ -89,22 +96,28 @@
</activity>
<activity
android:name=".SettingActivity"
android:exported="true"
android:label="@string/setting" />
<activity
android:name=".CloneActivity"
android:exported="true"
android:label="@string/clone" />
<activity
android:name=".RuleActivity"
android:exported="true"
android:label="@string/rule_setting" />
<activity
android:name=".SenderActivity"
android:exported="true"
android:label="@string/sender_setting" />
<activity
android:name=".AppListActivity"
android:exported="true"
android:label="@string/app_list" />
<receiver
android:name=".receiver.RebootBroadcastReceiver"
android:exported="true"
tools:ignore="IntentFilterExportedReceiver">
<intent-filter android:priority="2147483647">
<action android:name="android.intent.action.BOOT_COMPLETED" />
@ -114,6 +127,7 @@
</receiver>
<receiver
android:name=".receiver.SmsBroadcastReceiver"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS"
tools:ignore="IntentFilterExportedReceiver">
<intent-filter android:priority="2147483647">
@ -123,6 +137,7 @@
</receiver>
<receiver
android:name=".receiver.PhoneStateReceiver"
android:exported="true"
tools:ignore="IntentFilterExportedReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
@ -139,7 +154,8 @@
android:name=".service.NotifyService"
android:enabled="true"
android:label="@string/app_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
android:exported="false">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>

View File

@ -1,11 +1,14 @@
package com.idormy.sms.forwarder;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.*;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@ -27,6 +30,7 @@ import com.idormy.sms.forwarder.service.BatteryService;
import com.idormy.sms.forwarder.service.FrontService;
import com.idormy.sms.forwarder.utils.*;
import com.umeng.analytics.MobclickAgent;
import com.umeng.commonsdk.UMConfigure;
import java.lang.reflect.Method;
import java.util.*;
@ -41,6 +45,10 @@ public class MainActivity extends AppCompatActivity implements RefreshListView.I
private Intent serviceIntent;
private String currentType = "sms";
View inflate;
Dialog dialog;
SharedPreferencesHelper sharedPreferencesHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -95,6 +103,14 @@ public class MainActivity extends AppCompatActivity implements RefreshListView.I
super.onStart();
Log.d(TAG, "onStart");
/* sp中uminit为1已经同意隐私协议*/
sharedPreferencesHelper = new SharedPreferencesHelper(this, "umeng");
String isAllowed = String.valueOf(sharedPreferencesHelper.getSharedPreference("uminit", ""));
if (isAllowed.equals("") || isAllowed.equals("0")) {
dialog();
return;
}
//是否关闭页面提示
TextView help_tip = findViewById(R.id.help_tip);
help_tip.setVisibility(MyApplication.showHelpTip ? View.VISIBLE : View.GONE);
@ -165,6 +181,7 @@ public class MainActivity extends AppCompatActivity implements RefreshListView.I
@Override
protected void onResume() {
super.onResume();
MobclickAgent.onPageStart(TAG);
MobclickAgent.onResume(this);
//第一次打开未授权无法获取SIM信息尝试在此重新获取
@ -208,6 +225,7 @@ public class MainActivity extends AppCompatActivity implements RefreshListView.I
@Override
protected void onPause() {
super.onPause();
MobclickAgent.onPageEnd(TAG);
MobclickAgent.onPause(this);
try {
if (serviceIntent != null) startService(serviceIntent);
@ -398,4 +416,49 @@ public class MainActivity extends AppCompatActivity implements RefreshListView.I
return super.onMenuOpened(featureId, menu);
}
/*** 隐私协议授权弹窗*/
@SuppressLint({"ResourceType", "InflateParams"})
public void dialog() {
dialog = new Dialog(this, R.style.dialog);
inflate = LayoutInflater.from(MainActivity.this).inflate(R.layout.diaologlayout, null);
TextView succsebtn = (TextView) inflate.findViewById(R.id.succsebtn);
TextView canclebtn = (TextView) inflate.findViewById(R.id.caclebtn);
succsebtn.setOnClickListener(v -> {
/* uminit为1时代表已经同意隐私协议sp记录当前状态*/
sharedPreferencesHelper.put("uminit", "1");
UMConfigure.submitPolicyGrantResult(getApplicationContext(), true);
/* 友盟sdk正式初始化*/
UmInitConfig umInitConfig = new UmInitConfig();
umInitConfig.UMinit(getApplicationContext());
//关闭弹窗
dialog.dismiss();
//跳转到HomeActivity
final Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
//杀掉以前进程
android.os.Process.killProcess(android.os.Process.myPid());
finish();
});
canclebtn.setOnClickListener(v -> {
dialog.dismiss();
UMConfigure.submitPolicyGrantResult(getApplicationContext(), false);
//不同意隐私协议退出app
android.os.Process.killProcess(android.os.Process.myPid());
});
dialog.setContentView(inflate);
Window dialogWindow = dialog.getWindow();
dialogWindow.setGravity(Gravity.CENTER);
dialog.setCancelable(false);
dialog.show();
}
}

View File

@ -11,12 +11,11 @@ import android.util.Log;
import com.idormy.sms.forwarder.sender.SendHistory;
import com.idormy.sms.forwarder.service.BatteryService;
import com.idormy.sms.forwarder.service.FrontService;
import com.idormy.sms.forwarder.utils.CommonUtil;
import com.idormy.sms.forwarder.utils.Define;
import com.idormy.sms.forwarder.utils.PhoneUtils;
import com.idormy.sms.forwarder.utils.SettingUtil;
import com.idormy.sms.forwarder.utils.SharedPreferencesHelper;
import com.smailnet.emailkit.EmailKit;
import com.umeng.analytics.MobclickAgent;
import com.umeng.commonsdk.UMConfigure;
import java.util.ArrayList;
@ -28,6 +27,7 @@ public class MyApplication extends Application {
public static List<PhoneUtils.SimInfo> SimInfoList = new ArrayList<>();
//是否关闭页面提示
public static boolean showHelpTip = true;
SharedPreferencesHelper sharedPreferencesHelper;
@Override
protected void attachBaseContext(Context base) {
@ -40,14 +40,6 @@ public class MyApplication extends Application {
super.onCreate();
try {
//初始化组件化基础库, 所有友盟业务SDK都必须调用此初始化接口
//建议在宿主App的Application.onCreate函数中调用基础组件库初始化函数
UMConfigure.init(this, "60254fc7425ec25f10f4293e", CommonUtil.getChannelName(this), UMConfigure.DEVICE_TYPE_PHONE, "");
// 选用LEGACY_AUTO页面采集模式
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.LEGACY_MANUAL);
//pro close log
UMConfigure.setLogEnabled(true);
//前台服务
Intent intent = new Intent(this, FrontService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@ -77,6 +69,20 @@ public class MyApplication extends Application {
//电池状态监听
Intent batteryServiceIntent = new Intent(this, BatteryService.class);
startService(batteryServiceIntent);
//友盟统计
sharedPreferencesHelper = new SharedPreferencesHelper(this, "umeng");
//设置LOG开关默认为false
//UMConfigure.setLogEnabled(true);
//友盟预初始化
UMConfigure.preInit(getApplicationContext(), "60254fc7425ec25f10f4293e", "Umeng");
//判断是否同意隐私协议uminit为1时为已经同意直接初始化umsdk
if (sharedPreferencesHelper.getSharedPreference("uminit", "").equals("1")) {
//友盟正式初始化
UmInitConfig umInitConfig = new UmInitConfig();
umInitConfig.UMinit(getApplicationContext());
}
} catch (Exception e) {
Log.e(TAG, "onCreate:", e);
}

View File

@ -374,49 +374,49 @@ public class RuleActivity extends AppCompatActivity {
buttonInsertSender.setOnClickListener(view -> {
textSmsTemplate.setFocusable(true);
textSmsTemplate.requestFocus();
textSmsTemplate.append("{{来源号码}}");
insertOrReplaceText2Cursor(textSmsTemplate, "{{来源号码}}");
});
Button buttonInsertContent = view1.findViewById(R.id.bt_insert_content);
buttonInsertContent.setOnClickListener(view -> {
textSmsTemplate.setFocusable(true);
textSmsTemplate.requestFocus();
textSmsTemplate.append("{{短信内容}}");
insertOrReplaceText2Cursor(textSmsTemplate, "{{短信内容}}");
});
Button buttonInsertSenderApp = view1.findViewById(R.id.bt_insert_sender_app);
buttonInsertSenderApp.setOnClickListener(view -> {
textSmsTemplate.setFocusable(true);
textSmsTemplate.requestFocus();
textSmsTemplate.append("{{APP包名}}");
insertOrReplaceText2Cursor(textSmsTemplate, "{{APP包名}}");
});
Button buttonInsertContentApp = view1.findViewById(R.id.bt_insert_content_app);
buttonInsertContentApp.setOnClickListener(view -> {
textSmsTemplate.setFocusable(true);
textSmsTemplate.requestFocus();
textSmsTemplate.append("{{通知内容}}");
insertOrReplaceText2Cursor(textSmsTemplate, "{{通知内容}}");
});
Button buttonInsertExtra = view1.findViewById(R.id.bt_insert_extra);
buttonInsertExtra.setOnClickListener(view -> {
textSmsTemplate.setFocusable(true);
textSmsTemplate.requestFocus();
textSmsTemplate.append("{{卡槽信息}}");
insertOrReplaceText2Cursor(textSmsTemplate, "{{卡槽信息}}");
});
Button buttonInsertTime = view1.findViewById(R.id.bt_insert_time);
buttonInsertTime.setOnClickListener(view -> {
textSmsTemplate.setFocusable(true);
textSmsTemplate.requestFocus();
textSmsTemplate.append("{{接收时间}}");
insertOrReplaceText2Cursor(textSmsTemplate, "{{接收时间}}");
});
Button buttonInsertDeviceName = view1.findViewById(R.id.bt_insert_device_name);
buttonInsertDeviceName.setOnClickListener(view -> {
textSmsTemplate.setFocusable(true);
textSmsTemplate.requestFocus();
textSmsTemplate.append("{{设备名称}}");
insertOrReplaceText2Cursor(textSmsTemplate, "{{设备名称}}");
});
//正则替换
@ -433,6 +433,12 @@ public class RuleActivity extends AppCompatActivity {
}
private void insertOrReplaceText2Cursor(EditText editText, String str) {
int start = Math.max(editText.getSelectionStart(), 0);
int end = Math.max(editText.getSelectionEnd(), 0);
editText.getText().replace(Math.min(start, end), Math.max(start, end), str, 0, str.length());
}
//当更新选择的字段的时候更新之下各个选项的状态
// 如果设置了转发全部禁用选择模式和匹配值输入
// 如果设置了多重规则选择模式置为是
@ -592,12 +598,14 @@ public class RuleActivity extends AppCompatActivity {
@Override
protected void onResume() {
super.onResume();
MobclickAgent.onPageStart(TAG);
MobclickAgent.onResume(this);
}
@Override
protected void onPause() {
super.onPause();
MobclickAgent.onPageEnd(TAG);
MobclickAgent.onPause(this);
}

View File

@ -1022,6 +1022,7 @@ public class SenderActivity extends AppCompatActivity {
final EditText editTextTelegramApiToken = view1.findViewById(R.id.editTextTelegramApiToken);
final EditText editTextTelegramChatId = view1.findViewById(R.id.editTextTelegramChatId);
final RadioGroup radioGroupTelegramMethod = view1.findViewById(R.id.radioGroupTelegramMethod);
final RadioGroup radioGroupProxyType = view1.findViewById(R.id.radioGroupProxyType);
final EditText editTextProxyHost = view1.findViewById(R.id.editTextProxyHost);
@ -1058,6 +1059,7 @@ public class SenderActivity extends AppCompatActivity {
if (telegramSettingVo != null) {
editTextTelegramApiToken.setText(telegramSettingVo.getApiToken());
editTextTelegramChatId.setText(telegramSettingVo.getChatId());
radioGroupTelegramMethod.check(telegramSettingVo.getMethodCheckId());
radioGroupProxyType.check(telegramSettingVo.getProxyTypeCheckId());
layoutProxyAuthenticator.setVisibility(telegramSettingVo.getProxyAuthenticator() ? View.VISIBLE : View.GONE);
@ -1102,7 +1104,8 @@ public class SenderActivity extends AppCompatActivity {
editTextProxyPort.getText().toString().trim(),
switchProxyAuthenticator.isChecked(),
editTextProxyUsername.getText().toString().trim(),
editTextProxyPassword.getText().toString().trim()
editTextProxyPassword.getText().toString().trim(),
(radioGroupTelegramMethod.getCheckedRadioButtonId() == R.id.radioTelegramMethodGet ? "GET" : "POST")
);
newSenderModel.setJsonSetting(JSON.toJSONString(telegramSettingVoNew));
@ -1121,7 +1124,8 @@ public class SenderActivity extends AppCompatActivity {
editTextProxyPort.getText().toString().trim(),
switchProxyAuthenticator.isChecked(),
editTextProxyUsername.getText().toString().trim(),
editTextProxyPassword.getText().toString().trim()
editTextProxyPassword.getText().toString().trim(),
(radioGroupTelegramMethod.getCheckedRadioButtonId() == R.id.radioTelegramMethodGet ? "GET" : "POST")
);
senderModel.setJsonSetting(JSON.toJSONString(telegramSettingVoNew));
SenderUtil.updateSender(senderModel);
@ -1153,9 +1157,10 @@ public class SenderActivity extends AppCompatActivity {
editTextProxyPort.getText().toString().trim(),
switchProxyAuthenticator.isChecked(),
editTextProxyUsername.getText().toString().trim(),
editTextProxyPassword.getText().toString().trim()
editTextProxyPassword.getText().toString().trim(),
(radioGroupTelegramMethod.getCheckedRadioButtonId() == R.id.radioTelegramMethodGet ? "GET" : "POST")
);
SenderTelegramMsg.sendMsg(0, handler, telegramSettingVoNew, getString(R.string.test_phone_num), getString(R.string.test_sms));
SenderTelegramMsg.sendMsg(0, handler, telegramSettingVoNew, getString(R.string.test_phone_num), getString(R.string.test_sms), telegramSettingVoNew.getMethod());
} catch (Exception e) {
Toast.makeText(SenderActivity.this, getString(R.string.failed_to_fwd) + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
@ -1476,12 +1481,14 @@ public class SenderActivity extends AppCompatActivity {
@Override
protected void onResume() {
super.onResume();
MobclickAgent.onPageStart(TAG);
MobclickAgent.onResume(this);
}
@Override
protected void onPause() {
super.onPause();
MobclickAgent.onPageEnd(TAG);
MobclickAgent.onPause(this);
}

View File

@ -73,7 +73,8 @@ public class SettingActivity extends AppCompatActivity {
switchEnablePhone(switch_enable_phone);
@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_enable_app_notify = findViewById(R.id.switch_enable_app_notify);
switchEnableAppNotify(switch_enable_app_notify);
@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_cancel_app_notify = findViewById(R.id.switch_cancel_app_notify);
switchEnableAppNotify(switch_enable_app_notify, switch_cancel_app_notify);
@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_exclude_from_recents = findViewById(R.id.switch_exclude_from_recents);
switchExcludeFromRecents(switch_exclude_from_recents);
@ -151,10 +152,14 @@ public class SettingActivity extends AppCompatActivity {
}
//设置转发APP通知
private void switchEnableAppNotify(@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_enable_app_notify) {
switch_enable_app_notify.setChecked(SettingUtil.getSwitchEnableAppNotify());
private void switchEnableAppNotify(@SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_enable_app_notify, @SuppressLint("UseSwitchCompatOrMaterialCode") Switch switch_cancel_app_notify) {
final LinearLayout layout_cancel_app_notify = findViewById(R.id.layout_cancel_app_notify);
boolean isEnable = SettingUtil.getSwitchEnableAppNotify();
switch_enable_app_notify.setChecked(isEnable);
layout_cancel_app_notify.setVisibility(isEnable ? View.VISIBLE : View.GONE);
switch_enable_app_notify.setOnCheckedChangeListener((buttonView, isChecked) -> {
layout_cancel_app_notify.setVisibility(isChecked ? View.VISIBLE : View.GONE);
//TODO:校验使用APP通知转发必备的权限
if (isChecked) {
if (!CommonUtil.isNotificationListenerServiceEnabled(this)) {
@ -169,6 +174,12 @@ public class SettingActivity extends AppCompatActivity {
SettingUtil.switchEnableAppNotify(isChecked);
Log.d(TAG, "switchEnableAppNotify:" + isChecked);
});
switch_cancel_app_notify.setChecked(SettingUtil.getSwitchCancelAppNotify());
switch_cancel_app_notify.setOnCheckedChangeListener((buttonView, isChecked) -> {
SettingUtil.switchCancelAppNotify(isChecked);
Log.d(TAG, "switchCancelAppNotify:" + isChecked);
});
}
//不在最近任务列表中显示
@ -375,24 +386,30 @@ public class SettingActivity extends AppCompatActivity {
textSmsTemplate.requestFocus();
switch (v.getId()) {
case R.id.bt_insert_sender:
textSmsTemplate.append("{{来源号码}}");
insertOrReplaceText2Cursor(textSmsTemplate, "{{来源号码}}");
return;
case R.id.bt_insert_content:
textSmsTemplate.append("{{短信内容}}");
insertOrReplaceText2Cursor(textSmsTemplate, "{{短信内容}}");
return;
case R.id.bt_insert_extra:
textSmsTemplate.append("{{卡槽信息}}");
insertOrReplaceText2Cursor(textSmsTemplate, "{{卡槽信息}}");
return;
case R.id.bt_insert_time:
textSmsTemplate.append("{{接收时间}}");
insertOrReplaceText2Cursor(textSmsTemplate, "{{接收时间}}");
return;
case R.id.bt_insert_device_name:
textSmsTemplate.append("{{设备名称}}");
insertOrReplaceText2Cursor(textSmsTemplate, "{{设备名称}}");
return;
default:
}
}
private void insertOrReplaceText2Cursor(EditText editText, String str) {
int start = Math.max(editText.getSelectionStart(), 0);
int end = Math.max(editText.getSelectionEnd(), 0);
editText.getText().replace(Math.min(start, end), Math.max(start, end), str, 0, str.length());
}
//恢复初始化配置
public void initSetting(View view) {

View File

@ -0,0 +1,59 @@
package com.idormy.sms.forwarder;
import android.content.Context;
import com.umeng.analytics.MobclickAgent;
import com.umeng.commonsdk.UMConfigure;
public class UmInitConfig {
private static final String TAG = "MyApplication";
public void UMinit(Context context) {
//初始化组件化基础库, 统计SDK/推送SDK/分享SDK都必须调用此初始化接口
UMConfigure.init(context, "60254fc7425ec25f10f4293e", "Umeng", UMConfigure.DEVICE_TYPE_PHONE, "");
//集成umeng-crash-vx.x.x.aar则需要关闭原有统计SDK异常捕获功能
MobclickAgent.setCatchUncaughtExceptions(false);
//统计SDK是否支持采集在子进程中打点的自定义事件默认不支持
UMConfigure.setProcessEvent(true);//支持多进程打点
// 页面数据采集模式
// setPageCollectionMode接口参数说明
// 1. MobclickAgent.PageMode.AUTO: 建议大多数用户使用本采集模式SDK在此模式下自动采集Activity
// 页面访问路径开发者不需要针对每一个Activity在onResume/onPause函数中进行手动埋点在此模式下
// 开发者如需针对FragmentCustomView等自定义页面进行页面统计直接调用MobclickAgent.onPageStart/
// MobclickAgent.onPageEnd手动埋点即可此采集模式简化埋点工作唯一缺点是在Android 4.0以下设备中
// 统计不到Activity页面数据和各类基础指标(提示目前Android 4.0以下设备市场占比已经极小)
// 2. MobclickAgent.PageMode.MANUAL对于要求在Android 4.0以下设备中也能正常采集数据的App,可以使用
// 本模式开发者需要在每一个Activity的onResume函数中手动调用MobclickAgent.onResume接口在Activity的
// onPause函数中手动调用MobclickAgent.onPause接口在此模式下开发者如需针对FragmentCustomView等
// 自定义页面进行页面统计直接调用MobclickAgent.onPageStart/MobclickAgent.onPageEnd手动埋点即可
// 如下两种LEGACY模式不建议首次集成友盟统计SDK的新用户选用
// 如果您是友盟统计SDK的老用户App需要从老版本统计SDK升级到8.0.0版本统计SDK
// 并且您的App之前MobclickAgent.onResume/onPause接口埋点分散在所有Activity
// 逐个删除修改工作量很大且易出错
// 若您的App符合以上特征可以选用如下两种LEGACY模式否则不建议继续使用LEGACY模式
// 简单来说升级SDK的老用户如果不需要手动统计页面路径选用LEGACY_AUTO模式
// 如果需要手动统计页面路径选用LEGACY_MANUAL模式
// 3. MobclickAgent.PageMode.LEGACY_AUTO: 本模式适合不需要对FragmentCustomView
// 等自定义页面进行页面访问统计的开发者SDK仅对App中所有Activity进行页面统计开发者需要在
// 每一个Activity的onResume函数中手动调用MobclickAgent.onResume接口在Activity的
// onPause函数中手动调用MobclickAgent.onPause接口此模式下MobclickAgent.onPageStart
// ,MobclickAgent.onPageEnd这两个接口无效
// 4. MobclickAgent.PageMode.LEGACY_MANUAL: 本模式适合需要对FragmentCustomView
// 等自定义页面进行手动页面统计的开发者开发者如需针对FragmentCustomView等
// 自定义页面进行页面统计直接调用MobclickAgent.onPageStart/MobclickAgent.onPageEnd
// 手动埋点即可开发者还需要在每一个Activity的onResume函数中手动调用MobclickAgent.onResume接口
// 在Activity的onPause函数中手动调用MobclickAgent.onPause接口
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO);
}
}

View File

@ -17,6 +17,7 @@ public class TelegramSettingVo implements Serializable {
private Boolean proxyAuthenticator = false;
private String proxyUsername;
private String proxyPassword;
private String method;
public TelegramSettingVo() {
}
@ -25,9 +26,10 @@ public class TelegramSettingVo implements Serializable {
this.apiToken = apiToken;
this.chatId = chatId;
this.proxyType = Proxy.Type.DIRECT;
this.method = "POST";
}
public TelegramSettingVo(String apiToken, String chatId, int proxyTypeId, String proxyHost, String proxyPort, boolean proxyAuthenticator, String proxyUsername, String proxyPassword) {
public TelegramSettingVo(String apiToken, String chatId, int proxyTypeId, String proxyHost, String proxyPort, boolean proxyAuthenticator, String proxyUsername, String proxyPassword, String method) {
this.apiToken = apiToken;
this.chatId = chatId;
if (proxyTypeId == R.id.btnProxyHttp) {
@ -42,6 +44,7 @@ public class TelegramSettingVo implements Serializable {
this.proxyAuthenticator = proxyAuthenticator;
this.proxyUsername = proxyUsername;
this.proxyPassword = proxyPassword;
this.method = method;
}
public int getProxyTypeCheckId() {
@ -53,4 +56,12 @@ public class TelegramSettingVo implements Serializable {
return R.id.btnProxyNone;
}
}
public int getMethodCheckId() {
if (method == null || method.equals("POST")) {
return R.id.radioTelegramMethodPost;
} else {
return R.id.radioTelegramMethodGet;
}
}
}

View File

@ -3,11 +3,13 @@ package com.idormy.sms.forwarder.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import com.idormy.sms.forwarder.model.vo.SmsHubVo;
import androidx.annotation.RequiresApi;
import com.idormy.sms.forwarder.model.vo.SmsVo;
import com.idormy.sms.forwarder.sender.SendUtil;
import com.idormy.sms.forwarder.utils.*;
@ -21,6 +23,7 @@ import java.util.Objects;
public class SmsBroadcastReceiver extends BroadcastReceiver {
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onReceive(Context context, Intent intent) {

View File

@ -225,7 +225,7 @@ public class SendUtil {
TelegramSettingVo telegramSettingVo = JSON.parseObject(senderModel.getJsonSetting(), TelegramSettingVo.class);
if (telegramSettingVo != null) {
try {
SenderTelegramMsg.sendMsg(logId, handError, telegramSettingVo, smsVo.getMobile(), smsVo.getSmsVoForSend(smsTemplate, regexReplace));
SenderTelegramMsg.sendMsg(logId, handError, telegramSettingVo, smsVo.getMobile(), smsVo.getSmsVoForSend(smsTemplate, regexReplace), telegramSettingVo.getMethod());
} catch (Exception e) {
LogUtil.updateLog(logId, 0, e.getMessage());
Log.e(TAG, "senderSendMsg: SenderTelegramMsg error " + e.getMessage());

View File

@ -8,6 +8,9 @@ import com.idormy.sms.forwarder.utils.SettingUtil;
import com.smailnet.emailkit.Draft;
import com.smailnet.emailkit.EmailKit;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import io.reactivex.rxjava3.core.Observable;
@ -35,12 +38,15 @@ public class SenderMailMsg extends SenderBaseMsg {
.setAccount(fromEmail) //发件人邮箱
.setPassword(pwd); //密码或授权码
//多个收件人邮箱
Set<String> toSet = new HashSet<>(Arrays.asList(toAdd.replace("", ",").split(",")));
//设置一封草稿邮件
Draft draft = new Draft()
.setNickname(nickname) //发件人昵称
.setTo(toAdd) //收件人邮箱
.setSubject(title) //邮件主题
.setText(content); //邮件正文
.setTo(toSet) //收件人邮箱
.setSubject(title) //邮件主题
.setText(content); //邮件正文
//使用SMTP服务发送邮件
EmailKit.useSMTPService(config)

View File

@ -1,5 +1,6 @@
package com.idormy.sms.forwarder.sender;
import android.annotation.SuppressLint;
import android.os.Handler;
import android.util.Log;
@ -11,6 +12,7 @@ public class SenderSmsMsg extends SenderBaseMsg {
static final String TAG = "SenderSmsMsg";
@SuppressLint("NewApi")
public static void sendMsg(final long logId, final Handler handError, int simSlot, String mobiles, Boolean onlyNoNetwork, String from, String text) throws Exception {
Log.i(TAG, "sendMsg simSlot:" + simSlot + " mobiles:" + mobiles + " onlyNoNetwork:" + onlyNoNetwork + " from:" + from + " text:" + text);

View File

@ -37,7 +37,7 @@ public class SenderTelegramMsg extends SenderBaseMsg {
static final String TAG = "SenderTelegramMsg";
public static void sendMsg(final long logId, final Handler handError, TelegramSettingVo telegramSettingVo, String from, String text) throws Exception {
public static void sendMsg(final long logId, final Handler handError, TelegramSettingVo telegramSettingVo, final String from, final String text, final String method) throws Exception {
Log.i(TAG, "sendMsg telegramSettingVo:" + telegramSettingVo.toString() + " text:" + text);
String apiToken = telegramSettingVo.getApiToken();
@ -47,22 +47,15 @@ public class SenderTelegramMsg extends SenderBaseMsg {
}
//特殊处理避免标题重复
text = text.replaceAll("#", "").trim();
final String finalText = text.replaceAll("#", "").trim();
if (!apiToken.startsWith("http")) {
apiToken = "https://api.telegram.org/bot" + apiToken + "/sendMessage";
}
final String requestUrl = apiToken;
Log.i(TAG, "requestUrl:" + requestUrl);
Map bodyMap = new HashMap();
bodyMap.put("chat_id", chatId);
bodyMap.put("text", text);
bodyMap.put("parse_mode", "HTML");
final String requestMsg = JSON.toJSONString(bodyMap);
Log.i(TAG, "requestMsg:" + requestMsg);
//代理相关
final Proxy.Type proxyType = telegramSettingVo.getProxyType();
final String proxyHost = telegramSettingVo.getProxyHost();
@ -107,13 +100,27 @@ public class SenderTelegramMsg extends SenderBaseMsg {
.connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)).build();
}
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), requestMsg);
final Request request;
if (method.equals("GET")) {
request = new Request.Builder()
.url(requestUrl + "?chat_id=" + chatId + "&text=" + finalText)
.build();
} else {
Map bodyMap = new HashMap();
bodyMap.put("chat_id", chatId);
bodyMap.put("text", finalText);
bodyMap.put("parse_mode", "HTML");
final Request request = new Request.Builder()
.url(requestUrl)
.addHeader("Content-Type", "application/json; charset=utf-8")
.post(requestBody)
.build();
String requestMsg = JSON.toJSONString(bodyMap);
Log.i(TAG, "requestMsg:" + requestMsg);
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), requestMsg);
request = new Request.Builder()
.url(requestUrl)
.addHeader("Content-Type", "application/json; charset=utf-8")
.post(requestBody)
.build();
}
client.newCall(request).enqueue(new Callback() {
@Override
@ -137,7 +144,7 @@ public class SenderTelegramMsg extends SenderBaseMsg {
}
}
});
} catch (Exception e) {
LogUtil.updateLog(logId, 0, e.getMessage());
Log.e(TAG, e.getMessage(), e);

View File

@ -66,6 +66,12 @@ public class NotifyService extends NotificationListenerService {
packageName, title, text, time)
);
//自动关闭通知
if (SettingUtil.getSwitchCancelAppNotify()) {
String key = sbn.getKey();
cancelNotification(key);
}
//重复通知不再处理
String prevHash = SettingUtil.getPrevNoticeHash(packageName);
String currHash = CommonUtil.MD5(packageName + title + text + time);
@ -83,7 +89,7 @@ public class NotifyService extends NotificationListenerService {
} catch (Exception e) {
Log.e(TAG, "onNotificationPosted:", e);
}
//NotifyHelper.getInstance().onReceive(sbn);
}
/**
@ -99,8 +105,6 @@ public class NotifyService extends NotificationListenerService {
if (sbn.getNotification() == null) return;
Log.d(TAG, sbn.getPackageName());
//NotifyHelper.getInstance().onRemoved(sbn);
}
/**

View File

@ -6,10 +6,8 @@ import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationManagerCompat;
@ -27,40 +25,6 @@ public class CommonUtil {
public static final int NOTIFICATION_REQUEST_CODE = 9527;
private static final String ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";
/**
* <meta-data
* android:name="UMENG_CHANNEL"
* android:value="Umeng">
* </meta-data>
*
* @param ctx 上下文
* @return 渠道名称
*/
// 获取渠道工具函数
public static String getChannelName(Context ctx) {
if (ctx == null) {
return null;
}
String channelName = null;
try {
PackageManager packageManager = ctx.getPackageManager();
if (packageManager != null) {
//注意此处为ApplicationInfo 而不是 ActivityInfo,因为友盟设置的meta-data是在application标签中而不是activity标签中所以用ApplicationInfo
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(ctx.getPackageName(), PackageManager.GET_META_DATA);
if (applicationInfo.metaData != null) {
channelName = applicationInfo.metaData.get("UMENG_CHANNEL") + "";
}
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
if (TextUtils.isEmpty(channelName)) {
channelName = "Unknown";
}
return channelName;
}
//是否启用通知监听服务
public static boolean isNotificationListenerServiceEnabled(Context context) {
Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(context);

View File

@ -9,6 +9,7 @@ public class Define {
public static final String SP_MSG_KEY_STRING_ENABLE_SMS = "tsms_msg_key_switch_enable_sms";
public static final String SP_MSG_KEY_STRING_ENABLE_PHONE = "tsms_msg_key_switch_enable_phone";
public static final String SP_MSG_KEY_STRING_ENABLE_APP_NOTIFY = "tsms_msg_key_switch_enable_app_notify";
public static final String SP_MSG_KEY_STRING_CANCEL_APP_NOTIFY = "tsms_msg_key_switch_cancel_app_notify";
public static final String SP_MSG_KEY_STRING_ENABLE_EXCLUDE_FROM_RECENTS = "tsms_msg_key_switch_enable_exclude_from_recents";
public static final String SP_MSG_KEY_STRING_ADD_EXTRA_DEVICE_MARK = "tsms_msg_key_string_add_extra_device_mark";
public static final String SP_MSG_KEY_STRING_ADD_EXTRA_SIM1 = "tsms_msg_key_string_add_extra_sim1";

View File

@ -329,7 +329,7 @@ public class PhoneUtils {
*
* @return 多Sim卡的具体信息
*/
@SuppressLint("ObsoleteSdkInt")
@SuppressLint({"ObsoleteSdkInt", "Range"})
public static List<SimInfo> getSimMultiInfo() {
List<SimInfo> infos = new ArrayList<>();
Log.d(TAG, "Build.VERSION.SDK_INT = " + Build.VERSION.SDK_INT);
@ -533,6 +533,7 @@ public class PhoneUtils {
/**
* 获取后一条通话记录
*/
@SuppressLint("Range")
public static CallInfo getLastCallInfo(String phoneNumber) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
return null;

View File

@ -78,6 +78,16 @@ public class SettingUtil {
return sp_setting.getBoolean(Define.SP_MSG_KEY_STRING_ENABLE_APP_NOTIFY, false);
}
public static void switchCancelAppNotify(Boolean enable) {
sp_setting.edit()
.putBoolean(Define.SP_MSG_KEY_STRING_CANCEL_APP_NOTIFY, enable)
.apply();
}
public static boolean getSwitchCancelAppNotify() {
return sp_setting.getBoolean(Define.SP_MSG_KEY_STRING_CANCEL_APP_NOTIFY, true);
}
public static void switchEnableBatteryReceiver(Boolean enable) {
sp_setting.edit()
.putBoolean(Define.SP_MSG_KEY_STRING_BATTERY_RECEIVER, enable)

View File

@ -0,0 +1,87 @@
package com.idormy.sms.forwarder.utils;
import android.content.Context;
import android.content.SharedPreferences;
import java.util.Map;
public class SharedPreferencesHelper {
private final SharedPreferences sharedPreferences;
private final SharedPreferences.Editor editor;
public SharedPreferencesHelper(Context context, String FILE_NAME) {
sharedPreferences = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
}
/**
* 存储
*/
public void put(String key, Object object) {
if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
editor.putInt(key, (Integer) object);
} else if (object instanceof Boolean) {
editor.putBoolean(key, (Boolean) object);
} else if (object instanceof Float) {
editor.putFloat(key, (Float) object);
} else if (object instanceof Long) {
editor.putLong(key, (Long) object);
} else {
editor.putString(key, object.toString());
}
editor.commit();
}
/**
* 获取保存的数据
*/
public Object getSharedPreference(String key, Object defaultObject) {
if (defaultObject instanceof String) {
return sharedPreferences.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
return sharedPreferences.getInt(key, (Integer) defaultObject);
} else if (defaultObject instanceof Boolean) {
return sharedPreferences.getBoolean(key, (Boolean) defaultObject);
} else if (defaultObject instanceof Float) {
return sharedPreferences.getFloat(key, (Float) defaultObject);
} else if (defaultObject instanceof Long) {
return sharedPreferences.getLong(key, (Long) defaultObject);
} else {
return sharedPreferences.getString(key, null);
}
}
/**
* 移除某个key值已经对应的值
*/
public void remove(String key) {
editor.remove(key);
editor.commit();
}
/**
* 清除所有数据
*/
public void clear() {
editor.clear();
editor.commit();
}
/**
* 查询某个key是否存在
*/
public Boolean contain(String key) {
return sharedPreferences.contains(key);
}
/**
* 返回所有的键值对
*/
public Map<String, ?> getAll() {
return sharedPreferences.getAll();
}
}

View File

@ -300,7 +300,6 @@
android:gravity="end"
android:textSize="18sp"
tools:ignore="UseSwitchCompatOrMaterialXml" />
</LinearLayout>
<LinearLayout
@ -711,7 +710,7 @@
android:gravity="end"
android:text="@string/enable_exclude_from_recents_tips"
android:textSize="9sp"
tools:ignore="SmallSp" />
tools:ignore="SmallSp,TooManyViews" />
</LinearLayout>
<Switch

View File

@ -242,27 +242,42 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal">
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="5dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/email_to" />
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/email_to" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:text="@string/email_to_tips"
android:textSize="11sp" />
</LinearLayout>
<EditText
android:id="@+id/editTextEmailToAdd"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:autofillHints=""
android:ems="14"
android:inputType="textEmailAddress"
android:maxLines="1"
android:inputType="text"
android:gravity="start|top"
android:minLines="1"
android:text=""
tools:ignore="LabelFor" />
tools:ignore="LabelFor,TextFields" />
</LinearLayout>
<LinearLayout

View File

@ -58,6 +58,44 @@
tools:ignore="LabelFor" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:text="@string/Method"
android:textStyle="bold" />
<RadioGroup
android:id="@+id/radioGroupTelegramMethod"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:orientation="horizontal">
<RadioButton
android:id="@+id/radioTelegramMethodPost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/post" />
<RadioButton
android:id="@+id/radioTelegramMethodGet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/get" />
</RadioGroup>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -1,177 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/set_name" />
<EditText
android:id="@+id/editTextWebNotifyName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:autofillHints=""
android:ems="11"
android:inputType="text"
android:text=""
tools:ignore="LabelFor" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:text="@string/WebNotifyMethod" />
<RadioGroup
android:id="@+id/radioGroupWebNotifyMethod"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:orientation="horizontal">
<RadioButton
android:id="@+id/radioWebNotifyMethodPost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/post" />
<RadioButton
android:id="@+id/radioWebNotifyMethodGet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/get" />
</RadioGroup>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/WebNotifyWebServer" />
<EditText
android:id="@+id/editTextWebNotifyWebServer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autofillHints=""
android:ems="14"
android:inputType="text"
android:text=""
tools:ignore="LabelFor" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@string/WebNotifyWebParams' />
<EditText
android:id="@+id/editTextWebNotifyWebParams"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autofillHints=""
android:ems="14"
android:inputType="text"
android:text=""
tools:ignore="LabelFor" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/WebNotifySecret" />
<EditText
android:id="@+id/editTextWebNotifySecret"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autofillHints=""
android:ems="14"
android:inputType="textPassword"
android:text=""
tools:ignore="LabelFor" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="horizontal">
<Button
android:id="@+id/buttonWebNotifyTest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_weight="1"
android:text="@string/test"
tools:ignore="ButtonStyle,NestedWeights" />
<Button
android:id="@+id/buttonWebNotifyDel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_weight="1"
android:text="@string/del"
tools:ignore="ButtonStyle,NestedWeights" />
<Button
android:id="@+id/buttonWebNotifyOk"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/ok"
tools:ignore="ButtonStyle,NestedWeights" />
</LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/set_name" />
<EditText
android:id="@+id/editTextWebNotifyName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:autofillHints=""
android:ems="11"
android:inputType="text"
android:text=""
tools:ignore="LabelFor" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:text="@string/Method" />
<RadioGroup
android:id="@+id/radioGroupWebNotifyMethod"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:orientation="horizontal">
<RadioButton
android:id="@+id/radioWebNotifyMethodPost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/post" />
<RadioButton
android:id="@+id/radioWebNotifyMethodGet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/get" />
</RadioGroup>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/WebNotifyWebServer" />
<EditText
android:id="@+id/editTextWebNotifyWebServer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autofillHints=""
android:ems="14"
android:inputType="text"
android:text=""
tools:ignore="LabelFor" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@string/WebNotifyWebParams' />
<EditText
android:id="@+id/editTextWebNotifyWebParams"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autofillHints=""
android:ems="14"
android:inputType="text"
android:text=""
tools:ignore="LabelFor" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/WebNotifySecret" />
<EditText
android:id="@+id/editTextWebNotifySecret"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autofillHints=""
android:ems="14"
android:inputType="textPassword"
android:text=""
tools:ignore="LabelFor" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="horizontal">
<Button
android:id="@+id/buttonWebNotifyTest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_weight="1"
android:text="@string/test"
tools:ignore="ButtonStyle,NestedWeights" />
<Button
android:id="@+id/buttonWebNotifyDel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_weight="1"
android:text="@string/del"
tools:ignore="ButtonStyle,NestedWeights" />
<Button
android:id="@+id/buttonWebNotifyOk"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/ok"
tools:ignore="ButtonStyle,NestedWeights" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
android:background="#fff"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="Overdraw">
<TextView
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/privacy_policy"
android:textColor="#000"
android:textSize="17sp" />
<TextView
android:id="@+id/textlike"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp"
android:layout_marginBottom="10dp"
android:layout_width="wrap_content"
android:textColor="#000"
android:layout_height="wrap_content"
android:text="@string/privacy_policy_text"
android:textSize="17sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#514E4E" />
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="50dp">
<TextView
android:textColor="#000"
android:id="@+id/succsebtn"
android:gravity="center"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/agree"
android:textSize="20sp" />
<View
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:background="#5F6063" />
<TextView
android:textColor="#000"
android:id="@+id/caclebtn"
android:textSize="20sp"
android:gravity="center"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/disagree" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@ -132,6 +132,7 @@
<string name="email_password">Password/Auth Code</string>
<string name="email_nickname">Nickname</string>
<string name="email_to">Send To</string>
<string name="email_to_tips">TipSeparate multiple recipients with a ","</string>
<string name="email_title">Email Title</string>
<string name="feishu_webhook">Webhook</string>
<string name="feishu_secret">Secret (optional)</string>
@ -146,7 +147,7 @@
<string name="ServerChanSendKey">ServerChan\'s SendKey</string>
<string name="TelegramApiToken">ApiToken or Custom address</string>
<string name="TelegramChatId">ChatId</string>
<string name="WebNotifyMethod">Method</string>
<string name="Method">Method</string>
<string name="WebNotifyWebServer">WebServer e.g. https://a.b.com/msg?token=xyz</string>
<string name="WebNotifyWebParams">WebParams e.g. payload=%7B%22text%22%3A%22[msg]%22%7D [msg] will be replaced with text message content. \nSupport Json format, for example: {"text":[MSG]}.\n Note: MSG is automatically utF-8 encoded in addition to JSON format</string>
<string name="WebNotifySecret">Secret (sign is not counted if left blank)</string>
@ -167,8 +168,10 @@
<string name="forward_sms_tips">Main switch, requires permissions to read and sned SMS messages, especially verification SMS texts.</string>
<string name="forward_missed_calls">Forward missed calls</string>
<string name="forward_missed_calls_tips">Main switch, requires permissions to read call log and contacts.</string>
<string name="forward_app_notify">Forward app notify</string>
<string name="forward_app_notify">Forward app Ntf.</string>
<string name="forward_app_notify_tips">Main switch, requires permission to read notification.</string>
<string name="cancel_app_notify">Auto close Ntf.</string>
<string name="cancel_app_notify_tips">Automatically close a single notification after forwarding, to avoid stacking of multiple notifications.</string>
<string name="enable_custom_templates">Global custom template</string>
<string name="enable_custom_templates_tips">Priority: custom template for forwarding rules > Global custom template > System default</string>
<string name="enable_regex_replace">Enable regular replacement content</string>
@ -265,4 +268,8 @@
<string name="password">Password</string>
<string name="send_sms_config_title">SmsHub client Mode</string>
<string name="send_sms_config_title2">Execute the operation returned by the interface</string>
<string name="privacy_policy">Privacy Policy</string>
<string name="agree">Agree</string>
<string name="disagree">Disagree</string>
<string name="privacy_policy_text">SmsForwarder (the "Application/App"), is 100% free and open source, and is compliled and released basing on repository hosted on GitHub. The App will not collect any of your privacy data!\n\n Version information of the App will be sent in the following situations: \n 1. As startup, version information will be sent to "Umeng +· U-APP Mobile Statistics" for user retention analyze and crash stats;\n 2. Manual update check triggered by user;\n The App collects no any other data!!\n\n The App collects and uses version information only in accordance with the Privacy Policy, and will not collect any other information as an abuse of users\' consent to the Privacy Policy;</string>
</resources>

View File

@ -41,4 +41,12 @@
<item name="android:textColor">@drawable/txt_select_selector</item>
</style>
<style name="dialog" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item><!--边框-->
<item name="android:windowIsFloating">true</item><!--是否浮现在activity之上-->
<item name="android:windowIsTranslucent">true</item><!--半透明-->
<item name="android:windowNoTitle">true</item><!--无标题-->
<item name="android:windowBackground">@android:color/transparent</item><!--背景透明-->
<item name="android:backgroundDimEnabled">true</item><!--模糊-->
</style>
</resources>

View File

@ -132,6 +132,7 @@
<string name="email_password">登录密码/授权码</string>
<string name="email_nickname">发件人昵称</string>
<string name="email_to">收件地址</string>
<string name="email_to_tips">Tip多个收件人以半角逗号,分隔</string>
<string name="email_title">邮件主题</string>
<string name="feishu_webhook">Webhook 地址</string>
<string name="feishu_secret">加签 Secret (没有可不填)</string>
@ -146,7 +147,7 @@
<string name="ServerChanSendKey">设置Server酱·Turbo版的SendKey</string>
<string name="TelegramApiToken">设置Telegram机器人的ApiToken 或 自定义地址(http开头)</string>
<string name="TelegramChatId">设置被通知人(或群组)的ChatId</string>
<string name="WebNotifyMethod">请求方式</string>
<string name="Method">请求方式</string>
<string name="WebNotifyWebServer">设置WebServer例如https://a.b.com/msg?token=xyz</string>
<string name="WebNotifyWebParams">设置WebParams例如payload=%7B%22text%22%3A%22[msg]%22%7D [msg]将被替换成短信内容。\n支持Json格式例如{"text":[msg]}。\n注意除JSON格式外msg会自动进行UTF-8编码</string>
<string name="WebNotifySecret">设置Secret:置空则不计算sign</string>
@ -169,6 +170,8 @@
<string name="forward_missed_calls_tips">总开关,请授予读取通话记录、联系人等权限</string>
<string name="forward_app_notify">转发应用通知</string>
<string name="forward_app_notify_tips">总开关,请先授予通知使用权</string>
<string name="cancel_app_notify">自动关闭通知</string>
<string name="cancel_app_notify_tips">单条通知处理完毕后,自动关闭,避免多条通知堆叠</string>
<string name="enable_custom_templates">启用自定义模版</string>
<string name="enable_custom_templates_tips">优先级:转发规则的自定义模板 > 全局自定义模版 > 默认</string>
<string name="enable_regex_replace">启用正则替换内容</string>
@ -264,4 +267,8 @@
<string name="password">密码</string>
<string name="send_sms_config_title">SmsHub client 模式</string>
<string name="send_sms_config_title2">执行接口返回的操作</string>
<string name="privacy_policy">隐私政策</string>
<string name="agree">同意</string>
<string name="disagree">不同意</string>
<string name="privacy_policy_text">SmsForwarder-短信转发器(下称本软件) 100% 免费开源Github 在线编译发版,绝不会收集您的任何隐私数据! \n\n以下情形会上报本软件版本信息 \n 1、启动本软件时发送版本信息发送到《友盟+·U-App移动统计》用于分析本软件的用户版本留存与软件奔溃统计 \n 2、手动检查更新时发送版本号用于检查新版本 \n除此之外没有任何数据 \n\n本软件会遵循《隐私政策》收集、使用版本信息但不会因为您同意了《隐私政策》而进行强制捆绑式的信息收集。</string>
</resources>

View File

@ -43,4 +43,13 @@
<item name="android:letterSpacing">0.1</item>
<item name="android:textColor">@drawable/txt_select_selector</item>
</style>
<style name="dialog" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item><!--边框-->
<item name="android:windowIsFloating">true</item><!--是否浮现在activity之上-->
<item name="android:windowIsTranslucent">true</item><!--半透明-->
<item name="android:windowNoTitle">true</item><!--无标题-->
<item name="android:windowBackground">@android:color/transparent</item><!--背景透明-->
<item name="android:backgroundDimEnabled">true</item><!--模糊-->
</style>
</resources>

View File

@ -3,21 +3,25 @@
buildscript {
ext.jetty_version = '9.2.30.v20200428'
repositories {
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://maven.aliyun.com/repository/public' }
google()
jcenter()
maven { url "https://jitpack.io" }
maven { url 'https://repo1.maven.org/maven2/' }
}
dependencies {
classpath 'com.android.tools.build:gradle:7.0.3'
classpath 'com.android.tools.build:gradle:7.0.4'
classpath 'com.chenenyu:img-optimizer:1.2.0'
}
}
allprojects {
repositories {
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://maven.aliyun.com/repository/public' }
google()
jcenter()
maven { url "https://jitpack.io" }
maven { url 'https://repo1.maven.org/maven2/' }
}

View File

@ -1,3 +1,3 @@
#Fri Jul 16 10:33:23 CST 2021
versionName=2.3.0
versionCode=32
versionName=2.4.0
versionCode=33