如何将用户输入的数据保存到设备的本地内部存储器中?

How to save the data a user inputs into the device's local internal storage?

我在空闲时间在 Android 上开发 Grade/GPA 计算器应用程序。到目前为止,该应用基本上所做的是让用户在 Main Activity 中添加 Semesters,当用户点击某个 学期 用户被重定向到另一个Activity,用户可以在其中添加新的课程具体学期。我遇到的问题是,当用户点击后退按钮转到 Main Activity 时,Semesters位于该学期添加的课程被删除。当我转到 phone 的主页并重新启动应用程序时,也会发生同样的情况,用户创建的所有内容都已删除。

我很确定我的问题是我没有将用户创建的数据保存到 phone 的 storage/app 的存储中,但我似乎无法弄清楚如何做到这一点。如果有人能指出我正确的方向,我将不胜感激。谢谢!

这是我的 MainActivity class 的代码:(我的 MainActivity 是添加学期的地方)

package com.example.gradecalculator;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import java.util.ArrayList;
import java.util.Random;

public class MainActivity extends AppCompatActivity {

    // Private Fields
    private Dialog d;
    private EditText semesterName;
    private ListView semesterListView;
    private ArrayList<String> semesterArray = new ArrayList<String>();
    private SemesterAdapter customSemesterAdapter;
    private ArrayList<Semester> mySemesters = new ArrayList<>();
    private ArrayList<String> semesterBackgrounds = new ArrayList<String>();
    private String getSemesterName;
    private int randomBackground[] = new int[7];

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

        // Initiating toolbar
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Making a new dialog
        d = new Dialog(this);

        // Initializing variables
        semesterName = (EditText) d.findViewById(R.id.editTextSemesterName);
        semesterListView = (ListView) findViewById(R.id.semesterList);

        // Calling the removeSemesters() method
        removeSemesters();

        // Adding backgrounds to the backgrounds ArrayList
        semesterBackgrounds.add("orange_background");
        semesterBackgrounds.add("green_background");
        semesterBackgrounds.add("aqua_background");
        semesterBackgrounds.add("blue_background");
        semesterBackgrounds.add("pink_background");
        semesterBackgrounds.add("purple_background");
        semesterBackgrounds.add("red_background");
        semesterBackgrounds.add("yellow_background");
    }

    // Creating a custom Menu
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.top_menu, menu);
        return true;
    }

    // Buttons in the custom Menu
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.editButton:
                Toast.makeText(this, "Delete the desired Semesters by clicking on the trash button located to the right of each Semester", Toast.LENGTH_LONG).show();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    // When user clicks on "+New Semester" button open a popup where the user is prompted to
    // type in the Semester Name and when "Done" is clicked the new semester appears in the Main
    // Activity
    public void newSemesterPopup(View v) {
        TextView closePopup;
        ImageButton doneButton;

        d.setContentView(R.layout.new_semester_popup);

        semesterName = (EditText) d.findViewById(R.id.editTextSemesterName);
        semesterListView = (ListView) findViewById(R.id.semesterList);

        doneButton = (ImageButton) d.findViewById(R.id.doneButton);
        doneButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addSemesters();
            }
        });

        closePopup = (TextView) d.findViewById(R.id.exitButton);
        closePopup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                d.dismiss();
            }
        });
        d.show();
    }

    // Adds semesters to Main Activity
    public void addSemesters() {
        getSemesterName = semesterName.getText().toString();

        if (semesterArray.contains(getSemesterName)) {
            Toast.makeText(getBaseContext(), "Semester Name Already Exists", Toast.LENGTH_SHORT).show();
        } else if (getSemesterName == null || getSemesterName.trim().equals("")) {
            Toast.makeText(getBaseContext(), "Cannot Add Empty Semester Name", Toast.LENGTH_SHORT).show();
        } else {
            semesterArray.add(getSemesterName);
            mySemesters.add(new Semester(getSemesterName, semesterBackgrounds.get(new Random().nextInt(randomBackground.length))));
            customSemesterAdapter = new SemesterAdapter(getApplicationContext(), R.layout.semester_row, mySemesters);
            semesterListView.setAdapter(customSemesterAdapter);
            d.dismiss();
        }
    }

    // Removes unwanted semesters from Main Activity
    public void removeSemesters() {
        semesterListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {

                AlertDialog.Builder deleteAlert = new AlertDialog.Builder(MainActivity.this);
                deleteAlert.setTitle("Semester Deletion Process");
                deleteAlert.setMessage("Are you sure you want to delete the selected Semesters?");
                deleteAlert.setNegativeButton("No! Cancel", null);
                deleteAlert.setPositiveButton("Yes! Delete", new AlertDialog.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        customSemesterAdapter.remove(customSemesterAdapter.getItem(position));
                        semesterArray.remove(position);
                        customSemesterAdapter.notifyDataSetChanged();
                        Toast.makeText(MainActivity.this, "Semester Deleted Successfully.", Toast.LENGTH_SHORT).show();
                    }
                });
                deleteAlert.show();
                return false;
            }
        });
        openSemestersActivity();
    }

    // Open the SemesterActivity and uses .putExtra to pass data to the SemesterActivity to tell it what semester to render
    // data accordingly
    public void openSemestersActivity() {
        final Intent semester = new Intent(this, SemesterActivity.class);
        semesterListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                semester.putExtra("semester", semesterName.getText().toString());
                startActivity(semester);
            }
        });
    }
}

