初始化

pull/67/head
pppscn 3 years ago
parent 2ab4b0580e
commit 3875fe64ae

12
.gitignore vendored

@ -0,0 +1,12 @@
.idea/
.gradle
.git
build
local.properties
*.iml
*.project
*/*.project
*.classpath
*/*.classpath
.settings/*
*/.settings/*

@ -0,0 +1,94 @@
# 短信转发 信息转发 TranspondSms 把Android手动的短信通过邮件或者钉钉转出去
博文连接[https://www.jianshu.com/p/608d1b1477e3]
官网[https://tsms.allmything.com]
APP下载 [https://pan.baidu.com/s/1kbelTFIf5nwkOY9g6itkvA]
--------
## 该工具实现特点和准则:
* **简单** 只做两件事:监听短信---》转发
由此带来的好处:
* 功能简单:当时用Pad的时候看手机验证码各种不方便网上搜了好久也有解决方案
> + AirDroid:手机管理工具功能太多,看着都耗电,权限太多,数据经过三方,账号分级
> + IFTTT:功能太多,看着耗电,权限太多,数据经过三方,收费
> + 还有些其他的也是这些毛病
* 省电运行时只监听广播有短信才执行转发并记录最近n条的转发内容和转发状态
* 健壮越简单越不会出错UNIX设计哲学就越少崩溃运行越稳定持久
### 工作流程:
![工作流程](pic/showpic.png "工作流程")
### 功能列表:
| 功能 | 描述 |
| ---- | ---- |
| 转发监听 | 已实现 |
| 转发钉钉 | 单个钉钉群已实现 |
| 转发钉钉@某人 | 已实现 |
| 转发邮箱 | 单个邮箱已实现 |
| 转发企业微信群机器人 | 已实现 |
| 转发web页面 | 单个web页面已实现[向设置的url发送POST请求](doc/POST_WEB.md) |
| 转发规则 | (规则即:什么短信转发到哪里)已实现实现 |
| 兼容 | 已兼容6.xx、7.xx、8.xx、9.xx、10.xx |
### 使用流程:
1. 在Android手机上安装TSMS 本APP后点击应用图标打开
2. 在设置发送方页面,添加或点击已添加的发送方来设置转发短信使用的方式,现在支持钉钉机器人、邮箱、网页:
+ 设置钉钉机器人请先在钉钉群中添加自定义机器人复制机器人的token和secret,填入弹出框。点击测试会使用该机器人向群内发送一条消息;点击确认即可添加配置。
+ 配置邮箱请先在你邮箱的后台管理页面配置smtp选项并设置密码授权码并参照说明配置TSMS弹出框的smtp信息。点击测试会使用该邮箱向配置的邮箱发送一条测试邮件点击确认即可添加配置。
+ 配置网页通知请先在 msg.allmything.com 注册登陆并添加一个消息通道复制消息通道token填入配置弹框。点击测试会向该消息通道推送一条测试消息可在 msg.allmything.com 的消息页面查看(页面会自动刷新);点击确认即可添加配置。
3. 在设置转发规则页面,添加或点击已添加的转发规则来设置转发什么样的短信,现在支持转发全部、根据手机号、根据短信内容:
+ 当设置转发全部时,所以接收到的短信都会用转发出去。
+ 当设置根据手机号或短信内容时,请设置匹配的模式和值,例如:”手机号 是 10086 发送方选钉钉“。
4. 点击主页面右上角的菜单可进入设置页面,在设置页面可以更新应用查看应用信息提交意见反馈等
5. 在主页面下拉可刷新转发的短信,点击清空记录可删除转发的记录
*注该APP打开后会自动后台运行并在任务栏显示运行图标请勿强杀退出后请重新开启并加入到系统白名单中并允许后台运行*
### 应用截图:
![主界面](pic/main.jpg "应用主界面")
![转发详情](pic/maindetail.jpg "转发详情")
![转发规则](pic/rule.jpg "转发规则")
![添加编辑转发规则](pic/ruleset.jpg "添加编辑转发规则")
![发送方](pic/sender.jpg "发送方")
![添加编辑发送方钉钉](pic/sendersetdingding.jpg "添加编辑发送方钉钉")
![添加编辑发送方邮箱](pic/sendersetemail.jpg "添加编辑发送方邮箱")
![添加编辑发送方网页通知](pic/sendersetwebnotify.jpg "添加编辑发送方网页通知")
![状态栏运行状态](pic/taskbar.jpg "状态栏运行状态")
![应用设置](pic/setting.jpg "应用设置")
![意见反馈](pic/settingfeedback.jpg "意见反馈")
![应用更新](pic/update-dingdingsecret.jpg "应用更新")
### 更新记录:
> [v3.5.0](app/release/TSMS_release_20210126_3.5.0.apk) 1钉钉机器人添加 @ 功能
> [v3.4.0](pic/TSMS_release_20210120_3.4.0.apk) 1增加企业微信群机器人通知。2修复设置开机启动崩溃
> [v3.3.0](pic/TSMS_release_20210113_3.3.0.apk) 1增加网页通知验签。2修复网页及钉钉配置测试崩溃
> [v3.2.0](pic/TSMS_release_20210106_3.2.0.apk) 1增加邮箱SSL配置。2邮箱测试结果通知
> [v3.1.0](pic/TSMS_release_20201231_3.1.0.apk) 1界面重构。2增加转发规则页面。3增加发送方页面。4升级配置页面
> [v2.1.0](pic/TSMS_release_20200806_2.1.0.apk) 1增加新版钉钉群机器人安全设置中的加签
> [v2.00](pic/TSMS_release_20200729_2.00.apk) 1移除热点管理回归简单。2修复Android9Android10版本闪退。3添加更新接口。4修复bug
> v1.1 减少手动配置启动参数自启动配置、自动开启热点配置设置好后手机重启也不用重新打开了还能自动为pad开启热点
<u>热点管理
可设置跟随设备启动时启动热点并且在热点关闭后10秒自动重启热点所以想关闭热点先把设置页码的开启热点关掉</u>
(热点助手功能会在后期2020/07/29转移到单独的APP)详见[https://www.jianshu.com/p/f70cf475eddc]
> v1.0 项目初始化,实现转发
## LICENSE
BSD

@ -0,0 +1 @@
theme: jekyll-theme-cayman

@ -0,0 +1,70 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.idormy.sms.forwarder"
minSdkVersion 23
targetSdkVersion 28
versionCode 1
versionName "1.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
//apk file name
android.applicationVariants.all { variant ->
variant.outputs.all {
//def date = new Date().format("yyyyMMdd" , TimeZone.getTimeZone("Asia/Shanghai"))
def date = new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+08"))
if (variant.buildType.name.equals('debug')) {
outputFileName = "TSMS_debug_${date}_${versionName}.apk"
}
if (variant.buildType.name.equals('release')) {
outputFileName = "TSMS_release_${date}_${versionName}.apk"
}
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
//okhttp
implementation 'com.squareup.okhttp3:okhttp:3.6.0'
implementation 'com.squareup.okio:okio:1.11.0'
//mail
implementation 'com.sun.mail:android-mail:1.6.0'
implementation 'com.sun.mail:android-activation:1.6.0'
implementation 'com.android.support:design:28.0.0'
//android8.0使api
//使ProxyBuilder
// implementation 'com.linkedin.dexmaker:dexmaker-mockito:2.12.1'
//appupdate
implementation 'com.qianwen:update-app:3.5.2'
implementation 'com.qianwen:okhttp-utils:3.8.0'
implementation 'com.lzy.net:okgo:3.0.4'
// SDK
implementation "com.umeng.umsdk:common:2.1.0"
// SDK宿App使
// SDK
implementation "com.umeng.umsdk:analytics:8.1.3"
//fastjson
implementation "com.alibaba:fastjson:1.2.75"
}

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

@ -0,0 +1,19 @@
[
{
"outputType": {
"type": "APK"
},
"apkInfo": {
"type": "MAIN",
"splits": [],
"versionCode": 35,
"versionName": "3.5.0",
"enabled": true,
"outputFile": "TSMS_release_20210126_3.5.0.apk",
"fullName": "release",
"baseName": "release"
},
"path": "TSMS_release_20210126_3.5.0.apk",
"properties": {}
}
]

@ -0,0 +1,22 @@
package com.idormy.sms.forwarder
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getTargetContext()
assertEquals("com.idormy.sms.forwarder", appContext.packageName)
}
}

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.idormy.sms.forwarder">
<application
android:name="com.idormy.sms.forwarder.MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="UPDATE_APP_KEY"
android:value="SVSfseesfsf" />
<meta-data
android:name="UMENG_APPKEY"
android:value="5f217c02b4b08b653e8f6b3d" />
<meta-data
android:name="UMENG_CHANNEL"
android:value="Umeng" />
<activity android:name="com.idormy.sms.forwarder.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.idormy.sms.forwarder.SettingActivity" />
<activity
android:name="com.idormy.sms.forwarder.RuleActivity"
android:label="转发规则" />
<activity
android:name="com.idormy.sms.forwarder.SenderActivity"
android:label="发送方设置" />
<receiver android:name="com.idormy.sms.forwarder.BroadCastReceiver.RebootBroadcastReceiver">
<intent-filter android:priority="2147483647">
<!--重启广播-->
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver
android:name="com.idormy.sms.forwarder.BroadCastReceiver.TSMSBroadcastReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="999">
<!--短信广播-->
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<service android:name="com.idormy.sms.forwarder.FrontService" />
</application>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- 授予应用程序访问系统开机事件的权限 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!--Android 9API 级别 28或更高版本并使用前台服务则其必须请求 FOREGROUND_SERVICE 权限-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

@ -0,0 +1,26 @@
package com.idormy.sms.forwarder.BroadCastReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class MessageBroadcastReceiver extends BroadcastReceiver {
public static String EXTRA_DATA = "data";
public static String ACTION_DINGDING = "com.idormy.sms.forwarder.action_dingding";
private String TAG = "MessageBroadcastReceiver";
@Override
public void onReceive(Context arg0, Intent intent) {
Log.d(TAG, "onReceive intent " + intent.getAction());
String action = intent.getAction();
if (action.equals(ACTION_DINGDING)) {
String sendStatus = intent.getStringExtra(EXTRA_DATA);
Toast.makeText(arg0, "dingding sendStatus: " + sendStatus, Toast.LENGTH_LONG).show();
}
}
}

@ -0,0 +1,33 @@
package com.idormy.sms.forwarder.BroadCastReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import com.idormy.sms.forwarder.FrontService;
import com.idormy.sms.forwarder.utils.InitUtil;
public class RebootBroadcastReceiver extends BroadcastReceiver {
private String TAG = "RebootBroadcastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
String receiveAction = intent.getAction();
Log.d(TAG, "onReceive intent " + receiveAction);
if (receiveAction.equals("android.intent.action.BOOT_COMPLETED")) {
Log.d(TAG, "BOOT_COMPLETED");
InitUtil.init(context);
Intent frontServiceIntent = new Intent(context, FrontService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(frontServiceIntent);
} else {
context.startService(frontServiceIntent);
}
}
}
}

@ -0,0 +1,68 @@
package com.idormy.sms.forwarder.BroadCastReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
import android.util.Log;
import com.idormy.sms.forwarder.model.vo.SmsVo;
import com.idormy.sms.forwarder.utils.SendUtil;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class TSMSBroadcastReceiver extends BroadcastReceiver {
private String TAG = "TSMSBroadcastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
String receiveAction = intent.getAction();
Log.d(TAG, "onReceive intent " + receiveAction);
if (receiveAction.equals("android.provider.Telephony.SMS_RECEIVED")) {
try {
Object[] object = (Object[]) Objects.requireNonNull(intent.getExtras()).get("pdus");
if (object != null) {
List<SmsVo> smsVoList = new ArrayList<>();
String format = intent.getStringExtra("format");
Map<String, String> mobileToContent = new HashMap<>();
Date date = new Date();
for (Object pdus : object) {
byte[] pdusMsg = (byte[]) pdus;
SmsMessage sms = SmsMessage.createFromPdu(pdusMsg, format);
String mobile = sms.getOriginatingAddress();//发送短信的手机号
if (mobile == null) {
continue;
}
//下面是获取短信的发送时间
date = new Date(sms.getTimestampMillis());
String content = mobileToContent.get(mobile);
if (content == null) content = "";
content += sms.getMessageBody();//短信内容
mobileToContent.put(mobile, content);
}
for (String mobile : mobileToContent.keySet()) {
smsVoList.add(new SmsVo(mobile, mobileToContent.get(mobile), date));
}
Log.d(TAG, "短信:" + smsVoList);
SendUtil.send_msg_list(context, smsVoList);
}
} catch (Throwable throwable) {
Log.e(TAG, "解析短信失败:" + throwable.getMessage());
}
}
}
}

@ -0,0 +1,59 @@
package com.idormy.sms.forwarder;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
public class FrontService extends Service {
private static final String TAG = "FrontService";
private static final String CHANNEL_ONE_ID = "com.idormy.sms.forwarder";
private static final String CHANNEL_ONE_NAME = "com.idormy.sms.forwarderName";
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
Notification.Builder builder = new Notification.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launchert);
builder.setContentTitle("短信转发器");
builder.setContentText("根据规则转发到钉钉/微信/邮箱/bark/webhook等");
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity
(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
//修改安卓8.1以上系统报错
NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ONE_ID, CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_MIN);
notificationChannel.enableLights(false);//如果使用中的设备支持通知灯,则说明此通知通道是否应显示灯
notificationChannel.setShowBadge(false);//是否显示角标
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.createNotificationChannel(notificationChannel);
builder.setChannelId(CHANNEL_ONE_ID);
}
Notification notification = builder.build();
startForeground(1, notification);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "flags: " + flags + " startId: " + startId);
return START_STICKY;
}
}

@ -0,0 +1,227 @@
package com.idormy.sms.forwarder;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import com.idormy.sms.forwarder.BroadCastReceiver.TSMSBroadcastReceiver;
import com.idormy.sms.forwarder.adapter.LogAdapter;
import com.idormy.sms.forwarder.model.LogModel;
import com.idormy.sms.forwarder.model.vo.LogVo;
import com.idormy.sms.forwarder.utils.LogUtil;
import com.umeng.analytics.MobclickAgent;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class MainActivity extends AppCompatActivity implements ReFlashListView.IReflashListener {
private IntentFilter intentFilter;
private TSMSBroadcastReceiver smsBroadcastReceiver;
private String TAG = "MainActivity";
// logVoList用于存储数据
private List<LogVo> logVos = new ArrayList<>();
private LogAdapter adapter;
private ReFlashListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "oncreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LogUtil.init(this);
// 先拿到数据并放在适配器上
initTLogs(); //初始化数据
showList(logVos);
// 为ListView注册一个监听器当用户点击了ListView中的任何一个子项时就会回调onItemClick()方法
// 在这个方法中可以通过position参数判断出用户点击的是那一个子项
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
LogVo logVo = logVos.get(position - 1);
logDetail(logVo);
// Toast.makeText(MainActivity.this,String.valueOf(position),Toast.LENGTH_SHORT).show();
}
});
// textv_msg.setMovementMethod(ScrollingMovementMethod.getInstance());
// textv_msg.setText(SendHistory.getHistory());
checkPermission();
// intentFilter=new IntentFilter();
// intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
// intentFilter.addAction(MessageBroadcastReceiver.ACTION_DINGDING);
// smsBroadcastReceiver=new SMSBroadcastReceiver();
// //动态注册广播
// registerReceiver(smsBroadcastReceiver, intentFilter);
}
// 初始化数据
private void initTLogs() {
logVos = LogUtil.getLog(null, null);
}
private void showList(List<LogVo> logVosN) {
Log.d(TAG, "showList: " + logVosN);
if (adapter == null) {
// 将适配器上的数据传递给listView
listView = findViewById(R.id.list_view_log);
listView.setInterface(this);
adapter = new LogAdapter(MainActivity.this, R.layout.tlog_item, logVosN);
listView.setAdapter(adapter);
} else {
adapter.onDateChange(logVosN);
}
}
@Override
public void onReflash() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
//获取最新数据
initTLogs();
//通知界面显示
showList(logVos);
//通知listview 刷新数据完毕;
listView.reflashComplete();
}
}, 2000);
}
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
//取消注册广播
unregisterReceiver(smsBroadcastReceiver);
}
public void logDetail(LogVo logVo) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("详情");
builder.setMessage(logVo.getFrom() + "\n" + logVo.getContent() + "\n" + logVo.getRule() + "\n" + logVo.getTime());
builder.show();
}
public void toSetting() {
Intent intent = new Intent(this, SettingActivity.class);
startActivity(intent);
}
public void toRuleSetting(View view) {
Intent intent = new Intent(this, RuleActivity.class);
startActivity(intent);
}
public void toSendSetting(View view) {
Intent intent = new Intent(this, SenderActivity.class);
startActivity(intent);
}
public void cleanLog(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("确定要清空转发记录吗?")
.setPositiveButton("清空", new DialogInterface.OnClickListener() {// 积极
@Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
LogUtil.delLog(null, null);
initTLogs();
adapter.add(logVos);
}
});
builder.show();
}
public void addLog(View view) {
Log.d(TAG, "refreshLog");
LogModel newModel = new LogModel("199999", "content" + (new SimpleDateFormat("YYYY-MM-dd HH:mm:ss").format(new Date())), 1l);
LogUtil.addLog(newModel);
// initTLogs();
// adapter.add(logVos);
}
//按返回键不退出回到桌面
@Override
public void onBackPressed() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
}
private void checkPermission() {
// 检查权限是否获取android6.0及以上系统可能默认关闭权限,且没提示)
PackageManager pm = getPackageManager();
boolean permission_receive_boot = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.RECEIVE_BOOT_COMPLETED", this.getPackageName()));
boolean permission_readsms = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.READ_SMS", this.getPackageName()));
if (!(
permission_receive_boot
&& permission_readsms
)) {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.RECEIVE_BOOT_COMPLETED,
Manifest.permission.READ_SMS,
}, 0x01);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.to_setting:
toSetting();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true;
}
@Override
protected void onResume() {
super.onResume();
MobclickAgent.onResume(this);
}
@Override
protected void onPause() {
super.onPause();
MobclickAgent.onPause(this);
}
}

@ -0,0 +1,82 @@
package com.idormy.sms.forwarder;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import com.idormy.sms.forwarder.utils.SendHistory;
import com.idormy.sms.forwarder.utils.SettingUtil;
import com.umeng.analytics.MobclickAgent;
import com.umeng.commonsdk.UMConfigure;
public class MyApplication extends Application {
private static final String TAG = "MyApplication";
/**
* <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 != null) {
if (applicationInfo.metaData != null) {
channelName = applicationInfo.metaData.get("UMENG_CHANNEL") + "";
}
}
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
if (TextUtils.isEmpty(channelName)) {
channelName = "Unknown";
}
Log.d(TAG, "getChannelName: " + channelName);
return channelName;
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
}
@Override
public void onCreate() {
Log.d(TAG, "onCreate");
super.onCreate();
//初始化组件化基础库, 所有友盟业务SDK都必须调用此初始化接口。
//建议在宿主App的Application.onCreate函数中调用基础组件库初始化函数。
UMConfigure.init(this, "5f217c02b4b08b653e8f6b3d", getChannelName(this), UMConfigure.DEVICE_TYPE_PHONE, "");
// 选用LEGACY_AUTO页面采集模式
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.LEGACY_MANUAL);
//pro close log
UMConfigure.setLogEnabled(true);
Log.i(TAG, "uminit");
Intent intent = new Intent(this, FrontService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent);
} else {
startService(intent);
}
SendHistory.init(this);
SettingUtil.init(this);
}
}

@ -0,0 +1,272 @@
package com.idormy.sms.forwarder;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* listview
*/
public class ReFlashListView extends ListView implements AbsListView.OnScrollListener {
private static final String TAG = "ReFlashListView";
final int NONE = 0;// 正常状态;
final int PULL = 1;// 提示下拉状态;
final int RELESE = 2;// 提示释放状态;
final int REFLASHING = 3;// 刷新状态;
View header;// 顶部布局文件;
int headerHeight;// 顶部布局文件的高度;
int firstVisibleItem;// 当前第一个可见的item的位置
int scrollState;// listview 当前滚动状态;
boolean isRemark;// 标记当前是在listview最顶端摁下的
int startY;// 摁下时的Y值
int state;// 当前的状态;
IReflashListener iReflashListener;//刷新数据的接口
public ReFlashListView(Context context) {
super(context);
// TODO Auto-generated constructor stub
initView(context);
}
public ReFlashListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
initView(context);
}
public ReFlashListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
initView(context);
}
/**
* listview
*
* @param context
*/
private void initView(Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
header = inflater.inflate(R.layout.header_layout, null);
measureView(header);
headerHeight = header.getMeasuredHeight();
Log.i("tag", "headerHeight = " + headerHeight);
topPadding(-headerHeight);
this.addHeaderView(header);
this.setOnScrollListener(this);
}
/**
*
*
* @param view
*/
private void measureView(View view) {
ViewGroup.LayoutParams p = view.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int width = ViewGroup.getChildMeasureSpec(0, 0, p.width);
int height;
int tempHeight = p.height;
if (tempHeight > 0) {
height = MeasureSpec.makeMeasureSpec(tempHeight,
MeasureSpec.EXACTLY);
} else {
height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
view.measure(width, height);
}
/**
* header
*
* @param topPadding
*/
private void topPadding(int topPadding) {
header.setPadding(header.getPaddingLeft(), topPadding,
header.getPaddingRight(), header.getPaddingBottom());
header.invalidate();
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
this.firstVisibleItem = firstVisibleItem;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
this.scrollState = scrollState;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (firstVisibleItem == 0) {
isRemark = true;
startY = (int) ev.getY();
}
break;
case MotionEvent.ACTION_MOVE:
onMove(ev);
break;
case MotionEvent.ACTION_UP:
if (state == RELESE || state == PULL) {
state = REFLASHING;
// 加载最新数据;
reflashViewByState();
iReflashListener.onReflash();
}
// if (state == RELESE) {
// Log.d(TAG, "onTouchEvent: up release");
// state = REFLASHING;
// // 加载最新数据;
// reflashViewByState();
// iReflashListener.onReflash();
// } else if (state == PULL) {
// Log.d(TAG, "onTouchEvent: up pull");
// state = NONE;
// isRemark = false;
// reflashViewByState();
// }
break;
}
return super.onTouchEvent(ev);
}
/**
*
*
* @param ev
*/
private void onMove(MotionEvent ev) {
if (!isRemark) {
return;
}
int tempY = (int) ev.getY();
int space = tempY - startY;
int topPadding = space - headerHeight;
switch (state) {
case NONE:
if (space > 0) {
state = PULL;
reflashViewByState();
}
break;
case PULL:
topPadding(topPadding);
if (space > headerHeight + 30
&& scrollState == SCROLL_STATE_TOUCH_SCROLL) {
state = RELESE;
reflashViewByState();
}
break;
case RELESE:
topPadding(topPadding);
if (space < headerHeight + 30) {
state = PULL;
reflashViewByState();
} else if (space <= 0) {
state = NONE;
isRemark = false;
reflashViewByState();
}
break;
}
}
/**
*
*/
private void reflashViewByState() {
TextView tip = (TextView) header.findViewById(R.id.tip);
ImageView arrow = (ImageView) header.findViewById(R.id.arrow);
ProgressBar progress = (ProgressBar) header.findViewById(R.id.progress);
RotateAnimation anim = new RotateAnimation(0, 180,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
anim.setDuration(500);
anim.setFillAfter(true);
RotateAnimation anim1 = new RotateAnimation(180, 0,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
anim1.setDuration(500);
anim1.setFillAfter(true);
switch (state) {
case NONE:
arrow.clearAnimation();
topPadding(-headerHeight);
break;
case PULL:
arrow.setVisibility(View.VISIBLE);
progress.setVisibility(View.GONE);
tip.setText("下拉可以刷新!");
arrow.clearAnimation();
arrow.setAnimation(anim1);
break;
case RELESE:
arrow.setVisibility(View.VISIBLE);
progress.setVisibility(View.GONE);
tip.setText("松开可以刷新!");
arrow.clearAnimation();
arrow.setAnimation(anim);
break;
case REFLASHING:
topPadding(50);
arrow.setVisibility(View.GONE);
progress.setVisibility(View.VISIBLE);
tip.setText("正在刷新...");
arrow.clearAnimation();
break;
}
}
/**
*
*/
public void reflashComplete() {
state = NONE;
isRemark = false;
reflashViewByState();
TextView lastupdatetime = (TextView) header
.findViewById(R.id.lastupdate_time);
SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
Date date = new Date(System.currentTimeMillis());
String time = format.format(date);
lastupdatetime.setText(time);
}
public void setInterface(IReflashListener iReflashListener) {
this.iReflashListener = iReflashListener;
}
/**
*
*
* @author Administrator
*/
public interface IReflashListener {
public void onReflash();
}
}

@ -0,0 +1,201 @@
package com.idormy.sms.forwarder;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.idormy.sms.forwarder.adapter.RuleAdapter;
import com.idormy.sms.forwarder.model.RuleModel;
import com.idormy.sms.forwarder.model.SenderModel;
import com.idormy.sms.forwarder.utils.RuleUtil;
import com.idormy.sms.forwarder.utils.SenderUtil;
import com.umeng.analytics.MobclickAgent;
import java.util.ArrayList;
import java.util.List;
public class RuleActivity extends AppCompatActivity {
private String TAG = "RuleActivity";
// 用于存储数据
private List<RuleModel> ruleModels = new ArrayList<>();
private RuleAdapter adapter;
private Long selectSenderId = 0l;
private String selectSenderName = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "oncreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sender);
RuleUtil.init(RuleActivity.this);
SenderUtil.init(RuleActivity.this);
// 先拿到数据并放在适配器上
initRules(); //初始化数据
adapter = new RuleAdapter(RuleActivity.this, R.layout.rule_item, ruleModels);
// 将适配器上的数据传递给listView
ListView listView = findViewById(R.id.list_view_sender);
listView.setAdapter(adapter);
// 为ListView注册一个监听器当用户点击了ListView中的任何一个子项时就会回调onItemClick()方法
// 在这个方法中可以通过position参数判断出用户点击的是那一个子项
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
RuleModel ruleModel = ruleModels.get(position);
Log.d(TAG, "onItemClick: " + ruleModel);
setRule(ruleModel);
}
});
}
// 初始化数据
private void initRules() {
ruleModels = RuleUtil.getRule(null, null);
}
public void addSender(View view) {
setRule(null);
}
private void setRule(final RuleModel ruleModel) {
final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(RuleActivity.this);
final View view1 = View.inflate(RuleActivity.this, R.layout.activity_alter_dialog_setview_rule, null);
final RadioGroup radioGroupRuleFiled = (RadioGroup) view1.findViewById(R.id.radioGroupRuleFiled);
if (ruleModel != null) radioGroupRuleFiled.check(ruleModel.getRuleFiledCheckId());
final RadioGroup radioGroupRuleCheck = (RadioGroup) view1.findViewById(R.id.radioGroupRuleCheck);
if (ruleModel != null) radioGroupRuleCheck.check(ruleModel.getRuleCheckCheckId());
final TextView ruleSenderTv = (TextView) view1.findViewById(R.id.ruleSenderTv);
if (ruleModel != null && ruleModel.getSenderId() != null) {
List<SenderModel> getSeners = SenderUtil.getSender(ruleModel.getSenderId(), null);
if (!getSeners.isEmpty()) {
ruleSenderTv.setText(getSeners.get(0).getName());
ruleSenderTv.setTag(getSeners.get(0).getId());
}
}
final Button btSetRuleSender = (Button) view1.findViewById(R.id.btSetRuleSender);
btSetRuleSender.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(RuleActivity.this, "selectSender", Toast.LENGTH_LONG).show();
selectSender(ruleSenderTv);
}
});
final EditText editTextRuleValue = view1.findViewById(R.id.editTextRuleValue);
if (ruleModel != null)
editTextRuleValue.setText(ruleModel.getValue());
Button buttonruleok = view1.findViewById(R.id.buttonruleok);
Button buttonruledel = view1.findViewById(R.id.buttonruledel);
alertDialog71
.setTitle(R.string.setrule)
.setView(view1)
.create();
final AlertDialog show = alertDialog71.show();
buttonruleok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Object senderId = ruleSenderTv.getTag();
if (ruleModel == null) {
RuleModel newRuleModel = new RuleModel();
newRuleModel.setFiled(RuleModel.getRuleFiledFromCheckId(radioGroupRuleFiled.getCheckedRadioButtonId()));
newRuleModel.setCheck(RuleModel.getRuleCheckFromCheckId(radioGroupRuleCheck.getCheckedRadioButtonId()));
newRuleModel.setValue(editTextRuleValue.getText().toString());
if (senderId != null) {
newRuleModel.setSenderId(Long.valueOf(senderId.toString()));
}
RuleUtil.addRule(newRuleModel);
initRules();
adapter.add(ruleModels);
} else {
ruleModel.setFiled(RuleModel.getRuleFiledFromCheckId(radioGroupRuleFiled.getCheckedRadioButtonId()));
ruleModel.setCheck(RuleModel.getRuleCheckFromCheckId(radioGroupRuleCheck.getCheckedRadioButtonId()));
ruleModel.setValue(editTextRuleValue.getText().toString());
if (senderId != null) {
ruleModel.setSenderId(Long.valueOf(senderId.toString()));
}
RuleUtil.updateRule(ruleModel);
initRules();
adapter.update(ruleModels);
}
show.dismiss();
}
});
buttonruledel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (ruleModel != null) {
RuleUtil.delRule(ruleModel.getId());
initRules();
adapter.del(ruleModels);
}
show.dismiss();
}
});
}
public void selectSender(final TextView showTv) {
final List<SenderModel> senderModels = SenderUtil.getSender(null, null);
if (senderModels.isEmpty()) {
Toast.makeText(RuleActivity.this, "请先去设置发送方页面添加", Toast.LENGTH_SHORT).show();
return;
}
final CharSequence[] senderNames = new CharSequence[senderModels.size()];
for (int i = 0; i < senderModels.size(); i++) {
senderNames[i] = senderModels.get(i).getName();
}
AlertDialog.Builder builder = new AlertDialog.Builder(RuleActivity.this);
builder.setTitle("选择发送方");
builder.setItems(senderNames, new DialogInterface.OnClickListener() {//添加列表
@Override
public void onClick(DialogInterface dialogInterface, int which) {
Toast.makeText(RuleActivity.this, senderNames[which], Toast.LENGTH_LONG).show();
showTv.setText(senderNames[which]);
showTv.setTag(senderModels.get(which).getId());
}
});
builder.show();
}
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
MobclickAgent.onResume(this);
}
@Override
protected void onPause() {
super.onPause();
MobclickAgent.onPause(this);
}
}

