Сбой Android при запускеActivityForResult()

Проблема. При запуске действия для результата в CreateCourse.java приложение аварийно завершает работу.

Сообщение об ошибке:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nbdeg.unityplanner/com.nbdeg.unityplanner.Utils.CourseAddTime}: android.view.InflateException: Binary XML file line #103: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
                                                                        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
                                                                        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
                                                                        at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
                                                                        at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                        at android.os.Looper.loop(Looper.java:154)
                                                                        at android.app.ActivityThread.main(ActivityThread.java:6119)
                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
                                                                     Caused by: android.view.InflateException: Binary XML file line #103: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
                                                                     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
                                                                        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:761)
                                                                        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
                                                                        at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
                                                                        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
                                                                        at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
                                                                        at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
                                                                        at android.view.LayoutInflater.inflate(LayoutInflater.java:377)
                                                                        at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:412)
                                                                        at android.app.Activity.setContentView(Activity.java:2414)
                                                                        at com.nbdeg.unityplanner.Utils.CourseAddTime.onCreate(CourseAddTime.java:43)
                                                                        at android.app.Activity.performCreate(Activity.java:6679)
                                                                        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
                                                                        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
                                                                        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
                                                                        at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
                                                                        at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                        at android.os.Looper.loop(Looper.java:154)
                                                                        at android.app.ActivityThread.main(ActivityThread.java:6119)
                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Что я пробовал: добавление android.permission.WRITE_EXTERNAL_STORAGE и android.permission.READ_EXTERNAL_STORAGE и изменение кода запроса.

Если кто-нибудь знает, что происходит или как я могу это исправить, это было бы очень признательно.

Классы:

CreateCourse.java (класс, вызывающий startActivityForResult)

package com.nbdeg.unityplanner;

import android.app.Activity;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.util.ExponentialBackOff;
import com.google.firebase.auth.UserInfo;
import com.nbdeg.unityplanner.Data.Course;
import com.nbdeg.unityplanner.Data.Time;
import com.nbdeg.unityplanner.Utils.CourseAddTime;
import com.nbdeg.unityplanner.Utils.Database;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;

import eltos.simpledialogfragment.SimpleDialog;
import eltos.simpledialogfragment.color.SimpleColorDialog;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;

import static com.nbdeg.unityplanner.Dashboard.REQUEST_PERMISSION_GET_ACCOUNTS;

public class CreateCourse extends AppCompatActivity implements SimpleDialog.OnDialogResultListener {

    private static final int COURSE_GET_TIME = 1050;
    private GoogleAccountCredential gCredential;
    private Time time;

    private View viewColor;
    private Button viewAddTime;
    private TextView viewCourseTime;
    private EditText viewCourseName;
    private EditText viewCourseTeacher;
    private EditText viewCourseRoomNumber;
    private EditText viewCourseDescription;

