Skip to content

Commit d4c146d

Browse files
xyber3364rohanjain1
authored andcommitted
Service Notification (#155)
* Changes for service and notification. Currently buggy but seems to work somewhat * Adding Service Notification stuff * Adding a setting to specify refresh rate. * Added a button to stop service * Cleanup * Refactoring how service works. Always on mode for stability * Adding different type of event. * Merge issues still :( * Decided to go back to service when app minimized. * Fixing merge conflicts * Changing to SVG * SVG names are different * Fixing changes in API * Prevents location updates from being paused. * Adding screenshot to readme file
1 parent f8dc0de commit d4c146d

File tree

10 files changed

+363
-54
lines changed

10 files changed

+363
-54
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ A native Android client built with https://github.com/AHAAAAAAA/PokemonGo-Map
44
<img src="http://imgur.com/yMoVZBR.png" width="270" height="480"/>
55
<img src="http://imgur.com/B3S8XHg.png" width="270" height="480"/>
66
<img src="http://imgur.com/ttKW5YW.png" width="270" height="480"/>
7+
<img src="http://imgur.com/u9xaWGK.png" width="270" height="480"/>
78

89
screenshots from @linkout @mike @z14942744
910

app/src/main/AndroidManifest.xml

+51-51
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,64 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
package="com.omkarmoghe.pokemap">
44

5-
<uses-permission android:name="android.permission.INTERNET" />
6-
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
7-
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
8-
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
5+
<uses-permission android:name="android.permission.INTERNET" />
6+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
7+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
8+
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
99

10-
<application
11-
android:allowBackup="true"
12-
android:icon="@mipmap/ic_launcher"
13-
android:label="@string/app_name"
14-
android:supportsRtl="true"
15-
android:theme="@style/AppTheme">
16-
17-
<activity
18-
android:name=".views.MainActivity"
19-
android:theme="@style/AppTheme.NoActionBar">
20-
</activity>
21-
22-
<activity
23-
android:name=".views.LoginActivity">
24-
</activity>
25-
26-
<activity
27-
android:name=".views.PermissionActivity">
28-
</activity>
29-
30-
<activity
31-
android:name=".views.settings.SettingsActivity"
32-
android:launchMode="singleTask"
33-
android:parentActivityName=".views.MainActivity"
34-
android:theme="@style/AppTheme.NoActionBar" />
35-
<activity
36-
android:name=".views.GoogleAuthActivity"
37-
android:theme="@style/AppTheme.NoActionBar"
38-
android:parentActivityName=".views.LoginActivity">
39-
</activity>
10+
<application
11+
android:allowBackup="true"
12+
android:icon="@mipmap/ic_launcher"
13+
android:label="@string/app_name"
14+
android:supportsRtl="true"
15+
android:theme="@style/AppTheme">
16+
<activity
17+
android:name=".views.MainActivity"
18+
android:theme="@style/AppTheme.NoActionBar"></activity>
19+
<activity android:name=".views.LoginActivity"></activity>
20+
<activity android:name=".views.PermissionActivity"></activity>
21+
<activity
22+
android:name=".views.settings.SettingsActivity"
23+
android:launchMode="singleTask"
24+
android:parentActivityName=".views.MainActivity"
25+
android:theme="@style/AppTheme.NoActionBar" />
26+
<activity
27+
android:name=".views.GoogleAuthActivity"
28+
android:parentActivityName=".views.LoginActivity"
29+
android:theme="@style/AppTheme.NoActionBar"></activity>
4030

41-
<!--
31+
<!--
4232
use an alias in case we want to change the launch activity later without breaking
4333
homescreen shortcuts. Note must be defined after the targetActivity
4434
-->
45-
<activity-alias
46-
android:name=".Launcher"
47-
android:label="@string/app_name"
48-
android:targetActivity=".views.PermissionActivity">
49-
<intent-filter>
50-
<action android:name="android.intent.action.MAIN" />
35+
<activity-alias
36+
android:name=".Launcher"
37+
android:label="@string/app_name"
38+
android:targetActivity=".views.PermissionActivity">
39+
<intent-filter>
40+
<action android:name="android.intent.action.MAIN" />
41+
42+
<category android:name="android.intent.category.LAUNCHER" />
43+
</intent-filter>
44+
</activity-alias>
45+
46+
<meta-data
47+
android:name="com.google.android.gms.version"
48+
android:value="@integer/google_play_services_version" />
49+
<meta-data
50+
android:name="com.google.android.geo.API_KEY"
51+
android:value="AIzaSyBhI6GH4cMfMtv8kA-nQE9jPVmMa0PLuMg" />
5152

52-
<category android:name="android.intent.category.LAUNCHER" />
53-
</intent-filter>
54-
</activity-alias>
53+
<service
54+
android:name=".controllers.service.PokemonNotificationService"
55+
android:enabled="true"
56+
android:exported="false">
57+
<intent-filter>
58+
<action android:name="com.omkarmoghe.pokemap.STOP_SERVICE"/>
59+
</intent-filter>
5560

56-
<meta-data
57-
android:name="com.google.android.gms.version"
58-
android:value="@integer/google_play_services_version" />
59-
<meta-data
60-
android:name="com.google.android.geo.API_KEY"
61-
android:value="AIzaSyBhI6GH4cMfMtv8kA-nQE9jPVmMa0PLuMg" />
6261

63-
</application>
62+
</service>
63+
</application>
6464

6565
</manifest>

app/src/main/java/com/omkarmoghe/pokemap/controllers/app_preferences/PokemapAppPreferences.java

+13
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,17 @@ public interface PokemapAppPreferences {
4747
boolean getShowGyms();
4848

4949
void clearLoginCredentials();
50+
/**
51+
*
52+
* @param isEnabled Sets if the background service is enabled.
53+
*/
54+
void setServiceState(@NonNull boolean isEnabled);
55+
56+
/**
57+
*
58+
* @return Returns service state as set in preffs
59+
*/
60+
boolean isServiceEnabled();
61+
62+
int getServiceRefreshRate();
5063
}

app/src/main/java/com/omkarmoghe/pokemap/controllers/app_preferences/PokemapSharedPreferences.java

+16
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public final class PokemapSharedPreferences implements PokemapAppPreferences {
1616
private static final String SHOW_SCANNED_PLACES = "scanned_checkbox";
1717
private static final String SHOW_POKESTOPS = "pokestops_checkbox";
1818
private static final String SHOW_GYMS = "gyms_checkbox";
19+
private static final String SERVICE_KEY = "background_poke_service";
20+
private static final String SERVICE_REFRESH_KEY = "service_refresh_rate";
1921

2022
private final SharedPreferences sharedPreferences;
2123

@@ -64,6 +66,11 @@ public String getGoogleToken() {
6466
return sharedPreferences.getString(GOOGLE_TOKEN_KEY, "");
6567
}
6668

69+
@Override
70+
public void setServiceState(@NonNull boolean isEnabled) {
71+
sharedPreferences.edit().putBoolean(SERVICE_KEY,isEnabled).apply();
72+
}
73+
6774
@Override
6875
public void setGoogleToken(@NonNull String token) {
6976
sharedPreferences.edit().putString(GOOGLE_TOKEN_KEY, token).apply();
@@ -93,4 +100,13 @@ public void clearLoginCredentials() {
93100
}
94101

95102

103+
@Override
104+
public boolean isServiceEnabled() {
105+
return sharedPreferences.getBoolean(SERVICE_KEY,false);
106+
}
107+
108+
@Override
109+
public int getServiceRefreshRate() {
110+
return Integer.valueOf(sharedPreferences.getString(SERVICE_REFRESH_KEY,"60"));
111+
}
96112
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
package com.omkarmoghe.pokemap.controllers.service;
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.location.Location;
11+
import android.os.IBinder;
12+
import android.support.annotation.Nullable;
13+
import android.support.v4.app.NotificationCompat;
14+
import android.util.Log;
15+
16+
import com.google.android.gms.common.ConnectionResult;
17+
import com.google.android.gms.maps.model.LatLng;
18+
import com.omkarmoghe.pokemap.R;
19+
import com.omkarmoghe.pokemap.controllers.app_preferences.PokemapSharedPreferences;
20+
import com.omkarmoghe.pokemap.controllers.map.LocationManager;
21+
import com.omkarmoghe.pokemap.controllers.net.NianticManager;
22+
import com.omkarmoghe.pokemap.models.events.CatchablePokemonEvent;
23+
import com.omkarmoghe.pokemap.views.MainActivity;
24+
import com.pokegoapi.api.map.pokemon.CatchablePokemon;
25+
26+
import org.greenrobot.eventbus.EventBus;
27+
import org.greenrobot.eventbus.Subscribe;
28+
29+
import java.util.List;
30+
import java.util.concurrent.TimeUnit;
31+
32+
33+
public class PokemonNotificationService extends Service{
34+
private static final int notificationId = 2423235;
35+
private static final String ACTION_STOP_SELF = "com.omkarmoghe.pokemap.STOP_SERVICE";
36+
37+
private UpdateRunnable updateRunnable;
38+
private Thread workThread;
39+
private LocationManager locationManager;
40+
private NianticManager nianticManager;
41+
private NotificationCompat.Builder builder;
42+
private PokemapSharedPreferences preffs;
43+
44+
45+
public PokemonNotificationService() {
46+
}
47+
48+
@Override
49+
public IBinder onBind(Intent intent) {
50+
throw new UnsupportedOperationException("Not yet implemented");
51+
}
52+
53+
@Override
54+
public void onCreate() {
55+
Log.d("PokeMap","Service.onCreate()");
56+
EventBus.getDefault().register(this);
57+
createNotification();
58+
59+
preffs = new PokemapSharedPreferences(this);
60+
61+
locationManager = LocationManager.getInstance(this);
62+
nianticManager = NianticManager.getInstance();
63+
64+
updateRunnable = new UpdateRunnable(preffs.getServiceRefreshRate());
65+
workThread = new Thread(updateRunnable);
66+
67+
initBroadcastReciever();
68+
workThread.start();
69+
locationManager.onResume();
70+
71+
}
72+
73+
/**
74+
* This sets up the broadcast reciever.
75+
*/
76+
private void initBroadcastReciever() {
77+
IntentFilter intentFilter = new IntentFilter();
78+
intentFilter.addAction(ACTION_STOP_SELF);
79+
registerReceiver(mBroadcastReciever,intentFilter);
80+
}
81+
82+
@Override
83+
public void onDestroy() {
84+
cancelNotification();
85+
updateRunnable.stop();
86+
EventBus.getDefault().unregister(this);
87+
unregisterReceiver(mBroadcastReciever);
88+
}
89+
90+
@Override
91+
public int onStartCommand(Intent intent, int flags, int startId) {
92+
return START_NOT_STICKY;
93+
}
94+
95+
private void createNotification(){
96+
builder = new NotificationCompat.Builder(getApplication())
97+
.setSmallIcon(R.drawable.ic_gps_fixed_white_24px)
98+
.setContentTitle("Pokemon Service")
99+
.setContentText("Scanning").setOngoing(true);
100+
101+
Intent i = new Intent(this, MainActivity.class);
102+
i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
103+
104+
PendingIntent pi = PendingIntent.getActivity(this,0,i,PendingIntent.FLAG_CANCEL_CURRENT);
105+
106+
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
107+
108+
//builder.setContentIntent(pi);
109+
110+
Intent stopService = new Intent();
111+
stopService.setAction(ACTION_STOP_SELF);
112+
113+
PendingIntent piStopService = PendingIntent.getBroadcast(this,0,stopService,0);
114+
builder.addAction(R.drawable.ic_cancel_black_24px,"Stop Service",piStopService);
115+
116+
nm.notify(notificationId,builder.build());
117+
}
118+
119+
private void cancelNotification(){
120+
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
121+
nm.cancel(notificationId);
122+
}
123+
124+
@Subscribe
125+
public void onEvent(CatchablePokemonEvent event) {
126+
List<CatchablePokemon> catchablePokemon = event.getCatchablePokemon();
127+
128+
LatLng location = locationManager.getLocation();
129+
Location myLoc = new Location("");
130+
myLoc.setLatitude(location.latitude);
131+
myLoc.setLongitude(location.longitude);
132+
builder.setContentText(catchablePokemon.size() + " pokemon nearby.");
133+
builder.setStyle(null);
134+
135+
if(!catchablePokemon.isEmpty()){
136+
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
137+
inboxStyle.setBigContentTitle(catchablePokemon.size() + " pokemon in area:");
138+
for(CatchablePokemon cp : catchablePokemon){
139+
Location pokeLocation = new Location("");
140+
pokeLocation.setLatitude(cp.getLatitude());
141+
pokeLocation.setLongitude(cp.getLongitude());
142+
long remainingTime = cp.getExpirationTimestampMs() - System.currentTimeMillis();
143+
inboxStyle.addLine(cp.getPokemonId().name() + "(" +
144+
TimeUnit.MILLISECONDS.toMinutes(remainingTime) +
145+
" minutes," + Math.ceil(pokeLocation.distanceTo(myLoc)) + " meters)");
146+
}
147+
148+
builder.setStyle(inboxStyle);
149+
}
150+
151+
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
152+
nm.notify(notificationId,builder.build());
153+
}
154+
155+
private final class UpdateRunnable implements Runnable{
156+
private long refreshRate = preffs.getServiceRefreshRate() * 1000;
157+
private boolean isRunning = true;
158+
159+
public UpdateRunnable(int refreshRate){
160+
this.refreshRate = refreshRate;
161+
}
162+
163+
@Override
164+
public void run() {
165+
while(isRunning){
166+
try{
167+
LatLng currentLocation = locationManager.getLocation();
168+
169+
if(currentLocation != null){
170+
nianticManager.getMapInformation(currentLocation.latitude,currentLocation.longitude,0);
171+
}else {
172+
locationManager = LocationManager.getInstance(PokemonNotificationService.this);
173+
}
174+
Thread.sleep(refreshRate);
175+
176+
}catch(Exception e){
177+
e.printStackTrace();
178+
}
179+
}
180+
}
181+
182+
public void stop(){
183+
isRunning = false;
184+
}
185+
}
186+
187+
private BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() {
188+
@Override
189+
public void onReceive(Context context, Intent intent) {
190+
stopSelf();
191+
locationManager.onPause();
192+
}
193+
};
194+
}

0 commit comments

Comments
 (0)