I'm getting these null pointer exceptions crashses for my app. For some weird reason, they are only happening on samsung phones. Not sure what's going on. My code seems solid. Any help much appreciated.
I've read the documentation on nullpointerexceptions and how to find them, but this one really has me stumped. From the stacktrace, I looked at the lines referenced but can't seem to find any reference to null at those locations.
edit: this is different because the null pointer guide linked, I have already read. There is no null references in my code.
Here's the crash info:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'long java.util.Date.getTime()' on a null object reference
at java.util.Calendar.setTime(Calendar.java:1197)
at java.text.SimpleDateFormat.formatImpl(SimpleDateFormat.java:527)
at java.text.SimpleDateFormat.format(SimpleDateFormat.java:829)
at java.text.DateFormat.format(DateFormat.java:314)
at com.myapp.mapapp.helper.Utilities.getEvents(Utilities.java:108)
at com.myapp.mapapp.CalenderEventsActivity.onCreate(CalenderEventsActivity.java:125)
at android.app.Activity.performCreate(Activity.java:6876)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1135)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3206)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3349)
at android.app.ActivityThread.access$1100(ActivityThread.java:221)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
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)
Here's the first java file it says is causing it:
/**
* Created by data intelligence labs on 1/8/2017.
*/
public class Utilities {
@ColorInt
public static int getThemeColor(@NonNull final Context context, @AttrRes final int attributeColor)
{
final TypedValue value = new TypedValue();
context.getTheme ().resolveAttribute (attributeColor, value, true);
return value.data;
}
public static CalendarDay toCalendar(Date date){
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return CalendarDay.from(cal);
}
public static int GetRandomNumber(){
return (int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE);
}
public static Date ParseDate(String dateString, SimpleDateFormat format){
Date date=null;
try {
date = format.parse(dateString);
} catch (Exception e) {
Log.e("",e.toString());
}
return date;
}
public static Date addDays(Date date, int days, int months, int year)
{
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DATE, days); //minus number would decrement the days
cal.add(Calendar.MONTH, months);
cal.add(Calendar.YEAR, year);
return cal.getTime();
}
public static String ReadFromfile(String fileName, Context context) {
StringBuilder returnString = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(
new InputStreamReader(context.getAssets().open(fileName), "UTF-8"));
// do reading, usually loop until end of file reading
String mLine;
while ((mLine = reader.readLine()) != null) {
//process line
returnString.append(mLine + "\n");
}
} catch (IOException e) {
//log the exception
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
//log the exception
}
}
}
return returnString.toString();
}
public static Map<String, ArrayList<OtherEvents>> getEvents(Context content, SimpleDateFormat dateFormatString) {
Map<String, ArrayList<OtherEvents>> map= new ArrayMap<String, ArrayList<OtherEvents>>();
{
String lunar_file = ReadFromfile("lunar_eclipse.txt", content);
String lunar_lines[] = lunar_file.split("\\r?\\n");
SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yy");
//format.setTimeZone(TimeZone.getTimeZone("GMT"));
for (String line: lunar_lines){
String[] line_parts = line.split(",");
Date date= Utilities.ParseDate(line_parts[0],format);
OtherEvents s= new OtherEvents();
s.Date=date;
s.Type=line_parts[2];
s.EventType= EventTypes.LunarEclipse;
String date_string = dateFormatString.format(date);
if (map.containsKey(date_string)){
map.get(date_string).add(s);
}
else{
ArrayList<OtherEvents> ar = new ArrayList<>();
ar.add(s);
map.put(date_string,ar);
}
}
}
{
String lunar_file = ReadFromfile("full_moon.txt", content);
String lunar_lines[] = lunar_file.split("\\r?\\n");
SimpleDateFormat format = new SimpleDateFormat("MMM dd, yyyy");
//format.setTimeZone(TimeZone.getTimeZone("GMT"));
for (String line: lunar_lines){
String[] line_parts = line.split("\\|");
Date date=Utilities.ParseDate(line_parts[0].trim(),format);
OtherEvents s= new OtherEvents();
s.Date=date;
if (line_parts.length>3){
s.Type=line_parts[3].trim();
}
else{
s.Type="";
}
s.EventType= EventTypes.FullMoon;
String date_string = dateFormatString.format(date);
if (map.containsKey(date_string)){
map.get(date_string).add(s);
}
else{
ArrayList<OtherEvents> ar = new ArrayList<>();
ar.add(s);
map.put(date_string,ar);
}
}
}
{
String lunar_file = ReadFromfile("meteor.txt", content);
String lunar_lines[] = lunar_file.split("\\r?\\n");
SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy");
//format.setTimeZone(TimeZone.getTimeZone("GMT"));
for (String line: lunar_lines){
String[] line_parts = line.split("\\|");
Date startDate=Utilities.ParseDate(line_parts[1].trim(),format);
Date endDate=Utilities.ParseDate(line_parts[2].trim(),format);
Date peakDate=Utilities.ParseDate(line_parts[3].trim(),format);
for (int j=0;j<=50;j++){
startDate = Utilities.addDays(startDate,0,0,1);
endDate = Utilities.addDays(endDate,0,0,1);
peakDate = Utilities.addDays(peakDate,0,0,1);
long diff = endDate.getTime() - startDate.getTime();
long days = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
for (int d=0;d<=days;d++){
Date currentDate = Utilities.addDays(startDate, d,0,0);
String date_string = dateFormatString.format(currentDate);
OtherEvents s= new OtherEvents();
s.Date= (Date) peakDate.clone();
s.MeterorStartDate= (Date) startDate.clone();
s.MeterorEndDate = (Date) endDate.clone();
s.Type=line_parts[0];
if (currentDate.compareTo(peakDate)==0){
s.Type=line_parts[0].toString() + " - Peak";
}
s.EventType= EventTypes.MeteorShower;
if (map.containsKey(date_string)){
map.get(date_string).add(s);
}
else{
ArrayList<OtherEvents> ar = new ArrayList<>();
ar.add(s);
map.put(date_string,ar);
}
}
}
}
}
return map;
}
}
Here's the second java file it is also referencing:
public class CalenderEventsActivity extends AppCompatActivity implements OnDateSelectedListener,AdapterView.OnItemClickListener{
static final String LOG_TAG = CalenderEventsActivity.class.getSimpleName();
static final SimpleDateFormat DATE_TIME_FORMAT = new SimpleDateFormat("dd-MMM-yy");
private final OneDayDecorator oneDayDecorator = new OneDayDecorator();
private ListView listView;
private ArrayAdapter adapter;
private ArrayList<OtherEvents> eventsList;
@Bind(R.id.calendarView)
MaterialCalendarView widget;
private static Map<String, ArrayList<OtherEvents>> map = new HashMap<String, ArrayList<OtherEvents>>();
//Ads
private PurchaseHelper mPurchases1;
private AdView mAdView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calender_events);
widget = (MaterialCalendarView) findViewById(R.id.calendarView);
mPurchases1 = PurchaseHelper.createInstance();
initAds();
updatePro();
ButterKnife.bind(this);
try
{
Log.i(LOG_TAG,CalenderEventsActivity.this.toString());
widget.setOnDateChangedListener(CalenderEventsActivity.this);
}
catch (Exception e){
Log.e(LOG_TAG,e.toString());
}
widget.setShowOtherDates(MaterialCalendarView.SHOW_ALL);
Calendar instance = Calendar.getInstance();
if (getIntent().getStringExtra("date")!=null){
widget.setSelectedDate(Utilities.ParseDate(getIntent().getStringExtra("date"),DATE_TIME_FORMAT));
}
else {
widget.setSelectedDate(instance.getTime());
}
Calendar instance1 = Calendar.getInstance();
instance1.set(2016, Calendar.JANUARY, 1);
Calendar instance2 = Calendar.getInstance();
instance2.set(2049, Calendar.DECEMBER, 31);
widget.state().edit()
.setMinimumDate(instance1.getTime())
.setMaximumDate(instance2.getTime())
.commit();
widget.addDecorators(
new CalenderEventSelectorDecorator(this),
new HighlightWeekendsDecorator(),
oneDayDecorator
);
//new ApiSimulator().executeOnExecutor(Executors.newSingleThreadExecutor());
listView=(ListView)findViewById(R.id.lst_calender_events);
listView.setOnItemClickListener(this);
/*
listView.setOnClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getBaseContext(),parent.getItemAtPosition(position)+" is selected",Toast.LENGTH_LONG).show();
}
});
*/
if (map.size()==0){
map = Utilities.getEvents(this, DATE_TIME_FORMAT);
Log.i(LOG_TAG,Integer.toString(map.size()));
}
ArrayList<CalendarDay> eventDays= new ArrayList<CalendarDay>();
Set<String> eventDates = map.keySet();
for(String date: eventDates){
eventDays.add(Utilities.toCalendar(Utilities.ParseDate(date,DATE_TIME_FORMAT)));
}
widget.addDecorator(new EventDecorator(ContextCompat.getColor(this, R.color.colorNotification), eventDays));
dateSelected(widget.getSelectedDate());
//Show notification
if (getIntent().getSerializableExtra("event")!=null){
OtherEvents selectedItem = (OtherEvents) getIntent().getSerializableExtra("event");
ArrayList<OtherEvents> params = new ArrayList<>();
OtherEvents param = (OtherEvents) selectedItem.clone();
param.showButtonContainer = false;
param.remainingDaysString = "";
params.add(param);
FragmentManager fm = getSupportFragmentManager();
for(Iterator<OtherEvents> i = params.iterator(); i.hasNext(); ) {
OtherEvents item = i.next();
AlertDialogFragment alertDialog = AlertDialogFragment.newInstance(item);
alertDialog.setCancelable(true);
alertDialog.show(fm, "fragment_alert");
alertDialog.setOnFragDismissedListener(new AlertDialogFragment.OnDialogFragHide() {
@Override
public void onFragmentDismissed() {
Log.i(LOG_TAG,"alert fragment dismissed");
}
});
}
}
}
private void initAds() {
// Request for Ads
AdRequest adRequest = new AdRequest.Builder()
// Add a test device to show Test Ads
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.addTestDevice("CEDB1558F8E15156FAB8EF79CEC9C253")
.build();
//Locate the Banner Ad in activity_main.xml
mAdView = (AdView) this.findViewById(R.id.adView);
// Load ads into Banner Ads
mAdView.loadAd(adRequest);
}
private void updatePro() {
Boolean mIsPaid = !mPurchases1.showPurchaseDialog();
FrameLayout layout = (FrameLayout)findViewById(R.id.ads_layout);
if (mIsPaid) {
if (layout!=null)
layout.setVisibility(View.GONE);
if (mAdView!=null)
mAdView.pause();
}
else{
if (layout!=null)
layout.setVisibility(View.VISIBLE);
if (mAdView!=null)
mAdView.resume();
}
}
@Override
public void onDateSelected(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date, boolean selected) {
//If you change a decorate, you need to invalidate decorators
oneDayDecorator.setDate(date.getDate());
widget.invalidateDecorators();
dateSelected(date);
}
private void dateSelected(CalendarDay date) {
adapter = new AppEventsAdapter(this, R.layout.calendar_event_item_template); // the adapter is a member field in the activity
//setContentView(R.layout.activity_view_memo_layout);
ListView lv = (ListView) findViewById(R.id.lst_calender_events);
lv.setAdapter(adapter);
eventsList = new ArrayList<OtherEvents>(); //here you should use a list with some content in it
String date_string = DATE_TIME_FORMAT.format(date.getDate());
if (map.containsKey(date_string))
{
eventsList = map.get(date_string);
}
adapter.addAll(eventsList);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.i(LOG_TAG,"show dialog window");
OtherEvents selectedItem = eventsList.get(position);
ArrayList<OtherEvents> params = new ArrayList<OtherEvents>();
OtherEvents param = (OtherEvents) selectedItem.clone();
param.showButtonContainer = false;
param.remainingDaysString = "";
params.add(param);
FragmentManager fm = getSupportFragmentManager();
for(Iterator<OtherEvents> i = params.iterator(); i.hasNext(); ) {
OtherEvents item = i.next();
AlertDialogFragment alertDialog = AlertDialogFragment.newInstance(item);
alertDialog.setCancelable(true);
alertDialog.show(fm, "fragment_alert");
alertDialog.setOnFragDismissedListener(new AlertDialogFragment.OnDialogFragHide() {
@Override
public void onFragmentDismissed() {
Log.i(LOG_TAG,"alert fragment dismissed");
}
});
}
}
/**
* Simulate an API call to show how to add decorators
*/
private class ApiSimulator extends AsyncTask<Void, Void, List<CalendarDay>> {
@Override
protected List<CalendarDay> doInBackground(@NonNull Void... voids) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MONTH, -2);
ArrayList<CalendarDay> dates = new ArrayList<>();
for (int i = 0; i < 30; i++) {
CalendarDay day = CalendarDay.from(calendar);
dates.add(day);
calendar.add(Calendar.DATE, 5);
}
return dates;
}
@Override
protected void onPostExecute(@NonNull List<CalendarDay> calendarDays) {
super.onPostExecute(calendarDays);
if (isFinishing()) {
return;
}
widget.addDecorator(new EventDecorator(ContextCompat.getColor(getApplicationContext(), R.color.colorNotification), calendarDays));
}
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
}
}