Вот пример, в котором используется счетчик, и при его выборе отображается расстояние до следующего изменения элемента и текущие показания одометра.Это очень просто, и вместо использования даты / времени сервиса используются показания одометра и (километры).
Должен ли я использовать SQLite с int и временем для этого?
- Вы, вероятно, захотите два интервала: расстояние и время обслуживания часто зависят от того, что наступит раньше (пройденное расстояние или время с момента последнего обслуживания) в примерах принимается только расстояние .
Он основан на 3 таблицах: одна для автомобилей , одна для service_items (замена масляного фильтра и т. Д.), А затем таблица соответствия / справочная таблица ( интервалы ).Это имеет одну строку для каждого элемента автомобиля / услуги, каждая строка включает указанную машину и указанный service_item, показания одометра, когда элемент последний раз обслуживался, и интервал обслуживания.
Имеется счетчик, который позволяет выбиратьэлемент службы и выбор элемента службы показывают, как долго следующий сервис для этого элемента.
Помощник по базе данных, DBHelper.java (подкласс класса SQLiteOpenHelper): -
public class DBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "service";
public static final int DBVERSION = 1;
public static final String TBITEM = "service_item";
public static final String TBCAR = "car";
public static final String TBINTERVAL = "interval";
public static final String COL_TBITEMS_ID = BaseColumns._ID;
public static final String COL_TBITEMS_NAME = "item_name";
static final String crt_items_sql = "CREATE TABLE IF NOT EXISTS " +
TBITEM + "(" +
COL_TBITEMS_ID + " INTEGER PRIMARY KEY, " +
COL_TBITEMS_NAME + " TEXT " +
")";
public static final String COL_TBCAR_ID = BaseColumns._ID;
public static final String COL_TBCAR_OWNERNAME = "owner_name";
public static final String COL_TBCAR_ODOMETER = "odometer";
static final String crt_car_sql = "CREATE TABLE IF NOT EXISTS " +
TBCAR + "(" +
COL_TBCAR_ID + " INTEGER PRIMARY KEY, " +
COL_TBCAR_OWNERNAME + " TEXT, " +
COL_TBCAR_ODOMETER + " INTEGER " +
")";
public static final String COL_TBINTERVAL_ITEMREF = "item_id_reference";
public static final String COL_TBINTERVAL_CARREF = "car_id_reference";
public static final String COL_TBINTERVAL_INTERVAL = "item_interval";
public static final String COL_TBINTERVAL_LASTDONE = "item_last_done";
static final String crt_intervals_sql = "CREATE TABLE IF NOT EXISTS " +
TBINTERVAL + "(" +
COL_TBINTERVAL_ITEMREF + " INTEGER REFERENCES " + TBITEM + "(" + COL_TBITEMS_ID + ")," +
COL_TBINTERVAL_CARREF + " INTEGER REFERENCES " + TBCAR + "(" + COL_TBCAR_ID + ")," +
COL_TBINTERVAL_INTERVAL + " INTEGER, " +
COL_TBINTERVAL_LASTDONE + " INTEGER DEFAULT 0 " +
")";
SQLiteDatabase mDB;
public DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(crt_items_sql);
db.execSQL(crt_car_sql);
db.execSQL(crt_intervals_sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
public long addCar(String name, long odometer) {
ContentValues cv = new ContentValues();
cv.put(COL_TBCAR_OWNERNAME,name);
cv.put(COL_TBCAR_ODOMETER,odometer);
return mDB.insert(TBCAR,null,cv);
}
public long addItem(String name) {
ContentValues cv = new ContentValues();
cv.put(COL_TBITEMS_NAME,name);
return mDB.insert(TBITEM,null,cv);
}
public long addInterval(long item_id, long car_id, long interval, long last_done) {
ContentValues cv = new ContentValues();
cv.put(COL_TBINTERVAL_ITEMREF, item_id);
cv.put(COL_TBINTERVAL_CARREF, car_id);
cv.put(COL_TBINTERVAL_INTERVAL,interval);
cv.put(COL_TBINTERVAL_LASTDONE,last_done);
return mDB.insert(TBINTERVAL,null,cv);
}
public long getCarOdometer(long car_id) {
long rv = -1;
Cursor csr = mDB.query(TBCAR,null,null,null,null,null,null);
if (csr.moveToFirst()) {
rv = csr.getLong(csr.getColumnIndex(COL_TBCAR_ODOMETER));
}
csr.close();
return rv;
}
public long getNextDueForItem(long car_id, long item_id) {
long rv = -1;
long odometer = getCarOdometer(car_id);
long last_done = 0;
long interval = 0;
String whereclause = COL_TBINTERVAL_ITEMREF + "=? AND " + COL_TBINTERVAL_CARREF + "=?";
String[] whereargs = new String[]{String.valueOf(item_id),String.valueOf(car_id)};
Cursor csr = mDB.query(TBINTERVAL,null,whereclause,whereargs,null,null,null);
if (csr.moveToFirst()) {
last_done = csr.getLong(csr.getColumnIndex(COL_TBINTERVAL_LASTDONE));
interval = csr.getLong(csr.getColumnIndex(COL_TBINTERVAL_INTERVAL));
long dueat = last_done + interval;
rv = dueat - odometer;
}
csr.close();
return rv;
}
}
Активность MainActivity.java : -
public class MainActivity extends AppCompatActivity {
Spinner mSpinner;
TextView mSpinner_selection;
ArrayAdapter<String> mSA;
ArrayList<String> items = new ArrayList<>(
Arrays.asList("Change Oil","Change Oil Filter","Change Air Filter","Change Spark Plugs")
);
DBHelper mDBHlpr;
long mCurrentCar = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSpinner = this.findViewById(R.id.spinner);
mSpinner_selection = this.findViewById(R.id.selected_spinner);
mSpinner_selection.setText("Nothing selected as yet"); //<<<< will likely not be seen
// Instaiate the Database Helper (will create the Database and tables when first run)
mDBHlpr = new DBHelper(this);
addSomeData();
handleSpinner();
}
// Setup the Spinner and the Item Select Listener
private void handleSpinner() {
if (mSA == null) {
mSA = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,items);
mSpinner.setAdapter(mSA);
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
//<<<<<<<<<< NOTE not the best way as assumes a direct map
// from the list to the service_item.
long duein = mDBHlpr.getNextDueForItem(mCurrentCar,(long)i + 1);
long odometer = mDBHlpr.getCarOdometer(mCurrentCar);
String text_to_show =
"You are due to " + mSA.getItem(i) + " in " + String.valueOf(duein) +
"Your Odometer reads " + String.valueOf(odometer);
mSpinner_selection.setText(text_to_show);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
}
// Add some data, a car and the service items based upon the ArrayList of items
// noting that for display purposes the interval increase per service_item
private void addSomeData() {
long thiscar = mDBHlpr.addCar("My Car",1123);
long interval = 10000;
for (String s: items) {
long thisitem = mDBHlpr.addItem(s);
mDBHlpr.addInterval(thisitem,thiscar,interval,0);
interval = interval + 500;
}
}
}
Макет для MainActivity: activity_main.xml : -
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Spinner>
<TextView
android:id="@+id/selected_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
- Примечание Это просто демонстрация, показывающая, как можно использовать счетчик.
- При первом запуске он покажет: -
- Выбор замены масляного фильтра покажет: -
- 10500, потому что 500 постепенно добавляется к интервалу обслуживания в методе addSomeData в MainActivity (просто чтобы показать разные данные).