Skip to content

Commit

Permalink
Merge pull request #11 from optimalstrategy/update-checking-and-start…
Browse files Browse the repository at this point in the history
…up-on-boot

Update checking, startup on boot, test messages
  • Loading branch information
optimalstrategy authored Mar 25, 2021
2 parents 019f636 + ae030c8 commit 76c43ad
Show file tree
Hide file tree
Showing 10 changed files with 275 additions and 6 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,12 @@ Tap accept to confirm. This will also turn off forwarding.
<p align="center">
<img src="screenshots/reset_settings_popup.jpg" width="288" height="608">
</p>


## Global Settings and Launch on Startup
By default, the app will automatically launch on startup.
This option can be disabled in the global app settings that can be accessed by tapping the gear icon:

<p align="center">
<img src="screenshots/app_settings.jpg" width="288" height="608">
</p>
7 changes: 7 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,12 @@
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
<receiver
android:enabled="true"
android:name=".StartSmsForwarderServiceAtBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package team.whatever.sms_forwarder_app;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;


import static android.content.Context.MODE_PRIVATE;

class StartSmsForwarderServiceAtBootReceiver extends BroadcastReceiver {
private static final String TAG = StartSmsForwarderServiceAtBootReceiver.class.getSimpleName();

@Override
public void onReceive(Context context, Intent intent) {
Handler h = new Handler();
h.post(new Runnable() {
@Override
public void run() {
final SharedPreferences prefs = context.getSharedPreferences(
"FlutterSharedPreferences",
MODE_PRIVATE
);
final boolean launchOnStartup = prefs.getBoolean("flutter.launch_on_startup", true);
if (launchOnStartup) {
Intent intent_ = new Intent(context, MainActivity.class);
intent_.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent_);
}
}
});
}
}
156 changes: 156 additions & 0 deletions lib/app_settings.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sms_forwarder/background_forwarder.dart';
import 'package:telephony/telephony.dart';

class SettingStrings {
static final String launchOnStartup = "launch_on_startup";
}

/// A screen with the App's settings.
class AppSettingsScreen extends StatefulWidget {
const AppSettingsScreen(this.fwd, {Key key}) : super(key: key);

final BackgroundForwarder fwd;

@override
_AppSettingsScreenState createState() => _AppSettingsScreenState(this.fwd);
}

