我正在学习android开发和开发todolist应用。我想添加一项功能,以在完成给定时间后将其从待办事项列表中删除。我正在使用警报管理器来触发广播接收器,该接收器会在时间流逝后从数据集中删除该项目,但是一旦代码运行,此功能似乎将无法正常工作。我收到空指针异常。
这是我的回收站视图适配器的代码-
package Adapters;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
import Data.DataBaseHandler;
import Model.Target;
import siddharthbisht.targettracker.R;
public class RecyclerViewAdapter extends
RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{
Context context;
List<Target> targetList;
private AlertDialog.Builder alertDiaologBuilder;
private AlertDialog dialog;
private LayoutInflater inflater;
DataBaseHandler db;
public static final String TAG="RecyclerVIewAdapter";
public RecyclerViewAdapter(Context context){
this.context=context;
}
public RecyclerViewAdapter(Context context, List<Target> targetList) {
this.context=context;
this.targetList=targetList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int
viewType) {
View view=
LayoutInflater.from(
parent.getContext()).inflate(R.layout.item_row,parent,false);
return new ViewHolder(view,context);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Target target=targetList.get(position);
holder.taskName.setText(target.getTopic());
holder.finishDate.setText(target.getFinishDate()+"/"+
(target.getFinishMonth()+1)+"/"+target.getFinishYear());
holder.finishTime.setText(
target.getFinishHour()+":"+target.getFinishMinute());
}
@Override
public int getItemCount() {
return targetList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements
View.OnClickListener{
public TextView taskName;
public TextView finishDate;
public TextView finishTime;
public ImageView done;
public ImageView delete;
public ViewHolder(View itemView, Context ctx) {
super(itemView);
context=ctx;
taskName=itemView.findViewById(R.id.tvTaskName);
finishDate=itemView.findViewById(R.id.tvFinishDate);
finishTime=itemView.findViewById(R.id.tvFinishTime);
done=itemView.findViewById(R.id.ivCompleted);
delete=itemView.findViewById(R.id.ivDelete);
delete.setOnClickListener(this);
done.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Target target;
int position=getAdapterPosition();
switch (v.getId()){
case R.id.ivDelete:
target=targetList.get(position);
deleteItem(target.getId());
break;
case R.id.ivCompleted:
target=targetList.get(position);
moveToDone(target,position);
break;
}
}
private void deleteItem(final int id) {
alertDiaologBuilder=new AlertDialog.Builder(context);
inflater=LayoutInflater.from(context);
View view=inflater.inflate(R.layout.confirmation_dialog,null);
Button noButton=view.findViewById(R.id.noButton);
Button yesButton=view.findViewById(R.id.yesButton);
alertDiaologBuilder.setView(view);
dialog=alertDiaologBuilder.create();
dialog.show();
noButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
yesButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//delete the item
db=new DataBaseHandler(context);
db.DeleteTarget(id);
targetList.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
dialog.dismiss();
}
});
}
}
public void moveToDone(Target target,int position){
db=new DataBaseHandler(context);
db.updateCompletionStatus(target.getId());
targetList.remove(position);
Target target1=db.getTarget(target.getId());
notifyDataSetChanged();
notifyItemRemoved(position);
Log.d(TAG,target.getTopic()+" removed");
Log.d(TAG,"completion status: "+target1.getCompletionStatus());
Log.d(TAG,"due status: "+target1.getDue());
}
public int getTargetPosition(int id){
int position=0;
Target target=db.getTarget(id);
for (Target t: targetList){
if (t.getId()==target.getId()){
position=targetList.indexOf(t);
break;
}
}
return position;
}
}
这是我在其中将项目添加到列表中的活动的代码-
package Activities;
import android.app.AlarmManager;
import android.app.DatePickerDialog;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import java.util.Calendar;
import Data.DataBaseHandler;
import Model.Target;
import Receiver.AlarmReceiver;
import Receiver.SetDueOnComplete;
import Util.AlarmCreater;
import Util.CurrentDateAndTime;
import Util.Validator;
import siddharthbisht.targettracker.R;
public class AddTargetActivity extends AppCompatActivity implements
View.OnClickListener {
private EditText etTopic;
private TextView date;
private TextView time;
private Button submit;
DataBaseHandler handler;
private int mYear, mMonth, mDay, mHour, mMinute;
private int sYear, sMonth, sDate, sHour, sMinute;
public AlarmCreater creater;
public Validator validator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_target2);
etTopic = findViewById(R.id.etAddTopicName);
date = findViewById(R.id.tvDateToStore);
time = findViewById(R.id.tvTimeToStore);
submit = findViewById(R.id.btSubmitAdd);
handler=new DataBaseHandler(this);
initializeDateTime();
date.setOnClickListener(this);
time.setOnClickListener(this);
submit.setOnClickListener(this);
creater=new AlarmCreater();
validator=new Validator();
}
public void initializeDateTime() {
Calendar calendar = Calendar.getInstance();
mYear=calendar.get(Calendar.YEAR);
mMonth=calendar.get(Calendar.MONTH);
mDay=calendar.get(Calendar.DAY_OF_MONTH);
mHour=calendar.get(Calendar.HOUR_OF_DAY);
mMinute=calendar.get(Calendar.MINUTE);
int trueMonth=mMonth+1;
String dateStr = mDay + "/" + trueMonth+ "/"+mYear;
String timeStr = mHour + ":" + mMinute;
date.setText(dateStr);
time.setText(timeStr);
}
private void saveTargetToDb(View v,int year, int month, int date, int
hours, int minutes) {
Target target = new Target();
String topic = etTopic.getText().toString();
target.setTopic(topic);
target.setFinishDate(date);
target.setFinishMonth(month);
target.setFinishYear(year);
target.setFinishHour(hours);
target.setFinishMinute(minutes);
target.setDue(0);
target.setCompletionStatus(0);
//Save to database
handler.addTarget(target);
Log.d("added target:",target.getTopic());
int id=handler.getLastItem().getId();
Log.d("added item id:",String.valueOf(id));
//Getting alarm time in millis
Long timeinMillis=getTimeInMillis(year,month,date,hours,minutes);
creater.setAlarm(this,timeinMillis,id,target.getTopic());
setDueStatus(id,timeinMillis);
Snackbar.make(v, target.getTopic()+" Saved",
Snackbar.LENGTH_LONG).show();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent intent=new
Intent(AddTargetActivity.this,MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
}, 1000);
}
@Override
public void onClick(View v) {
initializeDateTime();
switch (v.getId()) {
case R.id.tvDateToStore:
DatePickerDialog datePickerDialog = new
DatePickerDialog(AddTargetActivity.this,
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int
dayOfMonth) {
sDate = dayOfMonth;
sMonth = monthOfYear;
sYear = year;
date.setText(sDate + "/" + (sMonth + 1) + "/" +
sYear);
Log.d("DatePicker:", String.valueOf(sDate) + "/"
+ String.valueOf(sMonth) + "/" +
String.valueOf(sYear));
}
}, mYear, mMonth, mDay);
datePickerDialog.show();
break;
case R.id.tvTimeToStore:
// Launch Time Picker Dialog
TimePickerDialog timePickerDialog = new
TimePickerDialog(AddTargetActivity.this,
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
sHour = hourOfDay;
sMinute = minute;
time.setText(sHour + ":" + sMinute);
Log.d("timePicker:", String.valueOf(sHour) + ":"
+ String.valueOf(sMinute));
}
}, mHour, mMinute, false);
timePickerDialog.show();
break;
case R.id.btSubmitAdd:
Log.d("Inside if 1:time:", String.valueOf(sYear) + "/" +
String.valueOf(sMonth) + "/" + String.valueOf(sDate) + " //" +
String.valueOf(sHour) + ":" + String.valueOf(sMinute));
saveTargetToDb(v, sYear, sMonth, sDate, sHour, sMinute);
/* if (!etTopic.getText().toString().isEmpty()&&
validator.validateTime(sHour,sMinute) &&
validator.validateDate(sDate,sMonth,sYear,sHour,sMinute)) {
}
else{
Toast.makeText(AddTargetActivity.this,"Enter correct
Values",Toast.LENGTH_SHORT).show();
}*/
}
}
public long getTimeInMillis(int year,int month,int date,int hour,int
minutes)
{
Calendar calendar=Calendar.getInstance();
calendar.set(year,month,date,hour,minutes,0);
return calendar.getTimeInMillis();
}
public void setDueStatus(int id,long timeInMillis){
AlarmManager alarmManager=(AlarmManager)
this.getSystemService(Context.ALARM_SERVICE);
Intent intent=new Intent(this, SetDueOnComplete.class);
intent.putExtra("id",id);
PendingIntent
pendingIntent= PendingIntent.getBroadcast(
this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP,timeInMillis,pendingIntent);
Toast.makeText(this,"due status is set",Toast.LENGTH_SHORT).show();
Log.d("Alarm:","alarm set for "+String.valueOf(timeInMillis));
}
}
广播接收器类---
package Receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Adapter;
import Adapters.RecyclerViewAdapter;
import Data.DataBaseHandler;
import Fragments.CurrentTaskFragment;
import Model.Target;
public class SetDueOnComplete extends BroadcastReceiver {
DataBaseHandler handler;
CurrentTaskFragment fragment;
RecyclerViewAdapter adapter;
private static final String TAG="SetDuoComplete";
public SetDueOnComplete() {
}
@Override
public void onReceive(Context context, Intent intent) {
handler=new DataBaseHandler(context);
Bundle bundle=intent.getExtras();
adapter=new RecyclerViewAdapter(context);
int id=bundle.getInt("id");
int position=adapter.getTargetPosition(id);
adapter.moveToDone(handler.getTarget(id),position);
Log.d(TAG,String.valueOf(id));
fragment=new CurrentTaskFragment();
fragment.initializeData();
Log.d(TAG,String.valueOf(id)+" removed");
}
}
这是片段类,我在其中显示列表-
package Fragments;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import java.util.ArrayList;
import java.util.List;
import Adapters.RecyclerViewAdapter;
import Data.DataBaseHandler;
import Model.Target;
import siddharthbisht.targettracker.R;
public class CurrentTaskFragment extends Fragment {
RecyclerView recyclerView;
private RecyclerViewAdapter adapter;
private List<Target> targetList;
private List<Target> listItems;
private DataBaseHandler db;
private OnFragmentInteractionListener mListener;
public CurrentTaskFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_current_task, container, false);
db=new DataBaseHandler(this.getContext());
recyclerView=view.findViewById(R.id.rvList);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext()));
targetList=new ArrayList<>();
listItems=new ArrayList<>();
initializeData();
return view;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
public void initializeData(){
//Get items from database
targetList=db.getAllCurrentTargets();
for(Target c: targetList){
Target target=new Target();
target.setTopic(c.getTopic());
target.setFinishDate(c.getFinishDate());
target.setFinishMonth(c.getFinishMonth());
target.setFinishYear(c.getFinishYear());
target.setFinishHour(c.getFinishHour());
target.setFinishMinute(c.getFinishMinute());
target.setId(c.getId());
listItems.add(target);
Log.d("fragement:",target.getTopic()+" added");
Log.d("fragment: ",String.valueOf(target.getCompletionStatus()));
}
adapter=new RecyclerViewAdapter(this.getContext(),listItems);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}