How to load pdf files to recycler view in fragment? - java

ello guys good day I'm trying to make an app using android java but I'm stuck any idea would be appreciated
I'm trying to access all pdf files in android device using the media store and cursor but it's not working the aim is to display all pdf files in a recycler view on a fragment the issue here is that it never displays meaning maybe the data wasn't passed because when the arraylist is populated manually it displays otherwise non I've checked the log but I can't seem to find anything.
This my fragment code
public class AllFragment extends Fragment {
View view;
private static final String TAG = "MyActivity";
ArrayList<String> pdfList;
private final int STORAGE_PERMISSION_CODE = 1;
private Activity mActivity;
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
mActivity = (Activity) context;
}
public void checkPermission(){
if ((ContextCompat.checkSelfPermission(mActivity, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED))
{
if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.READ_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(mActivity)
.setTitle("Permission needed")
.setMessage("Allow "+getResources().getString(R.string.app_name)+" to access your storage?")
.setPositiveButton("ok", new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int which){
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
}
}
)
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which){
dialog.dismiss();
Toast.makeText(mActivity, "Please allow this permission!", Toast.LENGTH_SHORT).show();
}
})
.create().show();
} else {
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
}
}
}
//checkPermission();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.AllFragment, container, false);
//pdfList = getPdfList();
//buildData();
//LinearLayoutManager
//pdfList = new String[] {"one", "two", "three", "fou4", "five", "six"};
getPdfList();
initRecyclerView(view);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkPermission();
}
//RecyclerView
public void initRecyclerView(View view){
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.allPdfsRecyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
AllPdfAdapter adapter = new AllPdfAdapter(pdfList);
recyclerView.setAdapter(adapter);
}
public ArrayList<String> getPdfList() {
pdfList = new ArrayList<>();
Uri collection;
final String[] projection = new String[]{
MediaStore.Files.FileColumns.DISPLAY_NAME,
MediaStore.Files.FileColumns.DATE_ADDED,
MediaStore.Files.FileColumns.DATA,
MediaStore.Files.FileColumns.MIME_TYPE,
};
final String sortOrder = MediaStore.Files.FileColumns.DATE_ADDED + " DESC";
final String selection = MediaStore.Files.FileColumns.MIME_TYPE + " = ?";
final String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf");
final String[] selectionArgs = new String[]{mimeType};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
collection = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL);
}else{
collection = MediaStore.Files.getContentUri("external");
}
try (Cursor cursor = getActivity().getContentResolver().query(collection, projection, selection, selectionArgs, sortOrder)) {
assert cursor != null;
if (cursor.moveToFirst()) {
int columnData = cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA);
int columnName = cursor.getColumnIndex(MediaStore.Files.FileColumns.DISPLAY_NAME);
//ArrayList pdfList = new ArrayList<>();
do {
pdfList.add((cursor.getString(columnData)));
System.out.println(cursor.getString(columnData));
Log.d(TAG, "getPdf: " + cursor.getString(columnData));
//you can get your pdf files
} while (cursor.moveToNext());
}
}
return pdfList;
}
}
This my adapter code
public class AllPdfAdapter extends RecyclerView.Adapter<AllPdfAdapter.My_ViewHolder>
{
private ArrayList<String> data;
public AllPdfAdapter(ArrayList<String>data){
this.data = data;
}
#Override
public AllPdfAdapter.My_ViewHolder onCreateViewHolder(ViewGroup p1, int p2)
{
LayoutInflater li = LayoutInflater.from(p1.getContext());
View v = li.inflate(R.layout.allList,p1,false);
// TODO: Implement this method
return new My_ViewHolder(v);
}
#Override
public void onBindViewHolder(AllPdfAdapter.My_ViewHolder holder, int position)
{
// TODO: Implement this method
String title = data.get(position);
holder.ttt.setText(title);
}
#Override
public int getItemCount()
{
// TODO: Implement this method
return data.size();
}
public class My_ViewHolder extends RecyclerView.ViewHolder{
ImageView iii;
TextView ttt;
public My_ViewHolder (View v){
super(v);
iii = (ImageView) v.findViewById(R.id.img);
ttt = (TextView) v.findViewById(R.id.title);
}
}
}
Your answers will be appreciated.

