Get data from sqlite on android - java

I an trying to fetch data from my SQLite database on Android. However, when I run the code and see the Android Monitor, I get this message:
04-14 15:27:27.737 11177-11177/com.example.daniel.toto E/CursorWindow: Failed to read row 0, column -1 from a CursorWindow which has 6 rows, 5 columns.
This is the method in the database helper class I use to get the data from the database:
public ArrayList<String> getAllSales() {
ArrayList<String> array_list = new ArrayList<String>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor res;
res = db.rawQuery( "select * from sales", null );
if (res != null) {
res.moveToFirst();
while (res.isAfterLast() == false) {
array_list.add(res.getString(res.getColumnIndex(SALES_TABLE_NAME)));
res.moveToNext();
}
return array_list;
} else {
array_list = null;
}
return array_list;
}
This is where I call it in onCreate method the activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sales);
mydb = new SalesDBHelper(this.getBaseContext());
array_list = mydb.getAllSales();
}

Thank you for deciphering the error message. Indeed the part of the error message column -1means: there is no such column.
Thank you a lot for pointing it out, it finally solved my problem!

Related

SQLLITE/ Android Studio Update Function Not Working

so I'm having some trouble with SQLLite/Android studio, I have an activity that lets me update a user's password through an SQLLite function but it doesn't seem to be working, when I press the update password button, nothing happens, and the database doesn't update.
SQLLITE Update:
public int updateShopper(Shopper shopper)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COL_SPPASS, shopper.getShopperPS());
String[] l = {shopper.getShopperID()+""};
return db.update(TABLE_NAME, values, COL_SPID + " =? ",l);
}
Get all shoppers :
public ArrayList<Shopper> getAllShoppers()
{
ArrayList splist = new ArrayList();
String selectQuery = "SELECT * FROM " + TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery(selectQuery, null);
if(c.moveToFirst())
{
do {
Shopper shopper = new Shopper();
shopper.setShopperUN(c.getString((c.getColumnIndex(COL_SPNAME))));
shopper.setShopperPS(c.getString(c.getColumnIndex(COL_SPPASS)));
splist.add(shopper);
} while(c.moveToNext());
}
return splist;
}
}
Activity Button :
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String username = ed1.getText().toString();
String password = ed2.getText().toString();
SQLShop sqlsp2 = new SQLShop(getApplicationContext());
ArrayList splist=sqlsp2.getAllShoppers();
for(int i=0;i<splist.size();i++)
{
Shopper sp=(Shopper) splist.get(i);
if(username.equalsIgnoreCase(sp.getShopperUN()))
{
Shopper shopper = new Shopper();
shopper.setShopperUN(username);
shopper.setShopperPS(password);
shopper.setShopperID(shopper.getShopperID());
sqlsp2.updateShopper(shopper);
break;
}
}
Intent i = new Intent(getApplicationContext(), MainActivity.class);
startActivity(i);
}
});
In your getAllShoppers() you're not setting the shopper id and it remains as 0. Trying to update a row with id 0 matches no rows, so no rows are updated.
After adding reading the shopper id from the database, fix this part too:
shopper.setShopperID(shopper.getShopperID());
Here you're assigning the id of a new Shopper back to itself so it stays as 0 default value. Change shopper.getShopperID() to sp.getShopperID().

Firebase: Android : How to show list of contacts who have the app Installed

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

passing data from one activity and displaying the database from the Main Activity

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

OnItemClickListener / SimpleDateFormat

I am working on a messaging app, and have made the conversation list show up fine, but am having trouble with my listview onitemclicklistner. I would like it to retrieve a textview (id=lblID), convert it to a string, then show the conversations list (with that string as the id) and display it in my listview.
Am I doing this correctly?
Solved the simplecursoradapter inside the onitemclicklistener wont let me use "this" as the context, what should I use instead?
I would like to use SimpleDateFormat, how would I do this between the cursor and adapter?
Solved I am now getting an error, does anyone no how to fix this?:
10-10 07:45:54.926 24231-24231/? E/AndroidRuntime: FATAL EXCEPTION: main
10-10 07:45:54.926 24231-24231/? E/AndroidRuntime: Process: com.example.wq.myapp, PID: 24231
10-10 07:45:54.926 24231-24231/? E/AndroidRuntime: android.database.sqlite.SQLiteException: near "*": syntax error (code 1): , while compiling: SELECT * FROM (SELECT DISTINCT date * 1 AS normalized_date, NULL AS * FROM sms WHERE (thread_id = 37 AND (type != 3)) UNION SELECT DISTINCT date * 1000 AS normalized_date, NULL AS * FROM pdu LEFT JOIN pending_msgs ON pdu._id = pending_msgs.msg_id WHERE (thread_id = 37 AND msg_box != 3 AND (msg_box != 3 AND (m_type = 128 OR m_type = 132 OR m_type = 130))) ORDER BY normalized_date desc) ORDER BY normalized_date desc
Here is my code:
#Override
public void onClick(View v) {
if (v == btnSMS) {
// Create Inbox box URI
Uri inboxURI = Uri.parse("content://mms-sms/conversations");
// Get Content Resolver object, which will deal with Content Provider
ContentResolver cr = getContentResolver();
// Fetch Inbox SMS Message from Built-in Content Provider
Cursor a = cr.query(inboxURI, new String[] {"*"}, null, null, "normalized_date desc");
// Attach Cursor with adapter and display in listView
adapter1 = new SimpleCursorAdapter(this, R.layout.row, a,
new String[]{ "body", "date", "address","_id"},
new int[]{ R.id.lblMsg, R.id.lblDate, R.id.lblNumber, R.id.lblID }, 0);
lvMsg.setAdapter(adapter1);
lvMsg.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView TVConvID = (TextView)findViewById(R.id.lblID);
String ConvID = TVConvID.getText().toString();
Uri ConvURI = Uri.parse("content://mms-sms/conversations/"+ConvID);
Cursor b = getContentResolver().query(ConvURI, new String[]{"*"}, null, null, "normalized_date desc");
adapter2 = new SimpleCursorAdapter(getApplicationContext(), R.layout.convrow, b,
new String[]{ "body", "date", "address" },
new int[]{ R.id.msglblMsg, R.id.msglblDate, R.id.msglblNumber }, 0);
lvMsg.setAdapter(adapter2);
}
});
}
Any help or extra knowledge would be greatly appreciated. :)
For 2:
SimpleCursorAdapter wants 'Context' as first Parameter. If you call 'this' in your OnItemClick method, your context is your OnItemClick.
If you are in a fragment, use getActivity(), or do this in your onCreate() method:
Context mContext = getActivity();
and use mContext as new SimpleCursorAdapter(mContext, .....);
In an activity, you can assign the variable mContext in onCreate like this:
Context mContext = this;
There are other methods like getApplicationContext() which you can try.