@ -0,0 +1,681 @@
package com.idormy.sms.forwarder;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Switch;
import android.widget.Toast;
import com.alibaba.fastjson.JSON;
import com.idormy.sms.forwarder.adapter.SenderAdapter;
import com.idormy.sms.forwarder.model.SenderModel;
import com.idormy.sms.forwarder.model.vo.BarkSettingVo;
import com.idormy.sms.forwarder.model.vo.DingDingSettingVo;
import com.idormy.sms.forwarder.model.vo.EmailSettingVo;
import com.idormy.sms.forwarder.model.vo.QYWXGroupRobotSettingVo;
import com.idormy.sms.forwarder.model.vo.WebNotifySettingVo;
import com.idormy.sms.forwarder.utils.SenderBarkMsg;
import com.idormy.sms.forwarder.utils.SenderDingdingMsg;
import com.idormy.sms.forwarder.utils.SenderMailMsg;
import com.idormy.sms.forwarder.utils.SenderQyWxGroupRobotMsg;
import com.idormy.sms.forwarder.utils.SenderUtil;
import com.idormy.sms.forwarder.utils.SenderWebNotifyMsg;
import com.umeng.analytics.MobclickAgent;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static com.idormy.sms.forwarder.model.SenderModel.STATUS_ON;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_BARK;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_DINGDING;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_EMAIL;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_QYWX_GROUP_ROBOT;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_WEB_NOTIFY;
public class SenderActivity extends AppCompatActivity {
public static final int NOTIFY = 0x9731993;
private String TAG = "SenderActivity";
// 用于存储数据
private List<SenderModel> senderModels = new ArrayList<>();
private SenderAdapter adapter;
//消息处理者,创建一个Handler的子类对象,目的是重写Handler的处理消息的方法(handleMessage())
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case NOTIFY:
Toast.makeText(SenderActivity.this, msg.getData().getString("DATA"), Toast.LENGTH_LONG).show();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "oncreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sender);
SenderUtil.init(SenderActivity.this);
// 先拿到数据并放在适配器上
initSenders(); //初始化数据
adapter = new SenderAdapter(SenderActivity.this, R.layout.sender_item, senderModels);
// 将适配器上的数据传递给listView
ListView listView = findViewById(R.id.list_view_sender);
listView.setAdapter(adapter);
// 为ListView注册一个监听器当用户点击了ListView中的任何一个子项时就会回调onItemClick()方法
// 在这个方法中可以通过position参数判断出用户点击的是那一个子项
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SenderModel senderModel = senderModels.get(position);
Log.d(TAG, "onItemClick: " + senderModel);
switch (senderModel.getType()) {
case TYPE_DINGDING:
setDingDing(senderModel);
break;
case TYPE_EMAIL:
setEmail(senderModel);
break;
case TYPE_WEB_NOTIFY:
setWebNotify(senderModel);
break;
case TYPE_QYWX_GROUP_ROBOT:
setQYWXGroupRobot(senderModel);
break;
case TYPE_BARK:
setBark(senderModel);
break;
default:
Toast.makeText(SenderActivity.this, "异常的发送方类型!删除", Toast.LENGTH_LONG).show();
break;
}
}
});
}
// 初始化数据
private void initSenders() {
senderModels = SenderUtil.getSender(null, null);
;
}
public void addSender(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(SenderActivity.this);
builder.setTitle("选择发送方类型");
builder.setItems(R.array.add_sender_menu, new DialogInterface.OnClickListener() {//添加列表
@Override
public void onClick(DialogInterface dialogInterface, int which) {
switch (which) {
case TYPE_DINGDING:
setDingDing(null);
break;
case TYPE_EMAIL:
setEmail(null);
break;
case TYPE_WEB_NOTIFY:
setWebNotify(null);
break;
case TYPE_QYWX_GROUP_ROBOT:
setQYWXGroupRobot(null);
break;
case TYPE_BARK:
setBark(null);
break;
default:
Toast.makeText(SenderActivity.this, "暂不支持这种转发!", Toast.LENGTH_LONG).show();
break;
}
}
});
builder.show();
Log.d(TAG, "setDingDing show" + senderModels.size());
}
private void setDingDing(final SenderModel senderModel) {
DingDingSettingVo dingDingSettingVo = null;
//try phrase json setting
if (senderModel != null) {
String jsonSettingStr = senderModel.getJsonSetting();
if (jsonSettingStr != null) {
dingDingSettingVo = JSON.parseObject(jsonSettingStr, DingDingSettingVo.class);
}
}
final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(SenderActivity.this);
View view1 = View.inflate(SenderActivity.this, R.layout.activity_alter_dialog_setview_dingding, null);
final EditText editTextDingdingName = view1.findViewById(R.id.editTextDingdingName);
if (senderModel != null)
editTextDingdingName.setText(senderModel.getName());
final EditText editTextDingdingToken = view1.findViewById(R.id.editTextDingdingToken);
if (dingDingSettingVo != null)
editTextDingdingToken.setText(dingDingSettingVo.getToken());
final EditText editTextDingdingSecret = view1.findViewById(R.id.editTextDingdingSecret);
if (dingDingSettingVo != null)
editTextDingdingSecret.setText(dingDingSettingVo.getSecret());
final EditText editTextDingdingAtMobiles = view1.findViewById(R.id.editTextDingdingAtMobiles);
if (dingDingSettingVo != null && dingDingSettingVo.getAtMobils() != null)
editTextDingdingAtMobiles.setText(dingDingSettingVo.getAtMobils());
final Switch switchDingdingAtAll = view1.findViewById(R.id.switchDingdingAtAll);
if (dingDingSettingVo != null && dingDingSettingVo.getAtAll() != null)
switchDingdingAtAll.setChecked(dingDingSettingVo.getAtAll());
Button buttondingdingok = view1.findViewById(R.id.buttondingdingok);
Button buttondingdingdel = view1.findViewById(R.id.buttondingdingdel);
Button buttondingdingtest = view1.findViewById(R.id.buttondingdingtest);
alertDialog71
.setTitle(R.string.setdingdingtitle)
.setIcon(R.mipmap.dingding)
.setView(view1)
.create();
final AlertDialog show = alertDialog71.show();
buttondingdingok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (senderModel == null) {
SenderModel newSenderModel = new SenderModel();
newSenderModel.setName(editTextDingdingName.getText().toString());
newSenderModel.setType(TYPE_DINGDING);
newSenderModel.setStatus(STATUS_ON);
DingDingSettingVo dingDingSettingVonew = new DingDingSettingVo(
editTextDingdingToken.getText().toString(),
editTextDingdingSecret.getText().toString(),
editTextDingdingAtMobiles.getText().toString(),
switchDingdingAtAll.isChecked());
newSenderModel.setJsonSetting(JSON.toJSONString(dingDingSettingVonew));
SenderUtil.addSender(newSenderModel);
initSenders();
adapter.add(senderModels);
// adapter.add(newSenderModel);
} else {
senderModel.setName(editTextDingdingName.getText().toString());
senderModel.setType(TYPE_DINGDING);
senderModel.setStatus(STATUS_ON);
DingDingSettingVo dingDingSettingVonew = new DingDingSettingVo(
editTextDingdingToken.getText().toString(),
editTextDingdingSecret.getText().toString(),
editTextDingdingAtMobiles.getText().toString(),
switchDingdingAtAll.isChecked());
senderModel.setJsonSetting(JSON.toJSONString(dingDingSettingVonew));
SenderUtil.updateSender(senderModel);
initSenders();
adapter.update(senderModels);
// adapter.update(senderModel,position);
}
show.dismiss();
}
});
buttondingdingdel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (senderModel != null) {
SenderUtil.delSender(senderModel.getId());
initSenders();
adapter.del(senderModels);
// adapter.del(position);
}
show.dismiss();
}
});
buttondingdingtest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String token = editTextDingdingToken.getText().toString();
String secret = editTextDingdingSecret.getText().toString();
String atMobiles = editTextDingdingAtMobiles.getText().toString();
Boolean atAll = switchDingdingAtAll.isChecked();
if (token != null && !token.isEmpty()) {
try {
SenderDingdingMsg.sendMsg(handler, token, secret, atMobiles, atAll, "测试内容(content)@" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
} catch (Exception e) {
Toast.makeText(SenderActivity.this, "发送失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
} else {
Toast.makeText(SenderActivity.this, "token 不能为空", Toast.LENGTH_LONG).show();
}
}
});
}
private void setEmail(final SenderModel senderModel) {
EmailSettingVo emailSettingVo = null;
//try phrase json setting
if (senderModel != null) {
String jsonSettingStr = senderModel.getJsonSetting();
if (jsonSettingStr != null) {
emailSettingVo = JSON.parseObject(jsonSettingStr, EmailSettingVo.class);
}
}
final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(SenderActivity.this);
View view1 = View.inflate(SenderActivity.this, R.layout.activity_alter_dialog_setview_email, null);
final EditText editTextEmailName = view1.findViewById(R.id.editTextEmailName);
if (senderModel != null) editTextEmailName.setText(senderModel.getName());
final EditText editTextEmailHost = view1.findViewById(R.id.editTextEmailHost);
if (emailSettingVo != null) editTextEmailHost.setText(emailSettingVo.getHost());
final EditText editTextEmailPort = view1.findViewById(R.id.editTextEmailPort);
if (emailSettingVo != null) editTextEmailPort.setText(emailSettingVo.getPort());
final Switch switchEmailSSl = view1.findViewById(R.id.switchEmailSSl);
if (emailSettingVo != null) switchEmailSSl.setChecked(emailSettingVo.getSsl());
final EditText editTextEmailFromAdd = view1.findViewById(R.id.editTextEmailFromAdd);
if (emailSettingVo != null) editTextEmailFromAdd.setText(emailSettingVo.getFromEmail());
final EditText editTextEmailPsw = view1.findViewById(R.id.editTextEmailPsw);
if (emailSettingVo != null) editTextEmailPsw.setText(emailSettingVo.getPwd());
final EditText editTextEmailToAdd = view1.findViewById(R.id.editTextEmailToAdd);
if (emailSettingVo != null) editTextEmailToAdd.setText(emailSettingVo.getToEmail());
Button buttonemailok = view1.findViewById(R.id.buttonemailok);
Button buttonemaildel = view1.findViewById(R.id.buttonemaildel);
Button buttonemailtest = view1.findViewById(R.id.buttonemailtest);
alertDialog71
.setTitle(R.string.setemailtitle)
.setIcon(R.drawable.ic_baseline_email_24)
.setView(view1)
.create();
final AlertDialog show = alertDialog71.show();
buttonemailok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (senderModel == null) {
SenderModel newSenderModel = new SenderModel();
newSenderModel.setName(editTextEmailName.getText().toString());
newSenderModel.setType(TYPE_EMAIL);
newSenderModel.setStatus(STATUS_ON);
EmailSettingVo emailSettingVonew = new EmailSettingVo(
editTextEmailHost.getText().toString(),
editTextEmailPort.getText().toString(),
switchEmailSSl.isChecked(),
editTextEmailFromAdd.getText().toString(),
editTextEmailPsw.getText().toString(),
editTextEmailToAdd.getText().toString()
);
newSenderModel.setJsonSetting(JSON.toJSONString(emailSettingVonew));
SenderUtil.addSender(newSenderModel);
initSenders();
adapter.add(senderModels);
} else {
senderModel.setName(editTextEmailName.getText().toString());
senderModel.setType(TYPE_EMAIL);
senderModel.setStatus(STATUS_ON);
EmailSettingVo emailSettingVonew = new EmailSettingVo(
editTextEmailHost.getText().toString(),
editTextEmailPort.getText().toString(),
switchEmailSSl.isChecked(),
editTextEmailFromAdd.getText().toString(),
editTextEmailPsw.getText().toString(),
editTextEmailToAdd.getText().toString()
);
senderModel.setJsonSetting(JSON.toJSONString(emailSettingVonew));
SenderUtil.updateSender(senderModel);
initSenders();
adapter.update(senderModels);
}
show.dismiss();
}
});
buttonemaildel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (senderModel != null) {
SenderUtil.delSender(senderModel.getId());
initSenders();
adapter.del(senderModels);
}
show.dismiss();
}
});
buttonemailtest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String host = editTextEmailHost.getText().toString();
String port = editTextEmailPort.getText().toString();
Boolean ssl = switchEmailSSl.isChecked();
String fromemail = editTextEmailFromAdd.getText().toString();
String pwd = editTextEmailPsw.getText().toString();
String toemail = editTextEmailToAdd.getText().toString();
if (!host.isEmpty() && !port.isEmpty() && !fromemail.isEmpty() && !pwd.isEmpty() && !toemail.isEmpty()) {
try {
SenderMailMsg.sendEmail(handler, host, port, ssl, fromemail, pwd, toemail, "SmsForwarder Title", "测试内容(content)@" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
} catch (Exception e) {
Toast.makeText(SenderActivity.this, "发送失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
} else {
Toast.makeText(SenderActivity.this, "token 不能为空", Toast.LENGTH_LONG).show();
}
}
});
}
private void setWebNotify(final SenderModel senderModel) {
WebNotifySettingVo webNotifySettingVo = null;
//try phrase json setting
if (senderModel != null) {
String jsonSettingStr = senderModel.getJsonSetting();
if (jsonSettingStr != null) {
webNotifySettingVo = JSON.parseObject(jsonSettingStr, WebNotifySettingVo.class);
}
}
final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(SenderActivity.this);
View view1 = View.inflate(SenderActivity.this, R.layout.activity_alter_dialog_setview_webnotify, null);
final EditText editTextWebNotifyName = view1.findViewById(R.id.editTextWebNotifyName);
if (senderModel != null) editTextWebNotifyName.setText(senderModel.getName());
final EditText editTextWebNotifyToken = view1.findViewById(R.id.editTextWebNotifyToken);
if (webNotifySettingVo != null)
editTextWebNotifyToken.setText(webNotifySettingVo.getToken());
final EditText editTextWebNotifySecret = view1.findViewById(R.id.editTextWebNotifySecret);
if (webNotifySettingVo != null)
editTextWebNotifySecret.setText(webNotifySettingVo.getSecret());
Button buttonbebnotifyok = view1.findViewById(R.id.buttonbebnotifyok);
Button buttonbebnotifydel = view1.findViewById(R.id.buttonbebnotifydel);
Button buttonbebnotifytest = view1.findViewById(R.id.buttonbebnotifytest);
alertDialog71
.setTitle(R.string.setwebnotifytitle)
.setIcon(R.mipmap.ic_launcher)
.setView(view1)
.create();
final AlertDialog show = alertDialog71.show();
buttonbebnotifyok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (senderModel == null) {
SenderModel newSenderModel = new SenderModel();
newSenderModel.setName(editTextWebNotifyName.getText().toString());
newSenderModel.setType(TYPE_WEB_NOTIFY);
newSenderModel.setStatus(STATUS_ON);
WebNotifySettingVo webNotifySettingVoNew = new WebNotifySettingVo(
editTextWebNotifyToken.getText().toString(),
editTextWebNotifySecret.getText().toString()
);
newSenderModel.setJsonSetting(JSON.toJSONString(webNotifySettingVoNew));
SenderUtil.addSender(newSenderModel);
initSenders();
adapter.add(senderModels);
} else {
senderModel.setName(editTextWebNotifyName.getText().toString());
senderModel.setType(TYPE_WEB_NOTIFY);
senderModel.setStatus(STATUS_ON);
WebNotifySettingVo webNotifySettingVoNew = new WebNotifySettingVo(
editTextWebNotifyToken.getText().toString(),
editTextWebNotifySecret.getText().toString()
);
senderModel.setJsonSetting(JSON.toJSONString(webNotifySettingVoNew));
SenderUtil.updateSender(senderModel);
initSenders();
adapter.update(senderModels);
}
show.dismiss();
}
});
buttonbebnotifydel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (senderModel != null) {
SenderUtil.delSender(senderModel.getId());
initSenders();
adapter.del(senderModels);
}
show.dismiss();
}
});
buttonbebnotifytest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String token = editTextWebNotifyToken.getText().toString();
String secret = editTextWebNotifySecret.getText().toString();
if (!token.isEmpty()) {
try {
SenderWebNotifyMsg.sendMsg(handler, token, secret, "SmsForwarder Title", "测试内容(content)@" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
} catch (Exception e) {
Toast.makeText(SenderActivity.this, "发送失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
} else {
Toast.makeText(SenderActivity.this, "token 不能为空", Toast.LENGTH_LONG).show();
}
}
});
}
private void setQYWXGroupRobot(final SenderModel senderModel) {
QYWXGroupRobotSettingVo qywxGroupRobotSettingVo = null;
//try phrase json setting
if (senderModel != null) {
String jsonSettingStr = senderModel.getJsonSetting();
if (jsonSettingStr != null) {
qywxGroupRobotSettingVo = JSON.parseObject(jsonSettingStr, QYWXGroupRobotSettingVo.class);
}
}
final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(SenderActivity.this);
View view1 = View.inflate(SenderActivity.this, R.layout.activity_alter_dialog_setview_qywxgrouprobot, null);
final EditText editTextQYWXGroupRobotName = view1.findViewById(R.id.editTextQYWXGroupRobotName);
if (senderModel != null) editTextQYWXGroupRobotName.setText(senderModel.getName());
final EditText editTextQYWXGroupRobotWebHook = view1.findViewById(R.id.editTextQYWXGroupRobotWebHook);
if (qywxGroupRobotSettingVo != null)
editTextQYWXGroupRobotWebHook.setText(qywxGroupRobotSettingVo.getWebHook());
Button buttonQyWxGroupRobotOk = view1.findViewById(R.id.buttonQyWxGroupRobotOk);
Button buttonQyWxGroupRobotDel = view1.findViewById(R.id.buttonQyWxGroupRobotDel);
Button buttonQyWxGroupRobotTest = view1.findViewById(R.id.buttonQyWxGroupRobotTest);
alertDialog71
.setTitle(R.string.setqywxgrouprobottitle)
.setIcon(R.mipmap.ic_launcher)
.setView(view1)
.create();
final AlertDialog show = alertDialog71.show();
buttonQyWxGroupRobotOk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (senderModel == null) {
SenderModel newSenderModel = new SenderModel();
newSenderModel.setName(editTextQYWXGroupRobotName.getText().toString());
newSenderModel.setType(TYPE_QYWX_GROUP_ROBOT);
newSenderModel.setStatus(STATUS_ON);
QYWXGroupRobotSettingVo qywxGroupRobotSettingVoNew = new QYWXGroupRobotSettingVo(
editTextQYWXGroupRobotWebHook.getText().toString()
);
newSenderModel.setJsonSetting(JSON.toJSONString(qywxGroupRobotSettingVoNew));
SenderUtil.addSender(newSenderModel);
initSenders();
adapter.add(senderModels);
} else {
senderModel.setName(editTextQYWXGroupRobotName.getText().toString());
senderModel.setType(TYPE_QYWX_GROUP_ROBOT);
senderModel.setStatus(STATUS_ON);
QYWXGroupRobotSettingVo qywxGroupRobotSettingVoNew = new QYWXGroupRobotSettingVo(
editTextQYWXGroupRobotWebHook.getText().toString()
);
senderModel.setJsonSetting(JSON.toJSONString(qywxGroupRobotSettingVoNew));
SenderUtil.updateSender(senderModel);
initSenders();
adapter.update(senderModels);
}
show.dismiss();
}
});
buttonQyWxGroupRobotDel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (senderModel != null) {
SenderUtil.delSender(senderModel.getId());
initSenders();
adapter.del(senderModels);
}
show.dismiss();
}
});
buttonQyWxGroupRobotTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String webHook = editTextQYWXGroupRobotWebHook.getText().toString();
if (!webHook.isEmpty()) {
try {
SenderQyWxGroupRobotMsg.sendMsg(handler, webHook, "SmsForwarder Title", "测试内容(content)@" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
} catch (Exception e) {
Toast.makeText(SenderActivity.this, "发送失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
} else {
Toast.makeText(SenderActivity.this, "webHook 不能为空", Toast.LENGTH_LONG).show();
}
}
});
}
private void setBark(final SenderModel senderModel) {
BarkSettingVo barkSettingVo = null;
//try phrase json setting
if (senderModel != null) {
String jsonSettingStr = senderModel.getJsonSetting();
if (jsonSettingStr != null) {
barkSettingVo = JSON.parseObject(jsonSettingStr, BarkSettingVo.class);
}
}
final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(SenderActivity.this);
View view1 = View.inflate(SenderActivity.this, R.layout.activity_alter_dialog_setview_bark, null);
final EditText editTextBarkName = view1.findViewById(R.id.editTextBarkName);
if (senderModel != null) editTextBarkName.setText(senderModel.getName());
final EditText editTextBarkServer = view1.findViewById(R.id.editTextBarkServer);
if (barkSettingVo != null) editTextBarkServer.setText(barkSettingVo.getServer());
Button buttonBarkOk = view1.findViewById(R.id.buttonBarkOk);
Button buttonBarkDel = view1.findViewById(R.id.buttonBarkDel);
Button buttonBarkTest = view1.findViewById(R.id.buttonBarkTest);
alertDialog71
.setTitle(R.string.setbarktitle)
.setIcon(R.mipmap.ic_launcher)
.setView(view1)
.create();
final AlertDialog show = alertDialog71.show();
buttonBarkOk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (senderModel == null) {
SenderModel newSenderModel = new SenderModel();
newSenderModel.setName(editTextBarkName.getText().toString());
newSenderModel.setType(TYPE_BARK);
newSenderModel.setStatus(STATUS_ON);
BarkSettingVo barkSettingVoNew = new BarkSettingVo(
editTextBarkServer.getText().toString()
);
newSenderModel.setJsonSetting(JSON.toJSONString(barkSettingVoNew));
SenderUtil.addSender(newSenderModel);
initSenders();
adapter.add(senderModels);
} else {
senderModel.setName(editTextBarkName.getText().toString());
senderModel.setType(TYPE_BARK);
senderModel.setStatus(STATUS_ON);
BarkSettingVo barkSettingVoNew = new BarkSettingVo(
editTextBarkServer.getText().toString()
);
senderModel.setJsonSetting(JSON.toJSONString(barkSettingVoNew));
SenderUtil.updateSender(senderModel);
initSenders();
adapter.update(senderModels);
}
show.dismiss();
}
});
buttonBarkDel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (senderModel != null) {
SenderUtil.delSender(senderModel.getId());
initSenders();
adapter.del(senderModels);
}
show.dismiss();
}
});
buttonBarkTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String barkServer = editTextBarkServer.getText().toString();
if (!barkServer.isEmpty()) {
try {
SenderBarkMsg.sendMsg(handler, barkServer, "信息来源", "【京东】验证码为387481切勿将验证码告知他人请在页面中输入完成验证如有问题请点击 ihelp.jd.com 联系京东客服");
} catch (Exception e) {
Toast.makeText(SenderActivity.this, "发送失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
} else {
Toast.makeText(SenderActivity.this, "bark-server 不能为空", Toast.LENGTH_LONG).show();
}
}
});
}
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
MobclickAgent.onResume(this);
}
@Override
protected void onPause() {
super.onPause();
MobclickAgent.onPause(this);
}
}

