i need to get all the MMS Data detalis like mms_image, address,date and type.
i am using following logic. In this i am using two cursors, one for images and other for remaining fields. but the size of two cursors are different. so, i am unable to match both image and other fields.
//for date,address,type
Cursor curPdu = getContentResolver ().query(Uri.parse("content://mms"), null, null, null, null);
while(curPdu.moveToNext())
{
String id = curPdu.getString (curPdu.getColumnIndex ("_id"));
String date = curPdu.getString (curPdu.getColumnIndex ("date"));
mms_add.add(getAddressNumber(Integer.parseInt(id)));
int type = Integer.parseInt(curPdu.getString(curPdu.getColumnIndex("m_type")));
mms_type.add((type==128)?"2":"1");
mms_date.add(getDate(Long.parseLong(date)));
}
//for image
Cursor curPart = getContentResolver (). query (Uri.parse ("content://mms/part"), null, null, null, null);
while(curPart.moveToNext())
{
coloumns = curPart.getColumnNames();
if(values == null)
values = new String[coloumns.length];
for(int i=0; i< curPart.getColumnCount(); i++)
{
values[i] = curPart.getString(i);
}
if(values[3].equals("image/jpeg"))
{
mms_image.add(GetMmsAttachment(values[0],values[12],values[4]));
}else{
mms_image.add("null");
}
}
so, please guide me how to get all the details using one cusor if possible.
You can try the solution and url provided here.
And may i know why you need 2 cursor ? I assume there is some mms without image attached so that's the reason you get a different count.
Related
I am trying to fetch all sms(both inbox,sent sms) in android.
I have tried with these
Uri uri_sent = Uri.parse("content://sms");
Cursor c_sent = getContentResolver().query(uri_sent, null, null, null,
null);
startManagingCursor(c_sent);
// Read the inbox sms data and store it in the list
if (c_sent.moveToFirst()) {
for (int i = 0; i < c_sent.getCount(); i++) {
SmsDataClass sms = new SmsDataClass();
sms.setAddress(c_sent.getString(
c_sent.getColumnIndexOrThrow("address")).toString());
sms.setBody(c_sent.getString(
c_sent.getColumnIndexOrThrow("body")).toString());
sms.setDate(c_sent.getString(
c_sent.getColumnIndexOrThrow("date")).toString());
sms.set_id(c_sent
.getString(c_sent.getColumnIndexOrThrow("_id"))
.toString());
sms.setType(c_sent.getString(
c_sent.getColumnIndexOrThrow("type")).toString());
// sms.setTitle(c.getString(c.getColumnIndexOrThrow("title")).toString());
all_sms_data.add(sms);
c_sent.moveToNext();
}
} else
c_sent.close();
it sometimes works but it doesn't work regularly. Sometimes it shows null pointer exception on c_sent.getColumnIndexOrThrow("address"),c_sent.getColumnIndexOrThrow("body") ....
What is the problem ???
I dont understand.
Before oneday it works fine when today i have nullpointer exception.
Why???
I have 5 empty TextViews where I add the names. After adding a name, it is stored in a database. The database consist on 2 columns, the item ID and the item NAME. This is an example of what I'm doing:
- Mark1 //ID=1, NAME= Mark1
- Mark2 //ID=2, NAME= Mark2
- Mark3 //ID=3, NAME= Mark3
- Empty
- Empty
I add and edit perfectly the textViews, but I'm facing a problem when deleting. This has something to do with the way I'm getting the values from the database, I'll explain:
Every time the app starts, or I edit, add or delete one element, what I do is get the items from the database, get them into a Map, and copy them into the textviews (whose at a first time are invisible) making visible just the ones that have a name setted.
This is the code I use to do that:
public void getTravelers() {
/*Create map where store items*/
Map<Integer, String> nameList = new HashMap<Integer, String>();
/*Lon in providers query() method to get database's items and save them into the map*/
Cursor c = getContentResolver().query(TravelersProvider.CONTENT_URI, PROJECTION, null, null, null);
if (c.moveToFirst()) {
do {
nameList.put(Integer.parseInt(c.getString(c.getColumnIndex(Travelers._ID))), c.getString(c.getColumnIndex(Travelers.NAME)));
}while(c.moveToNext());
}
if (c != null && !c.isClosed()) {
c.close();
}
/*Check size*/
int size = nameList.size();
if (size >= 1) {
/*Save items in TextViews*/
//TODO: This is the code I should fix
for (int i = 0; i <= size; i++) {
if (i==1) {
traveler1.setText(nameList.get(i).toString());
traveler1.setVisibility(View.VISIBLE);
}
if (i==2) {
traveler2.setText(nameList.get(i).toString());
traveler2.setVisibility(View.VISIBLE);
}
if (i==3) {
traveler3.setText(nameList.get(i).toString());
traveler3.setVisibility(View.VISIBLE);
}
if (i==4) {
traveler4.setText(nameList.get(i).toString());
traveler4.setVisibility(View.VISIBLE);
}
if (i==5) {
traveler5.setText(nameList.get(i).toString());
traveler5.setVisibility(View.VISIBLE);
}
}
}
}
The problem comes in the for loop. Let's supposse that from the items named above, I want to delete Mark2 with ID=2, so then the size of the new Map would be 2, and it would enter to (i == 1) and (i == 2). But when entering to this last one, it would do traveler2.setText(nameList.get(2).toString()); and as seen, there is no element existing with the ID=2 because that is the one that I've deleted and it throws a NPE.
So my question is, what would be the right way to do this without facing this problem?
You should go for switch case other than for loop. Than code will not be in loop.
Finally I get what I need just changing the Key value of the Map that was the same as the ID of the database:
if (c.moveToFirst()) {
int key = 0;
do {
key++;
nameList.put(key, c.getString(c.getColumnIndex(Travelers.NAME)));
}while(c.moveToNext());
}
if (c != null && !c.isClosed()) {
c.close();
}
Basically this way I don't need to change nothing more as now the key value of the Map will match with the Textview position
I have read several posts here on speed issues when looping through a cursor and tried the answers given in these posts such as e.g. do not use getcolumnindex in the loop call this once etc.
However with a database having around 2400 records it takes around 3 to 5 minutes to finish.
The loop is running in an async task method so that it does not hang up the device and the database is handled via a database adapter.
The loop code is as follows :
while (!exportrec.isAfterLast()) {
if ( exportrec.moveToNext() ) {
fulldate = exportnumberformatter(exportrec.getInt(daye))
+"/"+exportnumberformatter(exportrec.getInt(monthe))+"/"
+String.valueOf(exportrec.getInt(yeare));
fulltime = exportnumberformatter(exportrec.getInt(houre))+":"
+exportnumberformatter(exportrec.getInt(mine))+":"
+exportnumberformatter(exportrec.getInt(sece));
noiseid = exportrec.getInt(typee);
exportedinfo += exporttypes[id] +","+exportrec.getString(notee)+","+
fulldate+","+fulltime+" \n" ;
}
}
The exportnumberformatter does the following :
public String exportnumberformatter(int i) {
String result = Integer.toString(i);
if (result.length() >1 ) {
return Integer.toString(i);
}
String zeroprefix = "";
zeroprefix = "0"+result;
return zeroprefix ;
}
The cursor is called as follows before the loop to get the data :
exportrec = MD.GetAllLogs(2, "date_sort");
exportrec.moveToFirst();
The MD is the database adapter and the GetAllLogs Method (this has been played with to try and speed things up and so the date_sort that is used is really ignored here):
public Cursor GetAllLogs(Integer i,String sortfield)
{
String sorted = "";
if (i == 1 ) {
sorted = "DESC";
} else if (i == 2) {
sorted = "ASC";
}
return mDB.query(DB_TABLE, new String[] {COL_ID, COL_TYPE,COL_IMAGE, COL_INFO,COL_IMAGE,COL_HOUR,COL_SEC,COL_MIN,COL_DAY,COL_MON,COL_YEAR,COL_SORT_DATE},
null, null, null, null, COL_ID+" "+sorted);
}
When I created the table in the database it had no indexes so I created these via the upgrade method. However they did not error or appear to fail when I did this but what I do not know is A) does the database/table need rebuilding after an index is created and B) how to tell if they have been created ? the two indexes were based on the ID as the first and a field that holds the year month day hour minute second all in on Long Integer.
I am concerned that the loop appears to be taking this long to read through that many records.
Update:
rtsai2000's and the suggestion from CL answer has improved the speed from minutes to seconds
Your exportedInfo String is growing and growing. Save the results in an array and Stringify later (such as with StringBuilder).
You are not closing your cursor after reading the records.
List<String> exportedInfo = new ArrayList<String>();
Cursor exportrec = GetAllLogs();
try {
while (exportrec.moveToNext()) {
String info = String.format("%s, %s, %02d/%02d/%02d, %02d:%02d:%02d",
exporttypes[id],
exportrec.getString(notee),
exportrec.getInt(daye),
exportrec.getInt(monthe),
exportrec.getInt(yeare),
exportrec.getInt(houre),
exportrec.getInt(mine),
exportrec.getInt(sece));
exportedInfo.add(info);
}
} finally {
exportrec.close();
}
return exportedInfo;
Basically this is not a problem in itself, my code works so far.
What I have is a App, that lets a user log in and depending on his ID in the db, he gets displayed his saved notes. For this view I have this part of code:
title = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
MyDbHandler dbh = new MyDbHandler(this);
for(int i = 0; i < 999; i++) {
content = dbh.getNoteTitle(id, i); //getNoteTitle(int, int) returns String
if(content != null && content != "0")
title.add(content);
else
break;
}
list.setAdapter(title);
As I said, this works so far.
Thing is - I am very unhappy with the use of ' break; ' here, as I learned during education, this shouldn't be used.
Is there a smoother way to approach this issue?
Also ' content != "0" ' should be ' ! content.equals("0") ' normally, right? But that one doesn't work then... Why is this?
I am not sure what are you trying to do. First of all you should use "equal" method for Strings. The condition "content != "0" will always be true, because you are comparing 2 different objects. The condition "! content.equals("0")" should return true most of the time (when the value is not "0") and probably you should use the debugger to see exactly what is the value of content.
Second if you want to take all the notes from the database and show them to the user you should have first a method in the SQLiteOpenHelper similar to (it is not efficient to interrogate the database for each item, plus the separation of concerns):
public ArrayList<String> getNotesList (int userID){
SQLiteDatabase db = getWritableDatabase();
Cursor c = db.query(TABLE_NAME, new String[] {MyDbHandler.COLUMN_NOTE_TITLE}, MyDbHandler.userID + "=" + userID,null, null, null, null);
ArrayList<String> list = null;
String noteTitle;
if (c != null && c.moveToFirst())
{
list = new ArrayList<String>(c.getCount());
for (int i = 0; i < c.getCount(); i++)
{
noteTitle = c.getString(c.getColumnIndex(MyDbHandler.COLUMN_SESSION_PATH));
list.add(noteTitle);
c.moveToNext();
}
}
c.close();
db.close();
return list;
I think you should not save notes that you don't want to use (e.g. null or "0"), so instead of checking here, I would check in the addNote method.
For the list initialization you have:
MyDbHandler dbh = new MyDbHandler(this);
ArrayList listData = dbh.getNotesList(id)
if (listData != null && listData.length != 0){
title = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
listData.setAdapter(title);
}
I didn't test the code, but I hope it helps you. Good luck!
Pretty sure this is an easy one, but i'm getting confused by all the examples that adapt the data returned from a cursor into different views. I just want to run a rawquery and put each item of data returned into a float array (so that i can add them up later). What do i need to use for this? Thanks
You'll still have a cursor when you query your database, but once you got the cursor you could iterate over it, pulling out the values you need into an array, like this:
DbAdapter db = new DbAdapter(mContext);
int columnIndex = 3; // Whichever column your float is in.
db.open();
Cursor cursor = db.getAllMyFloats();
float[] myFloats = new float[cursor.getCount()-1];
if (cursor.moveToFirst())
{
for (int i = 0; i < cursor.getCount(); i++)
{
myFloats[i] = cursor.getFloat(columnIndex);
cursor.moveToNext();
}
}
cursor.close();
db.close();
// Do what you want with myFloats[].
Don't minus by 1 in float[] myFloats = new float[cursor.getCount()-1]; because (int i =0) or i start from 0. If you use it, will appear Java.lang.IndexOutOfBoundsException. You need array index until [cursor.getCount()], not until [cursor.getCount()-1]. So the correct thing is float[] myFloats = new float[cursor.getCount()];