简体   繁体   中英

android.database.sqlite.SQLiteException: near "2": syntax error (code 1 SQLITE_ERROR): , while compiling: SELECT phonetic_name, status_updates

I am trying to make an app that will access my phone's contact list then pick a contact and show the name, number, id, and the display picture. i can access contact. when I press the addFab button it shows my phones contactlist but when I pick a contact using the cursor the app crashes. I have also tried with a physical phone but same result. I am getting this ERROR :

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sosandvideo, PID: 11666
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { dat=content://com.android.contacts/contacts/lookup/0r2-2C/2 flg=0x1 }} to activity {com.example.sosandvideo/com.example.sosandvideo.MainActivity}: android.database.sqlite.SQLiteException: near "2": syntax error (code 1 SQLITE_ERROR): , while compiling: SELECT phonetic_name, status_updates.status_res_package AS status_res_package, custom_ringtone, contacts_status_updates.status_ts AS contact_status_ts, account_type, data_version, photo_file_id, contacts_status_updates.status_res_package AS contact_status_res_package, group_sourceid, display_name_alt, sort_key_alt, presence.mode AS mode, 0 AS last_time_used, starred, contacts_status_updates.status_label AS contact_status_label, has_phone_number, presence.chat_capability AS chat_capability, raw_contact_id, carrier_presence, contact_last_updated_timestamp, res_package, photo_uri, data_sync4, phonebook_bucket, 0 AS times_used, display_name, sort_key, data_sync1, version, data_sync2, data_sync3, photo_thumb_uri, status_updates.status_label AS status_label, agg_presence.mode AS contact_presence, in_default_directory, 0 AS times_contacted, _id, account_type_and_data_set, name_raw_contact_id, status_updates.status AS status, phonebook_bucket_alt, 0 AS last_time_contacted, pinned, is_primary, photo_id, contact_id, agg_presence.chat_capability AS contact_chat_capability, contacts_status_updates.status_icon AS contact_status_icon, in_visible_group, phonebook_label, account_name, display_name_source, data9, dirty, sourceid, phonetic_name_style, send_to_voicemail, data8, lookup, data7, data6, phonebook_label_alt, data5, is_super_primary, data4, data3, data2, data1, data_set, contacts_status_updates.status AS contact_status, backup_id, preferred_phone_account_component_name, raw_contact_is_user_profile, status_updates.status_ts AS status_ts, data10, preferred_phone_account_id, data12, mimetype, status_updates.status_icon AS status_icon, data11, data14, data13, hash_id, data15 FROM view_data data LEFT OUTER JOIN agg_presence ON (contact_id = agg_presence.presence_contact_id) LEFT OUTER JOIN status_updates contacts_status_updates ON (status_update_id=contacts_status_updates.status_update_data_id) LEFT OUTER JOIN presence ON (presence_data_id=data._id) LEFT OUTER JOIN status_updates ON (status_updates.status_update_data_id=data._id) LEFT OUTER JOIN (SELECT 0 as STAT_DATA_ID,0 as x_times_used, 0 as x_last_time_used,0 as times_used, 0 as last_time_used where 0) as data_usage_stat ON (STAT_DATA_ID=data._id) WHERE (1 AND mimetype_id=5) AND (contact_id 2)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:5015)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:5056)
    at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7656)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: android.database.sqlite.SQLiteException: near "2": syntax error (code 1 SQLITE_ERROR): , while compiling: SELECT phonetic_name, status_updates.status_res_package AS status_res_package, custom_ringtone, contacts_status_updates.status_ts AS contact_status_ts, account_type, data_version, photo_file_id, contacts_status_updates.status_res_package AS contact_status_res_package, group_sourceid, display_name_alt, sort_key_alt, presence.mode AS mode, 0 AS last_time_used, starred, contacts_status_updates.status_label AS contact_status_label, has_phone_number, presence.chat_capability AS chat_capability, raw_contact_id, carrier_presence, contact_last_updated_timestamp, res_package, photo_uri, data_sync4, phonebook_bucket, 0 AS times_used, display_name, sort_key, data_sync1, version, data_sync2, data_sync3, photo_thumb_uri, status_updates.status_label AS status_label, agg_presence.mode AS contact_presence, in_default_directory, 0 AS times_contacted, _id, account_type_and_data_set, name_raw_contact_id, status_updates.status AS status, phonebook_bucket_alt, 0 AS last_time_contacted, pinned, is_primary, photo_id, contact_id, agg_presence.chat_capability AS contact_chat_capability, contacts_status_updates.status_icon AS contact_status_icon, in_visible_group, phonebook_label, account_name, display_name_source, data9, dirty, sourceid, phonetic_name_style, send_to_voicemail, data8, lookup, data7, data6, phonebook_label_alt, data5, is_super_primary, data4, data3, data2, data1, data_set, contacts_status_updates.status AS contact_status, backup_id, preferred_phone_account_component_name, raw_contact_is_user_profile, status_updates.status_ts AS status_ts, data10, preferred_phone_account_id, data12, mimetype, status_updates.status_icon AS status_icon, data11, data14, data13, hash_id, data15 FROM view_data data LEFT OUTER JOIN agg_presence ON (contact_id = agg_presence.presence_contact_id) LEFT OUTER JOIN status_updates contacts_status_updates ON (status_update_id=contacts_status_updates.status_update_data_id) LEFT OUTER JOIN presence ON (presence_data_id=data._id) LEFT OUTER JOIN status_updates ON (status_updates.status_update_data_id=data._id) LEFT OUTER JOIN (SELECT 0 as STAT_DATA_ID,0 as x_times_used, 0 as x_last_time_used,0 as times_used, 0 as last_time_used where 0) as data_usage_stat ON (STAT_DATA_ID=data._id) WHERE (1 AND mimetype_id=5) AND (contact_id 2)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:186)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
    at android.content.ContentProviderProxy.query(ContentProviderNative.java:472)
    at android.content.ContentResolver.query(ContentResolver.java:1183)
    at android.content.ContentResolver.query(ContentResolver.java:1115)
    at android.content.ContentResolver.query(ContentResolver.java:1071)
    at com.example.sosandvideo.MainActivity.onActivityResult(MainActivity.java:130)
    at android.app.Activity.dispatchActivityResult(Activity.java:8304)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:5008)
        ... 11 more

