Related
I have created one listview where I want to retrieve the items from sqlite database. So I have created one method as a List named as getrequestitems where I will map the details and add to a arraylist.
public List<Map<String, String>> getrequestitems() {
List<Map<String, String>> data = null;
data = new ArrayList<Map<String, String>>();
try {
SQLiteDatabase db = dbHandler.getReadableDatabase();
String sql = "SELECT * from request WHERE time > date('now','-1 day')";
Cursor rs = db.rawQuery(sql,null);
if(rs.moveToFirst()) {
do {
Map<String, String> dtname = new HashMap<String, String>();
dtname.put("bloodgrp", rs.getString(rs.getColumnIndex("bloodgrp")));
dtname.put("date", "Date:- " + rs.getString(rs.getColumnIndex("Datetime1")));
dtname.put("time", "Time:- " + rs.getString(rs.getColumnIndex("time")));
dtname.put("name", "Name:- " + rs.getString(rs.getColumnIndex("Name")));
dtname.put("Username", rs.getString(rs.getColumnIndex("Username")));
data.add(dtname);
}
while (rs.moveToNext());
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
return data;
}
But When I open that activity It doesn't displayed any records. I have debug the code but can't any exception. I have written wrong query? as "SELECT * from request WHERE time > date('now','-1 day')";
Here is my complete code.
public class request extends AppCompatActivity {
SimpleAdapter ad;
TextView list3;
private SlidrInterface slidr;
private DBHandler dbHandler;
private static ArrayList<String> arrayList = new ArrayList<>();
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_request);
slidr = Slidr.attach(this);
slidr.unlock();
dbHandler = new DBHandler(this);
list3 = findViewById(R.id.list3);
TextView txt = findViewById(R.id.list4);
ListView lst1 = (ListView) findViewById(R.id.list2);
List<Map<String, String>> MyDataList = null;
MyDataList = getrequestitems();
String[] from = {"bloodgrp", "date", "time", "name", "Username"};
int[] to = {R.id.listt, R.id.date, R.id.time1, R.id.name3, R.id.user};
ad = new SimpleAdapter(request.this, MyDataList, R.layout.listrequest, from, to);
lst1.setAdapter(ad);
lst1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
List<Map<String, String>> MyDataList1 = null;
MyDataList1 = getrequestitems();
String[] from = {"Username"};
int[] to = {R.id.user};
Toast.makeText(getApplicationContext(), MyDataList1.toString(), Toast.LENGTH_SHORT).show();
ad = new SimpleAdapter(request.this, MyDataList1, R.layout.listrequest, from, to);
if(ad.getCount()==0){
Toast.makeText(getApplicationContext(), "No requests are currently visible", Toast.LENGTH_SHORT).show();
}
HashMap<String, String> obj = (HashMap<String, String>) ad.getItem(i);
String name = (String) obj.get("Username");
try {
SQLiteDatabase db = dbHandler.getReadableDatabase();
String sql = "select * from request where Username = '" + name + "'";
Cursor rs = db.rawQuery(sql,null);
if (rs.moveToFirst()) {
do {
runOnUiThread(new Runnable() {
#SuppressLint("Range")
#Override
public void run() {
try {
final AlertDialog.Builder alert = new AlertDialog.Builder(request.this);
View mView = getLayoutInflater().inflate(R.layout.custom_dialog3, null);
final TextView txt_inputText = (TextView) mView.findViewById(R.id.name1);
txt_inputText.setText(rs.getString(rs.getColumnIndex("Name")));
final TextView txt_inputText2 = (TextView) mView.findViewById(R.id.contactno1);
txt_inputText2.setText(rs.getString(rs.getColumnIndex("contactNo")));
final TextView txt_inputText3 = (TextView) mView.findViewById(R.id.message1);
txt_inputText3.setText(rs.getString(rs.getColumnIndex("message")));
Button btn_cancel = (Button) mView.findViewById(R.id.btn_cancel);
Button btn_okay = (Button) mView.findViewById(R.id.btn_okay);
alert.setView(mView);
final AlertDialog alertDialog = alert.create();
alertDialog.setCanceledOnTouchOutside(false);
btn_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
alertDialog.dismiss();
}
});
btn_okay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String number = txt_inputText2.getText().toString();
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + number));// Initiates the Intent
startActivity(intent);
alertDialog.dismiss();
}
});
alertDialog.show();
alertDialog.getWindow().setLayout(730, 850); //Controlling width and height.
} catch (Exception e) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
}
});
}while (rs.moveToNext());
}
} catch (Exception e) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
}
});
}
#SuppressLint("Range")
public List<Map<String, String>> getrequestitems() {
List<Map<String, String>> data = null;
data = new ArrayList<Map<String, String>>();
try {
SQLiteDatabase db = dbHandler.getReadableDatabase();
String sql = "SELECT * from request WHERE time > date('now','-1 day')";
Cursor rs = db.rawQuery(sql,null);
if(rs.moveToFirst()) {
do {
Map<String, String> dtname = new HashMap<String, String>();
dtname.put("bloodgrp", rs.getString(rs.getColumnIndex("bloodgrp")));
dtname.put("date", "Date:- " + rs.getString(rs.getColumnIndex("Datetime1")));
dtname.put("time", "Time:- " + rs.getString(rs.getColumnIndex("time")));
dtname.put("name", "Name:- " + rs.getString(rs.getColumnIndex("Name")));
dtname.put("Username", rs.getString(rs.getColumnIndex("Username")));
data.add(dtname);
}
while (rs.moveToNext());
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
return data;
}
}
But When I open that activity It doesn't displayed any records. I have debug the code but can't any exception. I have written wrong query?
probably as it appears that you are very likely comparing the anecdotal oranges and apples (see explanation/example) that is, at a guess you are comparing the time and a date (see Possible fix below BUT this very much depends upon what you are actually storing in the time column, see Possible debug action below that would allow you to see a) if you are extracting any data and if applying the get all (no WHERE clause) to see the actual underlying data)
format is yyyy-MM-dd –
That seems unlikely or if not a waste seeing that you have a column for the date and a column for the time.
If the time contains just the time hh:mm or even hh:mm:ss, as an example then extracting the date is going to result in unintended results.
Consider the following that highlights the issues that you may encounter:-
DROP TABLE IF EXISTS request;
CREATE TABLE IF NOT EXISTS request (booldgrp TEXT, Datetime1 TEXT, time TEXT, Name TEXT, Username TEXT);
INSERT INTO request VALUES
('O','2023-01-01 10:10','2023-01-01 10:10','FRED','USER001')
,('O','2023-01-01 10:10','10:10','FRED','USER002')
,('O','2023-01-01 10:10','2023-01-01 23:11','FRED','USER003')
,('O','2023-01-01 10:10','23:59','FRED','USER004')
,('O','2023-01-01 10:10','21:59','FRED','USER005')
,('O','2023-01-01 10:10','22:00','FRED','USER006')
,('O','2023-01-01 10:10','20:00','FRED','USER007')
,('O','2023-01-01 10:10','20:01','FRED','USER008')
,('O','2023-01-01 10:10','19:59:59','FRED','USER009')
;
SELECT *, date('now','-1 day') AS comparedate, time > date('now','-1 day') AS comparison FROM request;
SELECT *, date('now','-1 day') AS comparedate, datetime1 > date('now','-1 day') AS comparison FROM request;
DROP table IF EXISTS request;
that you can run in your favourite SQLite tool (Navicat was used)
The resultant output (what would be in the Cursor) is :-
As can be seen if the time is actually stored as hh:mm or hh:mm:ss (or similar where you just have the time and not the date) then the first 2 characters are significant, so if the year of the current date - 1 day is in the 21st century that only times that are 8 pm (20:00) or greater would be selected.
Possible fix (if date column has the date only or the date and time and the time column has the time)
Perhaps you want "SELECT * from request WHERE datetime1 > date('now','-1 day')"
Possible debug action
If the above is not the fix for your situation then consider changing your code to :-
SQLiteDatabase db = dbHandler.getReadableDatabase();
String sql = "SELECT * from request /* WHERE time > date('now','-1 day') */"; // <<<<<<<<<< WHERE clause commented out to get ALL data, try also with WHERE clause */
Cursor rs = db.rawQuery(sql,null);
DatabaseUtils.dumpCursor(rs); /* ADDED FOR DEBUG, run and check the LOG */
if(rs.moveToFirst()) {
see comments
The log would include either something like (where data is extracted ):-
2022-07-19 13:21:50.995 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor#31816bf
2022-07-19 13:21:50.996 I/System.out: 0 {
2022-07-19 13:21:50.996 I/System.out: bloodgrp=O
2022-07-19 13:21:50.996 I/System.out: Datetime1=2023-01-01
2022-07-19 13:21:50.996 I/System.out: time=10:30
2022-07-19 13:21:50.996 I/System.out: Name=FRED
2022-07-19 13:21:50.996 I/System.out: Username=USER001
2022-07-19 13:21:50.996 I/System.out: }
2022-07-19 13:21:50.996 I/System.out: <<<<<
or (where no data has been extracted) :-
2022-07-19 13:24:12.216 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor#30380ea
2022-07-19 13:24:12.217 I/System.out: <<<<<
Note
The getColumnIndex index method is case sensitive (or at least was) and as such if any of the column names mismatch, even if only due to the case, then the trapped exception row 0 column -1 will also result in no result (only a short while to notice this with a Toast). I would suggest:-
using Constants for column names and ALWAYS using those Constants to refer to column names i.e. only ever hard code each column name once. Incorrect variables names will not compile. Coded incorrect column names will happily compile and may not be noticed.
consider using e.printStackTrace() as well as or even instead of the Toast
trapping and catching SQLite errors can so easily mask issues
Example
based upon your code, but with :-
DBhandler and layouts composed from what can be gleaned from your code AND
with it inserting a row when the database is created as per :-
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
REQUEST_COLUMN_BLOODGROUP + " TEXT" +
"," + REQUEST_COLUMN_DATE + " TEXT" +
"," + REQUEST_COLUMN_TIME + " TEXT" +
"," + REQUEST_COLUMN_NAME + " TEXT " +
"," + REQUEST_COLUMN_USERNAME + " TEXT" +
"," + REQUEST_COLUMN_CONTACTNo + " TEXT" +
"," + REQUEST_COLUMN_MESSAGE + " TEXT" +
")");
ContentValues cv = new ContentValues();
cv.put(REQUEST_COLUMN_BLOODGROUP,"O");
cv.put(REQUEST_COLUMN_DATE,"2023-01-01");
cv.put(REQUEST_COLUMN_TIME,"10:30");
cv.put(REQUEST_COLUMN_NAME,"FRED");
cv.put(REQUEST_COLUMN_USERNAME,"USER001");
cv.put(REQUEST_COLUMN_CONTACTNo,"0000000000");
cv.put(REQUEST_COLUMN_MESSAGE,"MESSAGE X");
db.insert(TABLE_NAME,null,cv);
}
with the Request (changed to capitalise) Activity started directly from the MainActivity
and with the possible fix applied to the WHERE clause (i.e. Datetime column used for the comparison rather than the time column)
The ListView with a Teal background (to distinguish it)
Then when run :-
and then when the item is clicked:-
and if OK is clicked :-
I have an app where a user can create/login an account, when the user logs in, I pass their valid email as an intent to the main/landing activity .
I also have another activity for the user profile, from which I pass the intent from the landing activity (the user email).
With the user email I created queries to get all the user projects (it's a PM tool kind of thing) - in my landing activity i have a fragment also where I use these queries based on the user email.
In my user profile activity i also created queries to get the users details (name, email etc) to show in their profile where they can change it etc.
========
The issue is, initially when I log in with valid details and I'm brought to the landing activity, I get the users projects which is great, I can also navigate to the users profile activity and I get the users details which is what I want.
Then when I move back to the landing activity my intent (users emaill) which was passed from the Login activity is no longer valid, so I do not get any results from my DB queries and when I move back to the profile activity the intent is null so i can't get the current user anymore.
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.ppmtoolmobile.model.User.getFirstName()' on a null object reference
I wanted some advice on how to handle this to avoid getting NPE when moving back and forth.
I removed the variables for components to make it more readable, but I have initialized them all etc..
Landing Activity / ProjectActivity.java
public class ProjectActivity extends AppCompatActivity implements View.OnClickListener, MyRecyclerAdapter.OnProjectClickListener {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_project);
// My dao implementation with DB queries
daoHelper = new DaoHelper(this);
// getting current username through intent from LoginActivity.class
authenticatedUser = getIntent().getStringExtra("authenticatedUser");
Toast.makeText(this, "project activity: " + authenticatedUser, Toast.LENGTH_SHORT).show();
// current user id
userId = daoHelper.getCurrentUserId(authenticatedUser);
// Getting users first name and amount of projects (This will be displayed in the heading of the main screen)
userFirstName = daoHelper.getCurrentUserFirstName(authenticatedUser);
projectCount = daoHelper.getProjectCount(userId);
welcomeUserTextView1.setText("Welcome " + userFirstName + ", " + userId);
displayUserProjectCountTextView.setText("You currently have " + projectCount + " projects");
loadFragment(new ProjectFragment());
// Perform item selected listener
bottomNavView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch(item.getItemId())
{
case R.id.nav_profile:
Intent goToProfileActivityIntent = new Intent(ProjectActivity.this, ProfileActivity.class);
goToProfileActivityIntent.putExtra("authenticatedUser", authenticatedUser);
startActivity(goToProfileActivityIntent);
overridePendingTransition(0,0);
return true;
case R.id.nav_home:
return true;
case R.id.nav_settings:
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
overridePendingTransition(0,0);
return true;
}
return false;
}
});
}
}
ProfileActivity.java
public class ProfileActivity extends AppCompatActivity implements View.OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
// getting current username through intent from ProjectActivity.class
authenticatedUser = getIntent().getStringExtra("authenticatedUser");
Toast.makeText(this, "profile activity: " + authenticatedUser, Toast.LENGTH_SHORT).show();
daoHelper = new DaoHelper(this);
loadUserDetails();
// Perform item selected listener
bottomNavView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch(item.getItemId())
{
case R.id.nav_home:
startActivity(new Intent(getApplicationContext(), ProjectActivity.class));
overridePendingTransition(0,0);
return true;
case R.id.nav_profile:
return true;
case R.id.nav_settings:
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
overridePendingTransition(0,0);
return true;
}
return false;
}
});
}
private void loadUserDetails() {
// I get NPE here when moving from ProjectActivity for the second time
User user = daoHelper.getUserDetails(authenticatedUser);
profileFirstNameEditText.setText(user.getFirstName());
profileLastNameEditText.setText(user.getLastName());
profileEmailAddressEditText.setText(user.getEmailAddress());
}
}
DaoHelper.java methods
// get user details
public User getUserDetails(String theEmailAddress) {
SQLiteDatabase db = this.getReadableDatabase();
User user = null;
Cursor cursor = db.query(USER_TABLE,// Selecting Table
new String[]{COLUMN_USER_ID, COLUMN_USER_FIRST_NAME, COLUMN_USER_LAST_NAME, COLUMN_USER_EMAIL_ADDRESS, COLUMN_USER_PASSWORD},//Selecting columns want to query
COLUMN_USER_EMAIL_ADDRESS + " = ?",
new String[]{String.valueOf(theEmailAddress)},//Where clause
null, null, null);
System.out.println("cursor count: " + cursor.getCount());
if(cursor.moveToNext()) {
long userId = cursor.getLong(0);
String firstName = cursor.getString(1);
String lastName = cursor.getString(2);
String emailAddress = cursor.getString(3);
String password = cursor.getString(4);
user = new User(userId, firstName, lastName, emailAddress, password);
}
return user;
}
// get project count of user
public int getProjectCount(long userId) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + PROJECT_TABLE + " WHERE " + COLUMN_USER_PROJECT_FK + " = ?", new String[]{String.valueOf(userId)})
return cursor.getCount();
}
// get all of users projects
#RequiresApi(api = Build.VERSION_CODES.O)
public List<Project> getUserProjects(long userId) {
SQLiteDatabase db = this.getReadableDatabase();
List<Project> projectList = new ArrayList<>();
Cursor cursor = db.rawQuery("SELECT * FROM " + PROJECT_TABLE + " WHERE " + COLUMN_USER_PROJECT_FK + " = ?", new String[]{String.valueOf(userId)});
while(cursor.moveToNext()) {
long id = cursor.getLong(0);
String title = cursor.getString(1);
String description = cursor.getString(2);
String dateCreated = cursor.getString(3);
String dateDue = cursor.getString(4);
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
LocalDateTime dateCreatedFormatted = LocalDateTime.parse(dateCreated, formatter);
LocalDateTime dateDueFormatted = LocalDateTime.parse(dateDue, formatter);
String priority = cursor.getString(5);
String checklist = cursor.getString(6);
int theUserId = cursor.getInt(7);
Project project = new Project(id, title, description, dateCreatedFormatted, dateDueFormatted, priority, checklist, theUserId);
projectList.add(project);
}
return projectList;
}
The problem here is, your are starting another ProjectActivity instance in your ProfileActivity's onNavigationItemSelected listener of bottomNavView, which has no arguments (startActivity(new Intent(getApplicationContext(), ProjectActivity.class));)
That's why in your second instance of ProjectActivity, it has no value for parameter authenticatedUser and returning empty string.
You can fix this by modifying code of bottomNavView's onNavigationItemSelected listener in your ProfileActivity class.
Replace your switch case logic for id R.id.nav_home like below in ProfileActivity class
case R.id.nav_home:
finish();
overridePendingTransition(0,0);
return true;
Or, if you want to keep multiple instance of same activity (ProjectActivity and ProfileActivity), then you can add parameter to Intent instance in ProfileActivity's bottomNavView's itemSelectedListener.
In that case, your code would become something like below
case R.id.nav_home:
Intent goToProjectActivity = new Intent(ProfileActivity.this, ProjectActivity.class);
goToProjectActivity.putExtra("authenticatedUser", authenticatedUser);
startActivity(goToProjectActivity);
overridePendingTransition(0,0);
return true;
I am using Google auth via firebase and am logging the users in successfully. I also have retrieved the list of contacts from the phonebook (device) and displaying it on a listview in a fragment in my app. But now I wish to show the users amongst my contacts who have my app installed, so that when clicked on they will go to the private chat with them, the other contacts, when clicked on will enable them to send an app invite. In a nutshell: I want to view the list of contacts who have the app installed on their device.
I was able to achieve this in three straightforward steps.
Get a list of your phone contacts
Get a list of all the phone numbers on Firestore
Compare the two lists and return common elements.
In order to use my approach, you need to have a collection on Firestore that has the phone number of all your users as documents just like the image below:
Here are the steps:
Step 1: I got a list of all the user's contacts by using ContentResolver. You can use the method below to retrieve this list provided you have the READ_CONTACTS permission granted.
public ArrayList<String> getContacts(ContentResolver cr) {
// list to be returned
ArrayList<String> numbers = new ArrayList<>();
// cursor
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if ((cur != null ? cur.getCount() : 0) > 0) {
while (cur != null && cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
if (cur.getInt(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
while (pCur.moveToNext()) {
String phoneNo = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.i(TAG, "Name: " + name);
numbers.add(formatRightWay(phoneNo));
}
pCur.close();
}
}
}
if(cur!=null){
cur.close();
}
return numbers;
}
Step 2: I got a list of all the phone numbers on Firestore by fetching the document IDs of the user collection. Here's a quick implementation:
firestore.collection("users").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
List<String> list = new ArrayList<>();
for (QueryDocumentSnapshot document : task.getResult()) {
list.add(document.getId());
}
// this is the list you need
Log.d(TAG, list.toString());
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
Step 3: Write a method that compares the two lists and returns similar elements.
public static ArrayList<String> shuffleBothLists(ArrayList<String> phoneContacts, List<String> firebaseContacts) {
ArrayList<String> result = new ArrayList<>();
for(String s: firebaseContacts) {
if(phoneContacts.contains(s) && !result.contains(s)) {
result.add(s);
}
}
return result;
}
The list returned by the method above are your contacts that have the app installed.
Cheers!
It is not possible to list the contacts directly. You need to create one node for users in firebase database to store users details after registration and then you can retrieve those user details.
I am getting you in means that you are using firebase. Now you want to upload all contacts to your server in firebase databse by your app if installed in one's device.
Try below code:
public class YourActivity extends AppCompatActivity {
ProgressDialog dialog;
DatabaseReference yourReference;//your database reference
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
yourReference = FirebaseDatabase.getInstance().getReference().child("users");
setContentView(R.layout.activity_your);
dialog = new ProgressDialog(this);
dialog.setMessage("Uploading contacts...");
// Query for contacts through content resolver. You will get a cursor.
Cursor contacts = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
},
null,
null,
null
);
// If you have a list as your data, firebase facilitates you to upload that easily by a single HashMap object. Create a HashMap object.
HashMap<String,Object> map = new HashMap<>();
// Loop contacts cursor with map to put all contacts in map. I used contact name as key and number as its value (simple and pretty way).
if(contacts!=null) {
while(contacts.moveToNext()){
map.put(
contacts.getString(contacts.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)),
contacts.getString(contacts.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
);
}
contacts.close();
}
dialog.show();
//write map to firebase database reference...
yourReference.updateChildren(map)
//this onSuccessListener is optional. You can terminate above line of code by ";" (semicolon).
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
dialog.dismiss();
Toast.makeText(YourActivity.this, "Contacts uploaded suffessfully!", Toast.LENGTH_SHORT).show();
}
})
//this onFailureListener is also optional.
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
dialog.dismiss();
Log.w("MKN","Error: "+e.getMessage());
Toast.makeText(YourActivity.this, "Contacts upload failed.", Toast.LENGTH_SHORT).show();
}
});
}
}
You will need to provide READ_CONTACTS permission to query Contacts table.
Also in firebase rules, value for "write" key must be "true" to write to the database.
First retrieve the contact list ..
'ContentResolver cr = getContext().getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
Cursor cur1 = cr.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
new String[]{id}, null);
while (cur1.moveToNext()) {
//to get the contact names
HashMap<String, String> map = new HashMap<>();
String name=cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String email = cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
if( email != null ){
map.put("name", name);
map.put("email", email);
getContactList.add(map);
}
}
cur1.close();
}
}'
After this you can maintain a firebase database table that can store authenticated user's information, you can sync your contacts with the list you fetch from firebase user's database.
'mapChat = new HashMap<>();
Log.d("Debug", clist.toString());
userReference1 = FirebaseDatabase.getInstance().getReference().child("Users");
userReference1.keepSynced(true);
userReference1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (int x = 0; x < clist.size(); x++) {
//Log.d("Debug" ,list.get(x).get("email").toString());
for (DataSnapshot dsp : dataSnapshot.getChildren()) {
if (dsp.hasChild("email")) {
// Log.d("Debug" , "setnewuser " + dsp.child("email").getValue().toString());
if (dsp.child("email").getValue().toString().equals(clist.get(x).get("email").toString())) {
Log.d("Debug", "contact updated");
String uid = dsp.getKey().toString();
reference1 = FirebaseDatabase.getInstance().getReference().child("Users").child(id).child("contacts").child(uid);
mapChat.put("name", clist.get(x).get("name"));
mapChat.put("email", clist.get(x).get("email"));
mapChat.put("chats", "false");
reference1.setValue(mapChat);
}
}
}
}
reference1.onDisconnect();
contactIdInterface1.contactUpdated();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});'
Enable and Implement Phone number sign in method in firebase, so u can retrieve the contacts from firebase and compare it will local contact list after that its easy to implement ur logic
new to Java here :)
The problem I'm facing is that I am unable to display the database from the Main Activity with a click of a button. The data in the database is being passed from another activity, would like to know if I'm missing anything or how would I go about fixing this. Thanks :)
(Method being used in the Main Activity after the onCreate)
MainActivity
public void displayDataInTable() {
roomDatabase myOpenHelper;
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
String status = bundle.getString("status");
String roomValue =bundle.getString("roomValue");
//List for the name of the players and their scores
List<String> roomNumber = new ArrayList<String>();
List<String> roomStatus = new ArrayList<String>();
//The data being read from the database
myOpenHelper = new roomDatabase(this, DATABASE_NAME, null, VERSION_NUMBER);
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
Cursor cursor = db.query(roomDatabase.TABLE_NAME, null, null, null, null, null,null,null);
//The name and the score is printed on the row of the list
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor.getColumnIndex("_id"));
String roomValueA = cursor.getString(cursor.getColumnIndex("roomValue"));
String statusA = cursor.getString(cursor.getColumnIndex("status"));
roomNumber.add(roomValueA);
roomStatus.add(" Recipe Ordered " + statusA);
}
//The items to de displayed are sent to the AdapterB
if ((roomNumber != null) && (roomStatus != null)) {
AdapterB adapter = new AdapterB(this, roomNumber, roomStatus);
setListAdapter(adapter);
}
}
LogsActivity
public class LogsActivity extends ListActivity{
roomDatabase myOpenHelper;
final String DATABASE_NAME = "roomstatus.db";
final int VERSION_NUMBER = 1;
ContentValues values1 = new ContentValues();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//variables are extracted from the bundle
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
String status = bundle.getString("status");
String roomValue = bundle.getString("roomValue");
myOpenHelper = new roomDatabase(this, DATABASE_NAME, null, VERSION_NUMBER);
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
values1.put("status", status);
values1.put("roomValue", roomValue);
Toast.makeText(LogsActivity.this, status, Toast.LENGTH_LONG).show();
//Data is entered into the table
db.insert(roomDatabase.TABLE_NAME, null, values1);
Intent newIntentBundle = new Intent(LogsActivity.this, MainActivity.class);
Bundle bundleA = new Bundle();
bundle.putString("status", status);
bundle.putString("roomValue", roomValue);
newIntentBundle.putExtras(bundle);
startActivity(newIntentBundle);
}
}
NOTE - I am aware this may not be right way to do as it would mean creating a new database in the Main Activity and trouble with the adapter, so any help would be appreciated. :)
These are the methods to save and fetch in RoomDatabase class:-
public boolean addDetails(String status,String roomValue){
SQLiteDatabase db=this.getWritableDatabase();
ContentValues values=new ContentValues();
values.put(KEY_STATUS,status);
values.put(KEY_ROOMVALUE,roomValue);
db.insert(TABLE_NAME,null,values);
db.close();
return true;
}
public List<String> getAllDetail(){
List<String> detailList=new ArrayList<>();
SQLiteDatabase db=this.getReadableDatabase();
Cursor cursor=db.rawQuery("select * from "+TABLE_NAME,null);
String status,roomValue;
if(cursor.moveToFirst()){
do{
status=cursor.getString(cursor.getColumnIndex(KEY_STATUS));
roomValue=cursor.getString(cursor.getColumnIndex(KEY_ROOMVALUE));
detailList.add(status);
detailList.add(roomValue);
}while (cursor.moveToNext());
}
return detailList;
}
In your activity where you have to save in db:
RoomDatabase roomDatabase=new RoomDatabase(getContext());
roomDatabase.addDetails(status,roomValue);
In your activity where you have to retrieve from db:
RoomDatabase roomDatabase=new RoomDatabase(getContext());
List<String> detailList=db.getAllDetail();
in detailList you can get the values.
Create a separate class for Database. Here are some links to how to create SQLite database in android.
http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/
https://developer.android.com/training/basics/data-storage/databases.html
I am trying to get contacts from call log. I can get the contact numbers from main contacts using this code :
public void getContacts(View view) {
Intent intentContact = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intentContact, 0);
}
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
if (requestCode == 0)
{
try {
to.setText(getContactInfo(intent));
} catch(NullPointerException e) {
// Do nothing ;)
}
}
}
protected String getContactInfo(Intent intent)
{
String phoneNumber = to.getText().toString();
Cursor cursor = managedQuery(intent.getData(), null, null, null, null);
while (cursor.moveToNext())
{
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
if(phoneNumber.endsWith(">"))
phoneNumber += ", "+name;
else
phoneNumber += name;
String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
if ( hasPhone.equalsIgnoreCase("1"))
hasPhone = "true";
else
hasPhone = "false" ;
if (Boolean.parseBoolean(hasPhone))
{
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,null, null);
while (phones.moveToNext())
{ phoneNumber = phoneNumber + " <" + phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))+">";
}
phones.close();
}
}
cursor.close();
return phoneNumber;
}
What this does is when we click a "Contact" button it open a list with all the contacts, the user can select any contact and that selected contact will be added in the "To" field. I want to do the exactly same thing, but instead of displaying all the contacts i want to display only those who were recently used (call log) for selection.
Also it would be nice if you can tell how to do this with groups also.
I got this going using my own version. i used a dialog and handed it the cursor to the call log. Here is the function:
public void getCallLog() {
String[] callLogFields = { android.provider.CallLog.Calls._ID,
android.provider.CallLog.Calls.NUMBER,
android.provider.CallLog.Calls.CACHED_NAME /* im not using the name but you can*/};
String viaOrder = android.provider.CallLog.Calls.DATE + " DESC";
String WHERE = android.provider.CallLog.Calls.NUMBER + " >0"; /*filter out private/unknown numbers */
final Cursor callLog_cursor = getActivity().getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, callLogFields,
WHERE, null, viaOrder);
AlertDialog.Builder myversionOfCallLog = new AlertDialog.Builder(
getActivity());
android.content.DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int item) {
callLog_cursor.moveToPosition(item);
Log.v("number", callLog_cursor.getString(callLog_cursor
.getColumnIndex(android.provider.CallLog.Calls.NUMBER)));
callLog_cursor.close();
}
};
myversionOfCallLog.setCursor(callLog_cursor, listener,
android.provider.CallLog.Calls.NUMBER);
myversionOfCallLog.setTitle("Choose from Call Log");
myversionOfCallLog.create().show();
}
You can use ContactsContract.Contacts.CONTENT_STREQUENT_URI which will give you both Frequently called and Starred contacts.
From API 21 is possible to use this: https://developer.android.com/reference/kotlin/android/provider/CallLog.Calls#CACHED_LOOKUP_URI
CACHED_LOOKUP_URI added in API level 21 static val CACHED_LOOKUP_URI:
String The cached URI to look up the contact associated with the phone
number, if it exists.
This value is typically filled in by the dialer app for the caching
purpose, so it's not guaranteed to be present, and may not be current
if the contact information associated with this number has changed.