- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我构建了一个应用程序,它在 MainActivity.java 中执行一些计算并将结果存储在 SQLite 数据库中。当用户按下按钮时,将打开带有相应 GraphView 的 GraphActivity.java。也许是因为我对 SQLite 数据库还没有太多经验,但我无法让图表的 X 轴显示每个结果的存储日期。
那么,考虑到 Insert 方法和 Graph 发生在单独的 Activity 中,我如何才能使存储的日期在 GraphActivity 中显示为 X 轴?
我按照 GraphView 日期和 SQLite 的 YouTube 教程进行操作,但它在同一 Activity 中具有存储和图表。 (https://www.youtube.com/watch?v=lSgK6-cKjmA&list=PLFh8wpMiEi88ojfNpavGpMB0dtP4mvEqa&index=16)
我尝试使用 Intent EXTRAS 发送日期变量,但当按下“保存”按钮时,它会强制您进入 GraphActivity。然后我尝试在 GraphActivity 中获取时间,它可以工作,但每个结果的 X 轴日期显示为连续的“1-1-1970”。我使用格式来显示带有时间戳的当前日期,但它仍然不显示每个结果的存储日期,仅显示所有结果的当前日期。
MainActivity.java:结果和日期的插入方法
public void insertData() {
try {
(...)
// Gets the time & date the results are stored
String timeStamp = new SimpleDateFormat("d M yy hh:mm").format(Calendar.getInstance().getTime());
// Create a ContentValues object where column names are the keys,
// and container attributes from the MainActivity are the values.
ContentValues values = new ContentValues();
values.put(DexameniEntry.COLUMN_CONTAINER_NAME, "TODO");
values.put(DexameniEntry.COLUMN_a, X1aInput);
values.put(DexameniEntry.COLUMN_DATE, timeStamp);
values.put(DexameniEntry.COLUMN_b, X1bInput);
values.put(DexameniEntry.COLUMN_c, X1cInput);
values.put(DexameniEntry.COLUMN_d, dX1StringDouble);
values.put(DexameniEntry.COLUMN_e, eX1StringDouble);
values.put(DexameniEntry.COLUMN_percent, percentX1fromDoubletoString);
(...)
} catch (NumberFormatException e) {
} catch (NullPointerException e) {
}
}
GraphActivity.java:设置GraphView
public class GraphActivity extends AppCompatActivity {
(...)
SimpleDateFormat sdf = new SimpleDateFormat("EEE d M yyyy h mm", Locale.US);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.graph_activity);
GraphView bigGraphX1 = findViewById(R.id.bigGraph);
mDbHelper = new ResultsDbHelper(this);
sqLiteDatabase = mDbHelper.getWritableDatabase();
bigGraphX1.getGridLabelRenderer().setLabelFormatter(new DefaultLabelFormatter() {
@Override
public String formatLabel(double value, boolean isValueX) {
if (isValueX) {
return
sdf.format(new Date((long)value));
}else {
return super.formatLabel(value, isValueX);
}
}
});
(...)
编辑DbHelper.class(名为 ResultsDbHelper)
public class ResultsDbHelper extends SQLiteOpenHelper {
public static final String LOG_TAG = ResultsDbHelper.class.getSimpleName();
// Name of the database in a String type constant (to be referenced later)
private static final String DATABASE_NAME = "containerResults.db";
// Database version in a Integer type constant for updating the database
private static final int DATABASE_VERSION = 1;
// Constructor: Constructs a new instance of ResultsDbHelper.
// * @param is the context of the app
public ResultsDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Modify the onCreate method to have the table created on startup of the app
@Override
public void onCreate(SQLiteDatabase db) {
// Define the schema of the table: which columns will be created by the onCreate method.
// The whole schema creation is put in a String variable (CREATE_RESULTS_TABLE) for easy reference
String CREATE_RESULTS_TABLE = "CREATE TABLE " + DexameniEntry.TABLE_NAME + " ("
+ DexameniEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ DexameniEntry.COLUMN_CONTAINER_NAME + " TEXT NOT NULL, "
+ DexameniEntry.COLUMN_DATE + " TEXT NOT NULL, "
+ DexameniEntry.COLUMN_a + " REAL NOT NULL, "
+ DexameniEntry.COLUMN_b + " REAL NOT NULL, "
+ DexameniEntry.COLUMN_c + " REAL NOT NULL, "
+ DexameniEntry.COLUMN_d + " REAL NOT NULL, "
+ DexameniEntry.COLUMN_e + " REAL NOT NULL, "
+ DexameniEntry.COLUMN_percent + " REAL NOT NULL);";
// Execute the SQL Statement (Create the table)
db.execSQL(CREATE_RESULTS_TABLE);
}
/**
* This is called when the database needs to be upgraded.
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
final String LOG_TAG = ("Upgrading the database from version " + oldVersion + " to " + newVersion);
// on upgrade drop older tables
db.execSQL("DROP TABLE IF EXISTS " + DexameniEntry.TABLE_NAME);
// Recreate tables
onCreate(db);
}
}
我希望 X 轴显示每个结果的存储日期,以便所有值在 GraphView 中显示为 LineSeries。但我似乎无法将日期从数据库获取到图表,因此所有日期始终相同,并且 LineSeries 不连贯。
编辑:在发布问题之前,我还开始寻找一种方法,在 FormatLabel 方法内将 DATE 列的数据库引用放入 GraphActivity 中。例如
@Override
public String formatLabel(double value, boolean isValueX) {
if (isValueX) {
return
sdf.format(new Date(**put here the DATE column variable so that the X-axis is populated the column's data**);
}else {
return super.formatLabel(value, isValueX);
}
我也无法做到这一点,因为我不知道如何编写这段代码......
我不知道还能做什么来解决这个问题,你能帮我吗?
编辑2:GraphActivity after changes (看起来图表仍然没有由数据库数据填充。也许将数据保存在数据库中存在问题?idk..)
最佳答案
您试图在 MainActivity 中执行太多操作,并且您可能遇到日期问题,因为从您的评论中可以看出,它们/它是 0。
基本上,您可能希望传递生成图表的条件(例如图表的日期范围),然后通过 Databasehelper (ResultsHelper) 中编码的方法从数据库中提取数据。
而不是在添加数据时获取当前时间并以 D M Y 格式存储到数据库中。您可以通过以可排序的格式存储日期以及以 SQLite 友好的格式(主要是 YYYY-MM-DD HH:MM:SS)操作/格式化日期来简单地处理问题(例如根据日期范围提取数据)(尽管您可以简单地存储时间戳)。
因此,我建议进行一些相对简单的更改。
将日期列定义更改为:-
+ DexameniEntry.COLUMN_DATE + " TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, " //<<<<<<<<<< LET SQLITE GET THE DATE TIME
//values.put(DexameniEntry.COLUMN_DATE, timeStamp); //<<<<<<<<<< Use default
将 insertData 方法移至 ResultHeper 中(然后可以在其他地方使用)
向 ResultHelper 添加一个方法,将数据提取到 Cursor 中,包括动态生成列。
SELECT *, a + b AS my_addition FROM the_table;
结果将包括所有列以及 my_addition 列。将提取图形数据的基本/最低选择标准从 MainActivity 传递到 GraphActivity,然后提取 graphActivity 中的实际数据。
以下代码基于您的代码和上述几点,是一个工作示例(它不会填充图表,但会获取数据)。
public class DexameniEntry {
public static final String[] WEEKDAYS_LONG = new String[]{"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
public static final String[] WEEKDAYS_SHORT = new String[]{"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
public static final String _ID = BaseColumns._ID;
public static final String TABLE_NAME = "container_results";
public static final String COLUMN_CONTAINER_NAME = "container_name";
public static final String COLUMN_DATE = "container_date";
public static final String COLUMN_a = "container_value_a";
public static final String COLUMN_b = "container_value_b";
public static final String COLUMN_c = "container_value_c";
public static final String COLUMN_d = "container_value_d";
public static final String COLUMN_e = "container_value_e";
public static final String COLUMN_percent = "container_percent";
public static final String EXTRACT_COLUMN_DATELABEL = "date_label";
public static final String EXTRACT_COLUMN_GRAPHDATELABEL = "graph_date_label";
public static final String INTENTKEY_GRAPHVALUE = "ik_graph_value";
}
public class ResultsDbHelper extends SQLiteOpenHelper {
public static final String LOG_TAG = ResultsDbHelper.class.getSimpleName();
// Date format that suits SQLite i.e. YYYY-MM-DD HH:MM:SS
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); // Not used but could be useful
// Name of the database in a String type constant (to be referenced later)
private static final String DATABASE_NAME = "containerResults.db";
// Database version in a Integer type constant for updating the database
private static final int DATABASE_VERSION = 1;
SQLiteDatabase mDB;
// Constructor: Constructs a new instance of ResultsDbHelper.
// * @param is the context of the app
public ResultsDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mDB = this.getWritableDatabase(); // Sets mDB (also forces open of DB)
}
// Modify the onCreate method to have the table created on startup of the app
@Override
public void onCreate(SQLiteDatabase db) {
// Define the schema of the table: which columns will be created by the onCreate method.
// The whole schema creation is put in a String variable (CREATE_RESULTS_TABLE) for easy reference
String CREATE_RESULTS_TABLE = "CREATE TABLE " + DexameniEntry.TABLE_NAME + " ("
+ DexameniEntry._ID + " INTEGER PRIMARY KEY, " //<<<<<<<<<< AUTOINCREMENT NOT REQD AS IS INEFFICIENT
+ DexameniEntry.COLUMN_CONTAINER_NAME + " TEXT NOT NULL, "
+ DexameniEntry.COLUMN_DATE + " TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, " //<<<<<<<<<< LET SQLITE GET THE DATE TIME
+ DexameniEntry.COLUMN_a + " REAL NOT NULL, "
+ DexameniEntry.COLUMN_b + " REAL NOT NULL, "
+ DexameniEntry.COLUMN_c + " REAL NOT NULL, "
+ DexameniEntry.COLUMN_d + " REAL NOT NULL, "
+ DexameniEntry.COLUMN_e + " REAL NOT NULL, "
+ DexameniEntry.COLUMN_percent + " REAL NOT NULL);";
// Execute the SQL Statement (Create the table)
db.execSQL(CREATE_RESULTS_TABLE);
}
/**
* This is called when the database needs to be upgraded.
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
final String LOG_TAG = ("Upgrading the database from version " + oldVersion + " to " + newVersion);
// on upgrade drop older tables
db.execSQL("DROP TABLE IF EXISTS " + DexameniEntry.TABLE_NAME);
// Recreate tables
onCreate(db);
}
public void insertData(String name,
Double X1aInput,
Double X1bInput,
Double X1cInput,
Double X1dInput,
Double X1eInput,
Double percent) {
String timeStamp = "";
try {
// Gets the time & date the results are stored
//timeStamp = new SimpleDateFormat("d M yy hh:mm").format(Calendar.getInstance().getTime());
timeStamp = sdf.format(Calendar.getInstance().getTime());
} catch (NumberFormatException e) {
} catch (NullPointerException e) {
}
// Create a ContentValues object where column names are the keys,
// and container attributes from the MainActivity are the values.
ContentValues values = new ContentValues();
values.put(DexameniEntry.COLUMN_CONTAINER_NAME, name);
values.put(DexameniEntry.COLUMN_a, X1aInput);
//values.put(DexameniEntry.COLUMN_DATE, timeStamp); //<<<<<<<<<< Use default
values.put(DexameniEntry.COLUMN_b, X1bInput);
values.put(DexameniEntry.COLUMN_c, X1cInput);
values.put(DexameniEntry.COLUMN_d, X1dInput);
values.put(DexameniEntry.COLUMN_e, X1eInput);
values.put(DexameniEntry.COLUMN_percent, percent);
mDB.insert(DexameniEntry.TABLE_NAME,null,values);
}
public Cursor getAllResults() {
String formatted_date = "strftime('%d %m %Y'," +
DexameniEntry.COLUMN_DATE + ") AS " + DexameniEntry.EXTRACT_COLUMN_DATELABEL;
String unixtype_date = "julianday(" + DexameniEntry.COLUMN_DATE + ") * 86400 * 1000 AS " +DexameniEntry.EXTRACT_COLUMN_GRAPHDATELABEL;
String[] columns = new String[]{"*",formatted_date,unixtype_date};
return mDB.query(DexameniEntry.TABLE_NAME,columns,null,null,null,null,DexameniEntry.COLUMN_DATE + " ASC");
}
}
julianday(the_column) * 86400 * 1000 AS the_column_name
)MainActivity 加载一些数据(仅在第一次运行时),并有一个按钮,单击该按钮将启动 GraphActivity。
public class MainActivity extends AppCompatActivity {
Button mShowGraph;
Context mContext;
ResultsDbHelper mDBHlpr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
mShowGraph = this.findViewById(R.id.show_graph);
setupShowGraphButton();
//Instantiate the DatabaseHelper
mDBHlpr = new ResultsDbHelper(this);
// Add some data if none exists
if (DatabaseUtils.queryNumEntries(mDBHlpr.getWritableDatabase(),DexameniEntry.TABLE_NAME) < 1) {
mDBHlpr.insertData("C1", 10.12, 11.12, 12.12, 13.12, 14.12, 25D);
mDBHlpr.insertData("C2", 20.12, 21.12, 22.12, 23.12, 24.12, 35D);
mDBHlpr.insertData("C3", 31.12, 32.12, 33.12, 34.12, 35.12, 25D);
}
}
// Setup the Buttons on click listener to start the GraphActivity
private void setupShowGraphButton() {
mShowGraph.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(mContext,GraphActivity.class);
i.putExtra(DexameniEntry.INTENTKEY_GRAPHVALUE,100);
startActivity(i);
}
});
}
}
虽然这显示了图表,但它不加载任何数据,而是从数据库中提取日期并将其写入日志。
public class GraphActivity extends AppCompatActivity {
Context mContext;
Button mDone;
GraphView mBigGraphX1;
ResultsDbHelper mDBHlpr;
Cursor mResults;
LineGraphSeries<DataPoint> mLGS;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_graph);
mContext = this;
mDone = this.findViewById(R.id.done);
setupDoneButton();
mDBHlpr = new ResultsDbHelper(this);
mResults = mDBHlpr.getAllResults();
mBigGraphX1 = this.findViewById(R.id.graphview);
demoDatesFromDB();
doTheGraphLineStuff();
}
private void setupDoneButton() {
mDone.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
@Override
protected void onDestroy() {
mResults.close(); //<<<<<<<<<< Should always close cursor when done
super.onDestroy();
}
private void demoDatesFromDB() {
StringBuilder sb = new StringBuilder("Data From Table ").append(DexameniEntry.TABLE_NAME).append(" as per :-");
while (mResults.moveToNext()) {
String date_asperdb = mResults.getString(mResults.getColumnIndex(DexameniEntry.COLUMN_DATE));
String date_formatted = mResults.getString(mResults.getColumnIndex(DexameniEntry.EXTRACT_COLUMN_DATELABEL));
long unix_date = mResults.getLong(mResults.getColumnIndex(DexameniEntry.EXTRACT_COLUMN_GRAPHDATELABEL));
sb.append("\n\tResults for row ");
sb.append(String.valueOf(mResults.getPosition() + 1));
sb.append(" Date as per DB is ").append(date_asperdb);
sb.append(" Formatted Date is ").append(date_formatted);
sb.append(" Unix Date is ").append(unix_date);
}
Log.d("DEMODATEINFO",sb.toString());
}
private void doTheGraphLineStuff() {
long one_day = 1000 * 60 * 60 * 24;
mResults = mDBHlpr.getAllResults();
int rowcount = mResults.getCount();
long[] extracted_dates = new long[rowcount];
DataPoint[] dataPoints = new DataPoint[rowcount];
while (mResults.moveToNext()) {
/**
* NOTE as all 3 rows are added within milliseconds this adds on a day
*/
extracted_dates[mResults.getPosition()] = mResults.getLong(
mResults.getColumnIndex(
DexameniEntry.EXTRACT_COLUMN_GRAPHDATELABEL
))
+ (one_day * ((long)mResults.getPosition() + 1L) //<<<< Frig the data show it is one day more than the previous
);
dataPoints[mResults.getPosition()] = new DataPoint(
extracted_dates[mResults.getPosition()],
mResults.getDouble(mResults.getColumnIndex(DexameniEntry.COLUMN_a))
);
}
mLGS = new LineGraphSeries<>(dataPoints);
mBigGraphX1.addSeries(mLGS);
mBigGraphX1.getGridLabelRenderer().setLabelFormatter(new DateAsXAxisLabelFormatter(mContext));
mBigGraphX1.getGridLabelRenderer().setNumHorizontalLabels(rowcount);
mBigGraphX1.getViewport().setMinX(extracted_dates[0]);
mBigGraphX1.getViewport().setMaxX(extracted_dates[rowcount - 1]);
mBigGraphX1.getViewport().setXAxisBoundsManual(true);
mBigGraphX1.getGridLabelRenderer().setHumanRounding(false);
}
以下内容输出到日志:-
2019-01-12 09:01:07.194 3073-3073/so54140390.so54140390graph D/DEMODATEINFO: Data From Table container_results as per :-
Results for row 1 Date as per DB is 2019-01-11 21:02:06 Formatted Date is 11 01 2019
Results for row 2 Date as per DB is 2019-01-11 21:02:06 Formatted Date is 11 01 2019
Results for row 3 Date as per DB is 2019-01-11 21:02:06 Formatted Date is 11 01 2019
因此,这只是更改或添加格式以适应的问题。- 这方面的圣经是SQL As Understood By SQLite- Date And Time Functions
关于java - 如何在另一个 Activity 的 GraphView 中将 SQLite 数据库中的日期显示为 X 轴,仅显示 1-1-1970?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54140390/
我的数据库中有两张表,一张用于 field ,另一张用于预订。我需要的是一个查询来选择所有未预订的 field 。见下文: 餐 table 预订具有以下字段: bk_id venue_id 作为(预订
嗨,我是编码新手,我有一些培训项目,其中包括从 HTML 表单输入 MySQL 数据库。它就像你玩过的游戏的日志。第一个日期输入是您开始游戏的时间,第二个日期输入是您完成游戏的时间。但我需要检查器或类
我是这个 sql 编码的新手,我正在尝试学习新的东西。因此,我创建了一个交货表,其中包含一些属性,如商品代码、交货日期、交货数量。所以如何从同一张表中获取第一个交货日期(最小日期)和交货数量以及最晚交
我从支付网关返回了这个日期 2014-05-15T08:40:52+01:00 我得到 2014-05-15T08:40:52 但我无法识别时区 +01:00 的含义 我的位置时区是 UTC−06:0
我快要疯了,请帮忙。 我有一列包含日期时间值。 我需要找到每天的最小值和最大值。 数据看起来像这样 2012-11-23 05:49:26.000 2012-11-23 07:55:43.000
我从 json 数据中获取日期为 2015 年 4 月 15 日晚上 10:15我只想在 html 页面中显示 json 响应数据的时间,例如 10:15 PM这里我放了我的js函数和html代码 J
是否有 javascript 库或其他机制允许我将 .NET 日期/时间格式字符串(即 yyyy-MM-dd HH:mm:ss)传递给 javascript函数并让它相应地解析提供的日期时间值?我一直
我正在使用以下代码以正确的格式获取当前的 UTC 时间,但客户返回并要求时间戳现在使用 EST 而不是 UTC。我搜索了 Google 和 stackoverflow,但找不到适用于我现有代码的答案。
我有以下日期的平均温度数据。我想找到连续至少 5 天低于或高于 0 摄氏度的开始日期。 date_short mean.temp 1 2018-05-18 17.54 2 2018-05-19
它可以在其他网络浏览器中使用,但 IE11 返回无效日期。 为了调试我使用了下面的代码。 console.log('before - ' + date.value); date.value = new
我在 Excel 中有一个数据的 Web 提取,其中日期列带有/Date(1388624400000)/。我需要在 Excel 中将其转换为日期。 最佳答案 能够从 here 中推断出它. 假设字符串
嗨,我的 Schmema 有一个带有 ISO 日期的字段: ISODate("2015-04-30T14:47:46.501Z") Paypal 在成功付款后以该形式返回日期对象: Time/Date
我的 table : CREATE TABLE `tbdata` ( `ID` INT(10) NOT NULL AUTO_INCREMENT, `PatientID` INT(10) NOT
我正在 Ubuntu 服务器 12.04 中编写一个 shell 脚本,它应该比较日志文件中的一些数据。在日志文件中,日期以以下格式给出: [Mon Apr 08 15:02:54 2013] 如您所
我想使用 GROUP BY WITH ROLLUP 创建一个表并获取总行数而不是 null。 $sql ="SELECT IF(YEAR(transaktioner.datum
我正在创建博客文章,在成功迁移我的博客文件后,当我转到我网站的博客页面时返回一个错误(无法解析其余部分:':“Ymd”'来自'post.date|date: "Ymd"') 我似乎无法确定这是语法错误
我正在尝试获取要插入到 CAML 查询中的月份范围,即:2010-09-01 和 2010-09-30。 我使用以下代码生成这两个值: var month = "10/2010"; var month
如何将代码document.write("直到指定日期")更改为writeMessage(date)中的日期?此外,writeMessage(date) 中的日期未正确显示(仅显示年份)。感谢您帮助解
我在 Windows (XP) 和 Linux 上都尝试过 utime()。在 Windows 上我得到一个 EACCES 错误,在 Linux 上我没有得到任何错误(但时间没有改变)。我的 utim
我正在尝试计算发生在同一日期的值的总和(在 XYZmin 中)。 我的数据看起来像这样, bar <- structure(list(date = structure(c(15622, 15622,
我是一名优秀的程序员,十分优秀!