@ -0,0 +1,185 @@
package com.idormy.sms.forwarder;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.idormy.sms.forwarder.BroadCastReceiver.RebootBroadcastReceiver;
import com.idormy.sms.forwarder.model.vo.FeedBackResult;
import com.idormy.sms.forwarder.utils.HttpI;
import com.idormy.sms.forwarder.utils.HttpUtil;
import com.idormy.sms.forwarder.utils.UpdateAppHttpUtil;
import com.idormy.sms.forwarder.utils.aUtil;
import com.vector.update_app.UpdateAppManager;
import com.vector.update_app.UpdateCallback;
import com.vector.update_app.listener.ExceptionHandler;
import java.util.HashMap;
import java.util.Map;
public class SettingActivity extends AppCompatActivity {
private String TAG = "SettingActivity";
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "oncreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
Log.d(TAG, "onCreate: " + RebootBroadcastReceiver.class.getName());
Switch check_with_reboot = (Switch) findViewById(R.id.switch_with_reboot);
checkWithReboot(check_with_reboot);
TextView version_now = (TextView) findViewById(R.id.version_now);
Button check_version_now = (Button) findViewById(R.id.check_version_now);
try {
version_now.setText(aUtil.getVersionName(SettingActivity.this));
} catch (Exception e) {
e.printStackTrace();
}
check_version_now.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkNewVersion();
}
});
}
//检查重启广播接受器状态并设置
private void checkWithReboot(Switch withrebootSwitch) {
//获取组件
final ComponentName cm = new ComponentName(this.getPackageName(), RebootBroadcastReceiver.class.getName());
final PackageManager pm = getPackageManager();
int state = pm.getComponentEnabledSetting(cm);
if (state != PackageManager.COMPONENT_ENABLED_STATE_DISABLED
&& state != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
withrebootSwitch.setChecked(true);
} else {
withrebootSwitch.setChecked(false);
}
withrebootSwitch.setOnCheckedChangeListener(new Switch.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int newState = (Boolean) isChecked ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
pm.setComponentEnabledSetting(cm, newState, PackageManager.DONT_KILL_APP);
Log.d(TAG, "onCheckedChanged:" + isChecked);
}
});
}
private void checkNewVersion() {
String geturl = "http://api.allmything.com/api/version/hasnew?versioncode=";
try {
geturl += aUtil.getVersionCode(SettingActivity.this);
Log.i("SettingActivity", geturl);
new UpdateAppManager
.Builder()
//当前Activity
.setActivity(SettingActivity.this)
//更新地址
.setUpdateUrl(geturl)
//全局异常捕获
.handleException(new ExceptionHandler() {
@Override
public void onException(Exception e) {
Log.e(TAG, "onException: ", e);
Toast.makeText(SettingActivity.this, "更新失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
})
//实现httpManager接口的对象
.setHttpManager(new UpdateAppHttpUtil())
.build()
.checkNewApp(new UpdateCallback() {
/**
*
*/
protected void noNewApp(String error) {
Toast.makeText(SettingActivity.this, "没有新版本", Toast.LENGTH_SHORT).show();
}
});
// .update();
} catch (Exception e) {
e.printStackTrace();
}
}
public void feedbackcommit(View view) {
final AlertDialog.Builder builder = new AlertDialog.Builder(SettingActivity.this);
View view1 = View.inflate(SettingActivity.this, R.layout.dialog_feedback, null);
final EditText feedback_et_email = view1.findViewById(R.id.feedback_et_email);
final EditText feedback_et_text = view1.findViewById(R.id.feedback_et_text);
builder
.setTitle(R.string.feedback_input_text)
.setView(view1)
.create();
builder.setPositiveButton("提交反馈", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
Map<String, String> feedBackData = new HashMap<>();
feedBackData.put("email", feedback_et_email.getText().toString());
feedBackData.put("text", feedback_et_text.getText().toString());
new HttpUtil().asyncPost("https://api.sl.willanddo.com/api/tsms/feedBack", feedBackData, new HttpI.Callback() {
@Override
public void onResponse(String result) {
Log.i(TAG, "onResponse: " + result);
if (result != null) {
FeedBackResult feedBackResult = JSON.parseObject(result, FeedBackResult.class);
Log.i(TAG, "feedBackResult: " + feedBackResult);
if (feedBackResult != null) {
JSONObject feedBackResultObject = JSON.parseObject(result);
Toast.makeText(SettingActivity.this, feedBackResultObject.getString("message"), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(SettingActivity.this, "感谢您的反馈,我们将尽快处理!", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(SettingActivity.this, "感谢您的反馈,我们将尽快处理!", Toast.LENGTH_LONG).show();
}
}
@Override
public void onError(String error) {
Log.i(TAG, "onError: " + error);
Toast.makeText(SettingActivity.this, error, Toast.LENGTH_LONG).show();
}
});
} catch (Exception e) {
Toast.makeText(SettingActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
Log.d(TAG, "feedback e: " + e.getMessage());
}
}
}).show();
}
}

@ -0,0 +1,113 @@
package com.idormy.sms.forwarder.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.idormy.sms.forwarder.R;
import com.idormy.sms.forwarder.model.vo.LogVo;
import java.util.List;
public class LogAdapter extends ArrayAdapter<LogVo> {
private int resourceId;
private List<LogVo> list;
// 适配器的构造函数,把要适配的数据传入这里
public LogAdapter(Context context, int textViewResourceId, List<LogVo> objects) {
super(context, textViewResourceId, objects);
resourceId = textViewResourceId;
list = objects;
}
@Override
public int getCount() {
return list.size();
}
@Override
public LogVo getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
// convertView 参数用于将之前加载好的布局进行缓存
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LogVo logVo = getItem(position); //获取当前项的TLog实例
// 加个判断以免ListView每次滚动时都要重新加载布局以提高运行效率
View view;
ViewHolder viewHolder;
if (convertView == null) {
// 避免ListView每次滚动时都要重新加载布局以提高运行效率
view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
// 避免每次调用getView()时都要重新获取控件实例
viewHolder = new ViewHolder();
viewHolder.tLogFrom = view.findViewById(R.id.tlog_from);
viewHolder.tLogContent = view.findViewById(R.id.tlog_content);
viewHolder.tLogRule = view.findViewById(R.id.tlog_rule);
viewHolder.senderImage = view.findViewById(R.id.tlog_sender_image);
// 将ViewHolder存储在View中即将控件的实例存储在其中
view.setTag(viewHolder);
} else {
view = convertView;
viewHolder = (ViewHolder) view.getTag();
}
// 获取控件实例并调用set...方法使其显示出来
if (logVo != null) {
viewHolder.tLogFrom.setText(logVo.getFrom());
viewHolder.tLogContent.setText(logVo.getContent());
viewHolder.tLogRule.setText(logVo.getRule());
viewHolder.senderImage.setImageResource(logVo.getSenderImageId());
}
return view;
}
public void add(List<LogVo> logVos) {
if (list != null) {
list = logVos;
notifyDataSetChanged();
}
}
public void del(List<LogVo> logVos) {
if (list != null) {
list = logVos;
notifyDataSetChanged();
}
}
public void update(List<LogVo> logVos) {
if (list != null) {
list = logVos;
notifyDataSetChanged();
}
}
public void onDateChange(List<LogVo> logVos) {
list = logVos;
notifyDataSetChanged();
}
// 定义一个内部类,用于对控件的实例进行缓存
class ViewHolder {
TextView tLogFrom;
TextView tLogContent;
TextView tLogRule;
ImageView senderImage;
}
}

@ -0,0 +1,115 @@
package com.idormy.sms.forwarder.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.idormy.sms.forwarder.R;
import com.idormy.sms.forwarder.model.RuleModel;
import com.idormy.sms.forwarder.model.SenderModel;
import com.idormy.sms.forwarder.utils.SenderUtil;
import java.util.List;
public class RuleAdapter extends ArrayAdapter<RuleModel> {
private int resourceId;
private List<RuleModel> list;
// 适配器的构造函数,把要适配的数据传入这里
public RuleAdapter(Context context, int textViewResourceId, List<RuleModel> objects) {
super(context, textViewResourceId, objects);
resourceId = textViewResourceId;
list = objects;
}
@Override
public int getCount() {
return list.size();
}
@Override
public RuleModel getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
RuleModel item = list.get(position);
if (item == null) {
return 0;
}
return item.getId();
}
// convertView 参数用于将之前加载好的布局进行缓存
@Override
public View getView(int position, View convertView, ViewGroup parent) {
RuleModel ruleModel = getItem(position); //获取当前项的TLog实例
// 加个判断以免ListView每次滚动时都要重新加载布局以提高运行效率
View view;
ViewHolder viewHolder;
if (convertView == null) {
// 避免ListView每次滚动时都要重新加载布局以提高运行效率
view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
// 避免每次调用getView()时都要重新获取控件实例
viewHolder = new ViewHolder();
viewHolder.ruleMatch = view.findViewById(R.id.rule_match);
viewHolder.ruleSender = view.findViewById(R.id.rule_sender);
// 将ViewHolder存储在View中即将控件的实例存储在其中
view.setTag(viewHolder);
} else {
view = convertView;
viewHolder = (ViewHolder) view.getTag();
}
// 获取控件实例并调用set...方法使其显示出来
if (ruleModel != null) {
List<SenderModel> senderModel = SenderUtil.getSender(ruleModel.getSenderId(), null);
viewHolder.ruleMatch.setText(ruleModel.getRuleMatch());
if (!senderModel.isEmpty()) {
viewHolder.ruleSender.setText(senderModel.get(0).getName());
} else {
viewHolder.ruleSender.setText("");
}
}
return view;
}
public void add(List<RuleModel> ruleModels) {
if (list != null) {
list = ruleModels;
notifyDataSetChanged();
}
}
public void del(List<RuleModel> ruleModels) {
if (list != null) {
list = ruleModels;
notifyDataSetChanged();
}
}
public void update(List<RuleModel> ruleModels) {
if (list != null) {
list = ruleModels;
notifyDataSetChanged();
}
}
// 定义一个内部类,用于对控件的实例进行缓存
class ViewHolder {
TextView ruleMatch;
TextView ruleSender;
}
}

