diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ae21cc94 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +.idea/ +.gradle +.git +build +local.properties +*.iml +*.project +*/*.project +*.classpath +*/*.classpath +.settings/* +*/.settings/* \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..9bf6174c --- /dev/null +++ b/README.md @@ -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,修复Android9,Android10版本闪退。3,添加更新接口。4,修复bug + +> v1.1 减少手动配置启动参数:自启动配置、自动开启热点配置(设置好后手机重启也不用重新打开了,还能自动为pad开启热点) +热点管理 +可设置跟随设备启动时启动热点,并且在热点关闭后10秒自动重启热点(所以想关闭热点先把设置页码的开启热点关掉) +(热点助手功能会在后期2020/07/29转移到单独的APP)详见[https://www.jianshu.com/p/f70cf475eddc] + +> v1.0 项目初始化,实现转发 + + +## LICENSE +BSD diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000..c4192631 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 00000000..1bdcb348 --- /dev/null +++ b/app/build.gradle @@ -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" + +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 00000000..f1b42451 --- /dev/null +++ b/app/proguard-rules.pro @@ -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 diff --git a/app/release/output.json b/app/release/output.json new file mode 100644 index 00000000..652798b0 --- /dev/null +++ b/app/release/output.json @@ -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": {} + } +] \ No newline at end of file diff --git a/app/src/androidTest/java/com/idormy/sms/forwarder/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/idormy/sms/forwarder/ExampleInstrumentedTest.kt new file mode 100644 index 00000000..7b7e4af7 --- /dev/null +++ b/app/src/androidTest/java/com/idormy/sms/forwarder/ExampleInstrumentedTest.kt @@ -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) + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a14384b8 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 00000000..1760b0ae Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/MessageBroadcastReceiver.java b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/MessageBroadcastReceiver.java new file mode 100644 index 00000000..c1466a50 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/MessageBroadcastReceiver.java @@ -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(); + } + + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/RebootBroadcastReceiver.java b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/RebootBroadcastReceiver.java new file mode 100644 index 00000000..96cdacbe --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/RebootBroadcastReceiver.java @@ -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); + } + } + + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/TSMSBroadcastReceiver.java b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/TSMSBroadcastReceiver.java new file mode 100644 index 00000000..5aace446 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/TSMSBroadcastReceiver.java @@ -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 smsVoList = new ArrayList<>(); + String format = intent.getStringExtra("format"); + Map 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()); + } + + } + + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/FrontService.java b/app/src/main/java/com/idormy/sms/forwarder/FrontService.java new file mode 100644 index 00000000..10b35002 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/FrontService.java @@ -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; + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/MainActivity.java b/app/src/main/java/com/idormy/sms/forwarder/MainActivity.java new file mode 100644 index 00000000..97da1284 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/MainActivity.java @@ -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 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 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); + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/MyApplication.java b/app/src/main/java/com/idormy/sms/forwarder/MyApplication.java new file mode 100644 index 00000000..e476b40d --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/MyApplication.java @@ -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"; + + /** + * + * + * + * @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); + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/ReFlashListView.java b/app/src/main/java/com/idormy/sms/forwarder/ReFlashListView.java new file mode 100644 index 00000000..ea15a998 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/ReFlashListView.java @@ -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(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/RuleActivity.java b/app/src/main/java/com/idormy/sms/forwarder/RuleActivity.java new file mode 100644 index 00000000..c455eaf5 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/RuleActivity.java @@ -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 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 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 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); + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java b/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java new file mode 100644 index 00000000..b1306585 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java @@ -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 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); + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/SettingActivity.java b/app/src/main/java/com/idormy/sms/forwarder/SettingActivity.java new file mode 100644 index 00000000..1add46a7 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/SettingActivity.java @@ -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 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(); + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/adapter/LogAdapter.java b/app/src/main/java/com/idormy/sms/forwarder/adapter/LogAdapter.java new file mode 100644 index 00000000..a3f5e694 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/adapter/LogAdapter.java @@ -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 { + private int resourceId; + private List list; + + // 适配器的构造函数,把要适配的数据传入这里 + public LogAdapter(Context context, int textViewResourceId, List 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 logVos) { + if (list != null) { + list = logVos; + notifyDataSetChanged(); + } + } + + public void del(List logVos) { + if (list != null) { + list = logVos; + notifyDataSetChanged(); + } + } + + public void update(List logVos) { + if (list != null) { + list = logVos; + notifyDataSetChanged(); + } + } + + public void onDateChange(List logVos) { + list = logVos; + notifyDataSetChanged(); + } + + // 定义一个内部类,用于对控件的实例进行缓存 + class ViewHolder { + TextView tLogFrom; + TextView tLogContent; + TextView tLogRule; + ImageView senderImage; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/adapter/RuleAdapter.java b/app/src/main/java/com/idormy/sms/forwarder/adapter/RuleAdapter.java new file mode 100644 index 00000000..354e5e5d --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/adapter/RuleAdapter.java @@ -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 { + private int resourceId; + private List list; + + // 适配器的构造函数,把要适配的数据传入这里 + public RuleAdapter(Context context, int textViewResourceId, List 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 = 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 ruleModels) { + if (list != null) { + list = ruleModels; + notifyDataSetChanged(); + } + } + + public void del(List ruleModels) { + if (list != null) { + list = ruleModels; + notifyDataSetChanged(); + } + } + + public void update(List ruleModels) { + if (list != null) { + list = ruleModels; + notifyDataSetChanged(); + } + } + + // 定义一个内部类,用于对控件的实例进行缓存 + class ViewHolder { + TextView ruleMatch; + TextView ruleSender; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/adapter/SenderAdapter.java b/app/src/main/java/com/idormy/sms/forwarder/adapter/SenderAdapter.java new file mode 100644 index 00000000..abb25860 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/adapter/SenderAdapter.java @@ -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 { + private int resourceId; + private List list; + + // 适配器的构造函数,把要适配的数据传入这里 + public SenderAdapter(Context context, int textViewResourceId, List 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 senderModels) { + if (list != null) { + list = senderModels; + notifyDataSetChanged(); + } + } + + public void del(List senderModels) { + if (list != null) { + list = senderModels; + notifyDataSetChanged(); + } + } + + public void update(List senderModels) { + if (list != null) { + list = senderModels; + notifyDataSetChanged(); + } + } + + // 定义一个内部类,用于对控件的实例进行缓存 + class ViewHolder { + ImageView senderImage; + TextView senderName; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/LogModel.java b/app/src/main/java/com/idormy/sms/forwarder/model/LogModel.java new file mode 100644 index 00000000..322a2c28 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/LogModel.java @@ -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 + + '}'; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/LogTable.java b/app/src/main/java/com/idormy/sms/forwarder/model/LogTable.java new file mode 100644 index 00000000..74008890 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/LogTable.java @@ -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"; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/RuleModel.java b/app/src/main/java/com/idormy/sms/forwarder/model/RuleModel.java new file mode 100644 index 00000000..15f76064 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/RuleModel.java @@ -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 FILED_MAP = new HashMap(); + 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 CHECK_MAP = new HashMap(); + + 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 + + '}'; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/RuleTable.java b/app/src/main/java/com/idormy/sms/forwarder/model/RuleTable.java new file mode 100644 index 00000000..d1dd54f7 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/RuleTable.java @@ -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"; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/SenderModel.java b/app/src/main/java/com/idormy/sms/forwarder/model/SenderModel.java new file mode 100644 index 00000000..2396d117 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/SenderModel.java @@ -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 + + '}'; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/SenderTable.java b/app/src/main/java/com/idormy/sms/forwarder/model/SenderTable.java new file mode 100644 index 00000000..8c0a49af --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/SenderTable.java @@ -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"; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/BarkSettingVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/BarkSettingVo.java new file mode 100644 index 00000000..fabd9e79 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/BarkSettingVo.java @@ -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; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/DingDingSettingVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/DingDingSettingVo.java new file mode 100644 index 00000000..2057efe4 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/DingDingSettingVo.java @@ -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; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/EmailSettingVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/EmailSettingVo.java new file mode 100644 index 00000000..b771c2bc --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/EmailSettingVo.java @@ -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; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/FeedBackResult.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/FeedBackResult.java new file mode 100644 index 00000000..1c85a619 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/FeedBackResult.java @@ -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 + + '}'; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/LogVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/LogVo.java new file mode 100644 index 00000000..4df8843f --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/LogVo.java @@ -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; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/QYWXGroupRobotSettingVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/QYWXGroupRobotSettingVo.java new file mode 100644 index 00000000..045256f8 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/QYWXGroupRobotSettingVo.java @@ -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; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/RuleVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/RuleVo.java new file mode 100644 index 00000000..702844ad --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/RuleVo.java @@ -0,0 +1,6 @@ +package com.idormy.sms.forwarder.model.vo; + +public class RuleVo { + private String matchStr; + private String senderStr; +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/SmsVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/SmsVo.java new file mode 100644 index 00000000..8bea6c13 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/SmsVo.java @@ -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 + + '}'; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/WebNotifySettingVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/WebNotifySettingVo.java new file mode 100644 index 00000000..7c4232be --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/WebNotifySettingVo.java @@ -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; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/DbHelper.java b/app/src/main/java/com/idormy/sms/forwarder/utils/DbHelper.java new file mode 100644 index 00000000..d951266b --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/DbHelper.java @@ -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 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 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); + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/Define.java b/app/src/main/java/com/idormy/sms/forwarder/utils/Define.java new file mode 100644 index 00000000..ef7018a9 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/Define.java @@ -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"; +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/DingdingMsg.java b/app/src/main/java/com/idormy/sms/forwarder/utils/DingdingMsg.java new file mode 100644 index 00000000..0b329efd --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/DingdingMsg.java @@ -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 += "×tamp=" + 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); + } + }); + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/HttpI.java b/app/src/main/java/com/idormy/sms/forwarder/utils/HttpI.java new file mode 100644 index 00000000..2c6f645f --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/HttpI.java @@ -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 params, @NonNull Callback callBack); + + + /** + * 异步post + * + * @param url post请求地址 + * @param params post请求参数 + * @param callBack 回调 + */ + void asyncPost(@NonNull String url, @NonNull Map 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); + } +} + diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/HttpUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/HttpUtil.java new file mode 100644 index 00000000..b0cb782c --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/HttpUtil.java @@ -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 params, @NonNull final Callback callBack) { + params.put("aaa", "bbbbb"); + params.put("ccc", "ddd"); + Map 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 params, @NonNull final Callback callBack) { + params.put("eeee", "fff"); + params.put("gggg", "hhhh"); + Map 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(); + } + }); + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/InitUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/InitUtil.java new file mode 100644 index 00000000..9b33957e --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/InitUtil.java @@ -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); + } + + + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/LogUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/LogUtil.java new file mode 100644 index 00000000..c35f9ed3 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/LogUtil.java @@ -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 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 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 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 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; + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/MailInfo.java b/app/src/main/java/com/idormy/sms/forwarder/utils/MailInfo.java new file mode 100644 index 00000000..9a562322 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/MailInfo.java @@ -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; + } +} + diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/MailSender.java b/app/src/main/java/com/idormy/sms/forwarder/utils/MailSender.java new file mode 100644 index 00000000..f52c41a3 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/MailSender.java @@ -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; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/MailSenderInfo.java b/app/src/main/java/com/idormy/sms/forwarder/utils/MailSenderInfo.java new file mode 100644 index 00000000..51d2d95b --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/MailSenderInfo.java @@ -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; + } +} + diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/MyAuthenticator.java b/app/src/main/java/com/idormy/sms/forwarder/utils/MyAuthenticator.java new file mode 100644 index 00000000..6c78d78a --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/MyAuthenticator.java @@ -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); + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/RuleUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/RuleUtil.java new file mode 100644 index 00000000..f487806f --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/RuleUtil.java @@ -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 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 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 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 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; + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SendHistory.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SendHistory.java new file mode 100644 index 00000000..fb17f8fd --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SendHistory.java @@ -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 msg_set_default = new HashSet<>(); + Set 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 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 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 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 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 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; + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SendMailUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SendMailUtil.java new file mode 100644 index 00000000..129e04ea --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SendMailUtil.java @@ -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) { + *

+ * 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()); + * } + */ \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SendUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SendUtil.java new file mode 100644 index 00000000..429f022e --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SendUtil.java @@ -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 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 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 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; + } + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SenderBarkMsg.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderBarkMsg.java new file mode 100644 index 00000000..2e52a1ba --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderBarkMsg.java @@ -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©=" + 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); + } + + } + }); + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SenderDingdingMsg.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderDingdingMsg.java new file mode 100644 index 00000000..ed40e3d1 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderDingdingMsg.java @@ -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 += "×tamp=" + 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 += "×tamp=" + 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 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); + } + + } + }); + } + + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SenderMailMsg.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderMailMsg.java new file mode 100644 index 00000000..37641217 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderMailMsg.java @@ -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) { + *

