I'm working on google maps project.Users can add location and view them on the gridview.When I run my app to view all locations from database,all indexes get retrived from database successfuly and pushed arraylist.But when I try to add location.All previous locations get added database again , then my desired location added end of the array.So when I try to reach desired location from gridview,it shows me first location.I want it to be repeated just once.I think there's problem on my select query.Here's output result.
Result
GridView gridView= (GridView) findViewById(R.id.gridView);
list = new ArrayList<>();
try {
MapsActivity.database = this.openOrCreateDatabase("Places",MODE_PRIVATE,null);
Cursor cursor = MapsActivity.database.rawQuery("SELECT * FROM places",null);
int nameIx = cursor.getColumnIndex("name");
int latitudeIx = cursor.getColumnIndex("latitude");
int longitudeIx = cursor.getColumnIndex("longitude");
while (cursor.moveToNext()) {
nameFromDatabase = cursor.getString(nameIx);
String latitudeFromDatabase = cursor.getString(latitudeIx);
String longitudeFromDatabase = cursor.getString(longitudeIx);
image = cursor.getBlob(3);
// names.add(nameFromDatabase);
Double l1 = Double.parseDouble(latitudeFromDatabase);
Double l2 = Double.parseDouble(longitudeFromDatabase);
// System.out.println("coordinates:"+l1+","+l2);
locationFromDatabase = new LatLng(l1, l2);
names.add(nameFromDatabase);
locations.add(locationFromDatabase);
list.add(new Location(nameFromDatabase, image));
}
cursor.close();
} catch (Exception e) {
e.printStackTrace();
}
adapter = new LocationListAdapter(this, R.layout.location_items, list);
gridView.setAdapter(adapter);
I suspect that your issue is that when adding a new location, your get all the locations again from google maps.
Your code doesn't include the code for adding a location.
However, you could prevent duplicated data by defining appropriate UNIQUE constraints for your Places Database.
As an example, based upon your code, you could CREATE the table using :-
CREATE TABLE IF NOT EXISTS places (name TEXT UNIQUE ON CONFLICT IGNORE,longitude REAL,latitude REAL,image BLOB, UNIQUE (longitude,latitude) ON CONFLICT IGNORE)
Using name TEXT UNIQUE ON CONFLICT IGNORE will add a restriction/rule/constraint that the name must be unique and if an attempt is made to use a name that already exists (insert or update) then that attempt will be ignored (no error raised).
Using UNIQUE (longitude,latitude) ON CONFLICT IGNORE does the same BUT for the combination of BOTH columns.
e.g. if a row in the table has latitude 1 and longitude 1 then :-
an attempt to add a row with latitude 1 and longitude 1 will result in the attempt being ignored.
an attempt to add a row with latitude 2 and longitude 1 will work as the combination of the two values has not been used.
likewise, an attempt to add a row with latitude 1 and longitude 2 will work.
Related
I'm working on an application where I have a ListView that shows the coordinates of my smartphone's position previously stored on a database. The rows of the ListView appear to be like: (latitude, longitude), date.
Is it possible to get the single values of the item? I was thinking to retrieve only the latitude and longitude values of the clicked item so that I can open a new MapsActivity that sets a marker at those specific coordinates.
Looking through other similar questions I've got that with ((TextView) view).getText() or with listView.getItemAtPosition(position) I can read the entire content of the item, but I'd like to apply that to the first two values of the ListView.
So for anyone interested I solved my problem by parsing the content of the item as a String by doing like this:
String str = (String) listView.getItemAtPosition(position);
String parts[] = str.split(",");
String lat = parts[0];
String lon = parts[1];
I had to get rid of "(" and ")" in the visualization of the coordinates as they were hindering the string parsing.
I'm using this below to add map markers to a Google Map. I have a table column FIELD_NAME. There are several locations each tied to a same FIELD_NAME. So for example there may be 5 entries of FIELD_NAME Woods with each entry having its own latitude/long value. I'm trying to figure out how to query the table to provide the FIELD_NAME but I only want it to show one of each name, not every time it is used. Once I get the name I will use it to display all the lat long points of that selected FIELD_NAME. How do you do this and does anyone have any links to tutorials on queries of this type?
#Override
public void onLoadFinished(Loader<Cursor> arg0,
Cursor arg1) {
int locationCount = 0;
double lat=0;
double lng=0;
// Number of locations available in the SQLite database table
locationCount = arg1.getCount();
// Move the current record pointer to the first row of the table
arg1.moveToFirst();
for(int i=0;i<locationCount;i++){
// Get the latitude
name = arg1.getString(arg1.getColumnIndex(LocationsDB.FIELD_NAME));
lacomments = arg1.getString(arg1.getColumnIndex(LocationsDB.FIELD_COMMENTS));
lat = arg1.getDouble(arg1.getColumnIndex(LocationsDB.FIELD_LAT));
// Get the longitude
lng = arg1.getDouble(arg1.getColumnIndex(LocationsDB.FIELD_LNG));
// Creating an instance of LatLng to plot the location in Google Maps
locationEngine = new LatLng(lat, lng);
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(locationEngine);
// Adding marker on the Google Map
getMap().addMarker(markerOptions);
arg1.moveToNext();
}
}
if you want to populate distinct FIELD_NAME in some spinner and then on selection of it display all the location for that, better do it with 2 queries
bind the spinner with result of
"select distinct FIELD_NAME from tablename"
and then once user provides his selection, use the below query
select * from tablename where FIELD_NAME ='whatever_user_selected'
Note: tablename - replace with your table's name
Let me know if there is not UI for user selection and you want random
entries for a specific field
When my App gets installed for the first time, I create a database programmatically. Works fine so far. But when I want to add a trigger, I get an exception saying "syntax error near IF". The problem is, that I can not span the String over multiple lines in source code. So what can I do instead?
private void createTriggers(SQLiteDatabase database) {
final String triggerLocationArchived = "CREATE TRIGGER location_archived AFTER UPDATE ON location FOR EACH ROW BEGIN IF NEW.deleted <> OLD.deleted THEN UPDATE sector set sector.deleted = NEW.deleted WHERE sector.location = NEW._id; END IF; END;";
database.execSQL(triggerLocationArchived);
}
There are two tables: location and sector. Each has an INTEGER flag indicating if the row has been archived. So I want all children (sectors within a location) to be archived as well if the parent (the location) is archived.
Try this command:
CREATE TRIGGER location_archived
AFTER UPDATE ON location
FOR EACH ROW
WHEN NEW.deleted <> OLD.deleted
BEGIN
UPDATE sector
set deleted = NEW.deleted
WHERE location = NEW._id;
END
Your code will look like this:
private void createTriggers(SQLiteDatabase database) {
final String triggerLocationArchived = "CREATE TRIGGER location_archived AFTER UPDATE ON [location] FOR EACH ROW WHEN NEW.deleted <> OLD.deleted BEGIN UPDATE sector set deleted = NEW.deleted WHERE location = NEW._id; END";
database.execSQL(triggerLocationArchived);
}
I have a problem with Lists in Java and Android. I read and save all user contacts in a List with this code:
List<ContactInfo> list = new ArrayList<ContactInfo>();
ContactInfo contactInfo = new ContactInfo();
do {
contactInfo.name = people.getString(indexName);
contactInfo.phone = people.getString(indexNumber);
list.add(contactInfo);
} while (people.moveToNext());
In the do-while everything is OK, name and phone is correct but the list don't save correctly values (To be specific, it saves correctly the values but out of the do-while every value is replaced with the last inserted value).
It just saves the last contact in every position but if I try to debug what he add in every position during the do-while it says the correct values.
It's the code I used to check every item out of the do-while
int i = 0;
for(ContactInfo info : list)
{
Log.d(newMessage.TAG, "contactInfo(" + i + "): name = " + info.name + " ; phone = " + info.phone);
++i;
}
I have fixed the problem with this edit:
do {
contactInfo = new ContactInfo();
contactInfo.name = people.getString(indexName);
contactInfo.phone = people.getString(indexNumber);
list.add(contactInfo);
} while (people.moveToNext());
It creates a different instance of ContactInfo every contact but why don't work if I create one out of the do-while?
And, if I create a different instance for every contact it can cause memory-leak / out-of-memory or something similar if number of contacts are too much? Or maybe just make the application slow, because the GC should clear the memory?
The Problem is that the object will be the same when you do it your way. The objectreference of the object is the same all the time, so the only object which is added it the first one.
Greets
I am trying to develop a Registration screen from Android XML. As in every Registration form, I would need to display the list of countries. I am able to do this using string-array in strings.xml file.
The greater part of the problem is, when a user selects a country, the phone number field just below it should be initially filled with its respective country code, which may or may not be editable. Here, my problem is how do I get the country code when the country is selected. Do I need to use a database or is it achievable using xml itself?
Besides that, when user submits the Register form, I would have to send the abbreviated code of the country, not the full country name. Now, again this would require either a database or xml?
My app doesn't use database till now, it would not be so good to use database for this purpose. Moreover, almost any application that uses a registration needs this thing to be done, but I cannot find any resources on how to do this in Android.
Also, I would like to tell you that my minimum sdk is version 7.
Please help.
I was finally able to do it without using database. I'm writing down the steps so that it may help anyone else who needs the same thing to be done.
First I downloaded the CSV available at: https://github.com/mledoze/countries/blob/master/countries.csv
I removed all other fields, except those I needed. It left me with 3 fields: name, abbreviation and calling code.
Next, I downloaded the CSVReader from: http://code.google.com/p/secrets-for-android/source/browse/trunk/src/au/com/bytecode/opencsv/CSVReader.java
Got the items from the CSV as mentioned in How to parse the CSV file in android application? by "Kopfgeldjaeger" as:
String next[] = {};
List<String[]> list = new ArrayList<String[]>();
try {
CSVReader reader = new CSVReader(new InputStreamReader(getAssets().open("countries.csv")));
for(;;) {
next = reader.readNext();
if(next != null) {
list.add(next);
} else {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
Next I added an ArrayList for each of the values like:
ArrayList<String> countryNames = new ArrayList<String>();
ArrayList<String> countryAbber = new ArrayList<String>();
ArrayList<String> countryCodes = new ArrayList<String>();
for(int i=0; i < list.size(); i++)
{
countryNames.add(list.get(i)[0]); // gets name
countryAbber.add(list.get(i)[1]); // gets abbreviation
countryCodes.add(list.get(i)[2]); // gets calling code
}
Then added it to the spinner in the XML layout as:
ArrayAdapter<String> countryAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, countryNames);
spinner.setAdapter(countryAdapter);
// adding event to display codes when country is selected
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int pos, long arg3) {
// display the corresponding country code
TextView tvCountryCode = (TextView) findViewById(R.id.country_code);
tvCountryCode.setText("+"+list.get(pos)[2]);
countryPosition = pos;
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
This way, I was able to display country code in the xml file, when a country was selected from the dropdown list.
Remember to add the setOnItemSelectedListener() to achive that.
I hope this helps somebody in future.
I would advise you to use a database. API level 7 supports SQLite databases (I used them in android 2.1 myself). Create one table that has all the required info:
create table countries (
_id integer primary key autoincrement,
country_code char(2),
country_name varchar,
phone_code char(4),
editable integer
);
Then store your country information into this table. When populating your list of countries, use this table instead of XML; display country names and associate country codes with each corresponding list item. Then on selection, use the country code to get the phone code and the 'editable' flag - and act upon this info.