@ -0,0 +1,128 @@
package com.idormy.sms.forwarder.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.idormy.sms.forwarder.R;
import com.idormy.sms.forwarder.model.SenderModel;
import java.util.List;
public class SenderAdapter extends ArrayAdapter<SenderModel> {
private int resourceId;
private List<SenderModel> list;
// 适配器的构造函数,把要适配的数据传入这里
public SenderAdapter(Context context, int textViewResourceId, List<SenderModel> objects) {
super(context, textViewResourceId, objects);
resourceId = textViewResourceId;
list = objects;
}
@Override
public int getCount() {
return list.size();
}
@Override
public SenderModel getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
SenderModel item = list.get(position);
if (item == null) {
return 0;
}
return item.getId();
}
// convertView 参数用于将之前加载好的布局进行缓存
@Override
public View getView(int position, View convertView, ViewGroup parent) {
SenderModel senderModel = getItem(position); //获取当前项的TLog实例
// 加个判断以免ListView每次滚动时都要重新加载布局以提高运行效率
View view;
ViewHolder viewHolder;
if (convertView == null) {
// 避免ListView每次滚动时都要重新加载布局以提高运行效率
view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
// 避免每次调用getView()时都要重新获取控件实例
viewHolder = new ViewHolder();
viewHolder.senderImage = view.findViewById(R.id.sender_image);
viewHolder.senderName = view.findViewById(R.id.sender_name);
// 将ViewHolder存储在View中即将控件的实例存储在其中
view.setTag(viewHolder);
} else {
view = convertView;
viewHolder = (ViewHolder) view.getTag();
}
// 获取控件实例并调用set...方法使其显示出来
if (senderModel != null) {
viewHolder.senderImage.setImageResource(senderModel.getImageId());
viewHolder.senderName.setText(senderModel.getName());
}
return view;
}
public void add(SenderModel senderModel) {
if (list != null) {
list.add(senderModel);
notifyDataSetChanged();
}
}
public void del(int position) {
if (list != null) {
list.remove(position);
notifyDataSetChanged();
}
}
public void update(SenderModel senderModel, int position) {
if (list != null) {
list.set(position, senderModel);
notifyDataSetChanged();
}
}
public void add(List<SenderModel> senderModels) {
if (list != null) {
list = senderModels;
notifyDataSetChanged();
}
}
public void del(List<SenderModel> senderModels) {
if (list != null) {
list = senderModels;
notifyDataSetChanged();
}
}
public void update(List<SenderModel> senderModels) {
if (list != null) {
list = senderModels;
notifyDataSetChanged();
}
}
// 定义一个内部类,用于对控件的实例进行缓存
class ViewHolder {
ImageView senderImage;
TextView senderName;
}
}