Related

Data in RecycleCiew from Sql database only updates after i restart the app

I am making a feature for my app where the user can add a new food item inside RecyleView. But instead using a new activity I opted out for a popup that appears in the Main Activity where you can enter the food and the price which means the activity doesn't refresh. How can I display the items in the RecycleView without restarting the app?
Code in Main Activity:
public class SecondScreen extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_screen);
myDB = new MyDataBaseHelper(SecondScreen.this);
foodID = new ArrayList<>();
foodName = new ArrayList<>();
foodPrice = new ArrayList<>();
popUp();
//Data from Sql Tables
storeDataInArrays();
customAdapater = new CustomAdapater(SecondScreen.this, foodID, foodName, foodPrice);
recyclerView.setLayoutManager(new LinearLayoutManager(SecondScreen.this));
recyclerView.setAdapter(customAdapater);
//Storing the data from the sql table
public void storeDataInArrays(){
Cursor cursor = myDB.readAllData();
//Gets the count of the rows
if(cursor.getCount() == 0){
Toast.makeText(this, "No data", Toast.LENGTH_SHORT).show();
}else{
while(cursor.moveToNext()){
foodID.add(cursor.getString(0));
foodName.add(cursor.getString(1));
foodPrice.add(cursor.getString(2));
}
}
}
}
public void PopUP(){
btnAddFood.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyDataBaseHelper myDB = new MyDataBaseHelper(SecondScreen.this);
myDB.addFood(edtFoodName.getText().toString().trim(),
edtFoodPrice.getText().toString().trim());
//Dismisses the popUp after button click
myDialog.dismiss();
}
});
}
}
Code for RecycleView Adapter
public class CustomAdapater extends RecyclerView.Adapter<CustomAdapater.MyViewHolder> {
Context context;
private ArrayList foodID, foodName, foodPrice;
CheckBox chkItem;
//Constructor
CustomAdapater(Context context, ArrayList foodID, ArrayList foodName, ArrayList foodPrice){
//Declares to global variables that can be used in the MainAcivity
this.context = context;
this.foodID = foodID;
this.foodName = foodName;
this.foodPrice = foodPrice;
}
#NonNull
#Override
public CustomAdapater.MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//Inflates the item_row layout
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.item_row, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CustomAdapater.MyViewHolder holder, int position) {
holder.checkItem.setText(String.valueOf(foodName.get(position)));
holder.foodPrice_txt.setText(String.valueOf(foodPrice.get(position) + "$"));
}
#Override
public int getItemCount() {
return foodID.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView foodPrice_txt;
CheckBox checkItem;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
checkItem = itemView.findViewById(R.id.chkItemRow);
foodPrice_txt = itemView.findViewById(R.id.txtPriceRow);
}
}
}
Call notifyItemInserted after adding the item to your database and array lists, to update your adapter.
Like so:
String foodName = edtFoodName.getText().toString().trim();
String foodPrice = edtFoodPrice.getText().toString().trim();
myDB.addFood(foodName, foodPrice);
foodNames.add(foodName);
foodPrices.add(foodPrice);
customAdapater.notifyItemInserted(foodNames.size() - 1);

Refresh RecyclerView from BroadcastReceiver When TelephonyManager.EXTRA_STATE_RINGING

