I'm trying to compare the value of Markers with an id in my pre-made SQLite database. The reason being is so that I can have specific details for specific markers.
For example:
If the marker clicked has id = 1 then I wish to search the database for id '1' and then grab the details from that row. I thought it was simple enough to just loop through the database, but this doesn't seem to be working. My current code is:
final Cursor dbId = monDatabase.database.rawQuery("SELECT _id from monuments", null);
int idColumnCount = dbId.getColumnCount();
dbId.moveToFirst();
while(dbId.isAfterLast() == false) {
for(int f = 0; f < idColumnCount; f++) {
mainMarkerId = dbId.getInt(0);
map.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker marker) {
if(marker.getId().equals("m" + mainMarkerId)){
Log.v("marker.getId()", "the id is: " + marker.getId());
selectDesc = monDatabase.database.rawQuery("SELECT description from monuments WHERE _id = " + mainMarkerId, null);
selectDesc.moveToFirst();
_description = selectDesc.getString(0);
Intent descriptionIntent = new Intent(MainActivity.this, DisplayData.class);
descriptionIntent.putExtra(EXTRA_MESSAGE, _description);
startActivity(descriptionIntent);
markerId.moveToNext();
}
}
});
dbId.moveToNext();
}
}
I'm unsure if it is possible this way, or maybe I have to use a Hashmap or something.
Any help is much appreciated,
Thanks!
EDIT:
I forgot to mention that I have all the Markers already displayed on the maps, so it's more of a case of being able to get the description for that location and then passing it through to a new Intent.
SOLUTION:
Just thought I'd post the solution on here if anyone else needed it. I didn't need a Hashtable, all I used was:
selectDesc = monDatabase.database.rawQuery("SELECT description from monuments WHERE title = '" + marker.getTitle() + "'", null);
No need for all the for loops or anything. Very very simple!
your best bet is to create a HashMap of the database elements using the database id as the key and the marker as the value so then you can pull from your database and have what marker you need
Related
how to get the proper way or ShortCut or fastest way retrieving data of particular child from the firebase
baseRef.Child ("wordRun").Child("Players").Child(userid).Child("GameRun").Child("usercount").GetValueAsync ();
I try like something:-
example 1
var getTask =baseRef.Child ("wordRun").Child("Players").Child(userid).Child("GameRun").Child("usercount").GetValueAsync ();
yield return new WaitUntil(() => getTask.IsCompleted || getTask.IsFaulted);
if (getTask.IsCompleted) {
Debug.Log(getTask.Result.Value.ToString());
}
example 2:-
baseRef.Child("wordRun").Child("Players").Child(userid).Child("GameRun").Child("usercount").GetValueAsync .ContinueWith(task => {
if (task.IsFaulted) {
// Handle the error...
}
else if (task.IsCompleted) {
DataSnapshot snapshot = task.Result;
foreach ( DataSnapshot user in snapshot.Children){
IDictionary dictUser = (IDictionary)user.Value;
Debug.Log ("" + dictUser["usercount"]);
}
}
});
I want to get values write a single line in firebase database if anyone knew how got value in a single line in firebase then please give answer thank you for reading...
And Please Give me a way to get all data back in a class by getting GetRawJsonValue
you need to getting by the loop
foreach (var childSnapshot in args.Children) {
Debug.Log("ChildSnapshot"+childSnapshot..GetRawJsonValue());
}
and if you have any Class which have same data format then you try this
ClassName ClassObjectName = JsonUtility.FromJson<ClassName>(args.Snapshot.GetRawJsonValue());
Bounty Award - The bounty will be awarded to an answer that gets from a populated Telephony.Sms.Inbox.PERSON value, to the associated Contact using only ContractsContact tables.
I'm reading SMS messages in the standard way in my application:
final String[] projection = {Telephony.Sms.Inbox.BODY,
Telephony.Sms.Inbox.ADDRESS,
Telephony.Sms.Inbox.READ,
Telephony.Sms.Inbox.DATE,
Telephony.Sms.Inbox.PERSON};
final Cursor cursor = ctx.getContentResolver().query(Telephony.Sms.Inbox.CONTENT_URI,
projection, null, null, Telephony.Sms.Inbox.DEFAULT_SORT_ORDER);
When populated, the id returned from the index Telephony.Sms.Inbox.PERSON relates to the id of the deprecated Contacts.People._ID and can be used to query further contact information in the following way:
final String[] projection = {Contacts.People.DISPLAY_NAME};
final String[] selectionArgs = {contactId};
final Cursor cursor = ctx.getContentResolver().query(Contacts.People.CONTENT_URI,
projection, Contacts.People._ID + " = ?", selectionArgs, null);
Why would the relatively new Telephony API use deprecated tables, instead of ContactsContract?
Telephony.Sms.Inbox.PERSON documentation states:
Type: INTEGER (reference to item in content://contacts/people)
I've tried unsuccessfully (but not unsurprisingly?) to find a mapping to the id in any of the ContactsContract id fields, so I'm left having to use deprecated APIs in order to resolve the queries I need to perform quickly.
Such queries include searching for messages by a particular contact, for which I only have the name. The contact could have multiple numbers, which may not be in the correct format to potentially match Telephony.Sms.Inbox.ADDRESS entries.....
The workaround of using Telephony.Sms.Inbox.ADDRESS and ContactsContract.PhoneLookup is not the end of the world when going from the number to the contact, but I still feel I must be missing something here?
Here is the process I'm using to get the messages for 'Joe Bloggs'.
1) Query the ContactsContract table to confirm a contact by the name of Joe Bloggs exists on the device - or get a close match if the contact is actually listed as 'Joe Blogs'.
2) Using the confirmed name, I query the deprecated Contact.People table to get all associated ids for the contact in the following way:
final String selection = Contacts.People.DISPLAY_NAME + " LIKE ?";
final String[] projection = {Contacts.People.DISPLAY_NAME,
Contacts.People._ID};
final String[] selectionArgs = {contactName};
final Cursor cursor = ctx.getContentResolver().query(Contacts.People.CONTENT_URI,
projection, selection, selectionArgs, null);
3) Using the list of deprecated contact ids, I query the message table as so:
final String[] referredArgs = new String[contactIdArray.size()];
for (int i = 0; i < contactIdArray.size(); i++) {
referredArgs[i] = contactIdArray.get(i);
}
final String referredSelection = Telephony.Sms.Inbox.PERSON + " IN "
+ "(" + TextUtils.join(",", referredArgs) + ")";
final String[] projection = {Telephony.Sms.Inbox.BODY,
Telephony.Sms.Inbox.ADDRESS,
Telephony.Sms.Inbox.READ,
Telephony.Sms.Inbox.DATE,
Telephony.Sms.Inbox.PERSON};
final Cursor cursor = ctx.getContentResolver().query(Telephony.Sms.Inbox.CONTENT_URI,
projection, referredSelection, null, Telephony.Sms.Inbox.DEFAULT_SORT_ORDER);
I'm hoping someone will tell me I'm going round the houses here and there is a more obvious solution using current APIs. I don't consider iterating the entire message table using ContactsContract.PhoneLookup an optimised solution.
Thanks in advance.
I wouldn't use the Telephony.Sms.Inbox.PERSON field, and definitely wouldn't query the deprecated People apis if I were you.
The People apis had been deprecated for so long you can't count on all devices our there to properly support it anymore.
First thing you need to understand is that there isn't a one-to-one link between sms and contacts.
An SMS can come from a non-contact phone number, a single contact, multiple contacts, a mixture of contacts and non-contacts, alpha-numeric ids, and even other, more rare options.
Next thing, you should read carefully the stock code and how it handles a properly called "Recipient ID" that you can get from the SMS collection, there's a collection called canonical-addresses (or canonical-address) that serves as a mapping between a phone number (or a comma-separated list of phones) and a recipient id.
The code does a single query on launch to cache the entire table in memory, and then uses it to map between phones and recipient-ids.
Here's the mapping class
Why would the relatively new Telephony API use deprecated tables, instead of ContactsContract?
What you are referring to is not new. In Telephony.java, you see it relies on the existing content://sms provider:
public static final class Inbox implements BaseColumns, TextBasedSmsColumns {
/**
* The {#code content://} style URL for this table.
*/
public static final Uri CONTENT_URI = Uri.parse("content://sms/inbox");
It was already there in Donut (and probably before, but I didn't check).
What's new in Kitkat is the ability to change the SMS app.
It's been five years and it's still relevant. You still need to do endlessly phoneLookup and hang up callbacks on contact tables if all you need to do is synchronize text messages.
I do not understand your concern properly but I am working on similar project, here is the basic code, and basic, important columns for fetching and display a message:
ContentResolver contentResolver = getContentResolver();
final String[] projection = new String[]{"*"};
Cursor SMSL = contentResolver.query(Telephony.Sms.CONTENT_URI, projection, null, null, "date ASC");
int msgscount = SMSL.getCount();
if (msgscount>0) {
msgs = new String[SMSL.getCount()][msgs_column_count];
int i = 0;
while (SMSL.moveToNext()) {
progress.setProgress(i);
msgs[i][0] = SMSL.getString(SMSL.getColumnIndex("address"));
msgs[i][1] = SMSL.getString(SMSL.getColumnIndex("date_sent"));
msgs[i][2] = SMSL.getString(SMSL.getColumnIndex("date"));
msgs[i][3] = SMSL.getString(SMSL.getColumnIndex("type"));
msgs[i][4] = SMSL.getString(SMSL.getColumnIndex("body"));
msgs[i][5] = SMSL.getString(SMSL.getColumnIndex("read"));
if (SMSL.getString(SMSL.getColumnIndex("service_center")) != null){
msgs[i][6] = SMSL.getString(SMSL.getColumnIndex("service_center"));
}else{
msgs[i][6] = "";
}
i++;
}
SMSL.close();
}else{
msgs = new String[0][0];
Toast.makeText(getApplicationContext(),"No messages found!",Toast.LENGTH_LONG).show();
}
If you want any help with this or fetching messages, let me know.
In my endWorkout.java file, I am saving data into my Parse database using the following logic:
// Parse Storage
ParseObject testObject = new ParseObject("TestOne");
testObject.put("Device", ParseInstallation.getCurrentInstallation());
testObject.put("Reps", inputList);
testObject.saveInBackground();
Where I am first storing my Device ID for authentication purposes, and then storing inputList which is an ArrayList of integers.
In my Parse database, the data is properly saved, as shown below:
Now in my MainActivity.java, I would like to retrieve all the data in the Reps field of the Parse database for a single device. For example, the device yhmrKgokfS has 6 Arrays in the Parse database, I would like to sequentially retrieve each of them to display in a ListView on the screen.
Here is the logic I am trying to use:
List<ParseObject> importList = new ArrayList<ParseObject>();
//parse import list
ParseQuery<ParseObject> query = ParseQuery.getQuery("TestOne");
query.whereEqualTo("Device", ParseInstallation.getCurrentInstallation());
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> repList, ParseException e) {
if (e == null) {
Log.d("Reps", "Retrieved " + repList.size() + " reps");
} else {
Log.d("Reps", "Error: " + e.getMessage());
}
}
});
importList = repList;
I first want to make sure I'm importing from the current device, so I need to check if the Device field matches ParseInstallation.getCurrentInstallation(). Then I want to go ahead and get the first Reps array. However the last line importList = repList; does not work.
How can I go about achieving what I'm trying to do?
query.findInBackground works in asynchronous way. In other words, the line that you set the importList is executed after the line query.findInBackground. However, the query.findInBackground will make a network call that takes time. So if you want to use the repList when it is ready, you have to use it in done method where you are use the network call is done. Hope this helps.
Regards.
As #kinkspeech mentioned you need to move your line importList = repList; to your callback. And I suggest that you change it as follows:
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> repList, ParseException e) {
if (e == null) {
Log.d("Reps", "Retrieved " + repList.size() + " reps");
importList.addAll(replist);
} else {
Log.d("Reps", "Error: " + e.getMessage());
}
}
});
I have this simple application that I'm currently writing as practice. Its purpose is to allow the user to send a quote and the author of that quote on a server (in this case a Parse.com backend I have registered) and then show those quotes to other users of the app randomly. So by opening the app, you get a random comment that someone has posted.
The way I'm trying to accomplish this is:
On start-up, the app connects to the Parse.com backend and downloads all the currently available quotes (I call those Inanity objects because the quotes are supposedly enlightened but should actually be stupid and nonsensical - anyway, doesn't matter). This is the code:
query.findInBackground(new FindCallback<ParseObject>() {
SQLi sqlite = new SQLi(MainActivity.this);
SQLiteDatabase dbz = sqlite.getWritableDatabase();
#Override
public void done(List<ParseObject> list, ParseException e) {
//sqlite.dbDelete();
if (e == null) {
int size = list.size();
for (int i = 0; i < size; i++) {
ParseObject object = list.get(i);
String author = object.get("author").toString();
String content = object.get("content").toString();
Inanity inan = new Inanity(content, author, 1);
Log.d("FOR LOOP" + i, inan.toString());
sqlite.insertInanity(dbz, inan);
}
}
}
});
Pretty simple. (dbz is an SQLiteDatabase acquired by calling getWritableDatabase(), by the way). The code below is the code for the SQLiteOpenHelper insertInanity() method that I use to put the retrieved data from the server in the local SQLite database:
public void insertInanity(SQLiteDatabase db, Inanity inanity) {
ContentValues values = new ContentValues();
values.put(CONTENT_INANITIES, inanity.getContent());
values.put(AUTHOR_INANITIES, inanity.getAuthor());
values.put(UPVOTE_INANITIES, inanity.getUpvotes());
db.insert(TABLE_INANITIES, null, values);
}
I pass an SQLiteDatabase object to the method simply to avoid having to call getWriteableDatabase() - I had some trouble with recurring calls if I kept doing that.
After writing the server data on the local SQLite database, the user is taken to an Activity that starts showing the quotes and the author of the quotes in a couple of TextViews. This is the code the retrieves a quote/author object from the SQLite database:
public Inanity retrieveInanity(int id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_INANITIES, new String[] {
CONTENT_INANITIES, AUTHOR_INANITIES, UPVOTE_INANITIES },
ID_INANITIES + " = " + id, null, null, null, null);
if (cursor == null || cursor.getCount() == 0) {
return new Inanity("a", "b", 1);
}
else {
cursor.moveToFirst();
String contentL = cursor.getString(cursor
.getColumnIndex(CONTENT_INANITIES));
String authorL = cursor.getString(cursor
.getColumnIndex(AUTHOR_INANITIES));
int upvotesL = cursor.getInt(cursor
.getColumnIndex(UPVOTE_INANITIES));
Inanity inanity = new Inanity(contentL, authorL, upvotesL);
return inanity;
}
}
Finally, the quote to be displayed is randomly selected from the locally stored results thusly ("a" is an int variable declared earlier by the way)
final SQLi sql = new SQLi(this);
a = sql.getRowCount() + 1;
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Random rand = new Random();
int e = rand.nextInt(a);
if (e != 0) {
Inanity inanity = sql.retrieveInanity(e);
String content = inanity.getContent();
String author = inanity.getAuthor();
ImageView imageView = (ImageView) findViewById(R.id.downloaded);
TextView contentView = (TextView) findViewById(R.id.content);
TextView authorView = (TextView) findViewById(R.id.author);
Picasso.with(ShowActivity.this)
.load("http://img1.etsystatic.com/000/0/5356113/il_fullxfull.314192275.jpg")
.into(imageView);
contentView.setAlpha(0.9f);
authorView.setAlpha(0.9f);
Animation alpha = new AlphaAnimation(0.1f, 1.0f);
alpha.setDuration(2000);
contentView.setText(content);
authorView.setText(author);
contentView.startAnimation(alpha);
authorView.startAnimation(alpha);
}
else {
Toast.makeText(ShowActivity.this,
"Cursor trouble in wonderland!", Toast.LENGTH_LONG)
.show();
}
}
});
}
The getRowCount() method of the SQLi class is this:
public int getRowCount() {
int count = 1;
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_INANITIES, null);
if (cursor != null && cursor.getCount() > 0 && cursor.moveToFirst()) {
count = cursor.getCount();
}
return count;
}
For the most part. this works great. So, what's the problem, I hear you ask? Well, since I want to refresh the quotes every time the application starts up and get fresh ones from the server, the way I'm trying to accomplish that is by deleting the contents of the Inanity table of the database and re-populate them on start-up. So, I have created this method in the SQLi database helper class that's called dbDelete() which I call right at the start of the done() method of the FindCallback class of the Parse.com library (although I have commented this out from this code, it works swimmingly: it deletes the contents of the database just fine). Unfortunately, when I do that, it appears that the local SQLite database is not repopulated on app startup for some infernal reason, so I keep getting the placeholder "a", "b" and 1 values that are returned when the retrieveInanity() method cannot find cursor contents. Here is the dbDelete() method, which is quite simple:
public void dbDelete() {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_INANITIES, null, null);
}
I have been trying to solve this for quite some time and it's driving me crazy. I understand that the question is pretty convoluted, big and that it doesn't contain any catchy NullPointerExceptions/logcat action but any help would be appreciated. I must be missing something obvious related to the SQLite database use but I simply can't figure it out.
I wrote a similar app (one that made calls to a remote database and updated the info on local db). You should try using db.insertOrThrow. You will need to wrap the method in a Try...Catch statement. It will try to insert rows, and will throw an exception when a row already exists. You can then ignore the errors by leaving the Catch part blank. This will avoid the deletion and rebuild of the table.
try {
db.insertOrThrow(TABLE_INANITIES, null, values);
} catch SQLException s {
\\do nothing, as we don't care about existing rows
}
If you set up the quote server to have unique identifiers for the quote, then the local copy, your SQLite DB, will not insert duplicate entries. For example, your quote DB table on the server would look something like this
ID | Quote | Author
1 | blah | J. smith
Where the column ID is set as the unique identifier (or unique key). When your app calls the server and queries the remote DB, your local DB has only records that don't exist added to it.
You also want to make sure, I believe, that you update your cursor adapter in onResume().
i trying to insert my string into my database tables ,but it doesnt appear, so any advice on this how do i string my text so it able to appear on android database table
btnplayer = (Button) findViewById(R.id.button1);
tw1 = (TextView)findViewById(R.id.PX2);
btnplayer.setOnClickListener(new View.OnClickListener() {
SharedPreferences myPrefs = getSharedPreferences("PREF_COUNT", 0);
SharedPreferences.Editor myEditor = myPrefs.edit();
public void onClick(View v) {
String Player = myPrefs.getString("tw1",name);
DataStorage.this.btnplayer.setText("add name [" + Player + "]");
myEditor.putString("Player", Player);
myEditor.commit();
Please make your question more clear.
If you want store your data in database in android, you can go for SQLite database available in android http://developer.android.com/training/basics/data-storage/databases.html
but I suggest use sharedpreferences if only strings need to store.
I didn't get the meaning behind this statement String Player = myPrefs.getString("tw1",name); if you already have stored the same value (first time there will be no value so you will getting back the default "name" and then you will again store that name with the new key called "Player"). Where are you storing "tw1"? Exactly what issue you are facing?