Android SQLite CursorIndexOutOfBounds - java

For some reason when the username I input is not found, the application crashes. But when the username is found it seems to run perfect. I even do a check to see if the returned cursor == null. Heres the code
public boolean isUserAuthenticated(String username, String password) {
// TODO Auto-generated method stub
boolean authenticated = false;
String[] columns = new String[] {LOGIN_USERNAME, LOGIN_PASSWORD};
String sqlUsername = "\"" + username + "\"";
Cursor c = ourDatabase.query(LOGIN_TABLE, columns, LOGIN_USERNAME + "="+ sqlUsername, null, null, null, null);
if (c != null) {
c.moveToFirst();
String passwordAttachedToUsername = c.getString(1);
if(passwordAttachedToUsername.equals(password)) {
authenticated = true;
}
}
return authenticated;
}

Your Cursor object may not be null, but the size of its result set is 0. Instead of:
if (c != null) {
...
}
try:
if (c.getCount() > 0) {
...
}
Also, as #mu is too short mentioned, you could just use the return value of c.moveToFirst() in your conditional:
if (c.moveToFirst()) {
String passwordAttachedToUsername = c.getString(1);
if (passwordAttachedToUsername.equals(password)) {
authenticated = true;
}
}

First, the condition should be:
if (c != null && c.getCount() > 0)
Second, you can refactor
String passwordAttachedToUsername = c.getString(1);
if(passwordAttachedToUsername.equals(password)) {
authenticated = true;
}
with this instead:
authenticated = password.equals(c.getString(1));

Change:
if (c != null) {
c.moveToFirst();
...
}
to
if (c != null && c.moveToFirst()) {
...
}
which will return true if c != null and the size of the cursor is greater than 0.

The query command will always return a cursor so your test for null will always fail. You need to check the count the cursor contains using cursor.getCount()

if (cursor != null && cursor.getCount() > 0) {
if (c.moveToFirst()) {
String passwordAttachedToUsername = c.getString(1);
if(passwordAttachedToUsername.equals(password)) {
authenticated = true;
}}
// your logic goes here
} else {
Toast.makeText(getApplicationContext(), "No Record Found", 1000).show();
}

Related

error missing return statement in method

I want to get data based on a fragment of the name , but why the error with a description of the missing return statement ?
public Cursor getName (String nama){
Cursor c = db.query(Konstanta.NAMA_TABEL, new String[]{
Konstanta.ID_ARTIS,
Konstanta.NAMA_ARTIS,
Konstanta.GENDER_ARTIS_PRIA,
Konstanta.GENDER_ARTIS_WANITA,
Konstanta.TGLAHIR}, Konstanta.NAMA_ARTIS + "LIKE '%" + nama + "%'",
null, null, null, null, null);
if (c != null){
c.moveToFirst();
return c;
}
}
Your method returns a result only if c is not null. It must return a result in all scenarios, i.e. even if c is null.
You can change
if (c != null){
c.moveToFirst();
return c;
}
to
if (c != null){
c.moveToFirst();
}
return c;
Every method which has a return value must return the described bean. You need to return null or throw a custom exception if c is not null.
public Cursor getName (String nama){
Cursor c = db.query(Konstanta.NAMA_TABEL, new String[]{
Konstanta.ID_ARTIS,
Konstanta.NAMA_ARTIS,
Konstanta.GENDER_ARTIS_PRIA,
Konstanta.GENDER_ARTIS_WANITA,
Konstanta.TGLAHIR}, Konstanta.NAMA_ARTIS + "LIKE '%" + nama + "%'",
null, null, null, null, null);
if (c != null){
c.moveToFirst();
return c;
}
throw new IllegalStateException("c is null");
}
add below line -
return null;
in your code block -
public Cursor getName (String nama){
Cursor c = db.query(Konstanta.NAMA_TABEL, new String[]{
Konstanta.ID_ARTIS,
Konstanta.NAMA_ARTIS,
Konstanta.GENDER_ARTIS_PRIA,
Konstanta.GENDER_ARTIS_WANITA,
Konstanta.TGLAHIR}, Konstanta.NAMA_ARTIS + "LIKE '%" + nama + "%'",
null, null, null, null, null);
if (c != null){
c.moveToFirst();
return c;
}
return null;
}
Your method must return Cursor type value but you are returning value only in a if loop
do this way :
public Cursor getName (String nama){
Cursor c =null;
c = db.query(Konstanta.NAMA_TABEL, new String[]{
Konstanta.ID_ARTIS,
Konstanta.NAMA_ARTIS,
Konstanta.GENDER_ARTIS_PRIA,
Konstanta.GENDER_ARTIS_WANITA,
Konstanta.TGLAHIR}, Konstanta.NAMA_ARTIS + "LIKE '%" + nama + "%'",
null, null, null, null, null);
if (c != null){
c.moveToFirst();
return c;
}
return c;
}

SQLite Check if column exist or not

I want to check columns (not value) at agregasi table, if columns exist do something, but if columns does not exist show/print message 'Column does not exist'.
I could run code below while columns exist:
String keywords1={'pesawat','terbang'};
String sql1 = "SELECT " + keywords + " FROM agregasi"; //columns exist at agregasi table
Cursor c1 = myDbHelper.rawQuery(sql1, null);
if (c1.moveToFirst()) {
// i can do something (no problem)
}
But i have problem when columns name i change on purpose (to check). What should i do to print error message (in android/java way)?
**String keywords2={'psawat','terang'};**
String sql2 = "SELECT " + keywords + " FROM agregasi"; //columns does not exist at table
Cursor c2 = myDbHelper.rawQuery(sql2, null);
// what should i do get error message and show/print using toast
You're looking for getColumnIndex(String columnName).
int index = c2.getColumnIndex("someColumnName");
if (index == -1) {
// Column doesn't exist
} else {
...
}
Here's a general method you can use to check whether a particular column exists in a particular table:
public boolean isColumnExists(SQLiteDatabase sqliteDatabase,
String tableName,
String columnToFind) {
Cursor cursor = null;
try {
cursor = sqLiteDatabase.rawQuery(
"PRAGMA table_info(" + tableName + ")",
null
);
int nameColumnIndex = cursor.getColumnIndexOrThrow("name");
while (cursor.moveToNext()) {
String name = cursor.getString(nameColumnIndex);
if (name.equals(columnToFind)) {
return true;
}
}
return false;
} finally {
if (cursor != null) {
cursor.close();
}
}
}
Try this it works fine :)
Cursor res = db.rawQuery("PRAGMA table_info("+tableName+")",null);
int value = res.getColumnIndex(fieldName);

Get User's Google Account Profile Picture

I have so far looked at many questions where this is the topic, not a single answer has worked for me so far. In my code I get the user's google account and their contact info. I can successfully look at their email and display name fine. When I grab their id number and use it how http://developer.android.com/reference/android/provider/ContactsContract.Contacts.Photo.html would have me use it, the InputStream comes up null. When I debug through the following method the program never loads the blob into data, it immediately skips down to finally.
public InputStream openPhoto(long contactId) {
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
Uri photoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] {ContactsContract.Contacts.Photo.PHOTO}, null, null, null);
if (cursor == null) {
return null;
}
try {
if (cursor.moveToFirst()) {
byte[] data = cursor.getBlob(0);
if (data != null) {
return new ByteArrayInputStream(data);
}
}
} finally {
cursor.close();
}
return null;
}
Does this mean the selected contact does not have a profile image??? I no this to not be the case as it is accessing my personal gmail account and giving me the other data correctly. I get this id with the following code (along with email and display name). I get the email with googleAccount.name
AccountManager accountManager;
accountManager = AccountManager.get(context);
Account[] account = accountManager.getAccounts();
Account googleAccount = null;
for(int i = 0; i < account.length; i++) {
if(account[i].type.equals("com.google")) {
googleAccount = account[i];
}
}
Cursor c = context.getContentResolver().query(ContactsContract.Profile.CONTENT_URI, null, null, null, null);
int count = c.getCount();
c.moveToFirst();
String id = "";
String displayName = "";
String[] columnNames = c.getColumnNames();
int position = c.getPosition();
if (count == 1 && position == 0) {
for (int j = 0; j < columnNames.length; j++) {
String columnName = columnNames[j];
String columnValue = c.getString(c.getColumnIndex(columnName));
if(columnName.equals("_id"))
id = columnValue;
if(columnName.equals("display_name"))
displayName = columnValue;
// consume the values here
}
}
c.close();
Why is this inputstream coming up null? I got the code directly from google. Has anyone had this problem with this code before?

CursorIndexOutOfBoundsException while getting VideoUri content from File

I'm trying to share a video(to social media) in an app I'm building. I'm using intents for which I need a Uri to parse. I'm trying to select items on a simple file manager (List activity) and then share them on long press. Thus I require the following code to get the Uri of the video for using it in the intents.
ContentResolver contentResolver = ctx.getContentResolver();
String videoUriStr = null;
long videoId = -1;
Uri videosUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaStore.Video.VideoColumns._ID };
// TODO This will break if we have no matching item in the MediaStore.
Cursor cursor = contentResolver.query(videosUri, projection,
MediaStore.Video.VideoColumns.DATA + " =?",
new String[] { fileToShare }, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
cursor.close();
if (videoId != -1)
videoUriStr = videosUri.toString() + "/" + videoId;
{
return videoUriStr;
}
UPDATE
The first few items on the ListActivity File manager file will share properly. But the latest videos show the error.
Error: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
your cursor has 0 rows. So, the line cursor.getLong(columnIndex); throws CursorIndexOutOfBoundsException. please check for null and check whether any rows exist or not.
If there is no rows cursor.moveToFirst() will return false.
Cursor cursor = contentResolver.query(videosUri, projection,
MediaStore.Video.VideoColumns.DATA + " =?",
new String[] { fileToShare }, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
cursor.close();
if (videoId != -1)
{
videoUriStr = videosUri.toString() + "/" + videoId;
}
}
}
return videoUriStr;
The MediaStore.Video.VideoColumns.DATA field holds the path for the video file. So, if you are using uri (content://mnt/sdcard/Videos/test.mp4) to fetch the file change it to file path (/mnt/sdcard/Videos/test.mp4).
Use while loop to check is cursor have data or not :
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
cursor.close();
Replace with this code :
while (cursor.moveToNext()){
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
}
cursor.close();
Error: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
means your cursor has no data.
use check for cursor emptyness:
if (cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
}
cursor.close();
This scenario does not depend on phone to phone. The problem is that your cursor has no data.
You can use cursor.moveToFirst() which returns false if the cursor is empty, or use cursor.getCount() to know the number of rows in the cursor.
e.g
if (cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
}
cursor.close();
or
if (cursor.getCount() > 0) {
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
}
cursor.close();
first of all you need to check the size of the cursor.
if(cursor.size()>0)
{
// do here
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
cursor.close();
if (videoId != -1)
videoUriStr = videosUri.toString() + "/" + videoId;
{
return videoUriStr;
}
}
I was able to get my problem solved but I still don't understand why I faced that problem with the old code. Thanks for all the help.
public static Uri getVideoContentUriFromFilePath(Context context, File fileToShare) {
String filePath = fileToShare.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Video.Media._ID },
MediaStore.Video.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
return Uri.withAppendedPath(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, "" + id);
} else {
if (fileToShare.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Video.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}

Get the caller id

I'm trying to make app which will log my incoming and outgoing calls and the problem is i can't seem to get working this code to return caller id(Like name and surname) but it allways returns "Unknown"
public String getname(String num,String nbc ){
String namer="";
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
try {
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Log.i("",name);
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
System.out.println("name : " + name + ", ID : " + id);
// get the phone number
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
new String[]{id}, null);
while (pCur.moveToNext()) {
String phone = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
System.out.println("phone" + phone);
if(phone==nbc||phone==num)
{
namer = name;
return namer;
}
}
pCur.close();
}
}
}
}
catch (Exception e) {
// TODO: handle exception
}
return namer;
}
It doesn't execute this(if(phone==nbc||phone==num)) part.
Can you please tell me what's wrong or another way to do this or at least point me in the right direction.
Use equals to compare Strings
if(phone.equals(nbc)||phone.equals(num))

Categories

Resources