I have a tabLayout in which there is Log Fragment tab it store all the incoming calls details in LogsData List Object and set .
New callLogs is updated after App close and restart but I want to refresh my RecyclerView when the call is in ringing state.
My LogFragment
public class LogsFragment extends Fragment {
private RecyclerView mRecyclerView;
private ListAdapter mListadapter;
ArrayList data;
TinyDB tinyDB;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_call_log, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
tinyDB = new TinyDB(getContext());
data = tinyDB.getListObject("LogData", LogsData.class);
final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setHasFixedSize(false);
mRecyclerView.setLayoutManager(layoutManager);
data = tinyDB.getListObject("LogData", LogsData.class);
mListadapter = new ListAdapter(data);
mListadapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mListadapter);
return view;
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMyEvent(Object o) {
/* Refresh your adapter */
data = tinyDB.getListObject("LogData", LogsData.class);
mListadapter = new ListAdapter(data);
mListadapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mListadapter);
};
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {
private ArrayList<LogsData> dataList;
public ListAdapter(ArrayList<LogsData> data) {
this.dataList = data;
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView textViewName;
TextView textViewNumb;
TextView textViewTime;
public ViewHolder(View itemView) {
super(itemView);
this.textViewName = itemView.findViewById(R.id.cName);
this.textViewNumb = itemView.findViewById(R.id.number);
this.textViewTime = itemView.findViewById(R.id.time_stamp);
}
}
#Override
public ListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.log_list, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.textViewName.setText(dataList.get(position).getName());
holder.textViewNumb.setText(dataList.get(position).getNumber());
holder.textViewTime.setText(dataList.get(position).getTime());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "Item " + position + " is clicked.", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return dataList.size();
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMyEvent(Object o) {
/* Refresh your adapter */
data = tinyDB.getListObject("LogData", LogsData.class);
mListadapter = new ListAdapter(data);
mListadapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mListadapter);
};
}
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
}
And my PhoneStateReceiver Class
public class PhoneStateReceiver extends BroadcastReceiver {
public final static String TAG = "SSD";
String incomingNumber;
String state;
DateFormat timeFormat;
Context context;
String date;
String cName;
ArrayList data;
#SuppressLint("UnsafeProtectedBroadcastReceiver")
#Override
public void onReceive(Context context, Intent intent) {
TinyDB tinydb = new TinyDB(context);
data = tinydb.getListObject("LogData", LogsData.class);
try {
state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
cName = getContactName(incomingNumber, context);
timeFormat = new SimpleDateFormat("EEE, d MMM yyyy, HH:mm");
date = timeFormat.format(Calendar.getInstance().getTime());
Log.d(TAG, date);
String phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (phoneState.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
data.add(new LogsData(cName, incomingNumber, date));
tinydb.putListObject("LogData", data);
Toast.makeText(context, date + " " + incomingNumber + " " + cName, Toast.LENGTH_SHORT).show();
}
EventBus.getDefault().post(new Object());
} catch (Exception e) {
e.printStackTrace();
}
}
public String getContactName(final String phoneNumber, Context context) {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
String[] projection = new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME};
String contactName = "";
Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
contactName = cursor.getString(0);
}
cursor.close();
}
return contactName;
}
}
I update my codes please see it.
Use EventBus to do it
In your LogsFragment prepare subscriber like this:
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMyEvent(Object o) {
/* Refresh your adapter */
data = tinyDB.getListObject("LogData", LogsData.class);
mListadapter = new ListAdapter(data);
mListadapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mListadapter);
};
And in your PhoneStateReceiver call your subscriber like this:
EventBus.getDefault().post(new Object());
Do not forget to register and unregister your subscriber in LogsFragment
You can read more about EventBus in here

Why do I have to restart my app for my RecyclerView to display data from SQLite?