How to add Wi-Fi option in GPRS spinner

In my application i am using "apn" for GPRS connection display. I code a spinner in which i get the Telenor GPRS, Telenor MMS and Telenor WAP.
**I want to add Wi-Fi option in this spinner. and when i select Wi-Fi option device start sensing Wi-Fi.
Q: How can i add option of Wi-Fi in my spinner??
**
This is my Code
Spinner GPRS;
String [] name_of_GPRS__available;
int [] apn_id; public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.configuration);
EnumerateAPNs();
/* this is a android enviroment in which you can develop an android application in which you
* share all your basic necessities of thrkife bghhr4y2ghrrr*/
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
GPRS = (Spinner)findViewById(R.id.GPRS);
ArrayAdapter<?> spinner_array = new ArrayAdapter<Object>(this,android.R.layout.simple_dropdown_item_1line,name_of_GPRS__available);
spinner_array.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext());
Editor prefsEditor = prefs.edit();
prefsEditor.putString("Object", name_of_GPRS__available.toString());
prefsEditor.commit();
GPRS.setAdapter(spinner_array);
//GPRS.setOnItemSelectedListener(MyOnItemSelectedListener());
GPRS.setOnItemSelectedListener(new MyOnItemSelectedListener());`
GPRS.setAdapter(spinner_array);
//GPRS.setOnItemSelectedListener(MyOnItemSelectedListener());
GPRS.setOnItemSelectedListener(new MyOnItemSelectedListener());
public void onItemSelected(AdapterView<?> parent, View view,
final int position, long id) {
// An item was selected. You can retrieve the selected item using
// parent.getItemAtPosition(position)
SetDefaultAPN(apn_id[position]);
Toast.makeText(parent.getContext(), "ETracking System Selects " +
parent.getItemAtPosition(position).toString(), Toast.LENGTH_LONG).show();
}
public void onNothingSelected(AdapterView<?> parent) {
// Another interface callback
}
public boolean SetDefaultAPN(int id)
{
boolean res = false;
ContentResolver resolver = Configuration.this.getContentResolver();
ContentValues values = new ContentValues();
values.put("apn_id", id);
try
{
resolver.update(Uri.parse("content://telephony/carriers/preferapn"), values, null, null);
Cursor c = resolver.query(
Uri.parse("content://telephony/carriers/preferapn"),
null,
"_id="+id,
null,
null);
if(c != null)
{
res = true;
c.close();
}
}
catch (SQLException e)
{
//Log.d("TAG", e.getMessage());
}
return res;
}
/*
* Enumerate all APN data
*/
private void EnumerateAPNs()
{
Cursor c = this.getContentResolver().query(
Uri.parse("content://telephony/carriers/current"), null, null, null, null);
if (c != null)
{
//String s = "All APNs:\n";
//Log.d("TAG", s);
try
{
printAllData(c); //Print the entire result set
}
catch(SQLException e)
{
Toast.makeText(Configuration.this, "No Network Connection Available", Toast.LENGTH_LONG).show();
}
c.close();
}
}
/*
* Print all data records associated with Cursor c.
* Return a string that contains all record data.
* For some weird reason, Android SDK Log class cannot print very long string message.
* Thus we have to log record-by-record.
*/
private void printAllData(Cursor c)
{
//if(c == null) return null;
if(c.moveToFirst())
{
name_of_GPRS__available = new String[c.getCount()];
apn_id = new int [c.getCount()];
int i= 0;
do{
name_of_GPRS__available [i]= c.getString(c.getColumnIndex("name"));
apn_id[i]=c.getInt(c.getColumnIndex("_id"));
//Log.d("TAG",name[i]);
i++;
}while(c.moveToNext());
//Log.d("TAG","End Of Records");
//name_of_GPRS_available [1]=" GPRS";
}
}
Kindly guide me. How can i do it. I'll be very thankful to you
I assume that this is for a Gingerbread Device as Setting the Default APN was removed in ICS (4.0 - API 14), deprecated.
Have you tried adding in:
wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(true);
You will need to add these permissions to your Android Manifest:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
You can also have an additional Spinner come up to have the User select from available Wifi spots by using Scan Result: http://developer.android.com/reference/android/net/wifi/ScanResult.html
and then
WifiManager: http://developer.android.com/reference/android/net/wifi/WifiManager.html
to set the Desired Network if there is not a default connection in place.
Markana has a nice tutorial on using Wifi this way: http://marakana.com/forums/android/examples/40.html

Categories