@ -0,0 +1,52 @@
package com.idormy.sms.forwarder.model;
public class LogModel {
private String from;
private String content;
private Long ruleId;
private Long time;
public LogModel(String from, String content, Long ruleId) {
this.from = from;
this.content = content;
this.ruleId = ruleId;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Long getRuleId() {
return ruleId;
}
public void setRuleId(Long ruleId) {
this.ruleId = ruleId;
}
public Long getTime() {
return time;
}
@Override
public String toString() {
return "LogModel{" +
"from='" + from + '\'' +
", content='" + content + '\'' +
", ruleId=" + ruleId +
", time=" + time +
'}';
}
}

@ -0,0 +1,19 @@
package com.idormy.sms.forwarder.model;
import android.provider.BaseColumns;
public final class LogTable {
// To prevent someone from accidentally instantiating the contract class,
// make the constructor private.
private LogTable() {
}
/* Inner class that defines the table contents */
public static class LogEntry implements BaseColumns {
public static final String TABLE_NAME = "log";
public static final String COLUMN_NAME_FROM = "l_from";
public static final String COLUMN_NAME_CONTENT = "content";
public static final String COLUMN_NAME_RULE_ID = "rule_id";
public static final String COLUMN_NAME_TIME = "time";
}
}

@ -0,0 +1,179 @@
package com.idormy.sms.forwarder.model;
import com.idormy.sms.forwarder.R;
import java.util.HashMap;
import java.util.Map;
public class RuleModel {
public static final String FILED_TRANSPOND_ALL = "transpond_all";
public static final String FILED_PHONE_NUM = "phone_num";
public static final String FILED_MSG_CONTENT = "msg_content";
public static final Map<String, String> FILED_MAP = new HashMap<String, String>();
public static final String CHECK_IS = "is";
public static final String CHECK_CONTAIN = "contain";
public static final String CHECK_START_WITH = "startwith";
public static final String CHECK_END_WITH = "endwith";
public static final String CHECK_NOT_IS = "notis";
public static final Map<String, String> CHECK_MAP = new HashMap<String, String>();
static {
FILED_MAP.put("transpond_all", "转发全部");
FILED_MAP.put("phone_num", "手机号");
FILED_MAP.put("msg_content", "内容");
}
static {
CHECK_MAP.put("is", "是");
CHECK_MAP.put("contain", "包含");
CHECK_MAP.put("startwith", "开头是");
CHECK_MAP.put("endwith", "结尾是");
CHECK_MAP.put("notis", "不是");
}
private Long id;
private String filed;
private String check;
private String value;
private Long senderId;
private Long time;
public static String getRuleMatch(String filed, String check, String value) {
switch (filed) {
case FILED_TRANSPOND_ALL:
return "全部转发到 ";
default:
return "当 " + FILED_MAP.get(filed) + " " + CHECK_MAP.get(check) + " " + value;
}
}
public static String getRuleFiledFromCheckId(int id) {
switch (id) {
case R.id.btnContent:
return FILED_MSG_CONTENT;
case R.id.btnPhone:
return FILED_PHONE_NUM;
default:
return FILED_TRANSPOND_ALL;
}
}
public static String getRuleCheckFromCheckId(int id) {
switch (id) {
case R.id.btnContain:
return CHECK_CONTAIN;
case R.id.btnStartWith:
return CHECK_START_WITH;
case R.id.btnEndWith:
return CHECK_END_WITH;
case R.id.btnNotIs:
return CHECK_NOT_IS;
default:
return CHECK_IS;
}
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getSenderId() {
return senderId;
}
public void setSenderId(Long senderId) {
this.senderId = senderId;
}
public Long getTime() {
return time;
}
public void setTime(Long time) {
this.time = time;
}
public String getFiled() {
return filed;
}
public void setFiled(String filed) {
this.filed = filed;
}
public String getCheck() {
return check;
}
public void setCheck(String check) {
this.check = check;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getRuleMatch() {
switch (filed) {
case FILED_TRANSPOND_ALL:
return "全部转发到 ";
default:
return "当 " + FILED_MAP.get(filed) + " " + CHECK_MAP.get(check) + " " + value + " 转发到 ";
}
}
public Long getRuleSenderId() {
return senderId;
}
public int getRuleFiledCheckId() {
switch (filed) {
case FILED_MSG_CONTENT:
return R.id.btnContent;
case FILED_PHONE_NUM:
return R.id.btnPhone;
default:
return R.id.btnTranspondAll;
}
}
public int getRuleCheckCheckId() {
switch (check) {
case CHECK_CONTAIN:
return R.id.btnContain;
case CHECK_START_WITH:
return R.id.btnStartWith;
case CHECK_END_WITH:
return R.id.btnEndWith;
case CHECK_NOT_IS:
return R.id.btnNotIs;
default:
return R.id.btnIs;
}
}
@Override
public String toString() {
return "RuleModel{" +
"id=" + id +
", filed='" + filed + '\'' +
", check='" + check + '\'' +
", value='" + value + '\'' +
", senderId=" + senderId +
", time=" + time +
'}';
}
}

@ -0,0 +1,20 @@
package com.idormy.sms.forwarder.model;
import android.provider.BaseColumns;
public final class RuleTable {
// To prevent someone from accidentally instantiating the contract class,
// make the constructor private.
private RuleTable() {
}
/* Inner class that defines the table contents */
public static class RuleEntry implements BaseColumns {
public static final String TABLE_NAME = "rule";
public static final String COLUMN_NAME_FILED = "filed";
public static final String COLUMN_NAME_CHECK = "tcheck";
public static final String COLUMN_NAME_VALUE = "value";
public static final String COLUMN_NAME_SENDER_ID = "sender_id";
public static final String COLUMN_NAME_TIME = "time";
}
}

@ -0,0 +1,125 @@
package com.idormy.sms.forwarder.model;
import com.idormy.sms.forwarder.R;
public class SenderModel {
public static final int STATUS_ON = 1;
public static final int STATUS_OFF = 0;
public static final int TYPE_DINGDING = 0;
public static final int TYPE_EMAIL = 1;
public static final int TYPE_MESSAGE = 2;
public static final int TYPE_WEB_NOTIFY = 3;
public static final int TYPE_QYWX_GROUP_ROBOT = 4;
public static final int TYPE_BARK = 5;
private Long id;
private String name;
private int status;
private int type;
private String jsonSetting;
private long time;
public SenderModel() {
}
public SenderModel(String name, int status, int type, String jsonSetting) {
this.name = name;
this.status = status == STATUS_ON ? STATUS_ON : STATUS_OFF;
this.type = type;
this.jsonSetting = jsonSetting;
}
public static int getImageId(int type) {
switch (type) {
case (TYPE_DINGDING):
return R.mipmap.dingding;
case (TYPE_EMAIL):
return R.drawable.ic_baseline_email_24;
case (TYPE_QYWX_GROUP_ROBOT):
return R.mipmap.qywx;
case (TYPE_BARK):
return R.mipmap.qywx;
default:
return R.mipmap.ic_launcher_round;
}
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status == STATUS_ON ? STATUS_ON : STATUS_OFF;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getJsonSetting() {
return jsonSetting;
}
public void setJsonSetting(String jsonSetting) {
this.jsonSetting = jsonSetting;
}
public int getImageId() {
switch (type) {
case (TYPE_DINGDING):
return R.mipmap.dingding;
case (TYPE_EMAIL):
return R.drawable.ic_baseline_email_24;
case (TYPE_QYWX_GROUP_ROBOT):
return R.mipmap.qywx;
case (TYPE_BARK):
return R.mipmap.qywx;
default:
return R.mipmap.ic_launcher_round;
}
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
@Override
public String toString() {
return "SenderModel{" +
"id=" + id +
", name='" + name + '\'' +
", status=" + status +
", type=" + type +
", jsonSetting='" + jsonSetting + '\'' +
", time=" + time +
'}';
}
}

@ -0,0 +1,20 @@
package com.idormy.sms.forwarder.model;
import android.provider.BaseColumns;
public final class SenderTable {
// To prevent someone from accidentally instantiating the contract class,
// make the constructor private.
private SenderTable() {
}
/* Inner class that defines the table contents */
public static class SenderEntry implements BaseColumns {
public static final String TABLE_NAME = "sender";
public static final String COLUMN_NAME_NAME = "name";
public static final String COLUMN_NAME_STATUS = "status";
public static final String COLUMN_NAME_TYPE = "type";
public static final String COLUMN_NAME_JSON_SETTING = "json_setting";
public static final String COLUMN_NAME_TIME = "time";
}
}

@ -0,0 +1,22 @@
package com.idormy.sms.forwarder.model.vo;
import java.io.Serializable;
public class BarkSettingVo implements Serializable {
private String server;
public BarkSettingVo() {
}
public BarkSettingVo(String server) {
this.server = server;
}
public String getServer() {
return server;
}
public void setServer(String server) {
this.server = server;
}
}

@ -0,0 +1,52 @@
package com.idormy.sms.forwarder.model.vo;
import java.io.Serializable;
public class DingDingSettingVo implements Serializable {
private String token;
private String secret;
private String atMobils;
private Boolean atAll;
public DingDingSettingVo() {
}
public DingDingSettingVo(String token, String secret, String atMobils, Boolean atAll) {
this.token = token;
this.secret = secret;
this.atMobils = atMobils;
this.atAll = atAll;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public String getAtMobils() {
return atMobils;
}
public void setAtMobils(String atMobils) {
this.atMobils = atMobils;
}
public Boolean getAtAll() {
return atAll;
}
public void setAtAll(Boolean atAll) {
this.atAll = atAll;
}
}

@ -0,0 +1,72 @@
package com.idormy.sms.forwarder.model.vo;
import java.io.Serializable;
public class EmailSettingVo implements Serializable {
private String host;
private String port;
private Boolean ssl = true;
private String fromEmail;
private String pwd;
private String toEmail;
public EmailSettingVo() {
}
public EmailSettingVo(String host, String port, Boolean ssl, String fromEmail, String pwd, String toEmail) {
this.host = host;
this.port = port;
this.ssl = ssl;
this.fromEmail = fromEmail;
this.pwd = pwd;
this.toEmail = toEmail;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public Boolean getSsl() {
return ssl;
}
public void setSsl(Boolean ssl) {
this.ssl = ssl;
}
public String getFromEmail() {
return fromEmail;
}
public void setFromEmail(String fromEmail) {
this.fromEmail = fromEmail;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getToEmail() {
return toEmail;
}
public void setToEmail(String toEmail) {
this.toEmail = toEmail;
}
}

@ -0,0 +1,30 @@
package com.idormy.sms.forwarder.model.vo;
import java.io.Serializable;
public class FeedBackResult implements Serializable {
Integer code;
String message;
Object result;
public FeedBackResult() {
}
public String getMessage() {
return message;
}
public boolean isSuccess() {
return 1 == code;
}
@Override
public String toString() {
return "FeedBackResult{" +
"code=" + code +
", message='" + message + '\'' +
", result=" + result +
'}';
}
}

@ -0,0 +1,57 @@
package com.idormy.sms.forwarder.model.vo;
public class LogVo {
private String from;
private String content;
private String rule;
private int senderImageId;
private String time;
public LogVo(String from, String content, String time, String rule, int senderImageId) {
this.from = from;
this.content = content;
this.time = time;
this.rule = rule;
this.senderImageId = senderImageId;
}
public LogVo() {
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getRule() {
return rule;
}
public void setRule(String rule) {
this.rule = rule;
}
public String getTime() {
return time;
}
public int getSenderImageId() {
return senderImageId;
}
public void setSenderImageId(int senderImageId) {
this.senderImageId = senderImageId;
}
}

@ -0,0 +1,22 @@
package com.idormy.sms.forwarder.model.vo;
import java.io.Serializable;
public class QYWXGroupRobotSettingVo implements Serializable {
private String webHook;
public QYWXGroupRobotSettingVo() {
}
public QYWXGroupRobotSettingVo(String webHook) {
this.webHook = webHook;
}
public String getWebHook() {
return webHook;
}
public void setWebHook(String webHook) {
this.webHook = webHook;
}
}

@ -0,0 +1,6 @@
package com.idormy.sms.forwarder.model.vo;
public class RuleVo {
private String matchStr;
private String senderStr;
}

@ -0,0 +1,59 @@
package com.idormy.sms.forwarder.model.vo;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SmsVo implements Serializable {
String mobile;
String content;
Date date;
public SmsVo() {
}
public SmsVo(String mobile, String content, Date date) {
this.mobile = mobile;
this.content = content;
this.date = date;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getSmsVoForSend() {
return mobile + "\n" +
content + "\n" +
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
}
@Override
public String toString() {
return "SmsVo{" +
"mobile='" + mobile + '\'' +
", content='" + content + '\'' +
", date=" + date +
'}';
}
}

@ -0,0 +1,32 @@
package com.idormy.sms.forwarder.model.vo;
import java.io.Serializable;
public class WebNotifySettingVo implements Serializable {
private String token;
private String secret;
public WebNotifySettingVo() {
}
public WebNotifySettingVo(String token, String secret) {
this.token = token;
this.secret = secret;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
}

@ -0,0 +1,84 @@
package com.idormy.sms.forwarder.utils;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import com.idormy.sms.forwarder.model.LogTable;
import com.idormy.sms.forwarder.model.RuleTable;
import com.idormy.sms.forwarder.model.SenderTable;
import java.util.Arrays;
import java.util.List;
public class DbHelper extends SQLiteOpenHelper {
// If you change the database schema, you must increment the database version.
public static final String TAG = "DbHelper";
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "sms_forwarder.db";
private static final List<String> SQL_CREATE_ENTRIES =
Arrays.asList(
"CREATE TABLE " + LogTable.LogEntry.TABLE_NAME + " (" +
LogTable.LogEntry._ID + " INTEGER PRIMARY KEY," +
LogTable.LogEntry.COLUMN_NAME_FROM + " TEXT," +
LogTable.LogEntry.COLUMN_NAME_CONTENT + " TEXT," +
LogTable.LogEntry.COLUMN_NAME_RULE_ID + " INTEGER," +
LogTable.LogEntry.COLUMN_NAME_TIME + " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)"
, "CREATE TABLE " + RuleTable.RuleEntry.TABLE_NAME + " (" +
RuleTable.RuleEntry._ID + " INTEGER PRIMARY KEY," +
RuleTable.RuleEntry.COLUMN_NAME_FILED + " TEXT," +
RuleTable.RuleEntry.COLUMN_NAME_CHECK + " TEXT," +
RuleTable.RuleEntry.COLUMN_NAME_VALUE + " TEXT," +
RuleTable.RuleEntry.COLUMN_NAME_SENDER_ID + " INTEGER," +
RuleTable.RuleEntry.COLUMN_NAME_TIME + " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)"
, "CREATE TABLE " + SenderTable.SenderEntry.TABLE_NAME + " (" +
SenderTable.SenderEntry._ID + " INTEGER PRIMARY KEY," +
SenderTable.SenderEntry.COLUMN_NAME_NAME + " TEXT," +
SenderTable.SenderEntry.COLUMN_NAME_STATUS + " INTEGER," +
SenderTable.SenderEntry.COLUMN_NAME_TYPE + " INTEGER," +
SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING + " TEXT," +
SenderTable.SenderEntry.COLUMN_NAME_TIME + " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)"
);
private static final List<String> SQL_DELETE_ENTRIES =
Arrays.asList(
"DROP TABLE IF EXISTS " + LogTable.LogEntry.TABLE_NAME + " ; "
, "DROP TABLE IF EXISTS " + RuleTable.RuleEntry.TABLE_NAME + " ; "
, "DROP TABLE IF EXISTS " + SenderTable.SenderEntry.TABLE_NAME + " ; "
);
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
for (String createEntries : SQL_CREATE_ENTRIES
) {
Log.d(TAG, "onCreate:createEntries " + createEntries);
db.execSQL(createEntries);
}
}
public void delCreateTable(SQLiteDatabase db) {
for (String delCreateEntries : SQL_DELETE_ENTRIES
) {
Log.d(TAG, "delCreateTable:delCreateEntries " + delCreateEntries);
db.execSQL(delCreateEntries);
}
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// This database is only a cache for online data, so its upgrade policy is
// to simply to discard the data and start over
delCreateTable(db);
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}

@ -0,0 +1,11 @@
package com.idormy.sms.forwarder.utils;
public class Define {
public static String SP_MSG = "tsms_msg";
public static String SP_MSG_SET_KEY = "tsms_msg_set_key";
public static String SP_MSG_SEND_UTIL_EMAIL_HOST_KEY = "tsms_msg_send_util_email_host_key";
public static String SP_MSG_SEND_UTIL_EMAIL_PORT_KEY = "tsms_msg_send_util_email_port_key";
public static String SP_MSG_SEND_UTIL_EMAIL_FROMADD_KEY = "tsms_msg_send_util_email_fromadd_key";
public static String SP_MSG_SEND_UTIL_EMAIL_PSW_KEY = "tsms_msg_send_util_email_psw_key";
public static String SP_MSG_SEND_UTIL_EMAIL_TOADD_KEY = "tsms_msg_send_util_email_toadd_key";
}

@ -0,0 +1,71 @@
package com.idormy.sms.forwarder.utils;
import android.util.Base64;
import android.util.Log;
import java.io.IOException;
import java.net.URLEncoder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class DingdingMsg {
static String TAG = "DingdingMsg";
public static void sendMsg(String msg) throws Exception {
String webhook_token = SettingUtil.get_using_dingding_token();
String webhook_secret = SettingUtil.get_using_dingding_secret();
if (webhook_token.equals("")) {
return;
}
if (!webhook_secret.equals("")) {
Long timestamp = System.currentTimeMillis();
String stringToSign = timestamp + "\n" + webhook_secret;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(webhook_secret.getBytes("UTF-8"), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
String sign = URLEncoder.encode(new String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8");
webhook_token += "&timestamp=" + timestamp + "&sign=" + sign;
Log.i(TAG, "webhook_token:" + webhook_token);
}
final String msgf = msg;
String textMsg = "{ \"msgtype\": \"text\", \"text\": {\"content\": \"" + msg + "\"}}";
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"),
textMsg);
final Request request = new Request.Builder()
.url(webhook_token)
.addHeader("Content-Type", "application/json; charset=utf-8")
.post(requestBody)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure" + e.getMessage());
SendHistory.addHistory("钉钉转发:" + msgf + "onFailure" + e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseStr = response.body().string();
Log.d(TAG, "Code" + String.valueOf(response.code()) + responseStr);
SendHistory.addHistory("钉钉转发:" + msgf + "Code" + String.valueOf(response.code()) + responseStr);
}
});
}
}

@ -0,0 +1,94 @@
package com.idormy.sms.forwarder.utils;
import android.support.annotation.NonNull;
import java.io.File;
import java.io.Serializable;
import java.util.Map;
/**
* app
*/
public interface HttpI extends Serializable {
/**
* get
*
* @param url get
* @param params get
* @param callBack
*/
void asyncGet(@NonNull String url, @NonNull Map<String, String> params, @NonNull Callback callBack);
/**
* post
*
* @param url post
* @param params post
* @param callBack
*/
void asyncPost(@NonNull String url, @NonNull Map<String, String> params, @NonNull Callback callBack);
/**
*
*
* @param url
* @param path
* @param fileName
* @param callback
*/
void download(@NonNull String url, @NonNull String path, @NonNull String fileName, @NonNull FileCallback callback);
/**
*
*/
interface FileCallback {
/**
*
*
* @param progress 0.00 - 0.50 - 1.00
* @param total
*/
void onProgress(float progress, long total);
/**
*
*
* @param error
*/
void onError(String error);
/**
*
*
* @param file
*/
void onResponse(File file);
/**
*
*/
void onBefore();
}
/**
*
*/
interface Callback {
/**
*
*
* @param result
*/
void onResponse(String result);
/**
*
*
* @param error
*/
void onError(String error);
}
}

@ -0,0 +1,117 @@
package com.idormy.sms.forwarder.utils;
import android.support.annotation.NonNull;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.FileCallBack;
import com.zhy.http.okhttp.callback.StringCallback;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Request;
import okhttp3.Response;
public class HttpUtil implements HttpI {
/**
* get
*
* @param url get
* @param params get
* @param callBack
*/
public void asyncGet(@NonNull String url, @NonNull Map<String, String> params, @NonNull final Callback callBack) {
params.put("aaa", "bbbbb");
params.put("ccc", "ddd");
Map<String, String> headers = new HashMap<>();
OkHttpUtils.get()
.url(url)
.headers(headers)
.params(params)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Response response, Exception e, int id) {
callBack.onError(validateError(e, response));
}
@Override
public void onResponse(String response, int id) {
callBack.onResponse(response);
}
});
}
/**
* post
*
* @param url post
* @param params post
* @param callBack
*/
public void asyncPost(@NonNull String url, @NonNull Map<String, String> params, @NonNull final Callback callBack) {
params.put("eeee", "fff");
params.put("gggg", "hhhh");
Map<String, String> headers = new HashMap<>();
headers.put("heada", "bb");
OkHttpUtils.post()
.url(url)
.headers(headers)
.params(params)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Response response, Exception e, int id) {
callBack.onError(validateError(e, response));
}
@Override
public void onResponse(String response, int id) {
callBack.onResponse(response);
}
});
}
/**
*
*
* @param url
* @param path
* @param fileName
* @param callback
*/
public void download(@NonNull String url, @NonNull String path, @NonNull String fileName, @NonNull final FileCallback callback) {
OkHttpUtils.get()
.url(url)
.build()
.execute(new FileCallBack(path, fileName) {
@Override
public void inProgress(float progress, long total, int id) {
callback.onProgress(progress, total);
}
@Override
public void onError(Call call, Response response, Exception e, int id) {
callback.onError(validateError(e, response));
}
@Override
public void onResponse(File response, int id) {
callback.onResponse(response);
}
@Override
public void onBefore(Request request, int id) {
super.onBefore(request, id);
callback.onBefore();
}
});
}
}

@ -0,0 +1,24 @@
package com.idormy.sms.forwarder.utils;
import android.content.Context;
import android.util.Log;
public class InitUtil {
static Boolean hasInit = false;
private static String TAG = "InitUtil";
private static Context context = null;
public static void init(Context context1) {
Log.d(TAG, "TMSG init");
synchronized (hasInit) {
if (hasInit) return;
hasInit = true;
context = context1;
Log.d(TAG, "init context");
SettingUtil.init(context);
}
}
}

@ -0,0 +1,178 @@
package com.idormy.sms.forwarder.utils;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.provider.BaseColumns;
import android.util.Log;
import com.idormy.sms.forwarder.model.LogModel;
import com.idormy.sms.forwarder.model.LogTable;
import com.idormy.sms.forwarder.model.RuleModel;
import com.idormy.sms.forwarder.model.RuleTable;
import com.idormy.sms.forwarder.model.SenderModel;
import com.idormy.sms.forwarder.model.SenderTable;
import com.idormy.sms.forwarder.model.vo.LogVo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class LogUtil {
static String TAG = "LogUtil";
static Boolean hasInit = false;
static Context context;
static DbHelper dbHelper;
static SQLiteDatabase db;
public static void init(Context context1) {
synchronized (hasInit) {
if (hasInit) return;
hasInit = true;
context = context1;
dbHelper = new DbHelper(context);
// Gets the data repository in write mode
db = dbHelper.getReadableDatabase();
}
}
public static long addLog(LogModel logModel) {
Log.i(TAG, "addLog logModel: " + logModel);
//不保存转发消息
if (logModel == null) return 0;
// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(LogTable.LogEntry.COLUMN_NAME_FROM, logModel.getFrom());
values.put(LogTable.LogEntry.COLUMN_NAME_CONTENT, logModel.getContent());
values.put(LogTable.LogEntry.COLUMN_NAME_RULE_ID, logModel.getRuleId());
// Insert the new row, returning the primary key value of the new row
return db.insert(LogTable.LogEntry.TABLE_NAME, null, values);
}
public static int delLog(Long id, String key) {
// Define 'where' part of query.
String selection = " 1 ";
// Specify arguments in placeholder order.
List<String> selectionArgList = new ArrayList<>();
if (id != null) {
// Define 'where' part of query.
selection += " and " + LogTable.LogEntry._ID + " = ? ";
// Specify arguments in placeholder order.
selectionArgList.add(String.valueOf(id));
}
if (key != null) {
// Define 'where' part of query.
selection = " and (" + LogTable.LogEntry.COLUMN_NAME_FROM + " LIKE ? or " + LogTable.LogEntry.COLUMN_NAME_CONTENT + " LIKE ? ) ";
// Specify arguments in placeholder order.
selectionArgList.add(key);
selectionArgList.add(key);
}
String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]);
// Issue SQL statement.
return db.delete(LogTable.LogEntry.TABLE_NAME, selection, selectionArgs);
}
public static List<LogVo> getLog(Long id, String key) {
// Define a projection that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
LogTable.LogEntry.TABLE_NAME + "." + BaseColumns._ID,
LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_FROM,
LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_TIME,
LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_CONTENT,
RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_FILED,
RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_CHECK,
RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_VALUE,
SenderTable.SenderEntry.TABLE_NAME + "." + SenderTable.SenderEntry.COLUMN_NAME_NAME,
SenderTable.SenderEntry.TABLE_NAME + "." + SenderTable.SenderEntry.COLUMN_NAME_TYPE
};
// Define 'where' part of query.
String selection = " 1 ";
// Specify arguments in placeholder order.
List<String> selectionArgList = new ArrayList<>();
if (id != null) {
// Define 'where' part of query.
selection += " and " + LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry._ID + " = ? ";
// Specify arguments in placeholder order.
selectionArgList.add(String.valueOf(id));
}
if (key != null) {
// Define 'where' part of query.
selection = " and (" + LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_FROM + " LIKE ? or " + LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_CONTENT + " LIKE ? ) ";
// Specify arguments in placeholder order.
selectionArgList.add(key);
selectionArgList.add(key);
}
String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]);
// How you want the results sorted in the resulting Cursor
String sortOrder =
LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry._ID + " DESC";
Cursor cursor = db.query(
// The table to query
LogTable.LogEntry.TABLE_NAME
+ " LEFT JOIN " + RuleTable.RuleEntry.TABLE_NAME + " ON " + LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_RULE_ID + "=" + RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry._ID
+ " LEFT JOIN " + SenderTable.SenderEntry.TABLE_NAME + " ON " + SenderTable.SenderEntry.TABLE_NAME + "." + SenderTable.SenderEntry._ID + "=" + RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_SENDER_ID,
projection, // The array of columns to return (pass null to get all)
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
Log.d(TAG, "getLog: " + db.getPath());
List<LogVo> LogVos = new ArrayList<>();
Log.d(TAG, "getLog: itemId cursor" + Arrays.toString(cursor.getColumnNames()));
while (cursor.moveToNext()) {
try {
String itemfrom = cursor.getString(
cursor.getColumnIndexOrThrow(LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_FROM));
String content = cursor.getString(
cursor.getColumnIndexOrThrow(LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_CONTENT));
String time = cursor.getString(
cursor.getColumnIndexOrThrow(LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_TIME));
String ruleFiled = cursor.getString(
cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_FILED));
String ruleCheck = cursor.getString(
cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_CHECK));
String ruleValue = cursor.getString(
cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_VALUE));
String senderName = cursor.getString(
cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.TABLE_NAME + "." + SenderTable.SenderEntry.COLUMN_NAME_NAME));
Integer senderType = cursor.getInt(
cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.TABLE_NAME + "." + SenderTable.SenderEntry.COLUMN_NAME_TYPE));
Log.d(TAG, "getLog: time" + time);
String rule = RuleModel.getRuleMatch(ruleFiled, ruleCheck, ruleValue) + " 转发到 " + senderName;
// String rule = time+" 转发到 "+senderName;
int senderImageId = SenderModel.getImageId(senderType);
LogVo logVo = new LogVo(itemfrom, content, time, rule, senderImageId);
LogVos.add(logVo);
} catch (Exception e) {
Log.i(TAG, "getLog e:" + e.getMessage());
}
}
cursor.close();
return LogVos;
}
}

@ -0,0 +1,139 @@
package com.idormy.sms.forwarder.utils;
import java.util.Properties;
public class MailInfo {
private String mailServerHost;// 发送邮件的服务器的IP
private String mailServerPort;// 发送邮件的服务器的端口
private String fromAddress;// 邮件发送者的地址
private String toAddress; // 邮件接收者的地址
private String userName;// 登陆邮件发送服务器的用户名
private String password;// 登陆邮件发送服务器的密码
private boolean validate = true;// 是否需要身份验证
private boolean ssl = true;// ssl
private String subject;// 邮件主题
private String content;// 邮件的文本内容
private String[] attachFileNames;// 邮件附件的文件名
public String toString() {
return "mailServerHost:" + this.mailServerHost
+ "mailServerPort:" + this.mailServerPort
+ "fromAddress:" + this.fromAddress
+ "toAddress:" + this.toAddress
+ "userName:" + this.userName
+ "password:" + this.password
+ "subject:" + this.subject
+ "content:" + this.content;
}
/**
*
*/
public Properties getProperties() {
Properties p = new Properties();
p.put("mail.smtp.host", this.mailServerHost);
p.put("mail.smtp.port", this.mailServerPort);
p.put("mail.smtp.auth", validate ? "true" : "false");
// 设置SSL加密(未采用SSL时端口一般为25可以不用设置采用SSL时端口为465需要显示设置)
if (ssl) {
p.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
p.put("mail.smtp.socketFactory.fallback", "false");
p.put("mail.smtp.socketFactory.port", this.mailServerPort);
}
// props.setProperty("mail.smtp.port", "465");
// props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
// props.setProperty("mail.smtp.socketFactory.fallback", "false");
// props.setProperty("mail.smtp.socketFactory.port", "465");
return p;
}
public String getMailServerHost() {
return mailServerHost;
}
public void setMailServerHost(String mailServerHost) {
this.mailServerHost = mailServerHost;
}
public String getMailServerPort() {
return mailServerPort;
}
public void setMailServerPort(String mailServerPort) {
this.mailServerPort = mailServerPort;
}
public boolean isValidate() {
return validate;
}
public void setValidate(boolean validate) {
this.validate = validate;
}
public void ssl(boolean ssl) {
this.ssl = ssl;
}
public String[] getAttachFileNames() {
return attachFileNames;
}
public void setAttachFileNames(String[] fileNames) {
this.attachFileNames = fileNames;
}
public String getFromAddress() {
return fromAddress;
}
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getToAddress() {
return toAddress;
}
public void setToAddress(String toAddress) {
this.toAddress = toAddress;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String textContent) {
this.content = textContent;
}
}

@ -0,0 +1,205 @@
package com.idormy.sms.forwarder.utils;
import android.util.Log;
import java.io.File;
import java.util.Date;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
/**
*
*/
public class MailSender {
private static String TAG = "MailSender";
/**
* HTML
*
* @param mailInfo
*/
public static boolean sendHtmlMail(MailInfo mailInfo) {
Log.d(TAG, "sendHtmlMail MailInfo " + mailInfo.toString());
// 判断是否需要身份认证
MyAuthenticator authenticator = null;
Properties pro = mailInfo.getProperties();
// 如果需要身份认证,则创建一个密码验证器
if (mailInfo.isValidate()) {
authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
}
// 根据邮件会话属性和密码验证器构造一个发送邮件的session
Session sendMailSession = Session.getDefaultInstance(pro, authenticator);
try {
// 根据session创建一个邮件消息
Message mailMessage = new MimeMessage(sendMailSession);
// 创建邮件发送者地址
Address from = new InternetAddress(mailInfo.getFromAddress());
// 设置邮件消息的发送者
mailMessage.setFrom(from);
// 创建邮件的接收者地址,并设置到邮件消息中
Address to = new InternetAddress(mailInfo.getToAddress());
// Message.RecipientType.TO属性表示接收者的类型为TO
mailMessage.setRecipient(Message.RecipientType.TO, to);
// 设置邮件消息的主题
mailMessage.setSubject(mailInfo.getSubject());
// 设置邮件消息发送的时间
mailMessage.setSentDate(new Date());
// MiniMultipart类是一个容器类包含MimeBodyPart类型的对象
Multipart mainPart = new MimeMultipart();
// 创建一个包含HTML内容的MimeBodyPart
BodyPart html = new MimeBodyPart();
// 设置HTML内容
html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");
mainPart.addBodyPart(html);
// 将MiniMultipart对象设置为邮件内容
mailMessage.setContent(mainPart);
// 发送邮件
Transport.send(mailMessage);
return true;
} catch (MessagingException ex) {
ex.printStackTrace();
}
return false;
}
/**
*
*
* @param mailInfo
*/
public boolean sendTextMail(final MailInfo mailInfo) {
Log.d(TAG, "sendTextMail MailInfo " + mailInfo.toString());
// 判断是否需要身份认证
MyAuthenticator authenticator = null;
Properties pro = mailInfo.getProperties();
if (mailInfo.isValidate()) {
// 如果需要身份认证,则创建一个密码验证器
authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
}
// 根据邮件会话属性和密码验证器构造一个发送邮件的session
Session sendMailSession = Session.getDefaultInstance(pro, authenticator);
try {
// 根据session创建一个邮件消息
Message mailMessage = new MimeMessage(sendMailSession);
// 创建邮件发送者地址
Address from = new InternetAddress(mailInfo.getFromAddress());
// 设置邮件消息的发送者
mailMessage.setFrom(from);
// 创建邮件的接收者地址,并设置到邮件消息中
Address to = new InternetAddress(mailInfo.getToAddress());
mailMessage.setRecipient(Message.RecipientType.TO, to);
// 设置邮件消息的主题
mailMessage.setSubject(mailInfo.getSubject());
// 设置邮件消息发送的时间
mailMessage.setSentDate(new Date());
// 设置邮件消息的主要内容
String mailContent = mailInfo.getContent();
mailMessage.setText(mailContent);
// 发送邮件
Transport.send(mailMessage);
SendHistory.addHistory("Email mailInfo" + mailInfo.toString());
return true;
} catch (MessagingException ex) {
SendHistory.addHistory("Email Fail mailInfo" + mailInfo.toString());
Log.d(TAG, "sendTextMail MailInfo " + ex.getMessage());
ex.printStackTrace();
}
return false;
}
/**
*
*
* @param info
* @return
*/
public boolean sendFileMail(MailInfo info, File file) {
Log.d(TAG, "sendFileMail MailInfo " + info.toString());
Message attachmentMail = createAttachmentMail(info, file);
try {
Transport.send(attachmentMail);
return true;
} catch (MessagingException e) {
e.printStackTrace();
return false;
}
}
/**
*
*
* @return
*/
private Message createAttachmentMail(final MailInfo info, File file) {
Log.d(TAG, "createAttachmentMail MailInfo " + info.toString());
//创建邮件
MimeMessage message = null;
Properties pro = info.getProperties();
try {
Session sendMailSession = Session.getInstance(pro, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(info.getUserName(), info.getPassword());
}
});
message = new MimeMessage(sendMailSession);
// 设置邮件的基本信息
//创建邮件发送者地址
Address from = new InternetAddress(info.getFromAddress());
//设置邮件消息的发送者
message.setFrom(from);
//创建邮件的接受者地址,并设置到邮件消息中
Address to = new InternetAddress(info.getToAddress());
//设置邮件消息的接受者, Message.RecipientType.TO属性表示接收者的类型为TO
message.setRecipient(Message.RecipientType.TO, to);
//邮件标题
message.setSubject(info.getSubject());
// 创建邮件正文为了避免邮件正文中文乱码问题需要使用CharSet=UTF-8指明字符编码
MimeBodyPart text = new MimeBodyPart();
text.setContent(info.getContent(), "text/html;charset=UTF-8");
// 创建容器描述数据关系
MimeMultipart mp = new MimeMultipart();
mp.addBodyPart(text);
// 创建邮件附件
MimeBodyPart attach = new MimeBodyPart();
FileDataSource ds = new FileDataSource(file);
DataHandler dh = new DataHandler(ds);
attach.setDataHandler(dh);
attach.setFileName(MimeUtility.encodeText(dh.getName()));
mp.addBodyPart(attach);
mp.setSubType("mixed");
message.setContent(mp);
message.saveChanges();
} catch (Exception e) {
Log.e("TAG", "创建带附件的邮件失败");
e.printStackTrace();
}
// 返回生成的邮件
return message;
}
}

