my app retrieves VCards as Strings and puts all together to a big string via StringBuilder
public String getVcardStrings() throws Exception {
Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
StringBuilder builder = new StringBuilder();
if (cursor.moveToFirst()) ;
do {
String s = getVCardStringFromContact(cursor);
L.d("VCARD", s);
builder.append(s);
} while (cursor.moveToNext());
cursor.close();
L.d("VCARD", "Output: \n" + builder.toString());
return builder.toString();
}
The output of each getVCardAsString() call is correct. It contains all data. but calling builder.toString() onlly returns the vcard data of 1,5 Contacts, which is about 4kb of text data and the rest is simply missing!
There is no exception and I´ve read that StringBuilders capacity theoretically reaches up to 4GB. Now my question is, what is happening here?
I'm pretty sure this is a false positive:
In other words the data is there but is being truncated by logcat.
This observation would seem to be validated by this define:
#define LOGGER_ENTRY_MAX_LEN (4*1024)
Which is bang-on 4KB and relates directly to what you are experiencing.
Write your output to a file to check if its actually there.
Related
I am using a string buffer to read to store values being read from an SQLite database. Inside the loop, the buffer always starts reading from the first database reference.
Eg: The database has the values apple,orange,banana.
Everytime I call the funtion,the string buffer stores the items from the beginning:
first function call: apple
second function call: apple apple orange
third function call: apple apple orange apple orange banana
On the third call i need it just to be: apple orange banana
How can I do this?
public void db{
Cursor res= databaseHelper.getAllData();
if(res!=null){
res.moveToFirst();
try{
while(res.moveToNext())
{
if(res.getString(0)!=null){
stringBuffer.append(res.getString(0)+"\n");
Log.i("TAG",stringBuffer.toString());
stringBuffer1.append(res.getString(1)+"\n");
stringBuffer2.append(res.getString(2)+"\n");
stringBuffer.setLength(0);
stringBuffer1.setLength(0);
stringBuffer2.setLength(0);
}catch(Exception e){}}}
If you need just print "apple orange banana", then use as follow
public void db(){
Cursor res = databaseHelper.getAllData();
if (res != null) {
while (res.moveToNext()) {
String value = res.getString(0) + " ";
stringBuffer.append(value);
Log.d(TAG, stringBuffer.toString())
...
}
res.close()
}
}
Just put StringBuffer stringBuffer = new StringBuffer(""); after public void db{ or clear the stringBuffer by stringBuffer.delete(0, stringBuffer.length()); before you start the loop.
I don't know where you declared stringBuffer but it keeps the previous values. Also you may lose the 1st item in db because you do moveFirst and immediately moveNext, so drop moveFirst
int i =0;
if (cursor.moveToFirst()){
do{
stringBuffer.append.(cursor.getString (i));
i++;
}
while(cursor.moveToNext());
}
cursor.close();
}
Try this instead of that, may this helps you.
I have built an app where I loop through and collect the users phone contacts, my aim is to then use these numbers and query my parse database and look for records that contain the users contacts (this will be to check if any of the users contacts are a user of my app, a users phone number will be saved to my parse database when they register). The problem I've got is that when collecting the users contacts numbers they are returned in different formats, some +447966000000, some 07966000000, some 07 966000 000000, etc.
My question is, what would be the best way to format my numbers when saving them to the database and retrieving them from the users contacts so that all numbers are saved and retrieved in the same format so that when I do a conditional check on them they will be easy to compare?
I have downloaded phone Number Utils library but I am not sure what in the library could be used to do something like this.
Code so far:
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
while (phones.moveToNext())
{
String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Toast.makeText(getApplicationContext(),name + " " + phoneNumber, Toast.LENGTH_LONG).show();
}
phones.close();
You can use PhoneNumberUtils.compare to compare and check if they are same or not.It returns true if they are same ignoring country codes etc.
Example:
PhoneNumberUtils.compare(context, 1234567890, +911234567890);
returns true
I have done it for Indian mobile number format
private String getNumber(String moNumber) {
Pattern special = Pattern.compile ("[!##$%&*()_+=|<>?{}\\[\\]~-]");
if (moNumber.isEmpty()||moNumber.length()<10) {
MydebugClass.showToast(getContext(), "Please input valid Number");
return null;
}else if (moNumber.length()>10 && !special.matcher(moNumber).find()){
String[] number=moNumber.split("");
StringBuilder stringBuilder=new StringBuilder();
for(int i=moNumber.length();i>moNumber.length()-10;i--){
stringBuilder.append(number[i]);
}
String reverse=new StringBuffer(stringBuilder).reverse().toString();
return reverse;
}else if(moNumber.length()>10&&special.matcher(moNumber).find()){
String numberOnly= moNumber.replaceAll("[^0-9]", "");
String[] number=numberOnly.split("");
StringBuilder stringBuilder=new StringBuilder();
for(int i=moNumber.length();i>moNumber.length()-10;i--){
stringBuilder.append(number[i]);
}
String reverse=new StringBuffer(stringBuilder).reverse().toString();
Log.d("mobilenumberspecial",reverse);
return reverse;
}
else {
return moNumber;
}
return null;
}
I have a phone number with country code like +91XXXXXXXXXX. and a phone number in my android contacts database is in the form of XX XX XXXXXX. How to compare them in sqlite database query.
Any help would be appreciable....
I need this to update or delete the existing phone number in android database.
Note
Phone number can be of any country. Above is just the example.
you can try the code below
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode("Pass phone number here"));
Cursor c = getContentResolver().query(uri, new String[]{PhoneLookup.NUMBER}, null, null, null);
if(c.getCount()>0){
c.moveToFirst();
System.out.println(c.getString(c.getColumnIndex(PhoneLookup.NUMBER)));
}
c.close();
There can be multiple ways to do this:
As you see below here:
String yourInputString = "+91XXXXXXXXXX";
String dbContactString = "XX XX XXXXXX";
both have different format; so we must have to extract substring ("XXXXXXXXXX") from first string and also have to remove whitespaces ("XXXXXXXXXX") from the second string!
yourInputString = yourInputString.substring(2); // 2 is start index and result will be "XXXXXXXXXX"
dbContactString = dbContactString.replaceAll("\\s+",""); // replaces all whitespaces and result will be "XXXXXXXXXX"
now, both have same format so you can easily compare them with equals().
yourInputString.equals(dbContactString) is the way.
It returns true if yourInputString is equals to dbContactString in value. Else, it will return false.
Hope this helps!
I am creating a database in Android, all was going nice, but when I was testing the queries retrieving the correct data I've got an error.
E/AndroidRuntime(14126): java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
I know that means that there is no data matching the query, but the fact is that I inserted the data by query and it actually has a match. And the same query works with all the codes that doesn't have accents.
These are the queries for inserting the rows.
INSERT INTO "codigo" VALUES('A','PEATÓN');
INSERT INTO "codigo" VALUES('B','PEATÓN');
INSERT INTO "codigo" VALUES('C','PEATÓN');
So I did a query that gets the values of the field that I was replacing, like this:
String selectCode = "select distinct c.tipo from codigo c";
Cursor cursor = database.rawQuery(selectCodigo, new String[] {});
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String codigo= cursor.getString(0);
codigos.add(codigo);
System.out.println(codigo);
cursor.moveToNext();
}
cursor.close();
return codigos;
And the result was this:
10-14 16:40:32.140: I/System.out(13716): PEAT�N
I have the text file in the /raw folder and I edited from the Eclipse so I make sure it wasn't the table export I did, but I have the same results.
This is the code that reads the file:
public int insertFromFile(SQLiteDatabase db,Context context, int resourceId) throws IOException {
// Reseting Counter
int result = 0;
// Open the resource
InputStream insertsStream = context.getResources().openRawResource(resourceId);
BufferedReader insertReader = new BufferedReader(new InputStreamReader(insertsStream));
// Iterate through lines (assuming each insert has its own line and theres no other stuff)
while (insertReader.ready()) {
String insertStmt = insertReader.readLine();
db.execSQL(insertStmt);
result++;
}
insertReader.close();
// returning number of inserted rows
return result;
}
How could I get that accent working?
I am using a lot of them, so, replacing the word is not a way out.
Please help, is the only thing I need to finish this project.
UPDATE:
Had the same problems two more times later. The first I fixed it by working with a .sql file coded in cp1525 and opened it in Eclipse with the default editor and find/replaced the wrong characters.
The last time I've got this error I made it the right way, and found that if you are working with SQLiteManager it imports files encoded in UTF-8 but it export files in ANSI, so I opened the file with Notepad++, change the enconding of the .sql file from ANSI to UTF-8 and it works fine, all the characters were shown fine.
The InputStreamReader constructor documentation says:
Constructs a new InputStreamReader on the InputStream in. This constructor sets the character converter to the encoding specified in the "file.encoding" property and falls back to ISO 8859_1 (ISO-Latin-1) if the property doesn't exist.
If the file is encoded in UTF-8, you have to tell the reader this.
in your SQLQueryString just add before
PRAGMA encoding = "UTF-8";
example
"PRAGMA encoding = \"UTF-8\"; INSERT INTO MYTABLE (mytablefield) VALUES ('value'); "
I ran into trouble trying to send SQLite data to a web server using json (gson).
Everything was fine until the table came round 6000 rows.
I ran into Out of Memory errors.
In my datahelper I have:
public String DonneesToJson (SQLiteDatabase db, int chantier, int chantier_serveur )
{
Cursor c = db.rawQuery("select * from "+P_TABLE+" where "+P_CHANTIER+"="+chantier+ " order by "+P_TIME+" desc ", null);
List<Donnees> donnees = new ArrayList<Donnees>();
c.moveToFirst();
while (c.moveToNext())
{
Donnees d = new Donnees (
c.getInt(c.getColumnIndex(Datahelper.P_ID)),
chantier_serveur,
offset,
c.getInt(c.getColumnIndex(Datahelper.P_PLAN)),
c.getString(c.getColumnIndex(Datahelper.P_TIME)),
c.getInt(c.getColumnIndex(Datahelper.P_PRESSION)),
c.getInt(c.getColumnIndex(Datahelper.P_PROFONDEUR)),
c.getInt(c.getColumnIndex(Datahelper.P_PROFONDEUR_TOTALE)),
c.getInt(c.getColumnIndex(Datahelper.P_ANGLE_X)),
c.getInt(c.getColumnIndex(Datahelper.P_ANGLE_Y)),
c.getString(c.getColumnIndex(Datahelper.P_PIEU)),
c.getInt(c.getColumnIndex(Datahelper.P_NO_RALLONGE)),
c.getString(c.getColumnIndex(Datahelper.P_RALLONGE)),
c.getInt(c.getColumnIndex(Datahelper.P_MOTEUR)),
c.getString(c.getColumnIndex(Datahelper.P_SERIE)),
c.getDouble(c.getColumnIndex(Datahelper.P_COEFF_A)),
c.getDouble(c.getColumnIndex(Datahelper.P_COEFF_B))
);
donnees.add(d);
}
c.close();
Gson gson = new Gson();
return gson.toJson(donnees);
}
Basically I call this like that:
String resultat = dbHelper.DonneesToJson(db,i, chantier_serveur);
HttpPost post2 = new HttpPost("http://www.zzzzzzz.com/test.php");
StringEntity se = new StringEntity(resultat);
se.setContentEncoding( new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post2.setEntity(se);
response = client.execute(post2);
On the server side, it's quite basic php to store data in a big sql DB and then do analysis.
ie:
$decoded = json_decode($HTTP_RAW_POST_DATA,true);
foreach ( $decoded as $key => $value)
{
$query = ...
While doing OOM erros, it's slow. I mean getting sql data to json is slow.
I tried to go the jackson route, faster, no out of memory error, but... it can only write to a file or a stream.
I'd try to avoid writing to a file then send the file trough http post.
So I decided to open an http stream to send json data and I'm stuck.
I did not find any example on how to open an output stream to the web server using apache.
Any help appreciated.
Despite the answer from dmon to split the data into batches, you should work on other glitches. Try this code:
public String DonneesToJson (SQLiteDatabase db, int chantier, int chantier_serveur ) {
Cursor c = db.rawQuery("select * from "+P_TABLE+" where "+P_CHANTIER+"="+chantier+ " order by "+P_TIME+" desc ", null);
List<Donnees> donnees = new ArrayList<Donnees>();
if (c != null) { // nullcheck as rawQuery can return null!
Donnees d; // reuse variables for loops
while (c.moveToNext()) { // was buggy before, read comment below code
d = new Donnees (
c.getInt(c.getColumnIndex(Datahelper.P_ID)),
chantier_serveur,
offset,
c.getInt(c.getColumnIndex(Datahelper.P_PLAN)),
c.getString(c.getColumnIndex(Datahelper.P_TIME)),
c.getInt(c.getColumnIndex(Datahelper.P_PRESSION)),
c.getInt(c.getColumnIndex(Datahelper.P_PROFONDEUR)),
c.getInt(c.getColumnIndex(Datahelper.P_PROFONDEUR_TOTALE)),
c.getInt(c.getColumnIndex(Datahelper.P_ANGLE_X)),
c.getInt(c.getColumnIndex(Datahelper.P_ANGLE_Y)),
c.getString(c.getColumnIndex(Datahelper.P_PIEU)),
c.getInt(c.getColumnIndex(Datahelper.P_NO_RALLONGE)),
c.getString(c.getColumnIndex(Datahelper.P_RALLONGE)),
c.getInt(c.getColumnIndex(Datahelper.P_MOTEUR)),
c.getString(c.getColumnIndex(Datahelper.P_SERIE)),
c.getDouble(c.getColumnIndex(Datahelper.P_COEFF_A)),
c.getDouble(c.getColumnIndex(Datahelper.P_COEFF_B)));
donnees.add(d);
}
c.close();
}
return new Gson().toJson(donnees);
}
Your current implementation is buggy and you will never get the first entry. The reason for that is your call to moveToFirst() which moves you to the first. The while loop will move the internal pointer to the second entry with moveToNext() which will result in starting with the second element and completely ignoring the first one. Always and forever...