EDIT 1: I used debugging statements and it turns out that when I add an item to the database it is successful. However, the updateUI() method is not called because what I am launching is a DialogFragment() so my ListActivity does not enter a paused state. But, if I exit the app and launch again the adapter gets updated. So now the question becomes how do I update the adapter after exiting the dialog fragment?
I'm building a simple list app and added SQLite database to store task object. I am successfully adding items to the database, but they do not show up immediately in the RecyclerView I am using to show all tasks. It is only when I completely exit from the app and reload that tasks items show up in the RecyclerView.
ListFragment.java this will create the RecyclerView
public class ListFragment extends Fragment {
private static final String DEBUG_LOG = "debug_message";
private static final String ADD_DIALOG = "add_dialog";
private static final int REQUEST_TITLE = 0;
private RecyclerView mRecyclerView;
private TaskAdapter mAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_list, container, false);
mRecyclerView = view.findViewById(R.id.the_task_list);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(linearLayoutManager);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), linearLayoutManager.getOrientation());
mRecyclerView.addItemDecoration(dividerItemDecoration);
updateUI();
return view;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == Activity.RESULT_OK && requestCode == ListFragment.REQUEST_TITLE) {
UUID taskId = (UUID) data.getSerializableExtra(EditTaskFragment.EXTRA_TASK_ID);
String newTaskName = data.getStringExtra(EditTaskFragment.EXTRA_TASK_TITLE);
if(newTaskName != null) {
Task task = TaskLab.get(getActivity()).getTask(taskId);
task.setTitle(newTaskName);
TaskLab.get(getActivity()).updateTask(task);
}
updateUI();
}
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_list_item, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.add_new_task:
FragmentManager manager = getFragmentManager();
AddTaskFragment dialog = new AddTaskFragment();
dialog.show(manager, ADD_DIALOG);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onResume() {
super.onResume();
updateUI();
}
public void updateUI() {
// Retrieves ArrayList<Task>
List<Task> taskList = TaskLab.get(getActivity()).getTaskList();
if(mAdapter == null) {
mAdapter = new TaskAdapter(taskList);
mRecyclerView.setAdapter(mAdapter);
}else {
mAdapter.setCrimes(taskList);
mAdapter.notifyDataSetChanged();
}
}
private class TaskAdapter extends RecyclerView.Adapter<TaskHolder>{
private List<Task> mTaskList;
public TaskAdapter(List<Task> taskList) {
mTaskList = taskList;
}
#Override
public TaskHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.task_list_layout, parent, false);
return new TaskHolder(view);
}
#Override
public void onBindViewHolder(TaskHolder holder, int position) {
final Task currentTask = mTaskList.get(position);
holder.bindData(currentTask);
final TextView taskTitle = holder.mTaskTitle;
holder.mSolved.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
if(isChecked) {
taskTitle.setPaintFlags(taskTitle.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
currentTask.setSolved(true);
}else {
taskTitle.setPaintFlags(taskTitle.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
}
}
});
}
#Override
public int getItemCount() {
return mTaskList.size();
}
public void setCrimes(List<Task> taskList) {
mTaskList = taskList;
}
}
private class TaskHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private Task mTask;
private TextView mTaskTitle;
private CheckBox mSolved;
private static final String EDIT_DIALOG = "edit_dialog";
public TaskHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
mTaskTitle = itemView.findViewById(R.id.task_title);
mSolved = itemView.findViewById(R.id.task_solved);
}
public void bindData(Task task) {
mTask = task;
mTaskTitle.setText(mTask.getTitle());
mSolved.setChecked(mTask.isSolved());
}
#Override
public void onClick(View view) {
if(!mSolved.isChecked()) {
FragmentManager manager = getFragmentManager();
EditTaskFragment dialog = EditTaskFragment.newInstance(mTask.getId());
dialog.setTargetFragment(ListFragment.this, REQUEST_TITLE);
dialog.show(manager, EDIT_DIALOG);
}
}
}
AddTaskFragment.java this will allow the user to add a task item to the RecyclerView
public class AddTaskFragment extends DialogFragment {
private EditText mTaskTitle;
private void addTask() {
if(!mTaskTitle.getText().toString().equals("")) {
Task task = new Task();
task.setTitle(mTaskTitle.getText().toString());
TaskLab.get(getActivity()).addTask(task);
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
//return super.onCreateDialog(savedInstanceState);
View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_task_dialog,null);
mTaskTitle = view.findViewById(R.id.task_title);
return new AlertDialog.Builder(getActivity())
.setView(view)
.setTitle(R.string.add_new_task_dialog_title)
.setPositiveButton(R.string.add_new_task_dialog_positive, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
addTask();
}
})
.create();
}
}
TaskLab.java this is a singleton class
public class TaskLab {
private static TaskLab sTaskLab;
private Context mContext;
private SQLiteDatabase mDatabase;
private TaskLab(Context context){
mContext = context.getApplicationContext();
mDatabase = new TaskBaseHelper(mContext).getWritableDatabase();
}
public static TaskLab get(Context context) {
if(sTaskLab == null) {
sTaskLab = new TaskLab(context);
}
return sTaskLab;
}
public List<Task> getTaskList(){
List<Task> taskList = new ArrayList<Task>();
TaskCursorWrapper cursor = queryTasks(null, null);
// If there is something in the table query it
try {
cursor.moveToFirst();
while(!cursor.isAfterLast()) {
Task task = cursor.getTask();
taskList.add(task);
cursor.moveToNext();
}
} finally {
cursor.close();
}
return taskList;
}
public void addTask(Task task) {
ContentValues values = getContentValues(task);
mDatabase.insert(TaskTable.NAME, null, values);
}
public void updateTask(Task task) {
ContentValues values = getContentValues(task);
String uuidString = task.getId().toString();
mDatabase.update(TaskTable.NAME,values, TaskTable.Cols.UUID + " = ?", new String[] {uuidString});
}
public Task getTask(UUID id){
TaskCursorWrapper cursor = queryTasks(TaskTable.Cols.UUID + " = ?",
new String[] {id.toString()});
try {
if(cursor.getCount() == 0) {
return null;
}
cursor.moveToFirst();
return cursor.getTask();
} finally {
cursor.close();
}
}
private static ContentValues getContentValues(Task task) {
ContentValues values = new ContentValues();
values.put(TaskTable.Cols.UUID, task.getId().toString());
values.put(TaskTable.Cols.TITLE, task.getTitle());
values.put(TaskTable.Cols.SOLVED, task.isSolved());
return values;
}
private TaskCursorWrapper queryTasks(String whereClause, String[] whereArgs) {
Cursor cursor = mDatabase.query(TaskTable.NAME,
null,
whereClause,
whereArgs,
null,
null,
null);
return new TaskCursorWrapper(cursor);
}
}
It must be reCreate your adapter in updateUI every time from the beginning
Try it like this and see. In your onCreateView() of fragment before updateUI() add below line of code.
Note: Create taskList as global variable.
mRecyclerView = view.findViewById(R.id.the_task_list);
mAdapter = new TaskAdapter(taskList);
mRecyclerView.setAdapter(mAdapter);
updateUI();
After that create your updateUI() method as below
public void updateUI() {
taskList.clear;
taskList = TaskLab.get(getActivity()).getTaskList();
mAdapter.notifyDataSetChanged();
}
Update:
As per your updated question, declare one global variable in ListFragment as
public static ListFragment listFragment;
In your onCreate method of ListFragment after inflating view add below line of code.
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_list, container, false);
listFragment = this;
Then change your addTask method in AddTaskFragment as below.
private void addTask() {
if(!mTaskTitle.getText().toString().equals("")) {
Task task = new Task();
task.setTitle(mTaskTitle.getText().toString());
TaskLab.get(getActivity()).addTask(task);
//import listfragment from your ListFragment
listFragment.updateUI();
}
}