这是我的 SemesterActivity 代码:(我的 SemestersActivity 是添加课程的地方)

package com.example.gradecalculator;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import java.util.ArrayList;
import java.util.Random;

public class SemesterActivity extends AppCompatActivity {

    // Private Fields
    private Dialog d;
    private EditText courseName;
    private EditText courseCode;
    private EditText courseCredits;
    private ListView courseListView;
    private ArrayList<String> courseArray = new ArrayList<String>();
    private CourseAdapter customCourseAdapter;
    private ArrayList<Course> myCourses = new ArrayList<>();
    private ArrayList<String> coursesBackgrounds = new ArrayList<String>();
    private String getCourseName;
    private String getCourseCode;
    private String getCourseCredits;
    private int randomBackground[] = new int[7];
    private TextView courseNameView;
    private TextView courseCodeView;
    private TextView courseCreditsView;

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

        d = new Dialog(this);

        courseNameView = (TextView) d.findViewById(R.id.editTextCourseName);
        courseCodeView = (TextView) d.findViewById(R.id.editTextCourseCode);
        courseCreditsView = (TextView) d.findViewById(R.id.editTextCourseCredits);
        courseListView = (ListView) findViewById(R.id.coursesList);

        // Retrieving the Extra and determining the semester we want to load
        Intent myIntent = getIntent();
        String semester = myIntent.getStringExtra("semester");

        removeCourses();

        // Initiating toolbar
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Adding backgrounds to the backgrounds ArrayList
        coursesBackgrounds.add("orange_background_big");
        coursesBackgrounds.add("green_background_big");
        coursesBackgrounds.add("aqua_background_big");
        coursesBackgrounds.add("blue_background_big");
        coursesBackgrounds.add("pink_background_big");
        coursesBackgrounds.add("purple_background_big");
        coursesBackgrounds.add("red_background_big");
        coursesBackgrounds.add("yellow_background_big");
    }

    // Creating a custom Menu
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.top_menu, menu);
        return true;
    }

    // Buttons in the custom Menu
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.editButton:
                Toast.makeText(this, "Delete the desired Courses by clicking on the trash button located to the right of each Semester", Toast.LENGTH_LONG).show();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    // New course popup
    public void newCoursePopup(View v) {
        TextView closePopup;
        ImageButton doneButton;

        d.setContentView(R.layout.new_course_popup);

        courseName = (EditText) d.findViewById(R.id.editTextCourseName);
        courseCode = (EditText) d.findViewById(R.id.editTextCourseCode);
        courseCredits = (EditText) d.findViewById(R.id.editTextCourseCredits);

        doneButton = (ImageButton) d.findViewById(R.id.doneButton);
        doneButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addCourses();
            }
        });

        closePopup = (TextView) d.findViewById(R.id.exitButton);
        closePopup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                d.dismiss();
            }
        });
        d.show();
    }

    // Adding courses to the Semester
    public void addCourses() {
        getCourseName = courseName.getText().toString();
        getCourseCode = courseCode.getText().toString();
        getCourseCredits = courseCredits.getText().toString();

        if(courseArray.contains(getCourseName)) {
            Toast.makeText(getBaseContext(), "Course Name Already Exists", Toast.LENGTH_SHORT).show();
        }
        else if(getCourseName == null || getCourseName.trim().equals("")) {
            Toast.makeText(getBaseContext(), "Cannot Add Empty Course Name", Toast.LENGTH_SHORT).show();
        }
        else {
            courseArray.add(getCourseName);
            myCourses.add(new Course(getCourseName, getCourseCode, getCourseCredits, coursesBackgrounds.get(new Random().nextInt(randomBackground.length))));
            customCourseAdapter = new CourseAdapter(getApplicationContext(), R.layout.course_row, myCourses);
            courseListView.setAdapter(customCourseAdapter);
            d.dismiss();
        }
    }

    // Removing courses from the Semester
    public void removeCourses() {
        courseListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {

                AlertDialog.Builder deleteAlert = new AlertDialog.Builder(SemesterActivity.this);
                deleteAlert.setTitle("Course Deletion Process");
                deleteAlert.setMessage("Are you sure you want to delete the selected Courses?");
                deleteAlert.setNegativeButton("No! Cancel", null);
                deleteAlert.setPositiveButton("Yes! Delete", new AlertDialog.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        customCourseAdapter.remove(customCourseAdapter.getItem(position));
                        courseArray.remove(position);
                        customCourseAdapter.notifyDataSetInvalidated();
                        Toast.makeText(SemesterActivity.this, "Course Deleted Successfully", Toast.LENGTH_SHORT).show();
                    }
                });
                deleteAlert.show();
                return false;
            }
        });
    }
}

您可以查看几个数据库;您可以使用 Firebase 的 Room or Realm. You can also check out online DBs like Firestore。拥有在线数据库的美妙之处在于,如果用户(学生)丢失或替换了当前的数据,他们可以从不同的 phone 访问他们的数据。推荐的方法是同时涵盖两种情况。