I'm new to the Android branch, and I'm making an application that generates a notification when it gets close to places registered in the database, but it's giving an error:
E / AndroidRuntime: FATAL EXCEPTION: main Process: splashdev.devmedia.edu.br.location_rone, PID: 3938 java.lang.RuntimeException: Unable to start service splashdev.devmedia.edu.br.local_rone.GCMService@6694939 with Intent {cmp = splashdev.devmedia.edu.br.location_rone / .GCMService}: android.view.WindowManager $ BadTokenException: Unable to add window - token null is not for an application
My code:
public class GCMService extends Service{
public static final String TAG = "GCMService";
LocationRequest mLocationRequest;
FusedLocationProviderClient mFusedLocationClient;
LocationCallback mLocationCallback;
int raio = 100;
private NotificationManagerCompat notificationManager;
ArrayList<Double> loc = new ArrayList<Double>();
ArrayList<String> locaisnomes = new ArrayList<>();
public static ArrayList<String> listaEmpresasNotificadas = new ArrayList<>();
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
notificationManager = NotificationManagerCompat.from(this);
BuscaPontos();
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
initLocationRequest();
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
String s= "";
if (locationResult == null) Toast.makeText(GCMService.this, "\nLocationResult == null", Toast.LENGTH_LONG).show();
else {
for (Location location : locationResult.getLocations()) {
for(int i=0, j=0; i<loc.size();i+=2,j++) {
double dist = calcDistancia(location.getLatitude(), location.getLongitude(), loc.get(i), loc.get(i + 1));
dist = dist * 1000;
if (dist < raio) {
listaEmpresasNotificadas.add(locaisnomes.get(j));
}
else{}
if (verificarNotificacao(locaisnomes.get(j))==false){
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.putExtra("Location", location);
intent.putExtra("Parceiro", locaisnomes.get(j));
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
showNotification(getApplicationContext(), "Há descontos por perto!", locaisnomes.get(j) + " é uma empresa parceira e está próximo de você", contentIntent);
break;
}
}
}
}
}
};
startLocationUpdates();
return START_STICKY;
}
private void initLocationRequest(){
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(2000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private void startLocationUpdates() {
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.M){
//Verifica se já tem permissão
//Se não tem, pede a permissão
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)==
PackageManager.PERMISSION_GRANTED){
}
}
else { }
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback,null /* Looper */);
}
private double calcDistancia(double lat_inicial, double long_inicial, double lat_final, double long_final) {
double d2r = 0.017453292519943295769236;
double dlong = (long_final - long_inicial) * d2r;
double dlat = (lat_final - lat_inicial) * d2r;
double temp_sin = Math.sin(dlat/2.0);
double temp_cos = Math.cos(lat_inicial * d2r);
double temp_sin2 = Math.sin(dlong/2.0);
double a = (temp_sin * temp_sin) + (temp_cos * temp_cos) * (temp_sin2 * temp_sin2);
double c = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1.0 - a));
return 6368.1 * c;
}
public void BuscaPontos(){
HashMap postData = new HashMap();
PostResponseAsyncTask task1 = new PostResponseAsyncTask(GCMService.this, postData,
new AsyncResponse() {
@Override
public void processFinish(String s) {
String x = "";
try {
JSONArray jsonArray = new JSONArray(s);
for(int i=0; i<jsonArray.length();i++){
JSONObject aux = (JSONObject) jsonArray.get(i);
String lat = aux.getString("latitude");
String longi = aux.getString("longitude");
String nloja = aux.getString("nomeloja");
x = x + "\n" + "lat:" + lat + " long:" + longi + " nome da loja" + nloja;
double latitude = Double.parseDouble(lat);
double longitude = Double.parseDouble(longi);
loc.add(latitude);
loc.add(longitude);
locaisnomes.add(nloja);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
//ip = Sessao.getIp();
task1.execute("http://192.168.2.113/phpitgirl/buscapontos.php");
}
public static boolean verificarNotificacao(String empresa) {
for (int i = 0; i < listaEmpresasNotificadas.size(); i++) {
if (listaEmpresasNotificadas.get(i).equals(empresa)) {
return true;
}
};
return false;
}
public void showNotification(Context context, String title, String body, PendingIntent intent) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int notificationId = 2;
String channelId = "notificacoes-01";
String channelName = "Notificacoes";
int importance = NotificationManager.IMPORTANCE_HIGH;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(
channelId, channelName, importance);
notificationManager.createNotificationChannel(mChannel);
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle(title)
.setContentText(body)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND)
.setAutoCancel(true);
notificationManager.notify(notificationId, mBuilder.build());
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
MainActivity class:
public class MainActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(getBaseContext(), GCMService.class));
}
}
BootCompletedIntentReceiver class:
public class BootCompletedIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent pushIntent = new Intent(context, GCMService.class);
context.startService(pushIntent);
}
}
}