My Recyclerview list stopped working after implementing SQLite database

I'm building a to do list app. I'm learning SQLite databases and I'm trying to save the user input into an SQLite database table and also display it in my recyclerview list. When I did this without the SQLite, it worked so the problem is obviously with my implementation of the database table. The app is supposed to add the data into the list per button click:
addingItems.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(itemsInput.getText() != null){
items.add(new todo(itemsInput.getText().toString()));
itemsInput.setText("");
}else {
Toast.makeText(MainActivity.this, "Please enter something to do", Toast.LENGTH_SHORT).show();
}
itemAdapter.notifyDataSetChanged();
}
});
But now it does not do that. The app does not crash. The problem is just that my list shows absolutely no data. The following are my relevant Java files:
MainActivity.java
public class MainActivity extends AppCompatActivity {
private SQLiteDatabase sqLiteDatabase;
private List<todo> items = new ArrayList<>();
private ItemAdapter itemAdapter;
private RecyclerView listItemsRecyclerView;
EditText itemsInput;
Button addingItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
itemsInput = (EditText)findViewById(R.id.to_do_editText);
addingItems = (Button)findViewById(R.id.to_do_btn);
listItemsRecyclerView = (RecyclerView) findViewById(R.id.to_do_list);
ToDoListDatabaseHelper databaseHelper = new ToDoListDatabaseHelper(this);
sqLiteDatabase = databaseHelper.getWritableDatabase();
items = new ArrayList<>();
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
listItemsRecyclerView.setLayoutManager(layoutManager);
listItemsRecyclerView.setItemAnimator(new DefaultItemAnimator());;
itemAdapter = new ItemAdapter(items);
listItemsRecyclerView.setAdapter(itemAdapter);
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
});
addingItems.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(itemsInput.getText().length() > 0){
addNewToDo(itemsInput.getText().toString());
itemsInput.setText("");
}else {
Toast.makeText(MainActivity.this, "Please enter something to do", Toast.LENGTH_SHORT).show();
}
itemAdapter.notifyDataSetChanged();
}
});
}
private List<todo> getAllToDos(){
Cursor cursor = sqLiteDatabase.rawQuery("select * from " + ToDoContract.ToDoEntry.TABLE_NAME, new String[]{});
List<todo> todos = new ArrayList<>();
todo todo;
if (cursor != null && cursor.getCount() > 0) {
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(cursor.getColumnIndex(ToDoContract.ToDoEntry.COLUMN_TODO_NAME));
int priority = cursor.getInt(cursor.getColumnIndex(ToDoContract.ToDoEntry.COLUMN_TODO_PRIORITY));
int timestamp = cursor.getInt(cursor.getColumnIndex(ToDoContract.ToDoEntry.COLUMN_TODO_TIMESTAMP));
todo = new todo(name);
todos.add(todo);
} while (cursor.moveToNext());
}
cursor.close();
}
return todos;
}
private long addNewToDo(String name){
ContentValues cv = new ContentValues();
cv.put(ToDoContract.ToDoEntry.COLUMN_TODO_NAME, name);
return sqLiteDatabase.insert(ToDoContract.ToDoEntry.TABLE_NAME, null, cv);
}
}
My custom adapter:
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {
private List<todo> todoList;
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView toDoTextView;
public ViewHolder(View itemView) {
super(itemView);
toDoTextView = (TextView) itemView.findViewById(R.id.to_do);
}
}
public ItemAdapter(List<todo> todoList) {
this.todoList = todoList;
}
#Override
public ItemAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ItemAdapter.ViewHolder holder, int position) {
todo toDo = todoList.get(position);
holder.toDoTextView.setText(toDo.getToDo());
}
#Override
public int getItemCount() {
return todoList.size();
}
}
I ran unit tests on my SQLite classes so there is no issue with them.
You should not use Cursor as the data source for Adapter.Why don't you just fetch data(todos) from cursor then put the data into Adapter? As we known, cursor should be CLOSED at the end of data reading. You should code like that:
private List<todo> getAllToDos() {
Cursor cursor = sqLiteDatabase.rawQuery("select * from " + ToDoContract.ToDoEntry.TABLE_NAME, new String[]{});
List<todo> todos = new ArrayList<>();
todo todo;
if (cursor != null && cursor.getCount() > 0) {
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(cursor.getColumnIndex(ToDoContract.ToDoEntry.COLUMN_TODO_NAME));
int priority = cursor.getInt(cursor.getColumnIndex(ToDoContract.ToDoEntry.COLUMN_TODO_PRIORITY));
int timestamp = cursor.getInt(cursor.getColumnIndex(ToDoContract.ToDoEntry.COLUMN_TODO_TIMESTAMP));
todo = new todo(name);
todo.setPriority(priority);
todo.setTimestamp(timestamp);
todos.add(todo);
} while (cursor.moveToNext());
}
cursor.close();
}
return todos;
}
And your ItemAdapter will be simpler.
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {
private List<todo> todoList;
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView toDoTextView;
public ViewHolder(View itemView) {
super(itemView);
toDoTextView = (TextView) itemView.findViewById(R.id.to_do);
}
}
public ItemAdapter(List<todo> todoList) {
this.todoList = todoList;
}
#Override
public ItemAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ItemAdapter.ViewHolder holder, int position) {
todo toDo = todoList.get(position);
holder.toDoTextView.setText(toDo.getToDo());
}
#Override
public int getItemCount() {
return todoList.size();
}
}
There are some other changes.But I think you can fix them as I told you above.If you have any other question about that, please tell me.I will help you.
Try this
public void update()
{
cursor.requery();
notifyDataSetChanged();
}