    final static private String COLOR_DIALOG = "colorDialog";
    static private int courseColor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_create_course);

        Button colorSelector = (Button) findViewById(R.id.course_create_button);
        viewAddTime = (Button) findViewById(R.id.course_create_add_time);
        viewCourseTime = (TextView) findViewById(R.id.course_create_time);
        viewColor = findViewById(R.id.course_create_view_color);
        viewCourseName = (EditText) findViewById(R.id.course_create_name);
        viewCourseTeacher = (EditText) findViewById(R.id.course_create_teacher);
        viewCourseRoomNumber = (EditText) findViewById(R.id.course_create_room_number);
        viewCourseDescription = (EditText) findViewById(R.id.course_create_description);

        courseColor = getMatColor("200");
        viewColor.setBackgroundColor(courseColor);

        colorSelector.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SimpleColorDialog.build()
                        .title("Pick a course color")
                        .allowCustom(true)
                        .show(CreateCourse.this, COLOR_DIALOG);
            }
        });

        viewCourseTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(CreateCourse.this, CourseAddTime.class);
                startActivityForResult(intent, COURSE_GET_TIME);
            }
        });

        viewAddTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(CreateCourse.this, CourseAddTime.class);
                startActivityForResult(intent, COURSE_GET_TIME);
            }
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == COURSE_GET_TIME) {
            if (resultCode == Activity.RESULT_OK) {
                SimpleDateFormat formatter = new SimpleDateFormat("h:mm a", java.util.Locale.getDefault());

                time = (Time) data.getSerializableExtra("time");

                viewAddTime.setVisibility(View.GONE);
                if (time.isBlockSchedule()) {
                    viewCourseTime.setText("A/B Schedule");
                } else {
                    viewCourseTime.setText("Per Day Schedule");
                }
                viewCourseTime.append("; " + formatter.format(new Date(time.getStartLong())) + " - " + formatter.format(new Date(time.getEndLong())));
                viewCourseTime.setVisibility(View.VISIBLE);
            } else if (resultCode == Activity.RESULT_CANCELED) {
                viewAddTime.setVisibility(View.VISIBLE);
                viewCourseTime.setVisibility(View.GONE);
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.save, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Save course
        Course course = new Course();
        if (time == null) {
            Toast.makeText(this, "A time is needed", Toast.LENGTH_SHORT).show();
            return super.onOptionsItemSelected(item);
        }

        if (viewCourseName.getText().toString().equals("")) {
            Toast.makeText(this, "A course name is needed", Toast.LENGTH_SHORT).show();
            return super.onOptionsItemSelected(item);
        } else {
            course.setName(viewCourseName.getText().toString());
        }

        if (viewCourseTeacher.getText().toString().equals("")) {
            Toast.makeText(this, "A teacher is needed", Toast.LENGTH_SHORT).show();
            return super.onOptionsItemSelected(item);
        } else {
            course.setTeacher(viewCourseTeacher.getText().toString());
        }

        course.setRoomNumber(viewCourseRoomNumber.getText().toString());
        course.setDescription(viewCourseDescription.getText().toString());
        course.setColor(courseColor);

        for (UserInfo info : Database.getUser().getProviderData()) {
            if (info.getProviderId().equals("google.com")) {
                if (EasyPermissions.hasPermissions(this, android.Manifest.permission.GET_ACCOUNTS)) {
                    signInGoogleCredential();
                    return super.onOptionsItemSelected(item);
                } else {
                    EasyPermissions.requestPermissions(
                            this,
                            "This app needs to access your Google account (via Contacts).",
                            REQUEST_PERMISSION_GET_ACCOUNTS,
                            android.Manifest.permission.GET_ACCOUNTS);
                }
            }
        }

        if (time.isBlockSchedule()) {
            try {
                course.setTime(Database.createEventByBlock(this, gCredential, course.getName(), time.getStartLong(), time.getEndLong(), time.getFinish()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (time.isDaySchedule()) {
            try {
                course.setTime(Database.createEventByDay(this, gCredential, course.getName(), time.getDays(), time.getStartLong(), time.getEndLong(), time.getFinish()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        Database.createCourse(course);
        return super.onOptionsItemSelected(item);
    }

    private int getMatColor(String typeColor) {
        int returnColor = Color.BLACK;
        int arrayId = getResources().getIdentifier("mdcolor_" + typeColor, "array", getApplicationContext().getPackageName());

        if (arrayId != 0)
        {
            TypedArray colors = getResources().obtainTypedArray(arrayId);
            int index = (int) (Math.random() * colors.length());
            returnColor = colors.getColor(index, Color.BLACK);
            colors.recycle();
        }
        return returnColor;
    }

    @Override
    public boolean onResult(@NonNull String dialogTag, int which, @NonNull Bundle extras) {
        if (dialogTag.equals(COLOR_DIALOG)) {
            courseColor = extras.getInt(SimpleColorDialog.COLOR);
            viewColor.setBackgroundColor(courseColor);
            return true;
        }
        return false;
    }


    @AfterPermissionGranted(REQUEST_PERMISSION_GET_ACCOUNTS)
    private void signInGoogleCredential() {
        gCredential = GoogleAccountCredential.usingOAuth2(
                this, Arrays.asList(LauncherLogin.SCOPES))
                .setBackOff(new ExponentialBackOff());
        gCredential.setSelectedAccountName(Database.getUser().getEmail());
    }

}

CourseAddTime.java (запущенное действие):

package com.nbdeg.unityplanner.Utils;

import android.app.Activity;
import android.app.TimePickerDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RelativeLayout;
import android.widget.TimePicker;
import android.widget.Toast;

import com.nbdeg.unityplanner.Data.Time;
import com.nbdeg.unityplanner.R;

import java.util.Calendar;

public class CourseAddTime extends Activity {

    private int startHour;
    private int startMin;
    private int endHour;
    private int endMin;

    private EditTextDatePicker viewStartDate;
    private EditTextDatePicker viewStopDate;
    private RadioButton viewBlockSchedule;
    private RadioButton viewDaySchedule;

    private CheckBox viewDayMon;
    private CheckBox viewDayTue;
    private CheckBox viewDayWen;
    private CheckBox viewDayThu;
    private CheckBox viewDayFri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_course_add_time);

        final EditText viewStartTime = (EditText) findViewById(R.id.course_add_time_start_time);
        final EditText viewEndTime = (EditText) findViewById(R.id.course_add_time_stop_time);
        viewStartDate = new EditTextDatePicker(this, R.id.course_add_time_start_date);
        viewStopDate = new EditTextDatePicker(this, R.id.course_add_time_stop_date);

        viewBlockSchedule = (RadioButton) findViewById(R.id.course_add_time_ab_schedule);
        viewDaySchedule = (RadioButton) findViewById(R.id.course_add_time_per_day_schedule);
        final RelativeLayout layoutBlockSchedule = (RelativeLayout) findViewById(R.id.course_add_time_ab_schedule_layout);
        final LinearLayout layoutDaySchedule = (LinearLayout) findViewById(R.id.course_add_time_per_day_schedule_layout);

        viewDayMon = (CheckBox) findViewById(R.id.course_add_time_per_day_schedule_mon);
        viewDayTue = (CheckBox) findViewById(R.id.course_add_time_per_day_schedule_tue);
        viewDayWen = (CheckBox) findViewById(R.id.course_add_time_per_day_schedule_wen);
        viewDayThu = (CheckBox) findViewById(R.id.course_add_time_per_day_schedule_thu);
        viewDayFri = (CheckBox) findViewById(R.id.course_add_time_per_day_schedule_fri);

        viewStartTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Calendar mcurrentTime = Calendar.getInstance();
                int hour = mcurrentTime.get(Calendar.HOUR_OF_DAY);
                int minute = mcurrentTime.get(Calendar.MINUTE);
                TimePickerDialog mTimePicker;
                mTimePicker = new TimePickerDialog(CourseAddTime.this, new TimePickerDialog.OnTimeSetListener() {
                    @Override
                    public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
                        viewStartTime.setText( selectedHour + ":" + selectedMinute);
                        startHour = selectedHour;
                        startMin = selectedMinute;
                    }
                }, hour, minute, true);

                mTimePicker.setTitle("Select Time");
                mTimePicker.show();
            }
        });

        viewEndTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Calendar mcurrentTime = Calendar.getInstance();
                int hour = mcurrentTime.get(Calendar.HOUR_OF_DAY);
                int minute = mcurrentTime.get(Calendar.MINUTE);
                TimePickerDialog mTimePicker;
                mTimePicker = new TimePickerDialog(CourseAddTime.this, new TimePickerDialog.OnTimeSetListener() {
                    @Override
                    public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
                        viewEndTime.setText( selectedHour + ":" + selectedMinute);
                        endHour = selectedHour;
                        endMin = selectedMinute;
                    }
                }, hour, minute, true);

                mTimePicker.setTitle("Select Time");
                mTimePicker.show();
            }
        });

        viewBlockSchedule.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewBlockSchedule.setChecked(true);
                viewDaySchedule.setChecked(false);
                layoutBlockSchedule.setVisibility(View.VISIBLE);
                layoutDaySchedule.setVisibility(View.GONE);
            }
        });

        viewDaySchedule.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewBlockSchedule.setChecked(true);
                viewDaySchedule.setChecked(false);
                layoutBlockSchedule.setVisibility(View.GONE);
                layoutDaySchedule.setVisibility(View.VISIBLE);
            }
        });
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();

        if (viewStartDate.date == null || viewStopDate.date == null) {
            Toast.makeText(this, "No time was added", Toast.LENGTH_SHORT).show();
            Intent returnIntent = new Intent();
            setResult(Activity.RESULT_CANCELED, returnIntent);
            finish();
        }

        Time courseTime = null;

        if (viewBlockSchedule.isChecked()) {
            // Block Schedule
            Calendar startCal = Calendar.getInstance();
            Calendar endCal = Calendar.getInstance();
            startCal.setTime(viewStartDate.date);
            startCal.set(Calendar.HOUR_OF_DAY, startHour);
            startCal.set(Calendar.MINUTE, startMin);

            endCal.setTime(viewStartDate.date);
            endCal.set(Calendar.HOUR_OF_DAY, endHour);
            endCal.set(Calendar.MINUTE, endMin);

            courseTime = new Time(null, startCal.getTimeInMillis(), endCal.getTimeInMillis(), viewStopDate.date.getTime());

        } else if (viewDaySchedule.isChecked()) {
            // Day Schedule
            Calendar startCal = Calendar.getInstance();
            Calendar endCal = Calendar.getInstance();
            startCal.setTime(viewStartDate.date);
            startCal.set(Calendar.HOUR_OF_DAY, startHour);
            startCal.set(Calendar.MINUTE, startMin);

            endCal.setTime(viewStartDate.date);
            endCal.set(Calendar.HOUR_OF_DAY, endHour);
            endCal.set(Calendar.MINUTE, endMin);

            StringBuilder dayBuilder = new StringBuilder();
            if (viewDayMon.isChecked()) {
                dayBuilder.append("MON,");
            }
            if (viewDayTue.isChecked()) {
                dayBuilder.append("TUE,");
            }
            if (viewDayWen.isChecked()) {
                dayBuilder.append("WEN,");
            }
            if (viewDayThu.isChecked()) {
                dayBuilder.append("THU,");
            }
            if (viewDayFri.isChecked()) {
                dayBuilder.append("FRI,");
            }

            if (dayBuilder.toString().equals("")) {
                Toast.makeText(this, "No time was added", Toast.LENGTH_SHORT).show();
                Intent returnIntent = new Intent();
                setResult(Activity.RESULT_CANCELED, returnIntent);
                finish();
            } else {
                dayBuilder.deleteCharAt(dayBuilder.length());
                dayBuilder.append(";");
            }

            courseTime = new Time(dayBuilder.toString(), startCal.getTimeInMillis(), endCal.getTimeInMillis(), viewStopDate.date.getTime());
        }

        Intent returnIntent = new Intent();
        returnIntent.putExtra("time", courseTime);
        setResult(Activity.RESULT_OK,returnIntent);
        finish();
    }
}

person nickthegroot    schedule 12.05.2017    source источник
comment
У вас проблемы с xml. Выложите код макета.   -  person azizbekian    schedule 12.05.2017
comment
Похоже, возникла проблема с элементом в строке 103 макета activity_course_add_time. У вас есть элемент <view> без атрибута class? Пожалуйста, разместите соответствующую часть этого макета.   -  person Mike M.    schedule 12.05.2017
comment
@МайкМ. Это бы сработало. Забыл написать элемент ‹View› с заглавной буквы. Если вы опубликуете ответ, я был бы более чем счастлив принять его. Благодарю вас!   -  person nickthegroot    schedule 12.05.2017
comment
Ах, круто. Однако я просто отмечу это как дубликат, поскольку на него уже был дан ответ. Спасибо хоть. Рад, что у тебя получилось. Ваше здоровье!   -  person Mike M.    schedule 12.05.2017