@ -0,0 +1,147 @@
package com.idormy.sms.forwarder.utils;
import android.util.Log;
import com.sun.mail.util.MailSSLSocketFactory;
import java.security.GeneralSecurityException;
import java.util.Properties;
public class MailSenderInfo {
private static String TAG = "MailSenderInfo";
// 发送邮件的服务器的IP和端口
private String mailServerHost;
private String mailServerPort = "25";
// 邮件发送者的地址
private String fromAddress;
// 邮件接收者的地址
private String toAddress;
// 登陆邮件发送服务器的用户名和密码
private String userName;
private String password;
// 是否需要身份验证
private boolean validate = true;
//开启ssl
private boolean ssl = true;
// 邮件主题
private String subject;
// 邮件的文本内容
private String content;
// 邮件附件的文件名
private String[] attachFileNames;
/**
*
*/
public Properties getProperties() {
Properties props = new Properties();
props.put("mail.smtp.host", this.mailServerHost);
props.put("mail.smtp.port", this.mailServerPort);
props.put("mail.smtp.auth", validate ? "true" : "false");
if (ssl) {
try {
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.socketFactory", sf);
Log.i(TAG, "set ssl success");
} catch (GeneralSecurityException e) {
Log.e(TAG, "set ssl fail: " + e.getMessage());
e.printStackTrace();
}
}
return props;
}
public String getMailServerHost() {
return mailServerHost;
}
public void setMailServerHost(String mailServerHost) {
this.mailServerHost = mailServerHost;
}
public String getMailServerPort() {
return mailServerPort;
}
public void setMailServerPort(String mailServerPort) {
this.mailServerPort = mailServerPort;
}
public boolean isValidate() {
return validate;
}
public void setValidate(boolean validate) {
this.validate = validate;
}
public String[] getAttachFileNames() {
return attachFileNames;
}
public void setAttachFileNames(String[] fileNames) {
this.attachFileNames = fileNames;
}
public String getFromAddress() {
return fromAddress;
}
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getToAddress() {
return toAddress;
}
public void setToAddress(String toAddress) {
this.toAddress = toAddress;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String textContent) {
this.content = textContent;
}
public boolean isSsl() {
return ssl;
}
public void setSsl(boolean ssl) {
this.ssl = ssl;
}
}

@ -0,0 +1,21 @@
package com.idormy.sms.forwarder.utils;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
public class MyAuthenticator extends Authenticator {
String userName = null;
String password = null;
public MyAuthenticator() {
}
public MyAuthenticator(String username, String password) {
this.userName = username;
this.password = password;
}
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password);
}
}

@ -0,0 +1,157 @@
package com.idormy.sms.forwarder.utils;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.provider.BaseColumns;
import android.util.Log;
import com.idormy.sms.forwarder.model.RuleModel;
import com.idormy.sms.forwarder.model.RuleTable;
import java.util.ArrayList;
import java.util.List;
public class RuleUtil {
static String TAG = "RuleUtil";
static Boolean hasInit = false;
static Context context;
static DbHelper dbHelper;
static SQLiteDatabase db;
public static void init(Context context1) {
synchronized (hasInit) {
if (hasInit) return;
hasInit = true;
context = context1;
dbHelper = new DbHelper(context);
// Gets the data repository in write mode
db = dbHelper.getReadableDatabase();
}
}
public static long addRule(RuleModel ruleModel) {
// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(RuleTable.RuleEntry.COLUMN_NAME_FILED, ruleModel.getFiled());
values.put(RuleTable.RuleEntry.COLUMN_NAME_CHECK, ruleModel.getCheck());
values.put(RuleTable.RuleEntry.COLUMN_NAME_VALUE, ruleModel.getValue());
values.put(RuleTable.RuleEntry.COLUMN_NAME_SENDER_ID, ruleModel.getSenderId());
// Insert the new row, returning the primary key value of the new row
return db.insert(RuleTable.RuleEntry.TABLE_NAME, null, values);
}
public static long updateRule(RuleModel ruleModel) {
if (ruleModel == null) return 0;
// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(RuleTable.RuleEntry.COLUMN_NAME_FILED, ruleModel.getFiled());
values.put(RuleTable.RuleEntry.COLUMN_NAME_CHECK, ruleModel.getCheck());
values.put(RuleTable.RuleEntry.COLUMN_NAME_VALUE, ruleModel.getValue());
values.put(RuleTable.RuleEntry.COLUMN_NAME_SENDER_ID, ruleModel.getSenderId());
String selection = RuleTable.RuleEntry._ID + " = ? ";
String[] whereArgs = {String.valueOf(ruleModel.getId())};
return db.update(RuleTable.RuleEntry.TABLE_NAME, values, selection, whereArgs);
}
public static int delRule(Long id) {
// Define 'where' part of query.
String selection = " 1 ";
// Specify arguments in placeholder order.
List<String> selectionArgList = new ArrayList<>();
if (id != null) {
// Define 'where' part of query.
selection += " and " + RuleTable.RuleEntry._ID + " = ? ";
// Specify arguments in placeholder order.
selectionArgList.add(String.valueOf(id));
}
String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]);
// Issue SQL statement.
return db.delete(RuleTable.RuleEntry.TABLE_NAME, selection, selectionArgs);
}
public static List<RuleModel> getRule(Long id, String key) {
// Define a projection that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
BaseColumns._ID,
RuleTable.RuleEntry.COLUMN_NAME_FILED,
RuleTable.RuleEntry.COLUMN_NAME_CHECK,
RuleTable.RuleEntry.COLUMN_NAME_VALUE,
RuleTable.RuleEntry.COLUMN_NAME_SENDER_ID,
RuleTable.RuleEntry.COLUMN_NAME_TIME
};
// Define 'where' part of query.
String selection = " 1 ";
// Specify arguments in placeholder order.
List<String> selectionArgList = new ArrayList<>();
if (id != null) {
// Define 'where' part of query.
selection += " and " + RuleTable.RuleEntry._ID + " = ? ";
// Specify arguments in placeholder order.
selectionArgList.add(String.valueOf(id));
}
if (key != null) {
// Define 'where' part of query.
selection = " and (" + RuleTable.RuleEntry.COLUMN_NAME_VALUE + " LIKE ? ";
// Specify arguments in placeholder order.
selectionArgList.add(key);
}
String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]);
// How you want the results sorted in the resulting Cursor
String sortOrder =
RuleTable.RuleEntry._ID + " DESC";
Cursor cursor = db.query(
RuleTable.RuleEntry.TABLE_NAME, // The table to query
projection, // The array of columns to return (pass null to get all)
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
List<RuleModel> tRules = new ArrayList<>();
while (cursor.moveToNext()) {
long itemId = cursor.getLong(
cursor.getColumnIndexOrThrow(RuleTable.RuleEntry._ID));
String itemFiled = cursor.getString(
cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.COLUMN_NAME_FILED));
String itemCheck = cursor.getString(
cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.COLUMN_NAME_CHECK));
String itemValue = cursor.getString(
cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.COLUMN_NAME_VALUE));
long itemSenderId = cursor.getLong(
cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.COLUMN_NAME_SENDER_ID));
long itemTime = cursor.getLong(
cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.COLUMN_NAME_TIME));
Log.d(TAG, "getRule: itemId" + itemId);
RuleModel ruleModel = new RuleModel();
ruleModel.setId(itemId);
ruleModel.setFiled(itemFiled);
ruleModel.setCheck(itemCheck);
ruleModel.setValue(itemValue);
ruleModel.setSenderId(itemSenderId);
ruleModel.setTime(itemTime);
tRules.add(ruleModel);
}
cursor.close();
return tRules;
}
}

@ -0,0 +1,171 @@
package com.idormy.sms.forwarder.utils;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.provider.BaseColumns;
import android.util.Log;
import com.idormy.sms.forwarder.model.LogModel;
import com.idormy.sms.forwarder.model.LogTable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class SendHistory {
static String TAG = "SendHistory";
static Boolean hasInit = false;
static Context context;
static DbHelper dbHelper;
static SQLiteDatabase db;
public static void init(Context context1) {
synchronized (hasInit) {
if (hasInit) return;
hasInit = true;
context = context1;
dbHelper = new DbHelper(context);
db = dbHelper.getReadableDatabase();
}
}
public static void addHistory(String msg) {
//不保存转发消息
if (!SettingUtil.saveMsgHistory()) return;
//保存
SharedPreferences sp = context.getSharedPreferences(Define.SP_MSG, Context.MODE_PRIVATE);
Set<String> msg_set_default = new HashSet<>();
Set<String> msg_set;
msg_set = sp.getStringSet(Define.SP_MSG_SET_KEY, msg_set_default);
Log.d(TAG, "msg_set" + msg_set.toString());
Log.d(TAG, "msg_set" + Integer.toString(msg_set.size()));
msg_set.add(msg);
sp.edit().putStringSet(Define.SP_MSG_SET_KEY, msg_set).apply();
}
public static String getHistory() {
SharedPreferences sp = context.getSharedPreferences(Define.SP_MSG, Context.MODE_PRIVATE);
Set<String> msg_set = new HashSet<>();
msg_set = sp.getStringSet(Define.SP_MSG_SET_KEY, msg_set);
Log.d(TAG, "msg_set.toString()" + msg_set.toString());
String getMsg = "";
for (String str : msg_set) {
getMsg += str + "\n";
}
return getMsg;
}
public static long addHistoryDb(LogModel logModel) {
//不保存转发消息
if (!SettingUtil.saveMsgHistory()) return 0;
// Gets the data repository in write mode
SQLiteDatabase db = dbHelper.getWritableDatabase();
// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(LogTable.LogEntry.COLUMN_NAME_FROM, logModel.getFrom());
values.put(LogTable.LogEntry.COLUMN_NAME_CONTENT, logModel.getContent());
values.put(LogTable.LogEntry.COLUMN_NAME_TIME, logModel.getTime());
// Insert the new row, returning the primary key value of the new row
return db.insert(LogTable.LogEntry.TABLE_NAME, null, values);
}
public static int delHistoryDb(Long id, String key) {
// Define 'where' part of query.
String selection = " 1 ";
// Specify arguments in placeholder order.
List<String> selectionArgList = new ArrayList<>();
if (id != null) {
// Define 'where' part of query.
selection += " and " + LogTable.LogEntry._ID + " = ? ";
// Specify arguments in placeholder order.
selectionArgList.add(String.valueOf(id));
}
if (key != null) {
// Define 'where' part of query.
selection = " and (" + LogTable.LogEntry.COLUMN_NAME_FROM + " LIKE ? or " + LogTable.LogEntry.COLUMN_NAME_CONTENT + " LIKE ? ) ";
// Specify arguments in placeholder order.
selectionArgList.add(key);
selectionArgList.add(key);
}
String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]);
// Issue SQL statement.
return db.delete(LogTable.LogEntry.TABLE_NAME, selection, selectionArgs);
}
public static String getHistoryDb(Long id, String key) {
// Define a projection that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
BaseColumns._ID,
LogTable.LogEntry.COLUMN_NAME_FROM,
LogTable.LogEntry.COLUMN_NAME_CONTENT,
LogTable.LogEntry.COLUMN_NAME_TIME
};
// Define 'where' part of query.
String selection = " 1 ";
// Specify arguments in placeholder order.
List<String> selectionArgList = new ArrayList<>();
if (id != null) {
// Define 'where' part of query.
selection += " and " + LogTable.LogEntry._ID + " = ? ";
// Specify arguments in placeholder order.
selectionArgList.add(String.valueOf(id));
}
if (key != null) {
// Define 'where' part of query.
selection = " and (" + LogTable.LogEntry.COLUMN_NAME_FROM + " LIKE ? or " + LogTable.LogEntry.COLUMN_NAME_CONTENT + " LIKE ? ) ";
// Specify arguments in placeholder order.
selectionArgList.add(key);
selectionArgList.add(key);
}
String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]);
// How you want the results sorted in the resulting Cursor
String sortOrder =
LogTable.LogEntry._ID + " DESC";
Cursor cursor = db.query(
LogTable.LogEntry.TABLE_NAME, // The table to query
projection, // The array of columns to return (pass null to get all)
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
List<Long> tLogs = new ArrayList<>();
while (cursor.moveToNext()) {
long itemId = cursor.getLong(
cursor.getColumnIndexOrThrow(LogTable.LogEntry._ID));
tLogs.add(itemId);
}
cursor.close();
SharedPreferences sp = context.getSharedPreferences(Define.SP_MSG, Context.MODE_PRIVATE);
Set<String> msg_set = new HashSet<>();
msg_set = sp.getStringSet(Define.SP_MSG_SET_KEY, msg_set);
Log.d(TAG, "msg_set.toString()" + msg_set.toString());
String getMsg = "";
for (String str : msg_set) {
getMsg += str + "\n";
}
return getMsg;
}
}

@ -0,0 +1,85 @@
package com.idormy.sms.forwarder.utils;
import android.util.Log;
import java.io.File;
public class SendMailUtil {
private static String TAG = "SendMailUtil";
//qq
// private static final String HOST = "smtp.qq.com";
// private static final String PORT = "587";
// private static final String FROM_ADD = "teprinciple@foxmail.com"; //发送方邮箱
// private static final String FROM_PSW = "lfrlpganzjrwbeci";//发送方邮箱授权码
// //163
// private static final String HOST = "smtp.163.com";
// private static final String PORT = "465"; //nossl 25或者ssl465 994
// private static final String FROM_ADD = "xxxxxx@163.com";
// private static final String FROM_PSW = "xx";
public static void send(final File file, String toAdd, String title, String content) {
Log.d(TAG, "send file to " + toAdd);
final MailInfo mailInfo = creatMail(toAdd, title, content);
final MailSender sms = new MailSender();
new Thread(new Runnable() {
@Override
public void run() {
sms.sendFileMail(mailInfo, file);
}
}).start();
}
public static void send(String toAdd, String title, String content) {
Log.d(TAG, "send to " + toAdd);
final MailInfo mailInfo = creatMail(toAdd, title, content);
final MailSender sms = new MailSender();
new Thread(new Runnable() {
@Override
public void run() {
sms.sendTextMail(mailInfo);
}
}).start();
}
private static MailInfo creatMail(String toAdd, String title, String content) {
Log.d(TAG, "creatMail to " + toAdd);
final MailInfo mailInfo = new MailInfo();
mailInfo.setMailServerHost(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_HOST_KEY));
mailInfo.setMailServerPort(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_PORT_KEY));
mailInfo.setValidate(true);
mailInfo.ssl(true);
mailInfo.setUserName(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_FROMADD_KEY)); // 你的邮箱地址
mailInfo.setPassword(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_PSW_KEY));// 您的邮箱密码
mailInfo.setFromAddress(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_FROMADD_KEY)); // 发送的邮箱
mailInfo.setToAddress(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_TOADD_KEY)); // 发到哪个邮件去
mailInfo.setSubject(title); // 邮件主题
mailInfo.setContent(content); // 邮件文本
return mailInfo;
}
}
/**
* public void sendFileMail(View view) {
* <p>
* File file = new File(Environment.getExternalStorageDirectory()+File.separator+"test.txt");
* OutputStream os = null;
* try {
* os = new FileOutputStream(file);
* String str = "hello world";
* byte[] data = str.getBytes();
* os.write(data);
* } catch (FileNotFoundException e) {
* e.printStackTrace();
* } catch (IOException e) {
* e.printStackTrace();
* }finally{
* try {
* if (os != null)os.close();
* } catch (IOException e) {
* }
* }
* SendMailUtil.send(file,editText.getText().toString());
* }
*/

@ -0,0 +1,234 @@
package com.idormy.sms.forwarder.utils;
import android.content.Context;
import android.util.Log;
import com.alibaba.fastjson.JSON;
import com.idormy.sms.forwarder.model.LogModel;
import com.idormy.sms.forwarder.model.RuleModel;
import com.idormy.sms.forwarder.model.SenderModel;
import com.idormy.sms.forwarder.model.vo.BarkSettingVo;
import com.idormy.sms.forwarder.model.vo.DingDingSettingVo;
import com.idormy.sms.forwarder.model.vo.EmailSettingVo;
import com.idormy.sms.forwarder.model.vo.QYWXGroupRobotSettingVo;
import com.idormy.sms.forwarder.model.vo.SmsVo;
import com.idormy.sms.forwarder.model.vo.WebNotifySettingVo;
import java.util.List;
import static com.idormy.sms.forwarder.model.RuleModel.CHECK_CONTAIN;
import static com.idormy.sms.forwarder.model.RuleModel.CHECK_END_WITH;
import static com.idormy.sms.forwarder.model.RuleModel.CHECK_IS;
import static com.idormy.sms.forwarder.model.RuleModel.CHECK_NOT_IS;
import static com.idormy.sms.forwarder.model.RuleModel.CHECK_START_WITH;
import static com.idormy.sms.forwarder.model.RuleModel.FILED_MSG_CONTENT;
import static com.idormy.sms.forwarder.model.RuleModel.FILED_PHONE_NUM;
import static com.idormy.sms.forwarder.model.RuleModel.FILED_TRANSPOND_ALL;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_BARK;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_DINGDING;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_EMAIL;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_QYWX_GROUP_ROBOT;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_WEB_NOTIFY;
public class SendUtil {
private static String TAG = "SendUtil";
public static void send_msg(String msg) {
if (SettingUtil.using_dingding()) {
try {
SenderDingdingMsg.sendMsg(msg);
} catch (Exception e) {
Log.d(TAG, "发送出错:" + e.getMessage());
}
}
if (SettingUtil.using_email()) {
// SenderMailMsg.send(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_TOADD_KEY),"转发",msg);
}
}
public static void send_msg_list(Context context, List<SmsVo> smsVoList) {
Log.i(TAG, "send_msg_list size: " + smsVoList.size());
for (SmsVo smsVo : smsVoList) {
SendUtil.send_msg(context, smsVo);
}
}
public static void send_msg(Context context, SmsVo smsVo) {
Log.i(TAG, "send_msg smsVo:" + smsVo);
RuleUtil.init(context);
LogUtil.init(context);
List<RuleModel> rulelist = RuleUtil.getRule(null, null);
if (!rulelist.isEmpty()) {
SenderUtil.init(context);
for (RuleModel ruleModel : rulelist
) {
boolean canSend = false;
//使用转发规则制定的字段 匹配
switch (ruleModel.getFiled()) {
case FILED_TRANSPOND_ALL:
canSend = true;
break;
case FILED_PHONE_NUM:
switch (ruleModel.getCheck()) {
case CHECK_IS:
if (smsVo.getMobile() != null && smsVo.getMobile().equals(ruleModel.getValue())) {
canSend = true;
}
break;
case CHECK_NOT_IS:
if (smsVo.getMobile() != null && !smsVo.getMobile().equals(ruleModel.getValue())) {
canSend = true;
}
break;
case CHECK_START_WITH:
if (smsVo.getMobile() != null && smsVo.getMobile().startsWith(ruleModel.getValue())) {
canSend = true;
}
break;
case CHECK_END_WITH:
if (smsVo.getMobile() != null && smsVo.getMobile().endsWith(ruleModel.getValue())) {
canSend = true;
}
break;
case CHECK_CONTAIN:
if (smsVo.getMobile() != null && smsVo.getMobile().contains(ruleModel.getValue())) {
canSend = true;
}
break;
}
break;
case FILED_MSG_CONTENT:
switch (ruleModel.getCheck()) {
case CHECK_IS:
if (smsVo.getContent() != null && smsVo.getContent().equals(ruleModel.getValue())) {
canSend = true;
}
break;
case CHECK_NOT_IS:
if (smsVo.getContent() != null && !smsVo.getContent().equals(ruleModel.getValue())) {
canSend = true;
}
break;
case CHECK_START_WITH:
if (smsVo.getContent() != null && smsVo.getContent().startsWith(ruleModel.getValue())) {
canSend = true;
}
break;
case CHECK_END_WITH:
if (smsVo.getContent() != null && smsVo.getContent().endsWith(ruleModel.getValue())) {
canSend = true;
}
break;
case CHECK_CONTAIN:
if (smsVo.getContent() != null && smsVo.getContent().contains(ruleModel.getValue())) {
canSend = true;
}
break;
}
break;
}
//规则匹配发现需要发送
if (canSend) {
List<SenderModel> senderModels = SenderUtil.getSender(ruleModel.getSenderId(), null);
for (SenderModel senderModel : senderModels
) {
LogUtil.addLog(new LogModel(smsVo.getMobile(), smsVo.getContent(), senderModel.getId()));
SendUtil.senderSendMsg(smsVo, senderModel);
}
}
}
}
}
public static void senderSendMsg(SmsVo smsVo, SenderModel senderModel) {
Log.i(TAG, "senderSendMsg smsVo:" + smsVo + "senderModel:" + senderModel);
switch (senderModel.getType()) {
case TYPE_DINGDING:
//try phrase json setting
if (senderModel.getJsonSetting() != null) {
DingDingSettingVo dingDingSettingVo = JSON.parseObject(senderModel.getJsonSetting(), DingDingSettingVo.class);
if (dingDingSettingVo != null) {
try {
SenderDingdingMsg.sendMsg(null, dingDingSettingVo.getToken(), dingDingSettingVo.getSecret(), dingDingSettingVo.getAtMobils(), dingDingSettingVo.getAtAll(), smsVo.getSmsVoForSend());
} catch (Exception e) {
Log.e(TAG, "senderSendMsg: dingding error " + e.getMessage());
}
}
}
break;
case TYPE_EMAIL:
//try phrase json setting
if (senderModel.getJsonSetting() != null) {
EmailSettingVo emailSettingVo = JSON.parseObject(senderModel.getJsonSetting(), EmailSettingVo.class);
if (emailSettingVo != null) {
try {
SenderMailMsg.sendEmail(null, emailSettingVo.getHost(), emailSettingVo.getPort(), emailSettingVo.getSsl(), emailSettingVo.getFromEmail(),
emailSettingVo.getPwd(), emailSettingVo.getToEmail(), smsVo.getMobile(), smsVo.getSmsVoForSend());
} catch (Exception e) {
Log.e(TAG, "senderSendMsg: SenderMailMsg error " + e.getMessage());
}
}
}
break;
case TYPE_WEB_NOTIFY:
//try phrase json setting
if (senderModel.getJsonSetting() != null) {
WebNotifySettingVo webNotifySettingVo = JSON.parseObject(senderModel.getJsonSetting(), WebNotifySettingVo.class);
if (webNotifySettingVo != null) {
try {
SenderWebNotifyMsg.sendMsg(null, webNotifySettingVo.getToken(), webNotifySettingVo.getSecret(), smsVo.getMobile(), smsVo.getSmsVoForSend());
} catch (Exception e) {
Log.e(TAG, "senderSendMsg: SenderWebNotifyMsg error " + e.getMessage());
}
}
}
break;
case TYPE_QYWX_GROUP_ROBOT:
//try phrase json setting
if (senderModel.getJsonSetting() != null) {
QYWXGroupRobotSettingVo qywxGroupRobotSettingVo = JSON.parseObject(senderModel.getJsonSetting(), QYWXGroupRobotSettingVo.class);
if (qywxGroupRobotSettingVo != null) {
try {
SenderQyWxGroupRobotMsg.sendMsg(null, qywxGroupRobotSettingVo.getWebHook(), smsVo.getMobile(), smsVo.getSmsVoForSend());
} catch (Exception e) {
Log.e(TAG, "senderSendMsg: SenderQyWxGroupRobotMsg error " + e.getMessage());
}
}
}
break;
case TYPE_BARK:
//try phrase json setting
if (senderModel.getJsonSetting() != null) {
BarkSettingVo barkSettingVo = JSON.parseObject(senderModel.getJsonSetting(), BarkSettingVo.class);
if (barkSettingVo != null) {
try {
SenderBarkMsg.sendMsg(null, barkSettingVo.getServer(), smsVo.getMobile(), smsVo.getContent());
} catch (Exception e) {
Log.e(TAG, "senderSendMsg: SenderBarkMsg error " + e.getMessage());
}
}
}
break;
default:
break;
}
}
}

@ -0,0 +1,89 @@
package com.idormy.sms.forwarder.utils;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import static com.idormy.sms.forwarder.SenderActivity.NOTIFY;
public class SenderBarkMsg {
static String TAG = "SenderBarkMsg";
public static void sendMsg(final Handler handError, String barkServer, String from, String content) throws Exception {
Log.i(TAG, "sendMsg barkServer:" + barkServer + " from:" + from + " content:" + content);
if (barkServer == null || barkServer.isEmpty()) {
return;
}
barkServer += URLEncoder.encode(from, "UTF-8");
String body = "短信内容:" + content + "\n转发时间" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
barkServer += "/" + URLEncoder.encode(content, "UTF-8");
barkServer += "?isArchive=1"; //自动保存
int isCode = content.indexOf("验证码");
if (isCode != -1) {
Pattern p = Pattern.compile("(\\d{4,6})");
Matcher m = p.matcher(content);
if (m.find()) {
System.out.println(m.group());
barkServer += "&automaticallyCopy=1&copy=" + m.group();
}
}
OkHttpClient client = new OkHttpClient();
final Request request = new Request.Builder()
.url(barkServer)
.addHeader("Content-Type", "application/json; charset=utf-8")
.get()
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
Log.d(TAG, "onFailure" + e.getMessage());
if (handError != null) {
android.os.Message msg = new android.os.Message();
msg.what = NOTIFY;
Bundle bundle = new Bundle();
bundle.putString("DATA", "发送失败:" + e.getMessage());
msg.setData(bundle);
handError.sendMessage(msg);
}
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseStr = response.body().string();
Log.d(TAG, "Code" + response.code() + responseStr);
if (handError != null) {
android.os.Message msg = new android.os.Message();
msg.what = NOTIFY;
Bundle bundle = new Bundle();
bundle.putString("DATA", "发送状态:" + responseStr);
msg.setData(bundle);
handError.sendMessage(msg);
Log.d(TAG, "Response" + response.code() + responseStr);
}
}
});
}
}

@ -0,0 +1,184 @@
package com.idormy.sms.forwarder.utils;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import com.alibaba.fastjson.JSON;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import static com.idormy.sms.forwarder.SenderActivity.NOTIFY;
public class SenderDingdingMsg {
static String TAG = "SenderDingdingMsg";
public static void sendMsg(String msg) throws Exception {
String webhook_token = "https://oapi.dingtalk.com/robot/send?access_token=" + SettingUtil.get_using_dingding_token();
String webhook_secret = SettingUtil.get_using_dingding_secret();
if (webhook_token.equals("")) {
return;
}
if (!webhook_secret.equals("")) {
Long timestamp = System.currentTimeMillis();
String stringToSign = timestamp + "\n" + webhook_secret;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(webhook_secret.getBytes("UTF-8"), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
String sign = URLEncoder.encode(new String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8");
webhook_token += "&timestamp=" + timestamp + "&sign=" + sign;
Log.i(TAG, "webhook_token:" + webhook_token);
}
final String msgf = msg;
String textMsg = "{ \"msgtype\": \"text\", \"text\": {\"content\": \"" + msg + "\"}}";
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"),
textMsg);
final Request request = new Request.Builder()
.url(webhook_token)
.addHeader("Content-Type", "application/json; charset=utf-8")
.post(requestBody)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure" + e.getMessage());
SendHistory.addHistory("钉钉转发:" + msgf + "onFailure" + e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseStr = response.body().string();
Log.d(TAG, "Code" + String.valueOf(response.code()) + responseStr);
SendHistory.addHistory("钉钉转发:" + msgf + "Code" + String.valueOf(response.code()) + responseStr);
}
});
}
public static void sendMsg(final Handler handError, String token, String secret, String atMobiles, Boolean atAll, String msg) throws Exception {
Log.i(TAG, "sendMsg token:" + token + " secret:" + secret + " atMobiles:" + atMobiles + " atAll:" + atAll + " msg:" + msg);
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("UTF-8"), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
String sign = URLEncoder.encode(new String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8");
token = "https://oapi.dingtalk.com/robot/send?access_token=" + token;
token += "&timestamp=" + timestamp + "&sign=" + sign;
Log.i(TAG, "webhook_token:" + token);
}
Map textMsgMap = new HashMap();
textMsgMap.put("msgtype", "text");
Map textText = new HashMap();
textText.put("content", msg);
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);
}
String textMsg = JSON.toJSONString(textMsgMap);
Log.i(TAG, "textMsg:" + textMsg);
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"),
textMsg);
final Request request = new Request.Builder()
.url(token)
.addHeader("Content-Type", "application/json; charset=utf-8")
.post(requestBody)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
Log.d(TAG, "onFailure" + e.getMessage());
if (handError != null) {
android.os.Message msg = new android.os.Message();
msg.what = NOTIFY;
Bundle bundle = new Bundle();
bundle.putString("DATA", "发送失败:" + e.getMessage());
msg.setData(bundle);
handError.sendMessage(msg);
}
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseStr = response.body().string();
Log.d(TAG, "Code" + String.valueOf(response.code()) + responseStr);
if (handError != null) {
android.os.Message msg = new android.os.Message();
msg.what = NOTIFY;
Bundle bundle = new Bundle();
bundle.putString("DATA", "发送状态:" + responseStr);
msg.setData(bundle);
handError.sendMessage(msg);
Log.d(TAG, "Coxxyyde" + String.valueOf(response.code()) + responseStr);
}
}
});
}
}

@ -0,0 +1,148 @@
package com.idormy.sms.forwarder.utils;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import java.util.Date;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import static com.idormy.sms.forwarder.SenderActivity.NOTIFY;
public class SenderMailMsg {
private static String TAG = "SenderMailMsg";
//qq
// private static final String HOST = "smtp.qq.com";
// private static final String PORT = "587";
// private static final String FROM_ADD = "teprinciple@foxmail.com"; //发送方邮箱
// private static final String FROM_PSW = "lfrlpganzjrwbeci";//发送方邮箱授权码
// //163
// private static final String HOST = "smtp.163.com";
// private static final String PORT = "465"; //nossl 25或者ssl465 994
// private static final String FROM_ADD = "xxxxxx@163.com";
// private static final String FROM_PSW = "xx";
public static void sendEmail(final Handler handError, final String host, final String port, final boolean ssl, final String fromemail, final String pwd, final String toAdd, final String title, final String content) {
Log.d(TAG, "sendEmail: host:" + host + " port:" + port + " ssl:" + ssl + " fromemail:" + fromemail + " pwd:" + pwd + " toAdd:" + toAdd);
new Thread(new Runnable() {
@Override
public void run() {
try {
final MailSenderInfo mailInfo = new MailSenderInfo();
mailInfo.setMailServerHost(host);
mailInfo.setMailServerPort(port);
mailInfo.setValidate(true);
mailInfo.setUserName(fromemail); //你的邮箱地址
mailInfo.setPassword(pwd);//您的邮箱密码
mailInfo.setFromAddress(fromemail);//和上面username的邮箱地址一致
mailInfo.setToAddress(toAdd);
mailInfo.setSubject(title);
mailInfo.setContent(content);
mailInfo.setSsl(ssl);
//这个类主要来发送邮件
// 判断是否需要身份认证
MyAuthenticator authenticator = null;
Properties pro = mailInfo.getProperties();
if (mailInfo.isValidate()) {
// 如果需要身份认证,则创建一个密码验证器
authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
}
// 根据邮件会话属性和密码验证器构造一个发送邮件的session
Session sendMailSession = Session.getDefaultInstance(pro, authenticator);
try {
// 根据session创建一个邮件消息
final Message mailMessage = new MimeMessage(sendMailSession);
// 创建邮件发送者地址
Address from = new InternetAddress(mailInfo.getFromAddress());
// 设置邮件消息的发送者
mailMessage.setFrom(from);
// 创建邮件的接收者地址,并设置到邮件消息中
Address to = new InternetAddress(mailInfo.getToAddress());
mailMessage.setRecipient(Message.RecipientType.TO, to);
// 设置邮件消息的主题
mailMessage.setSubject(mailInfo.getSubject());
// 设置邮件消息发送的时间
mailMessage.setSentDate(new Date());
// 设置邮件消息的主要内容
String mailContent = mailInfo.getContent();
mailMessage.setText(mailContent);
// 发送邮件
Transport.send(mailMessage);
} catch (MessagingException ex) {
ex.printStackTrace();
Log.e(TAG, "error" + ex.getMessage());
if (handError != null) {
android.os.Message msg = new android.os.Message();
msg.what = NOTIFY;
Bundle bundle = new Bundle();
bundle.putString("DATA", ex.getMessage());
msg.setData(bundle);
handError.sendMessage(msg);
}
}
if (handError != null) {
android.os.Message msg = new android.os.Message();
msg.what = NOTIFY;
Bundle bundle = new Bundle();
bundle.putString("DATA", "发送成功");
msg.setData(bundle);
handError.sendMessage(msg);
}
Log.e(TAG, "sendEmail success");//sms.sendHtmlMail(mailInfo);//发送html格式
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
if (handError != null) {
android.os.Message msg = new android.os.Message();
msg.what = NOTIFY;
Bundle bundle = new Bundle();
bundle.putString("DATA", e.getMessage());
msg.setData(bundle);
handError.sendMessage(msg);
}
}
}
}).start();
}
}
/**
* public void sendFileMail(View view) {
* <p>
* File file = new File(Environment.getExternalStorageDirectory()+File.separator+"test.txt");
* OutputStream os = null;
* try {
* os = new FileOutputStream(file);
* String str = "hello world";
* byte[] data = str.getBytes();
* os.write(data);
* } catch (FileNotFoundException e) {
* e.printStackTrace();
* } catch (IOException e) {
* e.printStackTrace();
* }finally{
* try {
* if (os != null)os.close();
* } catch (IOException e) {
* }
* }
* SenderMailMsg.send(file,editText.getText().toString());
* }
*/

@ -0,0 +1,79 @@
package com.idormy.sms.forwarder.utils;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import static com.idormy.sms.forwarder.SenderActivity.NOTIFY;
public class SenderQyWxGroupRobotMsg {
static String TAG = "SenderQyWxGroupRobotMsg";
public static void sendMsg(final Handler handError, String webHook, String from, String content) throws Exception {
Log.i(TAG, "sendMsg webHook:" + webHook + " from:" + from + " content:" + content);
if (webHook == null || webHook.isEmpty()) {
return;
}
String textMsg = "{ \"msgtype\": \"text\", \"text\": {\"content\": \"" + from + " : " + content + "\"}}";
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"),
textMsg);
final Request request = new Request.Builder()
.url(webHook)
.addHeader("Content-Type", "application/json; charset=utf-8")
.post(requestBody)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
Log.d(TAG, "onFailure" + e.getMessage());
// SendHistory.addHistory("钉钉转发:"+msgf+"onFailure" + e.getMessage());
if (handError != null) {
android.os.Message msg = new android.os.Message();
msg.what = NOTIFY;
Bundle bundle = new Bundle();
bundle.putString("DATA", "发送失败:" + e.getMessage());
msg.setData(bundle);
handError.sendMessage(msg);
}
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseStr = response.body().string();
Log.d(TAG, "Code" + String.valueOf(response.code()) + responseStr);
if (handError != null) {
android.os.Message msg = new android.os.Message();
msg.what = NOTIFY;
Bundle bundle = new Bundle();
bundle.putString("DATA", "发送状态:" + responseStr);
msg.setData(bundle);
handError.sendMessage(msg);
Log.d(TAG, "Coxxyyde" + String.valueOf(response.code()) + responseStr);
}
}
});
}
}

@ -0,0 +1,194 @@
package com.idormy.sms.forwarder.utils;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.provider.BaseColumns;
import android.util.Log;
import com.idormy.sms.forwarder.model.SenderModel;
import com.idormy.sms.forwarder.model.SenderTable;
import java.util.ArrayList;
import java.util.List;
public class SenderUtil {
static String TAG = "SenderUtil";
static Boolean hasInit = false;
static Context context;
static DbHelper dbHelper;
static SQLiteDatabase db;
public static void init(Context context1) {
synchronized (hasInit) {
if (hasInit) return;
hasInit = true;
context = context1;
dbHelper = new DbHelper(context);
// Gets the data repository in write mode
db = dbHelper.getReadableDatabase();
}
}
public static long addSender(SenderModel senderModel) {
// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(SenderTable.SenderEntry.COLUMN_NAME_NAME, senderModel.getName());
values.put(SenderTable.SenderEntry.COLUMN_NAME_TYPE, senderModel.getType());
values.put(SenderTable.SenderEntry.COLUMN_NAME_STATUS, senderModel.getStatus());
values.put(SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING, senderModel.getJsonSetting());
// Insert the new row, returning the primary key value of the new row
return db.insert(SenderTable.SenderEntry.TABLE_NAME, null, values);
}
public static long updateSender(SenderModel senderModel) {
if (senderModel == null) return 0;
// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(SenderTable.SenderEntry.COLUMN_NAME_NAME, senderModel.getName());
values.put(SenderTable.SenderEntry.COLUMN_NAME_TYPE, senderModel.getType());
values.put(SenderTable.SenderEntry.COLUMN_NAME_STATUS, senderModel.getStatus());
values.put(SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING, senderModel.getJsonSetting());
String selection = SenderTable.SenderEntry._ID + " = ? ";
String[] whereArgs = {String.valueOf(senderModel.getId())};
return db.update(SenderTable.SenderEntry.TABLE_NAME, values, selection, whereArgs);
}
public static int delSender(Long id) {
// Define 'where' part of query.
String selection = " 1 ";
// Specify arguments in placeholder order.
List<String> selectionArgList = new ArrayList<>();
if (id != null) {
// Define 'where' part of query.
selection += " and " + SenderTable.SenderEntry._ID + " = ? ";
// Specify arguments in placeholder order.
selectionArgList.add(String.valueOf(id));
}
String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]);
// Issue SQL statement.
return db.delete(SenderTable.SenderEntry.TABLE_NAME, selection, selectionArgs);
}
public static List<SenderModel> getSender(Long id, String key) {
// Define a projection that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
BaseColumns._ID,
SenderTable.SenderEntry.COLUMN_NAME_NAME,
SenderTable.SenderEntry.COLUMN_NAME_TYPE,
SenderTable.SenderEntry.COLUMN_NAME_STATUS,
SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING,
SenderTable.SenderEntry.COLUMN_NAME_TIME
};
// Define 'where' part of query.
String selection = " 1 ";
// Specify arguments in placeholder order.
List<String> selectionArgList = new ArrayList<>();
if (id != null) {
// Define 'where' part of query.
selection += " and " + SenderTable.SenderEntry._ID + " = ? ";
// Specify arguments in placeholder order.
selectionArgList.add(String.valueOf(id));
}
if (key != null) {
// Define 'where' part of query.
selection = " and (" + SenderTable.SenderEntry.COLUMN_NAME_NAME + " LIKE ? or " + SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING + " LIKE ? ) ";
// Specify arguments in placeholder order.
selectionArgList.add(key);
selectionArgList.add(key);
}
String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]);
// How you want the results sorted in the resulting Cursor
String sortOrder =
SenderTable.SenderEntry._ID + " DESC";
Cursor cursor = db.query(
SenderTable.SenderEntry.TABLE_NAME, // The table to query
projection, // The array of columns to return (pass null to get all)
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
List<SenderModel> tSenders = new ArrayList<>();
while (cursor.moveToNext()) {
long itemId = cursor.getLong(
cursor.getColumnIndexOrThrow(SenderTable.SenderEntry._ID));
String itemName = cursor.getString(
cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.COLUMN_NAME_NAME));
int itemStatus = cursor.getInt(
cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.COLUMN_NAME_STATUS));
int itemType = cursor.getInt(
cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.COLUMN_NAME_TYPE));
String itemJsonSetting = cursor.getString(
cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING));
long itemTime = cursor.getLong(
cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.COLUMN_NAME_TIME));
Log.d(TAG, "getSender: itemId" + itemId);
SenderModel senderModel = new SenderModel();
senderModel.setId(itemId);
senderModel.setName(itemName);
senderModel.setStatus(itemStatus);
senderModel.setType(itemType);
senderModel.setJsonSetting(itemJsonSetting);
senderModel.setTime(itemTime);
tSenders.add(senderModel);
}
cursor.close();
return tSenders;
}
public static int countSender(String key) {
// Define a projection that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
};
// Define 'where' part of query.
String selection = " 1 ";
// Specify arguments in placeholder order.
List<String> selectionArgList = new ArrayList<>();
if (key != null) {
// Define 'where' part of query.
selection = " and (" + SenderTable.SenderEntry.COLUMN_NAME_NAME + " LIKE ? or " + SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING + " LIKE ? ) ";
// Specify arguments in placeholder order.
selectionArgList.add(key);
selectionArgList.add(key);
}
String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]);
// How you want the results sorted in the resulting Cursor
Cursor cursor = db.query(
SenderTable.SenderEntry.TABLE_NAME, // The table to query
projection, // The array of columns to return (pass null to get all)
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
null // The sort order
);
int count = cursor.getCount();
cursor.close();
return count;
}
}

@ -0,0 +1,100 @@
package com.idormy.sms.forwarder.utils;
import android.os.Bundle;
import android.os.Handler;
import android.util.Base64;
import android.util.Log;
import java.io.IOException;
import java.net.URLEncoder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import static com.idormy.sms.forwarder.SenderActivity.NOTIFY;
public class SenderWebNotifyMsg {
static String TAG = "SenderWebNotifyMsg";
public static void sendMsg(final Handler handError, String token, String secret, String from, String content) throws Exception {
Log.i(TAG, "sendMsg token:" + token + " from:" + from + " content:" + content);
if (token == null || token.isEmpty()) {
return;
}
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("text/plain");
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("from", from)
.addFormDataPart("content", content);
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("UTF-8"), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
String sign = URLEncoder.encode(new String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8");
Log.i(TAG, "sign:" + sign);
builder.addFormDataPart("content", content);
}
RequestBody body = builder.build();
Request request = new Request.Builder()
.url(token)
.method("POST", body)
.build();
// Response response = client.newCall(request).execute();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
Log.d(TAG, "onFailure" + e.getMessage());
if (handError != null) {
android.os.Message msg = new android.os.Message();
msg.what = NOTIFY;
Bundle bundle = new Bundle();
bundle.putString("DATA", "发送失败:" + e.getMessage());
msg.setData(bundle);
handError.sendMessage(msg);
}
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseStr = response.body().string();
Log.d(TAG, "Code" + String.valueOf(response.code()) + responseStr);
if (handError != null) {
android.os.Message msg = new android.os.Message();
msg.what = NOTIFY;
Bundle bundle = new Bundle();
bundle.putString("DATA", "发送状态:" + responseStr);
msg.setData(bundle);
handError.sendMessage(msg);
Log.d(TAG, "Coxxyyde" + String.valueOf(response.code()) + responseStr);
}
}
});
}
}

@ -0,0 +1,74 @@
package com.idormy.sms.forwarder.utils;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
public class SettingUtil {
static Boolean hasInit = false;
private static String TAG = "SettingUtil";
private static SharedPreferences sp_setting = null;
private static Context context = null;
public static void init(Context context1) {
synchronized (hasInit) {
if (hasInit) return;
hasInit = true;
context = context1;
Log.d(TAG, "init ");
sp_setting = PreferenceManager.getDefaultSharedPreferences(context1);
}
}
public static boolean option_withreboot() {
return sp_setting.getBoolean("option_withreboot", false);
}
public static boolean using_dingding() {
return sp_setting.getBoolean("option_dingding_on", false);
}
public static String get_using_dingding_token() {
return sp_setting.getString("option_dingding_token", "");
}
public static String get_using_dingding_secret() {
return sp_setting.getString("option_dingding_secret", "");
}
public static boolean using_email() {
return sp_setting.getBoolean("option_email_on", false);
}
public static void set_send_util_email(String host, String port, String from_add, String psw, String to_add) {
Log.d(TAG, "set_send_util_email host:" + host + "port" + port + "from_add" + from_add + "psw" + psw + "to_add" + to_add);
//验证
if (host.equals("") || port.equals("") || from_add.equals("") || psw.equals("") || to_add.equals("")) {
return;
}
sp_setting.edit()
.putString(Define.SP_MSG_SEND_UTIL_EMAIL_HOST_KEY, host)
.putString(Define.SP_MSG_SEND_UTIL_EMAIL_PORT_KEY, port)
.putString(Define.SP_MSG_SEND_UTIL_EMAIL_FROMADD_KEY, from_add)
.putString(Define.SP_MSG_SEND_UTIL_EMAIL_PSW_KEY, psw)
.putString(Define.SP_MSG_SEND_UTIL_EMAIL_TOADD_KEY, to_add)
.apply();
}
public static String get_send_util_email(String key) {
Log.d(TAG, "get_send_util_email key" + key);
String defaultstt = "";
if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_HOST_KEY)) defaultstt = "stmp服务器";
if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_PORT_KEY)) defaultstt = "端口";
if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_FROMADD_KEY)) defaultstt = "发送邮箱";
if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_PSW_KEY)) defaultstt = "密码";
if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_TOADD_KEY)) defaultstt = "接收邮箱";
return sp_setting.getString(key, defaultstt);
}
public static boolean saveMsgHistory() {
return sp_setting.getBoolean("option_save_history_on", false);
}
}

@ -0,0 +1,124 @@
package com.idormy.sms.forwarder.utils;
import android.support.annotation.NonNull;
import android.util.Log;
import com.vector.update_app.HttpManager;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.FileCallBack;
import com.zhy.http.okhttp.callback.StringCallback;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Request;
import okhttp3.Response;
public class UpdateAppHttpUtil implements HttpManager {
/**
* get
*
* @param url get
* @param params get
* @param callBack
*/
@Override
public void asyncGet(@NonNull String url, @NonNull Map<String, String> params, @NonNull final HttpManager.Callback callBack) {
Log.i("UpdateAppHttpUtil", "asyncGet" + url);
Map<String, String> headers = new HashMap<>();
headers.put("heada", "bb");
OkHttpUtils.get()
.url(url)
.headers(headers)
.params(params)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Response response, Exception e, int id) {
Log.i("UpdateAppHttpUtil", "err response" + response);
callBack.onError(validateError(e, response));
}
@Override
public void onResponse(String response, int id) {
Log.i("UpdateAppHttpUtil", "response" + response);
callBack.onResponse(response);
}
});
}
/**
* post
*
* @param url post
* @param params post
* @param callBack
*/
@Override
public void asyncPost(@NonNull String url, @NonNull Map<String, String> params, @NonNull final HttpManager.Callback callBack) {
Log.i("UpdateAppHttpUtil", "asyncPost" + url);
// params.put("gggg","hhhh");
Map<String, String> headers = new HashMap<>();
headers.put("heada", "bb");
OkHttpUtils.post()
.url(url)
.headers(headers)
.params(params)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Response response, Exception e, int id) {
callBack.onError(validateError(e, response));
}
@Override
public void onResponse(String response, int id) {
callBack.onResponse(response);
}
});
}
/**
*
*
* @param url
* @param path
* @param fileName
* @param callback
*/
@Override
public void download(@NonNull String url, @NonNull String path, @NonNull String fileName, @NonNull final HttpManager.FileCallback callback) {
OkHttpUtils.get()
.url(url)
.build()
.execute(new FileCallBack(path, fileName) {
@Override
public void inProgress(float progress, long total, int id) {
callback.onProgress(progress, total);
}
@Override
public void onError(Call call, Response response, Exception e, int id) {
callback.onError(validateError(e, response));
}
@Override
public void onResponse(File response, int id) {
callback.onResponse(response);
}
@Override
public void onBefore(Request request, int id) {
super.onBefore(request, id);
callback.onBefore();
}
});
}
}

@ -0,0 +1,56 @@
package com.idormy.sms.forwarder.utils;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class aUtil {
private static String TAG = "aUtil";
private static Context context = null;
/**
* MIUIhttp://blog.csdn.net/xx326664162/article/details/52438706
*
* @return
*/
public static boolean isMIUI() {
try {
String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";
Properties prop = new Properties();
prop.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
|| prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
|| prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null;
} catch (final IOException e) {
return false;
}
}
public static String getVersionName(Context context) throws Exception {
// 获取packagemanager的实例
PackageManager packageManager = context.getPackageManager();
// getPackageName()是你当前类的包名0代表是获取版本信息
PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
String version = packInfo.versionName;
return version;
}
public static Integer getVersionCode(Context context) throws Exception {
// 获取packagemanager的实例
PackageManager packageManager = context.getPackageManager();
// getPackageName()是你当前类的包名0代表是获取版本信息
PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
Integer versionCode = packInfo.versionCode;
return versionCode;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M20,4L4,4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM20,8l-8,5 -8,-5L4,6l8,5 8,-5v2z" />
</vector>

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="设置名称" />
<EditText
android:id="@+id/editTextBarkName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="设置Bark-Server地址示例https://bark.bms.ink/XXXXXXXX/" />
<EditText
android:id="@+id/editTextBarkServer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<Button
android:id="@+id/buttonBarkOk"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/ok" />
<Button
android:id="@+id/buttonBarkDel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/del" />
<Button
android:id="@+id/buttonBarkTest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/test" />
</LinearLayout>
</LinearLayout>

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="设置名称" />
<EditText
android:id="@+id/editTextDingdingName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="设置Token 例如 https://oapi.dingtalk.com/robot/send?access_token=XXXXXX 中的 XXXXXX" />
<EditText
android:id="@+id/editTextDingdingToken"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="加签 Secret 没有可不填" />
<EditText
android:id="@+id/editTextDingdingSecret"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="转发时@某人 填写某人的手机号,多个用逗号分开 例如18888888888,19999999999" />
<EditText
android:id="@+id/editTextDingdingAtMobiles"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="是否@所有人。" />
<Switch
android:id="@+id/switchDingdingAtAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:checked="false"
android:ems="10" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<Button
android:id="@+id/buttondingdingok"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/ok" />
<Button
android:id="@+id/buttondingdingdel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/del" />
<Button
android:id="@+id/buttondingdingtest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/test" />
</LinearLayout>
</LinearLayout>

@ -0,0 +1,184 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="设置名称" />
<EditText
android:id="@+id/editTextEmailName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="stmp服务器" />
<EditText
android:id="@+id/editTextEmailHost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="端口" />
<EditText
android:id="@+id/editTextEmailPort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="是否开启ssl" />
<Switch
android:id="@+id/switchEmailSSl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:checked="true"
android:ems="10" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="用哪个邮箱发送" />
<EditText
android:id="@+id/editTextEmailFromAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:ems="10"
android:inputType="textEmailAddress"
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="密码" />
<EditText
android:id="@+id/editTextEmailPsw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="发到哪个邮件去" />
<EditText
android:id="@+id/editTextEmailToAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:ems="10"
android:inputType="textEmailAddress"
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<Button
android:id="@+id/buttonemailok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="@string/ok" />
<Button
android:id="@+id/buttonemaildel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:layout_weight="1"
android:text="@string/del" />
<Button
android:id="@+id/buttonemailtest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:layout_weight="1"
android:text="@string/test" />
</LinearLayout>
</LinearLayout>

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="设置名称" />
<EditText
android:id="@+id/editTextQYWXGroupRobotName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="设置WebHook地址:示例https://qyapi.weixin.qq.com/cgixx?key=xxx" />
<EditText
android:id="@+id/editTextQYWXGroupRobotWebHook"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<Button
android:id="@+id/buttonQyWxGroupRobotOk"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/ok" />
<Button
android:id="@+id/buttonQyWxGroupRobotDel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/del" />
<Button
android:id="@+id/buttonQyWxGroupRobotTest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/test" />
</LinearLayout>
</LinearLayout>

@ -0,0 +1,168 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="设置匹配的字段:选择全部转发后不再匹配下方的模式值直接使用发送方发送" />
<RadioGroup
android:id="@+id/radioGroupRuleFiled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/btnTranspondAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="转发全部" />
<RadioButton
android:id="@+id/btnPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="手机号" />
<RadioButton
android:id="@+id/btnContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="内容" />
</RadioGroup>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="设置匹配的模式" />
<RadioGroup
android:id="@+id/radioGroupRuleCheck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/btnIs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="是" />
<RadioButton
android:id="@+id/btnNotIs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="不是" />
<RadioButton
android:id="@+id/btnContain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="包含" />
<RadioButton
android:id="@+id/btnStartWith"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开头" />
<RadioButton
android:id="@+id/btnEndWith"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="结尾" />
</RadioGroup>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="设置匹配的值" />
<EditText
android:id="@+id/editTextRuleValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:id="@+id/ruleSenderTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="" />
<Button
android:id="@+id/btSetRuleSender"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置发送方">
</Button>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<Button
android:id="@+id/buttonruleok"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/ok" />
<Button
android:id="@+id/buttonruledel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/del" />
</LinearLayout>
</LinearLayout>

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="设置名称" />
<EditText
android:id="@+id/editTextWebNotifyName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="设置Token:示例https://a.b.com/msg?token=xyz" />
<EditText
android:id="@+id/editTextWebNotifyToken"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="设置Secret:置空则不计算sign" />
<EditText
android:id="@+id/editTextWebNotifySecret"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:ems="10"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<Button
android:id="@+id/buttonbebnotifyok"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/ok" />
<Button
android:id="@+id/buttonbebnotifydel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/del" />
<Button
android:id="@+id/buttonbebnotifytest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight="1"
android:text="@string/test" />
</LinearLayout>
</LinearLayout>

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.idormy.sms.forwarder.ReFlashListView
android:id="@+id/list_view_log"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:layout_weight="1" />
<!-- <ListView-->
<!-- android:id="@+id/list_view_log"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:layout_margin="8dp"-->
<!-- android:layout_weight="1" />-->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="9"
android:orientation="horizontal">
<Button
android:id="@+id/bt_refresh_log"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:layout_weight="1"
android:background="@android:color/holo_blue_dark"
android:onClick="cleanLog"
android:text="清空记录"
tools:ignore="NestedWeights" />
<Button
android:id="@+id/bt_rule_set"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:layout_weight="1"
android:background="@android:color/holo_blue_dark"
android:onClick="toRuleSetting"
android:text="设置转发规则"
tools:ignore="NestedWeights" />
<Button
android:id="@+id/bt_send_set"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:layout_weight="1"
android:background="@android:color/holo_blue_dark"
android:onClick="toSendSetting"
android:text="设置发送方" />
</LinearLayout>
</LinearLayout>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/list_view_rule"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:layout_weight="1" />
<Button
android:id="@+id/btaddrule"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10px"
android:layout_weight="9"
android:background="@android:color/holo_blue_dark"
android:text="添加转发规则"
tools:ignore="NestedWeights" />
</LinearLayout>

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/list_view_sender"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:layout_weight="1" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="9"
android:orientation="horizontal">
<Button
android:id="@+id/button22"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:layout_weight="1"
android:background="@android:color/holo_blue_dark"
android:onClick="addSender"
android:text="添加"
tools:ignore="NestedWeights" />
</LinearLayout>
</LinearLayout>

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="20dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="当前版本" />
<TextView
android:id="@+id/version_now"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
android:text="v1.0" />
</LinearLayout>
<Button
android:id="@+id/check_version_now"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="检查新版本" />
</LinearLayout>
<LinearLayout
android:id="@+id/auto_reboot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="20dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="开机启动" />
<Switch
android:id="@+id/switch_with_reboot"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:gravity="end"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/about_web"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="20dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="官网" />
<TextView
android:id="@+id/linkweb"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:autoLink="web"
android:gravity="right"
android:text="idormy.com"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_wait_open_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="20dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="用户交流群" />
<TextView
android:id="@+id/tv_wait_open_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:text="562854376"
android:textColor="@color/colorPrimary"
android:textIsSelectable="true"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/feedback"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="20dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="建议反馈" />
<TextView
android:id="@+id/feedback_commit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:onClick="feedbackcommit"
android:text="提交反馈"
android:textColor="@color/colorPrimary"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

@ -0,0 +1,28 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/xxxxxx"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/feedback_et_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginTop="16dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="4dp"
android:hint="邮箱"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/feedback_et_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginTop="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="16dp"
android:fontFamily="sans-serif"
android:hint="内容" />
</LinearLayout>

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dip"
android:paddingBottom="10dip">
<LinearLayout
android:id="@+id/layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下拉可以刷新!" />
<TextView
android:id="@+id/lastupdate_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<ImageView
android:id="@+id/arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dip"
android:layout_toLeftOf="@id/layout"
android:src="@android:drawable/ic_popup_sync" />
<ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dip"
android:layout_toLeftOf="@id/layout"
android:visibility="gone" />
</RelativeLayout>
</LinearLayout>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/rule_match"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="10dp" />
<TextView
android:id="@+id/rule_sender"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="10dp" />
</LinearLayout>

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/sender_image"
android:layout_width="50dp"
android:layout_height="50dp" />
<TextView
android:id="@+id/sender_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp" />
</LinearLayout>

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dip"
android:paddingBottom="10dip">
<TextView
android:id="@+id/tlog_from"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginStart="10dp"
android:textColor="@android:color/black"
android:textColorHighlight="@android:color/holo_red_dark" />
<TextView
android:id="@+id/tlog_rule"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginStart="10dp" />
<ImageView
android:id="@+id/tlog_sender_image"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentEnd="true" />
</RelativeLayout>
<TextView
android:id="@+id/tlog_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp" />
</LinearLayout>

@ -0,0 +1,11 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.allmything.linkhelper.MainActivity">
<item
android:id="@+id/to_setting"
android:orderInCategory="100"
android:title="@string/to_setting"
app:showAsAction="never" />
</menu>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/qywx_background" />
<foreground android:drawable="@mipmap/qywx_foreground" />
</adaptive-icon>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/qywx_background" />
<foreground android:drawable="@mipmap/qywx_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save