+ * 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()); + * } + */ \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SenderQyWxGroupRobotMsg.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderQyWxGroupRobotMsg.java new file mode 100644 index 00000000..63dadbc3 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderQyWxGroupRobotMsg.java @@ -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); + } + + } + }); + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SenderUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderUtil.java new file mode 100644 index 00000000..1ea75100 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderUtil.java @@ -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 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 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 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 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 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; + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SenderWebNotifyMsg.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderWebNotifyMsg.java new file mode 100644 index 00000000..54560215 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderWebNotifyMsg.java @@ -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); + } + + } + }); + } + + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java new file mode 100644 index 00000000..213cab6f --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java @@ -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); + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/UpdateAppHttpUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/UpdateAppHttpUtil.java new file mode 100644 index 00000000..76b75f4b --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/UpdateAppHttpUtil.java @@ -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 params, @NonNull final HttpManager.Callback callBack) { + Log.i("UpdateAppHttpUtil", "asyncGet" + url); + Map 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 params, @NonNull final HttpManager.Callback callBack) { + Log.i("UpdateAppHttpUtil", "asyncPost" + url); + +// params.put("gggg","hhhh"); + Map 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(); + } + }); + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/aUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/aUtil.java new file mode 100644 index 00000000..7a138c29 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/aUtil.java @@ -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; + + /** + * 判断是否为MIUI系统,参考http://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; + } +} diff --git a/app/src/main/qywx-playstore.png b/app/src/main/qywx-playstore.png new file mode 100644 index 00000000..6816f0c1 Binary files /dev/null and b/app/src/main/qywx-playstore.png differ diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 00000000..1f6bb290 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_baseline_email_24.xml b/app/src/main/res/drawable/ic_baseline_email_24.xml new file mode 100644 index 00000000..2c852177 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_email_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..07d5da9c --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_alter_dialog_setview_bark.xml b/app/src/main/res/layout/activity_alter_dialog_setview_bark.xml new file mode 100644 index 00000000..81120bf3 --- /dev/null +++ b/app/src/main/res/layout/activity_alter_dialog_setview_bark.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +