Skip to content

Commit 0ddff28

Browse files
committed
Add option to notify user if a Freifunk network is available.
1 parent 5859e93 commit 0ddff28

File tree

16 files changed

+354
-4
lines changed

16 files changed

+354
-4
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## [unreleased] [unreleased]
44
### Added
55
- New SSIDs.
6+
- Option to notify the user if a freifunk network is available.
67

78
### Changed
89
- SSIDs will now be sorted by the app on start up.

app/src/main/AndroidManifest.xml

+13
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,25 @@
3333
android:name="android.support.PARENT_ACTIVITY"
3434
android:value="com.example.tobiastrumm.freifunkautoconnect.MainActivity" />
3535
</activity>
36+
3637
<service
3738
android:name=".AddAllNetworksService"
3839
android:exported="false" />
3940
<service
4041
android:name=".RemoveAllNetworksService"
4142
android:exported="false" />
43+
<service
44+
android:name=".NotificationService"
45+
android:exported="false" />
46+
47+
<activity
48+
android:name=".SettingsActivity"
49+
android:label="@string/title_activity_settings"
50+
android:parentActivityName=".MainActivity" >
51+
<meta-data
52+
android:name="android.support.PARENT_ACTIVITY"
53+
android:value="com.example.tobiastrumm.freifunkautoconnect.MainActivity" />
54+
</activity>
4255
</application>
4356

4457
</manifest>

app/src/main/java/com/example/tobiastrumm/freifunkautoconnect/MainActivity.java

+30-4
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
import android.content.Context;
88
import android.content.Intent;
99
import android.content.IntentFilter;
10+
import android.content.SharedPreferences;
1011
import android.media.MediaScannerConnection;
1112
import android.net.Uri;
1213
import android.net.wifi.WifiConfiguration;
1314
import android.net.wifi.WifiManager;
1415
import android.os.Bundle;
1516
import android.os.Environment;
17+
import android.preference.PreferenceManager;
1618
import android.support.v4.content.LocalBroadcastManager;
1719
import android.support.v4.view.MenuItemCompat;
1820
import android.support.v7.app.ActionBarActivity;
@@ -37,8 +39,8 @@
3739

3840
public class MainActivity extends ActionBarActivity implements AdapterView.OnItemClickListener, RemoveAllDialogFragment.OnRemoveAllListener, AddAllDialogFragment.OnAddAllListener{
3941

40-
private static String DIRECTORY = "freifunkautoconnect";
41-
private static String USER_SSIDS_FILE = "user_ssids.csv";
42+
public static String DIRECTORY = "freifunkautoconnect";
43+
public static String USER_SSIDS_FILE = "user_ssids.csv";
4244

4345
private static final String STATE_PROGRESSBAR_RUNNING = "state_progressbar_running";
4446
private static final String STATE_PROGRESSBAR_MAX = "state_progressbar_max";
@@ -222,6 +224,13 @@ protected void onCreate(Bundle savedInstanceState) {
222224
wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
223225
setupUI();
224226

227+
// Start NotificationService if it should running but isn't
228+
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
229+
boolean notifications = sharedPref.getBoolean("pref_notification", false);
230+
if(notifications && !isNotificationServiceRunning()){
231+
startService(new Intent(this, NotificationService.class));
232+
}
233+
225234
}
226235

227236
@Override
@@ -287,6 +296,13 @@ public boolean onOptionsItemSelected(MenuItem item) {
287296
return true;
288297
}
289298

299+
else if (id == R.id.action_settings){
300+
Intent intent = new Intent(MainActivity.this, SettingsActivity.class);
301+
startActivity(intent);
302+
return true;
303+
}
304+
305+
290306
return super.onOptionsItemSelected(item);
291307
}
292308

@@ -318,9 +334,9 @@ public void addAllNetworks(){
318334

319335
public void onClickRemoveAllNetworks(View view){
320336
RemoveAllDialogFragment df = new RemoveAllDialogFragment();
321-
df.show(this.getFragmentManager(),"");
337+
df.show(this.getFragmentManager(), "");
322338
}
323-
339+
324340
public void removeAllNetworks(){
325341
// Create ProgressDialog and show it
326342
progressBarMax = networks.size();
@@ -411,5 +427,15 @@ private boolean isRemoveAllNetworkServiceRunning(){
411427
}
412428
return false;
413429
}
430+
431+
private boolean isNotificationServiceRunning(){
432+
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
433+
for ( ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
434+
if(NotificationService.class.getName().equals(service.service.getClassName())) {
435+
return true;
436+
}
437+
}
438+
return false;
439+
}
414440
}
415441

app/src/main/java/com/example/tobiastrumm/freifunkautoconnect/Network.java

+16
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,22 @@ public int compareTo(Network o) {
2323
return ssid1.compareToIgnoreCase(ssid2);
2424
}
2525

26+
@Override
27+
public int hashCode() {
28+
return ssid.hashCode();
29+
}
30+
31+
@Override
32+
public boolean equals(Object o) {
33+
if(!(o instanceof Network)){
34+
return false;
35+
}
36+
if(o == this){
37+
return true;
38+
}
39+
return hashCode() == ((Network)o).hashCode();
40+
}
41+
2642
@Override
2743
public int describeContents() {
2844
return 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package com.example.tobiastrumm.freifunkautoconnect;
2+
3+
import android.app.NotificationManager;
4+
import android.app.PendingIntent;
5+
import android.app.Service;
6+
import android.content.BroadcastReceiver;
7+
import android.content.Context;
8+
import android.content.Intent;
9+
import android.content.IntentFilter;
10+
import android.net.wifi.ScanResult;
11+
import android.net.wifi.WifiManager;
12+
import android.os.Environment;
13+
import android.os.IBinder;
14+
import android.provider.Settings;
15+
import android.support.v4.app.NotificationCompat;
16+
import android.util.Log;
17+
18+
import java.io.BufferedReader;
19+
import java.io.File;
20+
import java.io.FileInputStream;
21+
import java.io.IOException;
22+
import java.io.InputStreamReader;
23+
import java.util.ArrayList;
24+
import java.util.Collections;
25+
import java.util.List;
26+
27+
/**
28+
* Created by Tobias on 29.07.2015.
29+
*/
30+
public class NotificationService extends Service {
31+
32+
private final static String TAG = NotificationService.class.getSimpleName();
33+
private final static int NOTIFICATION_ID = 1;
34+
35+
private List<Network> networks;
36+
private List<Network> foundNetworks = new ArrayList<>();
37+
38+
private WifiReceiver wifiReceiver;
39+
40+
private NotificationManager mNotificationManager;
41+
42+
private class WifiReceiver extends BroadcastReceiver{
43+
private WifiReceiver(){}
44+
45+
@Override
46+
public void onReceive(Context context, Intent intent) {
47+
Log.d(TAG, "onReceive was called");
48+
boolean alreadyConnected = false;
49+
50+
WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
51+
List<ScanResult> results = wm.getScanResults();
52+
List<Network> oldFoundNetworks = new ArrayList<>(foundNetworks);
53+
foundNetworks = new ArrayList<>();
54+
55+
if(results != null){
56+
// Look if known Freifunk networks are in reach.
57+
for(ScanResult r: results){
58+
Network compareWith = new Network('"' + r.SSID + '"');
59+
if(networks.contains(compareWith)){
60+
foundNetworks.add(compareWith);
61+
}
62+
}
63+
64+
// Look if device is already connected to a known Freifunk network
65+
String currentSSID = wm.getConnectionInfo().getSSID();
66+
if(currentSSID != null){
67+
Log.d(TAG, "Check if " + currentSSID + " is a Freifunk network");
68+
Network compareWith = new Network(currentSSID);
69+
if(foundNetworks.contains(compareWith)){
70+
alreadyConnected = true;
71+
Log.d(TAG, "Already connected with " + compareWith.ssid);
72+
}
73+
}
74+
75+
// Look if this scan found different Freifunk networks than the previous scan.
76+
boolean sameResults = oldFoundNetworks.containsAll(foundNetworks);
77+
78+
String foundNetworksStr = "";
79+
for(Network n: foundNetworks){
80+
foundNetworksStr += n.ssid + ", ";
81+
}
82+
Log.d(TAG, "Found networks: " + foundNetworksStr);
83+
84+
String oldfoundNetworksStr = "";
85+
for(Network n: oldFoundNetworks){
86+
oldfoundNetworksStr += n.ssid + ", ";
87+
}
88+
Log.d(TAG, "Old Found networks: " + oldfoundNetworksStr);
89+
90+
Log.d(TAG, "!isEmpty: " + !foundNetworks.isEmpty() + " !sameResults: " + !sameResults + " !alreadyConnected: " + !alreadyConnected);
91+
// Cancel the notification if no Freifunk network is in reach anymore.
92+
if(foundNetworks.isEmpty()){
93+
mNotificationManager.cancel(NOTIFICATION_ID);
94+
}
95+
if(!foundNetworks.isEmpty() && !sameResults && !alreadyConnected){
96+
sendNotification(foundNetworks);
97+
Log.d(TAG, "sendNotification was called");
98+
}
99+
}
100+
}
101+
102+
private void sendNotification(List<Network> networks){
103+
String text = getString(R.string.notification_text);
104+
for(Network n: networks){
105+
text += n.ssid + ", ";
106+
}
107+
text = text.substring(0, text.length()-2);
108+
109+
NotificationCompat.Builder mBuilder =
110+
new NotificationCompat.Builder(NotificationService.this)
111+
.setSmallIcon(R.mipmap.ic_wifi_white_48dp)
112+
.setContentTitle(getString(R.string.notification_title))
113+
.setContentText(text)
114+
.setContentIntent(PendingIntent.getActivity(NotificationService.this,0, new Intent(Settings.ACTION_WIFI_SETTINGS),0));
115+
116+
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
117+
Log.d(TAG, "Notification was sent.");
118+
}
119+
120+
121+
}
122+
123+
@Override
124+
public IBinder onBind(Intent intent) {
125+
return null;
126+
}
127+
128+
129+
@Override
130+
public int onStartCommand(Intent intent, int flags, int startId) {
131+
Log.d(TAG, "NotificationService was started");
132+
networks = new ArrayList<>();
133+
try{
134+
getSSIDs();
135+
}
136+
catch(IOException e){
137+
Log.w(TAG, "Could not read SSIDs from csv file.");
138+
stopSelf();
139+
}
140+
141+
// Register broadcast receiver
142+
wifiReceiver = new WifiReceiver();
143+
registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
144+
return START_STICKY;
145+
}
146+
147+
@Override
148+
public void onCreate() {
149+
super.onCreate();
150+
151+
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
152+
}
153+
154+
@Override
155+
public void onDestroy() {
156+
Log.d(TAG, "On destroyed was called");
157+
unregisterReceiver(wifiReceiver);
158+
mNotificationManager.cancel(NOTIFICATION_ID);
159+
super.onDestroy();
160+
}
161+
162+
private void getSSIDs() throws IOException {
163+
InputStreamReader is = new InputStreamReader(getAssets().open("ssids.csv"));
164+
BufferedReader reader = new BufferedReader(is);
165+
String line;
166+
while ((line = reader.readLine()) != null) {
167+
networks.add(new Network(line));
168+
}
169+
170+
// Read user defined ssids
171+
// Check if external storage is available
172+
String state = Environment.getExternalStorageState();
173+
if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
174+
File user_ssids = new File(Environment.getExternalStorageDirectory() + File.separator + MainActivity.DIRECTORY + File.separator + MainActivity.USER_SSIDS_FILE );
175+
// Check if file exists
176+
// If the file was found/created:
177+
if(user_ssids.exists()){
178+
is = new InputStreamReader(new FileInputStream(user_ssids));
179+
reader = new BufferedReader(is);
180+
while ((line = reader.readLine()) != null) {
181+
networks.add(new Network(line));
182+
}
183+
}
184+
else{
185+
Log.w(TAG, "Could not find.");
186+
}
187+
}
188+
Collections.sort(networks);
189+
}
190+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.example.tobiastrumm.freifunkautoconnect;
2+
3+
import android.content.Intent;
4+
import android.os.Bundle;
5+
import android.preference.Preference;
6+
import android.preference.PreferenceFragment;
7+
import android.preference.SwitchPreference;
8+
import android.support.v7.app.ActionBarActivity;
9+
import android.support.v7.widget.Toolbar;
10+
11+
12+
public class SettingsActivity extends ActionBarActivity {
13+
14+
public static class SettingsFragment extends PreferenceFragment {
15+
@Override
16+
public void onCreate(Bundle savedInstanceState) {
17+
super.onCreate(savedInstanceState);
18+
19+
// Load the preferences from an XML resource
20+
addPreferencesFromResource(R.xml.preferences);
21+
22+
SwitchPreference switchPref = (SwitchPreference)getPreferenceManager().findPreference("pref_notification");
23+
switchPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
24+
25+
public boolean onPreferenceChange(Preference preference, Object newValue) {
26+
27+
boolean myValue = (Boolean) newValue;
28+
29+
if (myValue)
30+
getActivity().startService(new Intent(getActivity(), NotificationService.class));
31+
else
32+
getActivity().stopService(new Intent(getActivity(), NotificationService.class));
33+
34+
return true;
35+
}
36+
});
37+
38+
}
39+
}
40+
41+
@Override
42+
protected void onCreate(Bundle savedInstanceState) {
43+
super.onCreate(savedInstanceState);
44+
setContentView(R.layout.activity_settings);
45+
46+
// Toolbar
47+
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
48+
setSupportActionBar(toolbar);
49+
50+
// Display the fragment as the main content.
51+
getFragmentManager().beginTransaction()
52+
.add(R.id.fragment_container, new SettingsFragment())
53+
.commit();
54+
55+
56+
57+
}
58+
}

0 commit comments

Comments
 (0)