class _AppSettingsScreenState extends State<AppSettingsScreen> {
_AppSettingsScreenState(this.fwd);

final BackgroundForwarder fwd;

OutlineInputBorder _testMessageBorder;
TextEditingController _testMessageController;

bool _launchOnStartup = true;
Map<String, bool> _forwardingResults;

@override
void initState() {
super.initState();

_testMessageController = new TextEditingController(text: "Test message");
_testMessageController.addListener(_onTextChanged);
setState(_onTextChanged);

_forwardingResults = {
"HttpCallbackForwarder": null,
"TelegramBotForwarder": null,
"DeployedTelegramBotForwarder": null,
};

fwd.loadFromPrefs();
SharedPreferences.getInstance().then((prefs) {
setState(() {
_launchOnStartup =
prefs.getBool(SettingStrings.launchOnStartup) ?? true;
});
});
}

void _onTextChanged() {
setState(() {
_testMessageBorder = OutlineInputBorder(
borderSide: BorderSide(
color: _testMessageController.text.length > 0
? Colors.green
: Colors.red));
});
}

void _updatePreferences() async {
final instance = await SharedPreferences.getInstance();
instance.setBool(SettingStrings.launchOnStartup, _launchOnStartup);
}

void _testForwarders() async {
// ignore: invalid_use_of_visible_for_testing_member
final results = await fwd.mgr.forward(SmsMessage.fromMap({
"address": "SmsForwarder",
"body": _testMessageController.text,
"date": DateTime.now().millisecondsSinceEpoch.toString(),
}, [
SmsColumn.ADDRESS,
SmsColumn.BODY,
SmsColumn.DATE,
]));
setState(() {
_forwardingResults = results;
});
}

@override
Widget build(BuildContext context) {
final results = _forwardingResults.keys.toList(growable: false);
return Scaffold(
appBar: AppBar(
title: Text("App Settings"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Row(children: <Widget>[
Text(
"Launch on Startup: ",
style: TextStyle(fontSize: 20),
),
Switch(
activeColor: Colors.green,
value: _launchOnStartup,
onChanged: (value) {
setState(() => _launchOnStartup = value);
_updatePreferences();
},
)
], mainAxisAlignment: MainAxisAlignment.spaceAround),
Column(children: <Widget>[
Container(
child: TextField(
controller: _testMessageController,
decoration: InputDecoration(
border: _testMessageBorder,
enabledBorder: _testMessageBorder,
disabledBorder: _testMessageBorder,
hintText: "Enter a test message"),
),
width: 350,
),
ElevatedButton(
child: Text('Send Test Message'),
onPressed: _testForwarders,
),
ListView.builder(
padding: const EdgeInsets.all(8),
shrinkWrap: true,
itemCount: results.length,
itemBuilder: (context, index) {
final forwarder = results[index];
final result = _forwardingResults[forwarder];
Color color;
if (result == null) {
color = Colors.grey;
} else if (result) {
color = Colors.green;
} else {
color = Colors.red[200];
}
return Container(
height: 50,
child: Center(child: Text(forwarder)),
decoration:
BoxDecoration(border: Border.all(), color: color),
margin: EdgeInsets.symmetric(vertical: 1),
);
},
)
])
],
),
),
);
}
}
4 changes: 2 additions & 2 deletions lib/forwarding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ abstract class HttpForwarder implements AbstractForwarder {
// TODO: remove debug prints
debugPrint("Response status: ${response.statusCode}.");
debugPrint("Response body: \'${response.body}\'.");
return response.statusCode == 200;
return response.statusCode >= 200 && response.statusCode < 400;
});
}
}
Expand Down Expand Up @@ -231,7 +231,7 @@ class TelegramBotForwarder extends AbstractForwarder with HttpForwarder {
/// Telegram chat id.
int get chatId => _chatId;

/// Creates a new TelegramBotForwared instance.
/// Creates a new TelegramBotForwarder instance.
TelegramBotForwarder(this._token, this._chatId);

/// Creates a new TelegramBotForwarder instances from [json].
Expand Down
44 changes: 41 additions & 3 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sms_forwarder/update_checker.dart';
import 'package:telephony/telephony.dart';
import 'package:url_launcher/url_launcher.dart';

import 'app_settings.dart';
import 'forwarding.dart';
import 'key_value_settings.dart';
import 'background_forwarder.dart';
Expand All @@ -24,7 +26,7 @@ class MyApp extends StatelessWidget {
theme: new ThemeData(
primarySwatch: Colors.green,
),
home: new HomePage(title: 'SMS Forwarder (v1.4.0)', fwd: this.fwd),
home: new HomePage(title: 'SMS Forwarder ($APP_VERSION)', fwd: this.fwd),
);
}
}
Expand All @@ -47,6 +49,8 @@ class _HomePageState extends State<HomePage> {
Color _tgBotBtnState = _yellowColor;
Color _callbackBtnState = _yellowColor;

bool _isUpdateAvailable;

@override
void initState() {
super.initState();
Expand Down Expand Up @@ -80,12 +84,39 @@ class _HomePageState extends State<HomePage> {
borderRadius: BorderRadius.all(Radius.circular(1))));
}

TextButton _getUpdateButton() {
IconData icon;
String label;

if (_isUpdateAvailable == null) {
icon = Icons.autorenew;
label = "Checking for updates...";
isUpdateAvailable().then((b) {
setState(() => _isUpdateAvailable = b);
});
} else if (_isUpdateAvailable) {
icon = Icons.update_sharp;
label = "An update is available";
} else {
icon = Icons.check;
label = "App is up to date";
}

return TextButton.icon(
onPressed: () async => await launch(GITHUB_URL),
icon: Icon(icon, color: Colors.white),
label: Text(
label,
style: TextStyle(fontSize: 12, color: Colors.white),
),
);
}

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
title: new Text(widget.title), actions: <Widget>[_getUpdateButton()]),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
Expand Down Expand Up @@ -152,6 +183,13 @@ class _HomePageState extends State<HomePage> {
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => showDialog(
context: context,
builder: (_) => AppSettingsScreen(this.widget.fwd)),
tooltip: "App Settings",
child: Icon(Icons.settings),
),
);
}
}
Expand Down
25 changes: 25 additions & 0 deletions lib/update_checker.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'dart:convert';
import 'dart:io';

import 'package:http/http.dart' as http;

const String APP_VERSION = "v1.5.0";
const String GITHUB_URL = "https://github.com/optimalstrategy/"
"sms_forwarder_app/releases/latest";
const String GITHUB_API_URL = "https://api.github.com/repos/"
+ "optimalstrategy/sms_forwarder_app/releases/latest";

Future<bool> isUpdateAvailable() async {
try {
var r = await http.get(GITHUB_API_URL);
if (r.statusCode != 200) return false;
var json = jsonDecode(r.body);
return json["tag_name"] != APP_VERSION;
} on HttpException {
return false;
} on JsonUnsupportedObjectError {
return false;
} on StateError {
return false;
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: sms_forwarder
description: An SMS forwarding application.
version: 1.4.0
version: 1.5.0

environment:
sdk: '>=2.10.0 <3.0.0'
Expand Down
Binary file added screenshots/app_settings.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/main_screen.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 76c43ad

Please sign in to comment.