Here are the relevant code that I have used:

package com.example.sosandvideo;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.nfc.Tag;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import org.jetbrains.annotations.NotNull;

public class MainActivity extends AppCompatActivity {
    //    private Button add;
    private ImageView thumbnailTv;
    private TextView contactTv;
    private FloatingActionButton addFab;

    private static final int CONTACT_PERMISSION_CODE = 1;
    private static final int CONTACT_PICK_CODE = 2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        thumbnailTv = findViewById(R.id.thumbnailTv);
        contactTv = findViewById(R.id.contactTv);
        addFab = findViewById(R.id.addFab);
        addFab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //first we need to check contact permission
                if (checkContactPermission()) {

                    //if granted, pick a contact
                    pickContact();

                } else {
                    //not granted request for permission
                    requestContactPermission();
                }
            }
        });
    }

    private Boolean checkContactPermission() {
        //checking if the contact permission is granted or not
        boolean result = ContextCompat.checkSelfPermission(this,
                Manifest.permission.READ_CONTACTS) == (PackageManager.PERMISSION_GRANTED);
        return result;// true if granted or false
    }

    private void requestContactPermission() {
        //permission to request
        String[] permission = {Manifest.permission.READ_CONTACTS};
        ActivityCompat.requestPermissions(this, permission, CONTACT_PERMISSION_CODE);
    }

    private void pickContact() {
        //intent to pick contact
        Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
        startActivityForResult(intent, CONTACT_PICK_CODE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull @NotNull String[] permissions, @NonNull @NotNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        // handle request for permission
        if (requestCode == CONTACT_PERMISSION_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //permission granted now we can pick contacts
                pickContact();
            } else {
                //permission denied
                Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
            }
        }

    }

    @SuppressLint("Range")
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //handle intent results
        if (resultCode == RESULT_OK) {
            //calls when user pick a contact from the list
            if (requestCode == CONTACT_PICK_CODE) {
                Cursor cursor1;
                Cursor cursor2;
                //get data from intent
                Uri uri = data.getData();
                cursor1 = getContentResolver().query(uri, null, null, null, null);
                if (cursor1.moveToFirst()) {
                    //get contact date
                    String contactId = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts._ID));
                    String contactName = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                    String contactThumnail = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI));
                    String idResult = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
                    int idResulthold = Integer.parseInt(idResult);
                    if (idResulthold == 1) {
                        cursor2 = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                null,
                                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " " + contactId,
                                null,
                                null);
                        while (cursor2.moveToNext()) {
                            String contactNum = cursor2.getString(cursor2.getColumnIndex
                                    (ContactsContract.CommonDataKinds.Phone.NUMBER));

                            contactTv.append("ID" + contactId);
                            contactTv.append("\nName" + contactName);
                            contactTv.append("\nNumber" + contactNum);
                            contactTv.append("\n\n");
                            if (contactThumnail != null) {
                                thumbnailTv.setImageURI(Uri.parse(contactThumnail));

                            } else {
                                thumbnailTv.setImageResource(R.drawable.ic_baseline_person_24);
                            }
                        }
                        cursor2.close();
                    }
                    cursor1.close();
                }


            }
        } else {
            //calls when user pressed back button or haven't selected any contacts
        }
    }
}

