我正在使用FCM通过应用服务器发送带有数据有效负载的通知,当应用程序处于后台时通知运行良好但是当应用程序处于前台时崩溃,请参阅下面
06-11 15:22:02.350 19744-19744/ng.proartisan.proartisans E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{ng.proartisan.proartisans/ng.proartisan.proartisans.ServiceAddress}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at ng.proartisan.proartisans.ServiceAddress.onCreate(ServiceAddress.java:77)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
这是我的firebasemessagingservice.java
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());
try {
JSONObject json = new JSONObject(remoteMessage.getData().toString());
sendPushNotification(json);
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
Intent intent = new Intent(this, ServiceAddress.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// launchIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder.setContentTitle(remoteMessage.getNotification().getTitle());
notificationBuilder.setContentText(remoteMessage.getNotification().getBody());
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSmallIcon(R.drawable.logo);
notificationBuilder.setSound(Settings.System.DEFAULT_NOTIFICATION_URI);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
//this method will display the notification
//We are passing the JSONObject that is received from
//firebase cloud messaging
private void sendPushNotification(JSONObject json) {
//optionally we can display the json into log
Log.e(TAG, "Notification JSON " + json.toString());
try {
//getting the json data
JSONObject data = json.getJSONObject("data");
//parsing json data
String title = data.getString("title");
String message = data.getString("message");
String phone = data.getString("phone");
String imageUrl = data.getString("image");
//creating MyNotificationManager object
Intent intent = new Intent(this, ServiceAddress.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// launchIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder.setContentTitle(data.getString("title"));
notificationBuilder.setContentText(data.getString("message"));
notificationBuilder.setContentText(data.getString("phone"));
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSmallIcon(R.drawable.logo);
notificationBuilder.setSound(Settings.System.DEFAULT_NOTIFICATION_URI);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
//if there is no image
} catch (JSONException e) {
Log.e(TAG, "Json Exception: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
}
而我的ServiceAddress.java类(点击操作定向到的那个)是
public class ServiceAddress extends AppCompatActivity {
String txtcategory, txttype, txtdetails, txtcustomer,txtsection, txtphone, txtcustomer_name, txtrefnumber, txtaic;
TextView category, type, details, customer, phone, customer_name,refnumber,aic;
Button btnDatePicker, btnTimePicker;
EditText txtDate, txtTime, txtAddress, txtLandmark, txtAdd_info;
LinearLayout job_information, service_address;
ImageView photo;
private int mYear, mMonth, mDay, mHour, mMinute;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service_address);
category = (TextView) findViewById(R.id.category);
type = (TextView) findViewById(R.id.type);
details = (TextView) findViewById(R.id.details);
customer = (TextView) findViewById(R.id.customer);
phone = (TextView) findViewById(R.id.phone);
job_information = (LinearLayout) findViewById(R.id.job_information);
service_address = (LinearLayout) findViewById(R.id.service_address);
customer_name = (TextView) findViewById(R.id.customer_name);
photo = (ImageView) findViewById(R.id.photo);
aic = (TextView) findViewById(R.id.aic);
refnumber = (TextView) findViewById(R.id.refnumber);
/* Bundle extras = getIntent().getExtras();
StringBuilder keys = new StringBuilder();
String txtcategory;
String txttype;
String txtdetails;
String txtcustomer = null;
String txtphone;
String txtcustomer_name;
String txtphoto;
String txtrefnumber;
String txtaic;
String txtsection;*/
Bundle extras = getIntent().getExtras();
if(extras !=null)
txtcustomer = extras.getString("acustomer");
txtphone = extras.getString("phone");
txtcategory = extras.getString("category");
txttype = extras.getString("type");
txtdetails = extras.getString("details");
txtsection = extras.getString("section");
if(txtsection.equals("Notification")){
job_information.setVisibility(View.GONE);
} else {
service_address.setVisibility(View.GONE);
}
category.setText(txtcategory);
type.setText(txttype);
details.setText(txtdetails);
customer.setText(txtcustomer);
phone.setText(txtphone);
customer_name.setText(txtcustomer_name);
refnumber.setText(txtrefnumber);
aic.setText(txtaic);
final ImageView imgForward = (ImageView) findViewById(R.id.othersImg);
btnDatePicker = (Button) findViewById(R.id.btn_date);
btnTimePicker = (Button) findViewById(R.id.btn_time);
txtDate = (EditText) findViewById(R.id.in_date);
txtTime = (EditText) findViewById(R.id.in_time);
txtAddress = (EditText) findViewById(R.id.address);
txtLandmark = (EditText) findViewById(R.id.landmark);
txtAdd_info = (EditText) findViewById(R.id.add_info);
btnDatePicker.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Calendar c = Calendar.getInstance();
mYear = c.get(Calendar.YEAR);
mMonth = c.get(Calendar.MONTH);
mDay = c.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog = new DatePickerDialog(ServiceAddress.this,
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
txtDate.setText(dayOfMonth + "-" + (monthOfYear + 1) + "-" + year);
}
}, mYear, mMonth, mDay);
datePickerDialog.show();
}
});
btnTimePicker.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Calendar c = Calendar.getInstance();
mHour = c.get(Calendar.HOUR_OF_DAY);
mMinute = c.get(Calendar.MINUTE);
// Launch Time Picker Dialog
TimePickerDialog timePickerDialog = new TimePickerDialog(ServiceAddress.this,
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
txtTime.setText(hourOfDay + ":" + minute);
}
}, mHour, mMinute, false);
timePickerDialog.show();
}
});
}
public void goforward(View v) {
String date, time, address, landmark, add_info;
date = txtDate.getText().toString();
time = txtTime.getText().toString();
address = txtAddress.getText().toString();
landmark = txtLandmark.getText().toString();
add_info = txtLandmark.getText().toString();
if ((date.equals("")) || (time.equals("")) || (address.equals("")) || (landmark.equals(""))) {
// Dialog Box to show error message for empty field
//
final Dialog dialog = new Dialog(ServiceAddress.this);
dialog.setContentView(R.layout.second_dialog);
dialog.setTitle("ERROR");
dialog.setCancelable(true);
//set up text
TextView text = (TextView) dialog.findViewById(R.id.TextView01);
text.setText(R.string.register_dialog_message);
//set up button
Button button = (Button) dialog.findViewById(R.id.btnOk);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
//now that the dialog is set up, it's time to show it
dialog.show();
} else {
ServiceAddress.GeocodingLocation locationAddress = new ServiceAddress.GeocodingLocation();
locationAddress.getAddressFromLocation(address,
getApplicationContext(), new ServiceAddress.GeocoderHandler());
Intent intent = new Intent(getApplicationContext(), Subscription.class);
//Create a bundle object
Bundle b = new Bundle();
//Inserts a String value into the mapping of this Bundle
b.putString("date", date);
b.putString("time", time);
b.putString("address", address);
b.putString("landmark", landmark);
b.putString("add_info", add_info);
b.putString("type", txttype);
b.putString("category", txtcategory);
b.putString("details", txtdetails);
b.putString("customer", txtcustomer);
b.putString("phone", txtphone);
//Add the bundle to the intent.
intent.putExtras(b);
// Add values to SharedReference
final String MY_PREFS_NAME = "MyPrefsFile";
SharedPreferences.Editor editor = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
editor.putString("CustomerAddress", txtAddress.getText().toString());
editor.putString("CustomerLandmark", txtLandmark.getText().toString());
editor.putString("CustomerAdd_info", txtAdd_info.getText().toString());
editor.putString("CustomerDate", txtDate.getText().toString());
editor.putString("CustomerTime", txtTime.getText().toString());
editor.putString("RequestType", txttype);
editor.putString("RequestCategory", txtcategory);
editor.putString("RequestDetails", txtdetails);
editor.putString("other_info", "");
editor.apply();
//start the Invoice Activity
startActivity(intent);
finish();
}
}
class GeocoderHandler extends Handler {
@Override
public void handleMessage(Message message) {
String locationAddress, latitude, longitude;
switch (message.what) {
case 1:
Bundle bundle = message.getData();
locationAddress = bundle.getString("address");
latitude = bundle.getString("Latitude");
longitude = bundle.getString("Longitude");
break;
default:
locationAddress = null;
latitude = null;
longitude = null;
}
// latLongTV.setText(locationAddress);
// txtLatitude.setText(latitude);
// txtLongitude.setText(longitude);
final String MY_PREFS_NAME = "MyPrefsFile";
SharedPreferences prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
editor.putString("Latitude", latitude);
editor.putString("Longitude", longitude);
editor.apply();
}
}
class GeocodingLocation {
private static final String TAG = "GeocodingLocation";
public void getAddressFromLocation(final String locationAddress,
final Context context, final Handler handler) {
Thread thread = new Thread() {
@Override
public void run() {
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
String result = null;
String strLatitude = null, strLongitude = null;
try {
List<Address> addressList = geocoder.getFromLocationName(locationAddress, 1);
if (addressList != null && addressList.size() > 0) {
Address address = addressList.get(0);
double latitude = address.getLatitude();
double longitude = address.getLongitude();
StringBuilder sb = new StringBuilder();
sb.append(address.getLatitude()).append("\n");
sb.append(address.getLongitude()).append("\n");
result = sb.toString();
strLatitude = String.valueOf(latitude);
strLongitude = String.valueOf(longitude);
}
} catch (IOException e) {
Log.e(TAG, "Unable to connect to Geocoder", e);
} finally {
Message message = Message.obtain();
message.setTarget(handler);
if (result != null) {
message.what = 1;
Bundle bundle = new Bundle();
result = "Address: " + locationAddress +
"\n\nLatitude and Longitude :\n" + result;
bundle.putString("address", result);
bundle.putString("Latitude", strLatitude);
bundle.putString("Longitude", strLongitude);
message.setData(bundle);
} else {
message.what = 1;
Bundle bundle = new Bundle();
result = "Address: " + locationAddress +
"\n Unable to get Latitude and Longitude for this address location.";
bundle.putString("address", result);
message.setData(bundle);
}
message.sendToTarget();
}
}
};
thread.start();
}
}
}
我想这与从onMessageReceived方法传递消息到ServiceAddress Activity
有关