Contact List not responding in Android M

I am displaying a Contacts From Mobile Contacts using RecyclerView,
here the problem is "when i tried my application to run on Android M it not responding it throws an error
Caused by: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord{3b9a84a 17730:com.strobilanthes.contactdetials/u0a224} (pid=17730, uid=10224) requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS"
my Code below:
public class MainAct extends AppCompatActivity implements AdapterView.OnItemClickListener {
private static final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;
List<String> phno1 = new ArrayList<String>();
Button select;
private EditText edtContactFilter;
private RecyclerView recyclerView;
private ICEAdapter iceAdapter;
ArrayList<ContactList> contactLists;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_display);
recyclerView = (RecyclerView) findViewById(R.id.recycle_view);
getAllContacts(this.getContentResolver());
updateCabLsit(contactLists);
select = (Button) findViewById(R.id.button1);
select.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
StringBuilder checkedcontacts = new StringBuilder();
Toast.makeText(MainAct.this, checkedcontacts, Toast.LENGTH_SHORT).show();
}
});
edtContactFilter = (EditText) findViewById(R.id.edt_contact_filter);
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
}
public void getAllContacts(ContentResolver cr) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.SORT_KEY_PRIMARY);
contactLists = new ArrayList<ContactList>();
while (phones.moveToNext()) {
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
System.out.println(".................." + phoneNumber + " >> " + name);
if (!phno1.contains(phoneNumber)) {
//name1.add(name);
phno1.add(phoneNumber);
ContactList c = new ContactList();
c.setIceName(name);
c.setIceNumber(phoneNumber);
contactLists.add(c);
}
}
phones.close();
} else {
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.SORT_KEY_PRIMARY);
contactLists = new ArrayList<ContactList>();
while (phones.moveToNext()) {
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
System.out.println(".................." + phoneNumber + " >> " + name);
if (!phno1.contains(phoneNumber)) {
//name1.add(name);
phno1.add(phoneNumber);
ContactList c = new ContactList();
c.setIceName(name);
c.setIceNumber(phoneNumber);
contactLists.add(c);
}
}
phones.close();
}
}
public class ICEAdapter extends RecyclerView.Adapter<ICEAdapter.ViewHolder> {
private ArrayList<ContactList> contactLists;
private Context mContext;
public ICEAdapter(Context context, ArrayList<ContactList> contactList) {
this.contactLists = contactList;
this.mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.ice_items, viewGroup, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.txtName.setText(contactLists.get(position).getIceName());
holder.txtNumber.setText(contactLists.get(position).getIceNumber());
}
#Override
public int getItemCount() {
return contactLists == null ? 0 : contactLists.size();
}
public ContactList getItem(int position) {
return contactLists.get(position);
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView txtName;
TextView txtNumber;
CheckBox chkSelect;
public ViewHolder(View itemView) {
super(itemView);
txtName = (TextView) itemView.findViewById(R.id.txt_name);
txtNumber = (TextView) itemView.findViewById(R.id.txt_number);
chkSelect = (CheckBox) itemView.findViewById(R.id.chk_select);
}
}
}
private void updateCabLsit(ArrayList<ContactList> contactLists) {
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayout = new LinearLayoutManager(this);
linearLayout.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayout);
iceAdapter = new ICEAdapter(this, contactLists);
recyclerView.setAdapter(iceAdapter);
iceAdapter.notifyDataSetChanged();
}}

Categories