Here is the manifest code:

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.sosandvideo">
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.SOSandVideo">
        <activity android:name=".Home"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MainActivity">
        </activity>
    </application>

</manifest>

How can I solve this ERROR

shrinking down your error log to the relevant parts...
SQLiteException: near "2": ... while compiling: SELECT... contact_id 2

your SQL should be SELECT... contact_id=2

In your source code you have this snipped that looks kind of wrong...
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " " + contactId,

The way you are concating your sql statement you are prone to sql injection you should read more on that topic as well...

I changed my main activity file to this and changed how to fetch data using cursor As I said there is no work of SQL, Cursor generates SQL code automatically. i had a problem with fetching data from cursor movement.

   package com.example.sosandvideo;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

;

import com.example.sosandvideo.Contacts.Contact;
import com.example.sosandvideo.Contacts.ContactAdapter;
import com.example.sosandvideo.Contacts.DBhelper;

import java.util.List;

public class MainActivity extends AppCompatActivity {
    private static final int RESULT_PICK_CONTACT =1;
    ListView listview;
    List<Contact> list;
    ContactAdapter contactAdapter;
    private Button add;
    DBhelper db=new DBhelper();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        setContentView (R.layout.activity_main);


       // phone = findViewById (R.id.contactTv);
        add = findViewById (R.id.addButton);
        listview=(ListView)findViewById(R.id.listView);
        list = db.getAllContacts();
        contactAdapter=new ContactAdapter(this,list);
        listview.setAdapter(contactAdapter);

        add.setOnClickListener (new View.OnClickListener () {
            @Override
            public void onClick(View v) {
                Intent in = new Intent (Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
                startActivityForResult (in, RESULT_PICK_CONTACT);
            }
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode,  Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case RESULT_PICK_CONTACT:
                    contactPicked(data);
                    break;
            }
        } else {
            Toast.makeText(this, "Failed To pick contact", Toast.LENGTH_SHORT).show();
        }
    }

    @SuppressLint("Range")
    private void contactPicked(Intent data) {
        Cursor cursor = null;

        try {
            String phoneNo = null;
            int id;
            String name;
            Uri uri = data.getData ();
            cursor = getContentResolver ().query (uri, null, null,null,null);
            cursor.moveToFirst ();
             id= cursor.getColumnIndex (ContactsContract.CommonDataKinds.Phone.CONTACT_ID);

            String phoneid= cursor.getString (id);
            String phoneNum= cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            name=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
            db.addContact(new Contact(phoneid,phoneNum,name));
            list = db.getAllContacts();
            contactAdapter.refresh(list);

        } catch (Exception e) {
            e.printStackTrace ();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM