根据时间过滤器从sqlite中获取数据
get the data from sqlite based on time filter
我正在开发显示表单数据列表的应用程序,我正在该列表中添加一个过滤器按钮,它根据源部门和日期(从日期 1 到日期 2)等各种过滤器来过滤数据。
我的部门和源过滤器工作正常,但当我 select 日期时什么也得不到。
sqlite 中的日期以整数格式存储,我正在尝试比较来自 sqlite 的日期和来自用户的日期。但它什么也没显示。
数据库助手class
public class DbHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 13;
public static final String DATABASE_NAME = "LoinReg.db";
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_REG_ENTRIES);
db.execSQL(SQL_CREATE_FORM_ENTRIES);
db.execSQL(SQL_ADD_HISTORY);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(newVersion > oldVersion){
db.execSQL(SQL_REG_DELETE_ENTRIES);
db.execSQL(SQL_FORM_DELETE);
db.execSQL(SQL_HISTORY_DELETE);
onCreate(db);
}
}
private static final String SQL_CREATE_FORM_ENTRIES =
"CREATE TABLE IF NOT EXISTS " + FormEntry.COLUMN_TABLE_NAME +
" (" + FormEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ FormEntry.COLUMN_NAME_NAME + " TEXT,"
+ FormEntry.COLUMN_NAME_EMAIL + " TEXT,"
+ FormEntry.COLUMN_NAME_MOBILE + " TEXT,"
+ FormEntry.COLUMN_NAME_ALTERNATE_NUMBER + " TEXT,"
+ FormEntry.COLUMN_NAME_JEE + " TEXT,"
+ COLUNM_NAME_JEERANK + " TEXT,"
+ FormEntry.COLUMN_NAME_PERCENTAGE + " TEXT,"
+ FormEntry.COLUMN_NAME_CITY + " TEXT,"
+ FormEntry.COLUMN_NAME_DEPT + " TEXT,"
+ FormEntry.COLUMN_NAME_SOURCE + " TEXT,"
+ FormEntry.TIMESTAMP + " INTEGER )";
public boolean insertForm(String name, String email, String phone, String alternate, String jee, String jeeRank, String percentage, String city, String dept, String source){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(FormContract.FormEntry.COLUMN_NAME_NAME,name);
values.put(FormContract.FormEntry.COLUMN_NAME_EMAIL,email);
values.put(FormContract.FormEntry.COLUMN_NAME_MOBILE,phone);
values.put(FormContract.FormEntry.COLUMN_NAME_ALTERNATE_NUMBER, alternate);
values.put(FormContract.FormEntry.COLUMN_NAME_JEE,jee);
values.put(FormContract.FormEntry.COLUNM_NAME_JEERANK,jeeRank);
values.put(FormContract.FormEntry.COLUMN_NAME_PERCENTAGE,percentage);
values.put(FormContract.FormEntry.COLUMN_NAME_CITY,city);
values.put(FormContract.FormEntry.COLUMN_NAME_DEPT,dept);
values.put(FormContract.FormEntry.COLUMN_NAME_SOURCE,source);
values.put(FormEntry.TIMESTAMP,System.currentTimeMillis());
long newRowId = db.insert(FormContract.FormEntry.COLUMN_TABLE_NAME,null,values);
if(newRowId == -1){
return false;
}else{
return true;
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, EnquiryAdapter.OnItemClickListener {
DbHelper mDbHelper;
public static final String FORM_ID = "form_id";
public static final String SQL = "sql";
public static final String DEPT = "dept";
public static final String SOURCE = "source";
public static final String STARTDATE = "start_date";
public static final String ENDDATE = "end_date";
private static String sql, department, source;
long StartDate, EndDate;
private RecyclerView mRecyclerView;
private EnquiryAdapter mAdapter;
private EditText mStartDate, mEndDate;
private Spinner mDeptSpinner, mSourceSpinner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDbHelper = new DbHelper(this);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,FormActivity.class);
startActivity(intent);
}
});
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
View headerView = navigationView.getHeaderView(0);
Intent intent = getIntent();
String email = intent.getStringExtra(LoginActivity.EXTRA_EMAIL);
TextView mEmail = headerView.findViewById(R.id.email);
mEmail.setText(email);
//RecyclerView Setup
mRecyclerView = findViewById(R.id.recyclerview);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new EnquiryAdapter(MainActivity.this,mDbHelper.getFormData());
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(MainActivity.this);
}
private void showFilterDialog(){
LayoutInflater layoutInflater = LayoutInflater.from(MainActivity.this);
View filterDialog = layoutInflater.inflate(R.layout.filters,null);
/**
* getting the reference to the @View
* */
mStartDate = filterDialog.findViewById(R.id.editText);
mEndDate = filterDialog.findViewById(R.id.editText2);
mDeptSpinner = filterDialog.findViewById(R.id.filter_dept);
mSourceSpinner = filterDialog.findViewById(R.id.filter_source);
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(MainActivity.this);
alertBuilder.setTitle("Filters");
alertBuilder.setView(filterDialog);
mStartDate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDatePicker(v);
hideKeyboard(v);
}
});
mEndDate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showEndDatePicker(v);
hideKeyboard(v);
}
});
/**
* Assigning the list of items to the @Spinner.
* */
ArrayAdapter<CharSequence> deptAdapter = ArrayAdapter.createFromResource(this,R.array.Department,android.R.layout.simple_spinner_dropdown_item);
deptAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mDeptSpinner.setAdapter(deptAdapter);
ArrayAdapter<CharSequence> sourceAdapter = ArrayAdapter.createFromResource(this,R.array.Source,android.R.layout.simple_spinner_dropdown_item);
sourceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSourceSpinner.setAdapter(sourceAdapter);
/**
* @sql statement.
* */
sql = "Select * from " +FormEntry.COLUMN_TABLE_NAME+ " where ";
alertBuilder.setPositiveButton("Apply", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("Date in milisec", String.valueOf(StartDate));
Log.d("Date 2 in milisec", String.valueOf(EndDate));
if(sd != null && ed != null){
sql = sql + FormEntry.TIMESTAMP+ " BETWEEN" + " ?" + " AND" + " ?";
}else{
sql = "Select * from " +FormEntry.COLUMN_TABLE_NAME+ " where ";
}
department = mDeptSpinner.getSelectedItem().toString();
source = mSourceSpinner.getSelectedItem().toString();
if(mDeptSpinner.getSelectedItem() != null){
sql = sql + FormEntry.COLUMN_NAME_DEPT + " = ?";
}
if(mSourceSpinner.getSelectedItem() != null){
sql = sql + " OR "+ FormEntry.COLUMN_NAME_SOURCE + " = ?";
}
Intent intent = new Intent(MainActivity.this, FilterActivity.class);
intent.putExtra(STARTDATE, StartDate);
intent.putExtra(ENDDATE, EndDate);
intent.putExtra(DEPT,department);
intent.putExtra(SOURCE, source);
intent.putExtra(SQL,sql);
startActivity(intent);
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alertDialog = alertBuilder.create();
alertDialog.show();
Button pos = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
pos.setTextColor(Color.BLUE);
Button neg = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
neg.setTextColor(Color.BLUE);
}
public void showDatePicker(View view) {
DialogFragment newFragment = new DateFragment();
newFragment.show(getSupportFragmentManager(),"datePicker");
}
public void showEndDatePicker(View v){
DialogFragment dialogFragment = new EndDateFragment();
dialogFragment.show(getSupportFragmentManager(),"End Date");
}
public void processDatePickerResult(int year,int month,int day){
String month_string = Integer.toString(month +1);
String day_string = Integer.toString(day);
String year_string = Integer.toString(year);
String dateMessage = (year_string + "-" + month_string +
"-" + day_string);
mStartDate.setText(dateMessage);
StartDate = getTimeInMillis(day,month,year);
}
public void processEndDatePickerResult(int year, int month, int day){
String month_string = Integer.toString(month + 1);
String day_string = Integer.toString(day);
String year_String = Integer.toString(year);
String dateMessage = (year_String + "-" + month_string +
"-" + day_string);
mEndDate.setText(dateMessage);
EndDate = getTimeInMillis(day,month,year);
}
private void hideKeyboard(View view){
InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
public static long getTimeInMillis(int day, int month, int year) {
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, day);
return calendar.getTimeInMillis();
}
}
FilterActivity.java
public class FilterActivity extends AppCompatActivity implements EnquiryAdapter.OnItemClickListener {
private RecyclerView mRecyclerView;
private EnquiryAdapter mAdapter;
private DbHelper mDbHelper;
public static final String FORM_ID = "form_id";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_filter);
mRecyclerView = findViewById(R.id.filter_recyclerview);
mDbHelper = new DbHelper(this);
SQLiteDatabase db = mDbHelper.getReadableDatabase();
Intent intent = getIntent();
intent.getExtras();
String sql = intent.getStringExtra(MainActivity.SQL);
String dept = intent.getStringExtra(MainActivity.DEPT);
String source = intent.getStringExtra(MainActivity.SOURCE);
long startDate = intent.getIntExtra(MainActivity.STARTDATE,0);
long endDate = intent.getIntExtra(MainActivity.ENDDATE,0);
Cursor cursor = db.rawQuery(sql,new String[]{String.valueOf(startDate), String.valueOf(endDate), dept, source});
mAdapter = new EnquiryAdapter(FilterActivity.this, cursor);
//RecyclerView Setup
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//mAdapter = new EnquiryAdapter(FilterActivity.this,mDbHelper.getFormData());
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(FilterActivity.this);
}
@Override
public void onItemClick(int position) {
Intent intent = new Intent(this, DetailedActivity.class);
int id = EnquiryAdapter.id;
intent.putExtra(FORM_ID,id);
startActivity(intent);
}
}
您的问题似乎是 BETWEEN 子句和生成的 SQL 中 WHERE 子句的其他部分没有逻辑连接。
即如果变量sd和ed都不为空(在代码,前提是它们似乎没有被声明或实例化),因此 SQL 将包含 BETWEEN 子句,不会有 AND 或 OR(我猜前者是必需的)。因此,通过 Intent Extra 传递的 SQL 将遵循 :-
SELECT * FROM your_table WHERE your_timestamp_column BETWEEN ? AND ? your_dept_column = ? OR your_source_column = ?
虽然它应该是(假设 AND):-
SELECT * FROM your_table WHERE your_timestamp_column BETWEEN ? AND ?
AND ( -- <<<<<<<<<<<< MISSING CONJUNCTION
your_dept_column = ? OR your_source_column = ?
)
- 其中 your_table、your_timestamp_column、your_dept_column 和 your_source_column 是从您的变量解析的标识符。
我猜你的代码可能是这样的:-
String time_filter_end_char = ""; //<<<<<<<<<< NO ) at end if no time_filter
String sd = String.valueOf(StartDate); //<<<<<<<<<< ?????????
String ed = String.valueOf(EndDate); //<<<<<<<<<< ??????????
if(sd != null && ed != null && sd.length() > 0 && ed.length() > 0 ){
time_filter_end_char = ")";
sql = sql + FormEntry.TIMESTAMP+ " BETWEEN" + " ?" + " AND" + " ? AND("; //<<<<<<<<<< CONJUNCTION ADDED
}
//<<<<<<<<<< else construct/clause REMOVED as it does nothing
department = mDeptSpinner.getSelectedItem().toString();
source = mSourceSpinner.getSelectedItem().toString();
if(mDeptSpinner.getSelectedItem() != null){
sql = sql + FormEntry.COLUMN_NAME_DEPT + " = ?";
}
if(mSourceSpinner.getSelectedItem() != null){
sql = sql + " OR "+ FormEntry.COLUMN_NAME_SOURCE + " = ?";
}
sql = sql + time_filter_end_char;
但是,如果 dept 或 source 都为 null 或为空,则上述情况会成为问题。
所以也许更正确的代码应该是这样的:-
String sd = String.valueOf(StartDate);
String ed = String.valueOf(EndDate);
String department = mDeptSpinner.getSelectedItem().toString();
String source = mSourceSpinner.getSelectedItem().toString();
String sql = "SELECT * FROM " + FormEntry.COLUMN_TABLE_NAME; //<<<<<<< no filtering
String time_filter = "";
String department_filter = "";
String source_filter = "";
if (sd != null && ed != null && sd.length() > 0 && ed.length() > 0) {
time_filter = FormEntry.TIMESTAMP + " BETWEEN" + " ?" + " AND" + " ? ";
}
if (department != null && department.length() > 0) {
department_filter = FormEntry.COLUMN_NAME_DEPT + " = ?";
}
if (source != null && source.length() > 0) {
source_filter = FormEntry.COLUMN_NAME_SOURCE + " = ?";
}
String dept_source_conjunction = "";
if (department_filter.length() > 0 && source_filter.length() > 0) {
dept_source_conjunction = " OR ";
}
if (time_filter.length() > 0 || department_filter.length() > 0 || source_filter.length() > 0) {
sql = sql + " WHERE ";
}
String end_dept_source_char = "";
if (time_filter.length() > 0) {
sql = sql + time_filter;
if (department_filter.length() > 0 || source_filter.length() > 0) {
sql = sql + " AND ";
if (dept_source_conjunction.length() > 0) {
sql = sql + "(";
end_dept_source_char = ")";
}
}
}
sql = sql + department_filter + dept_source_conjunction + source_filter + end_dept_source_char;
测试:-
上面的以下改编用于测试代码:-
private String testit(String StartDate, String EndDate, String mDS, String mSS) {
//String sd = String.valueOf(StartDate);
//String ed = String.valueOf(EndDate);
String sd = StartDate; //<<<<<<<<<< FOR TESTING
String ed = EndDate; //<<<<<<<<<< FOR TESTING
//String department = mDeptSpinner.getSelectedItem().toString();
//String source = mSourceSpinner.getSelectedItem().toString();
String department = mDS; //<<<<<<<<<< FOR TESTING
String source = mSS; //<<<<<<<<<< FOR TESTING
String sql = "SELECT * FROM " + FormEntry.COLUMN_TABLE_NAME; //<<<<<<< no filtering
String time_filter = "";
String department_filter = "";
String source_filter = "";
if (sd != null && ed != null && sd.length() > 0 && ed.length() > 0) {
time_filter = FormEntry.TIMESTAMP + " BETWEEN" + " ?" + " AND" + " ? ";
}
if (department != null && department.length() > 0) {
department_filter = FormEntry.COLUMN_NAME_DEPT + " = ?";
}
if (source != null && source.length() > 0) {
source_filter = FormEntry.COLUMN_NAME_SOURCE + " = ?";
}
String dept_source_conjunction = "";
if (department_filter.length() > 0 && source_filter.length() > 0) {
dept_source_conjunction = " OR ";
}
if (time_filter.length() > 0 || department_filter.length() > 0 || source_filter.length() > 0) {
sql = sql + " WHERE ";
}
String end_dept_source_char = "";
if (time_filter.length() > 0) {
sql = sql + time_filter;
if (department_filter.length() > 0 || source_filter.length() > 0) {
sql = sql + " AND ";
if (dept_source_conjunction.length() > 0) {
sql = sql + "(";
end_dept_source_char = ")";
}
}
}
sql = sql + department_filter + dept_source_conjunction + source_filter + end_dept_source_char;
return sql;
}
然后使用了以下内容:-
Log.d("TEST2", testit(null,null,null,null)); //<<<<<<<<<< no filter
Log.d("TEST1",testit("1111111111","2222222222",null,null)); // time filter only
Log.d("TEST3", testit("1111111111","2222222222","d1","s1")); // full filter
Log.d("TEST4",testit("1111111111","2222222222",null,"s1")); // time and source
Log.d("TEST5",testit("1111111111","2222222222","d1","")); // time and dept
结果是:-
D/TEST2: SELECT * FROM your_table_name
D/TEST1: SELECT * FROM your_table_name WHERE your_timestamp_column BETWEEN ? AND ?
D/TEST3: SELECT * FROM your_table_name WHERE your_timestamp_column BETWEEN ? AND ? AND (your_department_column = ? OR your_source_column = ?)
D/TEST4: SELECT * FROM your_table_name WHERE your_timestamp_column BETWEEN ? AND ? AND your_source_column = ?
D/TEST5: SELECT * FROM your_table_name WHERE your_timestamp_column BETWEEN ? AND ? AND your_department_column = ?
我正在开发显示表单数据列表的应用程序,我正在该列表中添加一个过滤器按钮,它根据源部门和日期(从日期 1 到日期 2)等各种过滤器来过滤数据。 我的部门和源过滤器工作正常,但当我 select 日期时什么也得不到。
sqlite 中的日期以整数格式存储,我正在尝试比较来自 sqlite 的日期和来自用户的日期。但它什么也没显示。
数据库助手class
public class DbHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 13;
public static final String DATABASE_NAME = "LoinReg.db";
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_REG_ENTRIES);
db.execSQL(SQL_CREATE_FORM_ENTRIES);
db.execSQL(SQL_ADD_HISTORY);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(newVersion > oldVersion){
db.execSQL(SQL_REG_DELETE_ENTRIES);
db.execSQL(SQL_FORM_DELETE);
db.execSQL(SQL_HISTORY_DELETE);
onCreate(db);
}
}
private static final String SQL_CREATE_FORM_ENTRIES =
"CREATE TABLE IF NOT EXISTS " + FormEntry.COLUMN_TABLE_NAME +
" (" + FormEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ FormEntry.COLUMN_NAME_NAME + " TEXT,"
+ FormEntry.COLUMN_NAME_EMAIL + " TEXT,"
+ FormEntry.COLUMN_NAME_MOBILE + " TEXT,"
+ FormEntry.COLUMN_NAME_ALTERNATE_NUMBER + " TEXT,"
+ FormEntry.COLUMN_NAME_JEE + " TEXT,"
+ COLUNM_NAME_JEERANK + " TEXT,"
+ FormEntry.COLUMN_NAME_PERCENTAGE + " TEXT,"
+ FormEntry.COLUMN_NAME_CITY + " TEXT,"
+ FormEntry.COLUMN_NAME_DEPT + " TEXT,"
+ FormEntry.COLUMN_NAME_SOURCE + " TEXT,"
+ FormEntry.TIMESTAMP + " INTEGER )";
public boolean insertForm(String name, String email, String phone, String alternate, String jee, String jeeRank, String percentage, String city, String dept, String source){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(FormContract.FormEntry.COLUMN_NAME_NAME,name);
values.put(FormContract.FormEntry.COLUMN_NAME_EMAIL,email);
values.put(FormContract.FormEntry.COLUMN_NAME_MOBILE,phone);
values.put(FormContract.FormEntry.COLUMN_NAME_ALTERNATE_NUMBER, alternate);
values.put(FormContract.FormEntry.COLUMN_NAME_JEE,jee);
values.put(FormContract.FormEntry.COLUNM_NAME_JEERANK,jeeRank);
values.put(FormContract.FormEntry.COLUMN_NAME_PERCENTAGE,percentage);
values.put(FormContract.FormEntry.COLUMN_NAME_CITY,city);
values.put(FormContract.FormEntry.COLUMN_NAME_DEPT,dept);
values.put(FormContract.FormEntry.COLUMN_NAME_SOURCE,source);
values.put(FormEntry.TIMESTAMP,System.currentTimeMillis());
long newRowId = db.insert(FormContract.FormEntry.COLUMN_TABLE_NAME,null,values);
if(newRowId == -1){
return false;
}else{
return true;
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, EnquiryAdapter.OnItemClickListener {
DbHelper mDbHelper;
public static final String FORM_ID = "form_id";
public static final String SQL = "sql";
public static final String DEPT = "dept";
public static final String SOURCE = "source";
public static final String STARTDATE = "start_date";
public static final String ENDDATE = "end_date";
private static String sql, department, source;
long StartDate, EndDate;
private RecyclerView mRecyclerView;
private EnquiryAdapter mAdapter;
private EditText mStartDate, mEndDate;
private Spinner mDeptSpinner, mSourceSpinner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDbHelper = new DbHelper(this);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,FormActivity.class);
startActivity(intent);
}
});
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
View headerView = navigationView.getHeaderView(0);
Intent intent = getIntent();
String email = intent.getStringExtra(LoginActivity.EXTRA_EMAIL);
TextView mEmail = headerView.findViewById(R.id.email);
mEmail.setText(email);
//RecyclerView Setup
mRecyclerView = findViewById(R.id.recyclerview);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new EnquiryAdapter(MainActivity.this,mDbHelper.getFormData());
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(MainActivity.this);
}
private void showFilterDialog(){
LayoutInflater layoutInflater = LayoutInflater.from(MainActivity.this);
View filterDialog = layoutInflater.inflate(R.layout.filters,null);
/**
* getting the reference to the @View
* */
mStartDate = filterDialog.findViewById(R.id.editText);
mEndDate = filterDialog.findViewById(R.id.editText2);
mDeptSpinner = filterDialog.findViewById(R.id.filter_dept);
mSourceSpinner = filterDialog.findViewById(R.id.filter_source);
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(MainActivity.this);
alertBuilder.setTitle("Filters");
alertBuilder.setView(filterDialog);
mStartDate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDatePicker(v);
hideKeyboard(v);
}
});
mEndDate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showEndDatePicker(v);
hideKeyboard(v);
}
});
/**
* Assigning the list of items to the @Spinner.
* */
ArrayAdapter<CharSequence> deptAdapter = ArrayAdapter.createFromResource(this,R.array.Department,android.R.layout.simple_spinner_dropdown_item);
deptAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mDeptSpinner.setAdapter(deptAdapter);
ArrayAdapter<CharSequence> sourceAdapter = ArrayAdapter.createFromResource(this,R.array.Source,android.R.layout.simple_spinner_dropdown_item);
sourceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSourceSpinner.setAdapter(sourceAdapter);
/**
* @sql statement.
* */
sql = "Select * from " +FormEntry.COLUMN_TABLE_NAME+ " where ";
alertBuilder.setPositiveButton("Apply", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("Date in milisec", String.valueOf(StartDate));
Log.d("Date 2 in milisec", String.valueOf(EndDate));
if(sd != null && ed != null){
sql = sql + FormEntry.TIMESTAMP+ " BETWEEN" + " ?" + " AND" + " ?";
}else{
sql = "Select * from " +FormEntry.COLUMN_TABLE_NAME+ " where ";
}
department = mDeptSpinner.getSelectedItem().toString();
source = mSourceSpinner.getSelectedItem().toString();
if(mDeptSpinner.getSelectedItem() != null){
sql = sql + FormEntry.COLUMN_NAME_DEPT + " = ?";
}
if(mSourceSpinner.getSelectedItem() != null){
sql = sql + " OR "+ FormEntry.COLUMN_NAME_SOURCE + " = ?";
}
Intent intent = new Intent(MainActivity.this, FilterActivity.class);
intent.putExtra(STARTDATE, StartDate);
intent.putExtra(ENDDATE, EndDate);
intent.putExtra(DEPT,department);
intent.putExtra(SOURCE, source);
intent.putExtra(SQL,sql);
startActivity(intent);
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alertDialog = alertBuilder.create();
alertDialog.show();
Button pos = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
pos.setTextColor(Color.BLUE);
Button neg = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
neg.setTextColor(Color.BLUE);
}
public void showDatePicker(View view) {
DialogFragment newFragment = new DateFragment();
newFragment.show(getSupportFragmentManager(),"datePicker");
}
public void showEndDatePicker(View v){
DialogFragment dialogFragment = new EndDateFragment();
dialogFragment.show(getSupportFragmentManager(),"End Date");
}
public void processDatePickerResult(int year,int month,int day){
String month_string = Integer.toString(month +1);
String day_string = Integer.toString(day);
String year_string = Integer.toString(year);
String dateMessage = (year_string + "-" + month_string +
"-" + day_string);
mStartDate.setText(dateMessage);
StartDate = getTimeInMillis(day,month,year);
}
public void processEndDatePickerResult(int year, int month, int day){
String month_string = Integer.toString(month + 1);
String day_string = Integer.toString(day);
String year_String = Integer.toString(year);
String dateMessage = (year_String + "-" + month_string +
"-" + day_string);
mEndDate.setText(dateMessage);
EndDate = getTimeInMillis(day,month,year);
}
private void hideKeyboard(View view){
InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
public static long getTimeInMillis(int day, int month, int year) {
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, day);
return calendar.getTimeInMillis();
}
}
FilterActivity.java
public class FilterActivity extends AppCompatActivity implements EnquiryAdapter.OnItemClickListener {
private RecyclerView mRecyclerView;
private EnquiryAdapter mAdapter;
private DbHelper mDbHelper;
public static final String FORM_ID = "form_id";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_filter);
mRecyclerView = findViewById(R.id.filter_recyclerview);
mDbHelper = new DbHelper(this);
SQLiteDatabase db = mDbHelper.getReadableDatabase();
Intent intent = getIntent();
intent.getExtras();
String sql = intent.getStringExtra(MainActivity.SQL);
String dept = intent.getStringExtra(MainActivity.DEPT);
String source = intent.getStringExtra(MainActivity.SOURCE);
long startDate = intent.getIntExtra(MainActivity.STARTDATE,0);
long endDate = intent.getIntExtra(MainActivity.ENDDATE,0);
Cursor cursor = db.rawQuery(sql,new String[]{String.valueOf(startDate), String.valueOf(endDate), dept, source});
mAdapter = new EnquiryAdapter(FilterActivity.this, cursor);
//RecyclerView Setup
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//mAdapter = new EnquiryAdapter(FilterActivity.this,mDbHelper.getFormData());
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(FilterActivity.this);
}
@Override
public void onItemClick(int position) {
Intent intent = new Intent(this, DetailedActivity.class);
int id = EnquiryAdapter.id;
intent.putExtra(FORM_ID,id);
startActivity(intent);
}
}
您的问题似乎是 BETWEEN 子句和生成的 SQL 中 WHERE 子句的其他部分没有逻辑连接。
即如果变量sd和ed都不为空(在代码,前提是它们似乎没有被声明或实例化),因此 SQL 将包含 BETWEEN 子句,不会有 AND 或 OR(我猜前者是必需的)。因此,通过 Intent Extra 传递的 SQL 将遵循 :-
SELECT * FROM your_table WHERE your_timestamp_column BETWEEN ? AND ? your_dept_column = ? OR your_source_column = ?
虽然它应该是(假设 AND):-
SELECT * FROM your_table WHERE your_timestamp_column BETWEEN ? AND ?
AND ( -- <<<<<<<<<<<< MISSING CONJUNCTION
your_dept_column = ? OR your_source_column = ?
)
- 其中 your_table、your_timestamp_column、your_dept_column 和 your_source_column 是从您的变量解析的标识符。
我猜你的代码可能是这样的:-
String time_filter_end_char = ""; //<<<<<<<<<< NO ) at end if no time_filter
String sd = String.valueOf(StartDate); //<<<<<<<<<< ?????????
String ed = String.valueOf(EndDate); //<<<<<<<<<< ??????????
if(sd != null && ed != null && sd.length() > 0 && ed.length() > 0 ){
time_filter_end_char = ")";
sql = sql + FormEntry.TIMESTAMP+ " BETWEEN" + " ?" + " AND" + " ? AND("; //<<<<<<<<<< CONJUNCTION ADDED
}
//<<<<<<<<<< else construct/clause REMOVED as it does nothing
department = mDeptSpinner.getSelectedItem().toString();
source = mSourceSpinner.getSelectedItem().toString();
if(mDeptSpinner.getSelectedItem() != null){
sql = sql + FormEntry.COLUMN_NAME_DEPT + " = ?";
}
if(mSourceSpinner.getSelectedItem() != null){
sql = sql + " OR "+ FormEntry.COLUMN_NAME_SOURCE + " = ?";
}
sql = sql + time_filter_end_char;
但是,如果 dept 或 source 都为 null 或为空,则上述情况会成为问题。
所以也许更正确的代码应该是这样的:-
String sd = String.valueOf(StartDate);
String ed = String.valueOf(EndDate);
String department = mDeptSpinner.getSelectedItem().toString();
String source = mSourceSpinner.getSelectedItem().toString();
String sql = "SELECT * FROM " + FormEntry.COLUMN_TABLE_NAME; //<<<<<<< no filtering
String time_filter = "";
String department_filter = "";
String source_filter = "";
if (sd != null && ed != null && sd.length() > 0 && ed.length() > 0) {
time_filter = FormEntry.TIMESTAMP + " BETWEEN" + " ?" + " AND" + " ? ";
}
if (department != null && department.length() > 0) {
department_filter = FormEntry.COLUMN_NAME_DEPT + " = ?";
}
if (source != null && source.length() > 0) {
source_filter = FormEntry.COLUMN_NAME_SOURCE + " = ?";
}
String dept_source_conjunction = "";
if (department_filter.length() > 0 && source_filter.length() > 0) {
dept_source_conjunction = " OR ";
}
if (time_filter.length() > 0 || department_filter.length() > 0 || source_filter.length() > 0) {
sql = sql + " WHERE ";
}
String end_dept_source_char = "";
if (time_filter.length() > 0) {
sql = sql + time_filter;
if (department_filter.length() > 0 || source_filter.length() > 0) {
sql = sql + " AND ";
if (dept_source_conjunction.length() > 0) {
sql = sql + "(";
end_dept_source_char = ")";
}
}
}
sql = sql + department_filter + dept_source_conjunction + source_filter + end_dept_source_char;
测试:-
上面的以下改编用于测试代码:-
private String testit(String StartDate, String EndDate, String mDS, String mSS) {
//String sd = String.valueOf(StartDate);
//String ed = String.valueOf(EndDate);
String sd = StartDate; //<<<<<<<<<< FOR TESTING
String ed = EndDate; //<<<<<<<<<< FOR TESTING
//String department = mDeptSpinner.getSelectedItem().toString();
//String source = mSourceSpinner.getSelectedItem().toString();
String department = mDS; //<<<<<<<<<< FOR TESTING
String source = mSS; //<<<<<<<<<< FOR TESTING
String sql = "SELECT * FROM " + FormEntry.COLUMN_TABLE_NAME; //<<<<<<< no filtering
String time_filter = "";
String department_filter = "";
String source_filter = "";
if (sd != null && ed != null && sd.length() > 0 && ed.length() > 0) {
time_filter = FormEntry.TIMESTAMP + " BETWEEN" + " ?" + " AND" + " ? ";
}
if (department != null && department.length() > 0) {
department_filter = FormEntry.COLUMN_NAME_DEPT + " = ?";
}
if (source != null && source.length() > 0) {
source_filter = FormEntry.COLUMN_NAME_SOURCE + " = ?";
}
String dept_source_conjunction = "";
if (department_filter.length() > 0 && source_filter.length() > 0) {
dept_source_conjunction = " OR ";
}
if (time_filter.length() > 0 || department_filter.length() > 0 || source_filter.length() > 0) {
sql = sql + " WHERE ";
}
String end_dept_source_char = "";
if (time_filter.length() > 0) {
sql = sql + time_filter;
if (department_filter.length() > 0 || source_filter.length() > 0) {
sql = sql + " AND ";
if (dept_source_conjunction.length() > 0) {
sql = sql + "(";
end_dept_source_char = ")";
}
}
}
sql = sql + department_filter + dept_source_conjunction + source_filter + end_dept_source_char;
return sql;
}
然后使用了以下内容:-
Log.d("TEST2", testit(null,null,null,null)); //<<<<<<<<<< no filter
Log.d("TEST1",testit("1111111111","2222222222",null,null)); // time filter only
Log.d("TEST3", testit("1111111111","2222222222","d1","s1")); // full filter
Log.d("TEST4",testit("1111111111","2222222222",null,"s1")); // time and source
Log.d("TEST5",testit("1111111111","2222222222","d1","")); // time and dept
结果是:-
D/TEST2: SELECT * FROM your_table_name
D/TEST1: SELECT * FROM your_table_name WHERE your_timestamp_column BETWEEN ? AND ?
D/TEST3: SELECT * FROM your_table_name WHERE your_timestamp_column BETWEEN ? AND ? AND (your_department_column = ? OR your_source_column = ?)
D/TEST4: SELECT * FROM your_table_name WHERE your_timestamp_column BETWEEN ? AND ? AND your_source_column = ?
D/TEST5: SELECT * FROM your_table_name WHERE your_timestamp_column BETWEEN ? AND ? AND your_department_column = ?