如何为BMI应用添加SQLite数据库以存储用户体重指数记录?
Got it, let's get your SQLite integration sorted for your BMI app. Here's a step-by-step solution that builds on your existing code to save and view BMI history:
Step 1: Create the Database Helper Class
First, make a new class called BMIDatabaseHelper to handle database setup and operations. This is Android's standard way to manage SQLite databases.
import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import java.util.ArrayList; import java.util.HashMap; public class BMIDatabaseHelper extends SQLiteOpenHelper { // Core database config private static final String DATABASE_NAME = "BMIHistory.db"; private static final int DATABASE_VERSION = 1; // Table and column definitions private static final String TABLE_BMI = "bmi_records"; private static final String COLUMN_ID = "_id"; private static final String COLUMN_BMI_VALUE = "bmi_value"; private static final String COLUMN_BMI_CATEGORY = "bmi_category"; private static final String COLUMN_RECORD_DATE = "record_date"; public BMIDatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { // Create the BMI records table String CREATE_TABLE_QUERY = "CREATE TABLE " + TABLE_BMI + "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_BMI_VALUE + " REAL," + COLUMN_BMI_CATEGORY + " TEXT," + COLUMN_RECORD_DATE + " DATETIME DEFAULT CURRENT_TIMESTAMP" + ")"; db.execSQL(CREATE_TABLE_QUERY); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // Drop old table and re-create on version upgrade db.execSQL("DROP TABLE IF EXISTS " + TABLE_BMI); onCreate(db); } // Insert a new BMI record into the database public void insertBMIRecord(float bmiValue, String category) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COLUMN_BMI_VALUE, bmiValue); values.put(COLUMN_BMI_CATEGORY, category); // Insert row (record_date uses default current timestamp) db.insert(TABLE_BMI, null, values); db.close(); } // Fetch all saved BMI records, sorted by most recent first public ArrayList<HashMap<String, String>> getAllBMIRecords() { ArrayList<HashMap<String, String>> recordList = new ArrayList<>(); String fetchQuery = "SELECT * FROM " + TABLE_BMI + " ORDER BY " + COLUMN_RECORD_DATE + " DESC"; SQLiteDatabase db = this.getWritableDatabase(); Cursor cursor = db.rawQuery(fetchQuery, null); // Loop through results and build the list if (cursor.moveToFirst()) { do { HashMap<String, String> record = new HashMap<>(); record.put("bmi", String.valueOf(cursor.getFloat(cursor.getColumnIndexOrThrow(COLUMN_BMI_VALUE)))); record.put("category", cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_BMI_CATEGORY))); record.put("date", cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_RECORD_DATE))); recordList.add(record); } while (cursor.moveToNext()); } cursor.close(); db.close(); return recordList; } }
Step 2: Update Your MainActivity
Now modify your MainActivity to use the database helper, implement save/view functionality, and fix a small typo in your input validation.
First, add a member variable for the database helper:
private BMIDatabaseHelper dbHelper; private String currentBMICategory; // To store the calculated BMI category for saving
Initialize the helper in onCreate:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); height = findViewById(R.id.height); weight = findViewById(R.id.weight); result = findViewById(R.id.result); // Initialize database helper dbHelper = new BMIDatabaseHelper(this); }
Update displayBMI to track the current category (needed for saving):
private void displayBMI(float bmi) { currentBMICategory = ""; if (Float.compare(bmi, 15f) <= 0) { currentBMICategory = getString(R.string.v_sev_underweight); } else if (Float.compare(bmi, 15f) > 0 && Float.compare(bmi, 16f) <= 0) { currentBMICategory = getString(R.string.sev_underweight); } else if (Float.compare(bmi, 16f) > 0 && Float.compare(bmi, 18.5f) <= 0) { currentBMICategory = getString(R.string.underweight); } else if (Float.compare(bmi, 18.5f) > 0 && Float.compare(bmi, 25f) <= 0) { currentBMICategory = getString(R.string.healthy); } else if (Float.compare(bmi, 25f) > 0 && Float.compare(bmi, 30f) <= 0) { currentBMICategory = getString(R.string.overweight); } else if (Float.compare(bmi, 30f) > 0 && Float.compare(bmi, 35f) <= 0) { currentBMICategory = getString(R.string.obese1); } else if (Float.compare(bmi, 35f) > 0 && Float.compare(bmi, 40f) <= 0) { currentBMICategory = getString(R.string.obese2); } else { currentBMICategory = getString(R.string.obese3); } String bmiLabel = bmi + "\n\n" + currentBMICategory; result.setText(bmiLabel); }
Fix the input validation typo in calculateBMI (you had three quotes instead of two):
public void calculateBMI(View v) { String heightStr = height.getText().toString(); String weightStr = weight.getText().toString(); // Fixed the quote typo here if (heightStr != null && !"".equals(heightStr) && weightStr != null && !"".equals(weightStr)) { float heightValue = Float.parseFloat(heightStr) / 100; float weightValue = Float.parseFloat(weightStr); float bmi = weightValue / (heightValue * heightValue); displayBMI(bmi); } }
Implement the saveBMI method (add a View parameter if you're calling this from a button click):
public void saveBMI(View v) { if (currentBMICategory == null || currentBMICategory.isEmpty()) { Toast.makeText(this, "Calculate your BMI first!", Toast.LENGTH_SHORT).show(); return; } // Extract BMI value from the result text String resultText = result.getText().toString(); float bmiValue = Float.parseFloat(resultText.split("\n")[0]); // Save to database dbHelper.insertBMIRecord(bmiValue, currentBMICategory); Toast.makeText(this, "BMI record saved successfully!", Toast.LENGTH_SHORT).show(); }
Implement the viewBMI method to display history in a dialog:
public void viewBMI(View v) { ArrayList<HashMap<String, String>> records = dbHelper.getAllBMIRecords(); if (records.isEmpty()) { Toast.makeText(this, "No BMI records found!", Toast.LENGTH_SHORT).show(); return; } // Build the history text StringBuilder historyBuilder = new StringBuilder(); for (HashMap<String, String> record : records) { historyBuilder.append("Date: ").append(record.get("date")).append("\n") .append("BMI: ").append(record.get("bmi")).append("\n") .append("Category: ").append(record.get("category")).append("\n\n"); } // Show dialog with history new AlertDialog.Builder(this) .setTitle("Your BMI History") .setMessage(historyBuilder.toString()) .setPositiveButton("Close", null) .show(); }
Step 3: Add Buttons to Your Layout (Optional)
Update your activity_main.xml to add save and view buttons:
<Button android:id="@+id/save_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Save BMI" android:onClick="saveBMI"/> <Button android:id="@+id/view_history_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="View History" android:onClick="viewBMI"/>
Quick Notes
- Don't forget to add imports for
Toast,AlertDialog, and other used classes to yourMainActivity. - For better UX, you could move history display to a separate activity with a
RecyclerViewinstead of a dialog, but this implementation works for a quick start.
内容的提问来源于stack exchange,提问作者JSTAN

