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();
}}
Related
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.
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
Am looking to create a fragment conaining listview by retriveing data from firebase database.This listview gets cards having buttons and seekbar. All I want is to have a global variable listen to these buttons. I tried creating onClicklistener in the fragment itself but wasn't successful.Then I created onClicklistener for these buttons on the Adapter itself which was working. Now when I use the buttonclick to create a Toast, the Toast string is coming up as I expect. But the problem is that I want this Toasted string to store somewhere like global variable so that I could use it in another fragment as well. So I used:
String alpha = ((MyApplication) getContext()).getCartitem();
((MyApplication)getContext()).setCartitem("XYZ");
inside my adapter class's on Click Listener itself but the application crashes showing error log "First cannot be cast to com.fastfrooot.fastfrooot.MyApplication". First being my Activity containing Fragment and MyApplication is the class extending application.
MyApplication.java
package com.fastfrooot.fastfrooot;
import android.app.Application;
import android.widget.Button;
public class MyApplication extends Application {
private boolean[] cartsitem = {
false,
false,
false,
false,
false,
false
};
private String orderitem;
private String pkname;
private boolean oncomp = false;
private Button[] cartbuttons = new Button[20];
private String cartitem = "Alpha";
public boolean[] getcartsitem() {
return cartsitem;
}
public void setcartsitem(boolean[] cartsitem) {
this.cartsitem = cartsitem;
}
public String getorderitem() {
return orderitem;
}
public void setorderitem(String orderitem) {
this.orderitem = orderitem;
}
public String getpkname() {
return pkname;
}
public void setpkname(String pkname) {
this.pkname = pkname;
}
public boolean getoncomp() {
return oncomp;
}
public void setoncomp(boolean oncomp) {
this.oncomp = oncomp;
}
public Button[] getcartbuttons() {
return cartbuttons;
}
public void setCartbuttons(Button[] cartbuttons) {
this.cartbuttons = cartbuttons;
}
public String getCartitem() {
return cartitem;
}
public void setCartitem(String cartitem) {
this.cartitem = cartitem;
}
}
public class CustomListAdapterfir extends ArrayAdapter < Cardfir > {
private static final String TAG = "CustomListAdapter";
private Context mContext;
private int mResource;
private int lastPosition = -1;
private int procount;
String Cartkeitem;
private static class ViewHolder {
TextView title;
ImageView image;
TextView Status;
Button cartbutton;
SeekBar seekbar;
}
public CustomListAdapterfir(Context context, int resource, List < Cardfir > objects) {
super(context, resource, objects);
mContext = context;
mResource = resource;
//sets up the image loader library
setupImageLoader();
}
#NonNull
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//get the persons information
final String title = getItem(position).getTitle();
String imgUrl = getItem(position).getImgURL();
final String Status = getItem(position).getStatus();
Button cartbutton = getItem(position).getCartbutton();
final SeekBar seekBar = getItem(position).getSeekbar();
try {
//create the view result for showing the animation
final View result;
//ViewHolder object
final ViewHolder holder;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(mResource, parent, false);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.cardTitle);
holder.Status = (TextView) convertView.findViewById(R.id.cardstat);
holder.image = (ImageView) convertView.findViewById(R.id.cardImage);
holder.seekbar = (SeekBar) convertView.findViewById(R.id.seekBarf);
holder.cartbutton = (Button) convertView.findViewById(R.id.Addbutton);
result = convertView;
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
result = convertView;
}
lastPosition = position;
holder.title.setText(title);
holder.Status.setText(Status);
holder.cartbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int seekerpos = holder.seekbar.getProgress() + 1;
Cartkeitem = title + " " + String.valueOf(seekerpos);
Toast.makeText(mContext, Cartkeitem, Toast.LENGTH_SHORT).show();
String alpha = ((MyApplication) getContext()).getCartitem();
((MyApplication) getContext()).setCartitem("XYZ");
}
});
holder.seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
//create the imageloader object
ImageLoader imageLoader = ImageLoader.getInstance();
int defaultImage = mContext.getResources().getIdentifier("#drawable/logo", null, mContext.getPackageName());
DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true)
.cacheOnDisc(true).resetViewBeforeLoading(true)
.showImageForEmptyUri(defaultImage)
.showImageOnFail(defaultImage)
.showImageOnLoading(defaultImage).build();
imageLoader.displayImage(imgUrl, holder.image, options);
return convertView;
} catch (IllegalArgumentException e) {
Log.e(TAG, "getView: IllegalArgumentException: " + e.getMessage());
return convertView;
}
}
private void setupImageLoader() {
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheOnDisc(true).cacheInMemory(true)
.imageScaleType(ImageScaleType.EXACTLY)
.displayer(new FadeInBitmapDisplayer(300)).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
mContext)
.defaultDisplayImageOptions(defaultOptions)
.memoryCache(new WeakMemoryCache())
.discCacheSize(100 * 1024 * 1024).build();
ImageLoader.getInstance().init(config);
}
}
public class Tab1fragment extends Fragment implements View.OnClickListener {
private static final String TAG = "TAG1 fragment";
private ListView mListView;
DatabaseReference Complete = FirebaseDatabase.getInstance().getReference();
DatabaseReference Products = Complete.child("Products");
ValueEventListener productlistener;
final ArrayList < Cardfir > list = new ArrayList < Cardfir > ();
String productname;
String producttype;
final ArrayList < Button > Cartbuttons = new ArrayList < Button > ();
final ArrayList < SeekBar > Seekbars = new ArrayList < SeekBar > ();
int productnumber = -1;
Button[] Cartsbut = new Button[20];
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab1_fragment, container, false);
mListView = (ListView) view.findViewById(R.id.listview);
productlistener = Products.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (final DataSnapshot delphi: dataSnapshot.getChildren()) {
productnumber = productnumber + 1;
productname = delphi.child("Name").getValue().toString();
producttype = delphi.child("Type").getValue().toString();
list.add(new Cardfir("drawable://" + R.drawable.trans, productname, producttype));
}
CustomListAdapterfir adapter = new CustomListAdapterfir(getActivity(), R.layout.card_layout_liveorder, list);
mListView.setAdapter(adapter);
Products.removeEventListener(productlistener);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return view;
}
#Override
public void onClick(View view) {
Toast.makeText(getContext(), "HI", Toast.LENGTH_SHORT).show();
}
}
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();
}
After clicking on the list and setting the information on EditText & ImageView to update the database information
When I return to the previous one and return to the same activity again, the information on EditText & ImageView will not be deleted and will still be displayed.
How can I fix this problem?
code java class Manage:
MyDB db = new MyDB(getApplicationContext());
List<InfoData> data = db.fetchmaindata();
db.close();
adapter = new MyListAdapter(getApplicationContext(), postdata(data));
BtnLoadAll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
}
});
}
private View.OnClickListener onEditEmployeeSubmit = new View.OnClickListener() {
#Override
public void onClick(View view) {
if (EdtNAME.length()>0 && EdtFAMILY.length()>0 && EdtDESCRIPTION.length()>0) {
try {
myDB.open();
myDB.editEmployee(
Integer.parseInt(EdtID.getText().toString()),
EdtNAME.getText().toString(),
EdtFAMILY.getText().toString(),
EdtDESCRIPTION.getText().toString(),
ImgViewOrgsToByte(ImgViewOrgs)
);
//refreshList();
Toast.makeText(getApplicationContext(), "Information was updated!", Toast.LENGTH_SHORT).show();
EdtID.setText("");
EdtNAME.setText("");
EdtFAMILY.setText("");
EdtDESCRIPTION.setText("");
ImgViewOrgs.setImageResource(R.mipmap.ic_launcher);
myDB.close();
}catch (Exception e){
e.printStackTrace();
myDB.close();
}
}else{
Toast.makeText(getApplicationContext(),"Fill in all the information!",Toast.LENGTH_SHORT).show();
}
//btnCancel.performClick();
}
};
public void info(){
findViewById(R.id.EdtID).setVisibility(View.VISIBLE);
byte[] infoimage = Manage.image;
if (infoimage != null && infoimage.length > 0) {
Bitmap bitmap = BitmapFactory.decodeByteArray(infoimage, 0, infoimage.length);
EdtID.setText(Integer.toString(id));
EdtNAME.setText(title);
EdtFAMILY.setText(family);
EdtDESCRIPTION.setText(description);
ImgViewOrgs.setImageBitmap(bitmap);
}else{
return;
}
}
private List<Info> postdata(List<InfoData> db) {
List<Info> data = new ArrayList<>();
for (int i = 0; i < db.size(); i++) {
Info cur = new Info();
cur.name = db.get(i).getName();
cur.family = db.get(i).getFamily();
cur.description = db.get(i).getDescription();
cur.image = db.get(i).getImage();
data.add(cur);
}
return data;
}
code adapter:
public class MyListAdapter extends RecyclerView.Adapter<MyListAdapter.ViewHolder> {
private Context context;
private List<Info> data;
private LayoutInflater inflater;
public MyListAdapter(Context context, List<Info> data) {
inflater = LayoutInflater.from(context);
this.data = data;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.custom_row_main, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Info cur = data.get(position);
holder.textView.setText(cur.name);
holder.textViewf.setText(cur.family);
byte[] infoimage = cur.image;
Bitmap bitmap = BitmapFactory.decodeByteArray(infoimage, 0, infoimage.length);
holder.imageView.setImageBitmap(bitmap);
Typeface font = Typeface.createFromAsset(context.getAssets(), "BKoodkBd.ttf");
holder.textView.setTypeface(font);
holder.textViewf.setTypeface(font);
}
#Override
public int getItemCount() {
return data.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView textView,textViewf,textViewi;
private ImageView imageView;
public ViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.title_main);
textViewi = (TextView) itemView.findViewById(R.id.textViewi);
textViewf = (TextView) itemView.findViewById(R.id.title_mainf);
imageView = (ImageView) itemView.findViewById(R.id.imageView);
Button btnEdit = (Button) itemView.findViewById(R.id.btn_edit);
final Button btnDelete = (Button) itemView.findViewById(R.id.btn_delete);
//imageView = (ImageView) itemView.findViewById(R.id.iii);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Info curr = new Info();
curr = data.get(getPosition());
Manage.id = curr.id;
Manage.title = curr.name;
Manage.family = curr.family;
Manage.description = curr.description;
Manage.image = curr.image;
Manage.id = getPosition() + 1;
Intent intent = new Intent(context, Manage.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
}
}
}
Picture of the program