Я пытаюсь найти ошибки, которые есть в приложении, но я не могу их идентифицировать.Может ли кто-нибудь помочь мне определить причину ошибки с помощью logcat, полученного от жизненно важных функций Android?
Должен ли я проанализировать / опубликовать карту?
Ниже приведены logcat и код.
logcat:
java.lang.NullPointerException:
at com.xxxxx.xxxxx.Service.GeofenceNotification.access$002 (GeofenceNotification.java)
or .access$100 (GeofenceNotification.java)
or .access$200 (GeofenceNotification.java)
or .access$300 (GeofenceNotification.java)
or .access$402 (GeofenceNotification.java)
or .access$502 (GeofenceNotification.java)
at com.xxxxx.xxxxx.Service.GeofenceNotification$1.onCancelled (GeofenceNotification.java)
or .onDataChange (GeofenceNotification.java)
at com.google.firebase.database.zzp.onCancelled (zzp.java)
or .onDataChange (zzp.java)
at com.google.android.gms.internal.firebase_database.zzfc.zza (zzfc.java)
or .zzbe (zzfc.java)
or .zzc (zzfc.java)
at com.google.android.gms.internal.firebase_database.zzgx.zzdr (zzgx.java)
at com.google.android.gms.internal.firebase_database.zzhd.run (zzhd.java)
at android.os.Handler.handleCallback (Handler.java:739)
at android.os.Handler.dispatchMessage (Handler.java:95)
at android.os.Looper.loop (Looper.java:148)
at android.app.ActivityThread.main (ActivityThread.java:7325)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1120)
Вот мой код GeofenceNotification:
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.RemoteViews;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.MutableData;
import com.google.firebase.database.Transaction;
import com.google.firebase.database.ValueEventListener;
import com.xxxxx.xxxxx.Auxiliares.Utils;
import com.xxxxx.xxxxx.R;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import static com.xxxxx.xxxxx.MainActivity.remote_geofence_temp_abast;
public class GeofenceNotification {
private static final String TAG = "GeofenceNotification";
private static final Integer NOTIFICATION_ID = 38;
protected Context context;
private static NotificationManager mNotificationManager;
GeofenceNotification(Context context) {
this.context = context;
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
void displayNotification(final String postoID, final long dataNotif) {
DatabaseReference mPostosDBRef = Utils.getDatabase().getReference().child("postos");
mPostosDBRef.child(postoID).addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dtSnap) {
String mNome = "Nome do posto";
if (dtSnap.exists()) { mNome = dtSnap.child("nome").getValue(String.class); }
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
boolean cfgNotif = sharedPreferences.getBoolean("CfgNotif", true);
if (cfgNotif) {
startNotification(context, postoID, mNome, dataNotif);
} else {
gravaAbastecimento(context, postoID, dataNotif);
}
}
public void onCancelled(DatabaseError databaseError) {
System.out.println("****** The read failed: " + databaseError.getCode());
}
});
}
private void startNotification(final Context context, final String postoID, final String mNome, final long dataNotif){
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
final String userID = sharedPreferences.getString("CfgUserID", "");
final String dateQuery = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).format(dataNotif-remote_geofence_temp_abast);
DatabaseReference statsRef = Utils.getDatabase().getReference().child("stats").child("users").child(userID).child(postoID);
statsRef.orderByKey().startAt(dateQuery).addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dtSnap) {
// Verifica se não existe outro abastecimento neste posto desde o tempo minimo
if ( dtSnap.hasChildren() ) {
Log.w(TAG,"Tentativa de registrar abastecimento dentro do tempo mínimo : "+ remote_geofence_temp_abast/60/1000 +" minutos.");
Log.w(TAG,"Já existe um abastecimento realizado após "+dateQuery);
return;
}
//this is the intent that is supposed to be called when the button is clicked
Intent intentSim = new Intent(context, notificationBtnSim.class);
intentSim.putExtra("postoID", postoID);
intentSim.putExtra("dataNotif", dataNotif);
Intent intentNao = new Intent(context, notificationBtnNao.class);
PendingIntent pendingIntentSim = PendingIntent.getBroadcast(context, 0, intentSim, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntentNao = PendingIntent.getBroadcast(context, 0, intentNao, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews notificationView = new RemoteViews(context.getPackageName(), R.layout.notification_abast);
Notification notification = new Notification.Builder(context)
.setContentText(null)
.setSmallIcon(R.drawable.gnvbr)
.setWhen(System.currentTimeMillis())
.setContent(notificationView)
.build();
notification.flags |= Notification.FLAG_NO_CLEAR;
notification.defaults |= Notification.DEFAULT_LIGHTS;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm", Locale.US);
String dateString=sdf.format(dataNotif);
String notification_date = "Abastecimento em "+dateString+" hs";
notificationView.setOnClickPendingIntent(R.id.notification_sim, pendingIntentSim);
notificationView.setOnClickPendingIntent(R.id.notification_nao, pendingIntentNao);
notificationView.setTextViewText(R.id.notification_date, notification_date);
notificationView.setTextViewText(R.id.notification_posto, mNome);
mNotificationManager.notify(NOTIFICATION_ID, notification);
//Schedule Alarm
Long time = new GregorianCalendar().getTimeInMillis()+(3540000); // tempo maximo para responder à notificação de abastecimento (59 min)
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntentSim);
}
}
public void onCancelled(DatabaseError databaseError) {
System.out.println("****** The read failed: " + databaseError.getCode());
}
});
}
public static class notificationBtnSim extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String postoID = intent.getStringExtra("postoID");
long dataNotif = intent.getLongExtra("dataNotif", System.currentTimeMillis());
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
alarmManager.cancel(sender);
}
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (mNotificationManager != null) {
mNotificationManager.cancel(NOTIFICATION_ID);
}
gravaAbastecimento(context, postoID, dataNotif);
}
}
public static class notificationBtnNao extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
alarmManager.cancel(sender);
}
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (mNotificationManager != null) {
mNotificationManager.cancel(NOTIFICATION_ID);
}
}
}
private static void gravaAbastecimento(final Context context, final String postoID, final long dataNotif) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sharedPreferences.edit();
final String userName = sharedPreferences.getString("CfgUserName", "");
final String userID = sharedPreferences.getString("CfgUserID", "");
final String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).format(dataNotif);
final String ano = new SimpleDateFormat("yyyy", Locale.US).format(dataNotif);
final String mes = new SimpleDateFormat("MM", Locale.US).format(dataNotif);
final String dia = new SimpleDateFormat("dd", Locale.US).format(dataNotif);
final String hora = new SimpleDateFormat("HH:mm:ss", Locale.US).format(dataNotif);
// Grava coordenadas e horário do ultimo abastecimento e limpa flag CfgSaiuDoPosto
Double cfgLastKnowLatitude = Double.longBitsToDouble(sharedPreferences.getLong("CfgLastKnowLatitude", 0L));
Double cfgLastKnowLongitude = Double.longBitsToDouble(sharedPreferences.getLong("CfgLastKnowLongitude", 0L));
editor.putLong("CfgLatLastAbast", Double.doubleToLongBits(cfgLastKnowLatitude));
editor.putLong("CfgLngLastAbast", Double.doubleToLongBits(cfgLastKnowLongitude));
editor.putLong("CfgLastAbast", new Date(dataNotif).getTime()).apply();
editor.putBoolean("CfgSaiuDoPosto", false).apply();
// grava log de registro de abastecimento
DatabaseReference mLogDBRef = Utils.getDatabase().getReference().child("log");
mLogDBRef.child("abastecimentos").child(ano).child(mes).child(dia).child(hora+ " "+postoID).setValue(userID+" "+userName);
Log.w(TAG,"============================================================");
Log.w(TAG,"Novo abastecimento registrado no posto: "+postoID+" em "+date+" hs");
Log.w(TAG,"============================================================");
DatabaseReference mStatDBRef = Utils.getDatabase().getReference().child("stats");
mStatDBRef.child("postos").child(postoID).runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
int qtde;
if (mutableData.hasChild(userID)) {
qtde = Integer.parseInt(mutableData.child(userID).getValue(String.class));
} else { qtde = 0; }
qtde++;
mutableData.child(userID).setValue(qtde);
return Transaction.success(mutableData);
}
@Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot errSnapshot) {
Log.d(TAG, "postoTransaction:onComplete:" + databaseError);
}
});
mStatDBRef.child("users").child(userID).runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
int qtde;
if (mutableData.child(postoID).hasChild(date)) {
qtde = Integer.parseInt(mutableData.child(postoID).child(date).getValue(String.class));
} else { qtde = 0; }
qtde++;
mutableData.child(postoID).child(date).setValue(qtde);
return Transaction.success(mutableData);
}
@Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot errSnapshot) {
Log.d(TAG, "usersTransaction:onComplete:" + databaseError);
}
});
}
}
А вот часть моего MappingFile:
com.xxxxx.xxxxx.Service.GeofenceNotification -> com.xxxxx.xxxxx.Service.GeofenceNotification:
java.lang.Integer NOTIFICATION_ID -> a
android.content.Context context -> b
android.app.NotificationManager mNotificationManager -> c
int qtde -> d
android.content.SharedPreferences sharedPreferences -> e
void <init>(android.content.Context) -> <init>
android.content.SharedPreferences access$000(com.xxxxx.xxxxx.Service.GeofenceNotification) -> a
void access$100(com.xxxxx.xxxxx.Service.GeofenceNotification,android.content.Context,java.lang.String,java.lang.String,long) -> a
void access$200(android.content.Context,java.lang.String,long) -> a
android.app.NotificationManager access$300() -> a
android.app.NotificationManager access$302(android.app.NotificationManager) -> a
int access$402(int) -> a
int access$408() -> b
int access$400() -> c
void <clinit>() -> <clinit>
com.xxxxx.xxxxx.Service.GeofenceNotification$1 -> com.xxxxx.xxxxx.Service.GeofenceNotification$1:
java.lang.String val$postoID -> a
long val$dataNotif -> b
com.xxxxx.xxxxx.Service.GeofenceNotification this$0 -> c
void <init>(com.xxxxx.xxxxx.Service.GeofenceNotification,java.lang.String,long) -> <init>
void onDataChange(com.google.firebase.database.DataSnapshot) -> a
void onCancelled(com.google.firebase.database.DatabaseError) -> a
com.xxxxx.xxxxx.Service.GeofenceNotification$2 -> com.xxxxx.xxxxx.Service.GeofenceNotification$2:
java.lang.String val$dateQuery -> a
android.content.Context val$context -> b
java.lang.String val$postoID -> c
long val$dataNotif -> d
java.lang.String val$mNome -> e
com.xxxxx.xxxxx.Service.GeofenceNotification this$0 -> f
void <init>(com.xxxxx.xxxxx.Service.GeofenceNotification,java.lang.String,android.content.Context,java.lang.String,long,java.lang.String) -> <init>
void onDataChange(com.google.firebase.database.DataSnapshot) -> a
void onCancelled(com.google.firebase.database.DatabaseError) -> a
com.xxxxx.xxxxx.Service.GeofenceNotification$3 -> com.xxxxx.xxxxx.Service.GeofenceNotification$3:
java.lang.String val$userID -> a
void <init>(java.lang.String) -> <init>
com.google.firebase.database.Transaction$Result doTransaction(com.google.firebase.database.MutableData) -> a
void onComplete$5e9da46a(com.google.firebase.database.DatabaseError) -> a
com.xxxxx.xxxxx.Service.GeofenceNotification$4 -> com.xxxxx.xxxxx.Service.GeofenceNotification$4:
java.lang.String val$postoID -> a
java.lang.String val$date -> b
void <init>(java.lang.String,java.lang.String) -> <init>
com.google.firebase.database.Transaction$Result doTransaction(com.google.firebase.database.MutableData) -> a
void onComplete$5e9da46a(com.google.firebase.database.DatabaseError) -> a
com.xxxxx.xxxxx.Service.GeofenceNotification$notificationBtnNao -> com.xxxxx.xxxxx.Service.GeofenceNotification$notificationBtnNao:
void <init>() -> <init>
void onReceive(android.content.Context,android.content.Intent) -> onReceive
com.xxxxx.xxxxx.Service.GeofenceNotification$notificationBtnSim -> com.xxxxx.xxxxx.Service.GeofenceNotification$notificationBtnSim:
void <init>() -> <init>
void onReceive(android.content.Context,android.content.Intent) -> onReceive
com.xxxxx.xxxxx.Service.GeofenceService -> com.xxxxx.xxxxx.Service.GeofenceService:
android.content.SharedPreferences sharedPreferences -> d
android.app.PendingIntent mGeofencePendingIntent -> e
java.util.ArrayList mGeofenceList -> a
java.lang.Double cfgLastKnowLatitude -> f
java.lang.Double cfgLastKnowLongitude -> g
long cfgSaiu -> h
float maiorDist -> i
com.google.android.gms.location.FusedLocationProviderClient mFusedLocationClient -> j
com.google.android.gms.location.GeofencingClient mGeofencingClient -> k
java.util.Timer timer -> l
android.location.Location mLastLocation -> b
boolean $assertionsDisabled -> c
void <init>() -> <init>
android.os.IBinder onBind(android.content.Intent) -> onBind
void onCreate() -> onCreate
int onStartCommand(android.content.Intent,int,int) -> onStartCommand
void onDestroy() -> onDestroy
android.app.PendingIntent getGeofencePendingIntent() -> b
void populateGeofenceList() -> c
void getLastLocation() -> a
void getRemoteVariables() -> d
java.lang.Double access$002(com.xxxxx.xxxxx.Service.GeofenceService,java.lang.Double) -> a
java.lang.Double access$102(com.xxxxx.xxxxx.Service.GeofenceService,java.lang.Double) -> b
java.lang.Double access$000(com.xxxxx.xxxxx.Service.GeofenceService) -> a
android.content.SharedPreferences access$200(com.xxxxx.xxxxx.Service.GeofenceService) -> b
java.lang.Double access$100(com.xxxxx.xxxxx.Service.GeofenceService) -> c
long access$302(com.xxxxx.xxxxx.Service.GeofenceService,long) -> a
long access$308(com.xxxxx.xxxxx.Service.GeofenceService) -> d
long access$300(com.xxxxx.xxxxx.Service.GeofenceService) -> e
void <clinit>() -> <clinit>
Мне нужна большая помощьнайти эту ошибку, и я не знаю, где причина этого исключения (доступ).