onActivityResult не переопределяется и никогда не достигается в Button.ClickListener

Я начну с того, что надеюсь, что это не настолько глупо, что я не мог этого заметить, но после нескольких часов исследований я не нашел ответа. В моем SMSActivity я создал Button cmdApriRubrica, который открывает приложение «Контакты» по умолчанию, а затем, когда контакт выбран, теоретически возвращает его данные в мою активность (я просмотрел это на Базовые тренинги для разработчиков Android). Приложение "Контакты" открывается нормально, но проблема в том, что я никогда не получаю результат. Мой код следующий:

((Button)findViewById(R.id.cmdApriRubrica)).setOnClickListener( new Button.OnClickListener() {

        @Override
        public void onClick(View v) {

            Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
            pickContactIntent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
            startActivityForResult(pickContactIntent, 200);
        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {

            //super.onActivityResult(int requestCode, int resultCode, Intent data); CAN'T CALL THIS

            // Check which request it is that we're responding to

            if (requestCode == 200 && resultCode == RESULT_OK) {

                // Make sure the request was successful
                    // Get the URI that points to the selected contact

                    Uri contactUri = data.getData();

                    // We only need the NUMBER column, because there will be only one row in the result

                    String[] projection = {ContactsContract.CommonDataKinds.Phone.NUMBER};

                    // Perform the query on the contact to get the NUMBER column
                    // We don't need a selection or sort order (there's only one result for the given URI)
                    // CAUTION: The query() method should be called from a separate thread to avoid blocking
                    // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
                    // Consider using CursorLoader to perform the query.

                    Cursor cursor = getContentResolver()
                            .query(contactUri, projection, null, null, null);
                    cursor.moveToFirst();


                    // Retrieve the phone number from the NUMBER column

                    int column = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
                    String nome = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                    String numero = cursor.getString(column);

                    Log.i("Dati contatto: ","Nome = "+nome+", numero = "+numero);


                    // Do something with the phone number...

                    txtDati.setText(new StringBuilder().append(nome).append("\t------------\t").append(numero).toString()); //Android Studio suggested me doing this...
                }
            }
    });

Я думаю, что основная проблема заключается в том, что я нахожусь в событии onClick(): я искал этот ответ, этот ответ, эта ошибка, этот ответ, этот сайт и некоторые другие менее популярные ответы. Многие предлагали вызвать super.onActivityResult, но он не находит метод, поэтому я не могу его вызвать. Кроме того, Android Studio сообщает мне, что onActivityResult, который я там написал, не переопределяет метод своего суперкласса. Почему это происходит? Я не нашел ответа по этому поводу. Есть ли способ избежать написания этого внутри метода onClick, если это проблема, или я делаю что-то неправильно, и я не мог найти решение? Спасибо за ваше время.


РЕДАКТИРОВАТЬ: я изменил код, как мне было предложено; мой код теперь следующий:

    TextView txtDati = null; //This is initialized just below the class declaration to have it visible
    public static final int PICK_CONTACT_REQ_CODE = 200;
        ...
        findViewById(R.id.cmdApriRubrica).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
                pickContactIntent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
                startActivityForResult(pickContactIntent, PICK_CONTACT_REQ_CODE);
            }
        });

        ...
//At the same level of the onCreate() method, as I've been told!
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // Check which request it is that we're responding to

        if (requestCode == 200 && resultCode == RESULT_OK && txtDati != null) {

            // Make sure the request was successful
            // Get the URI that points to the selected contact

            Uri contactUri = data.getData();

            // We only need the NUMBER column, because there will be only one row in the result

            String[] projection = {ContactsContract.CommonDataKinds.Phone.NUMBER};

            // Perform the query on the contact to get the NUMBER column
            // We don't need a selection or sort order (there's only one result for the given URI)
            // CAUTION: The query() method should be called from a separate thread to avoid blocking
            // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
            // Consider using CursorLoader to perform the query.

            Cursor cursor = getContentResolver()
                    .query(contactUri, projection, null, null, null);
            cursor.moveToFirst();


            // Retrieve the phone number from the NUMBER column

            int column = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
            String nome = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            String numero = cursor.getString(column);

            Log.i("Dati contatto: ","Nome = "+nome+", numero = "+numero);


            // Do something with the phone number...

            txtDati.setText(new StringBuilder().append(nome).append("\t------------\t").append(numero).toString()); //Android Studio suggested me doing this...
        }

        else
            Log.i("Problem ActivityResult","Something wrong in onActivityResult method!");
    }

Теперь я получаю это исключение, но не могу понять, как работает Cursor.query:


java.lang.RuntimeException: Ошибка доставки результата ResultInfo{who=null, request=200, result=-1, data= Намерение { dat=content://com.android.contacts/data/3045 flg=0x1 }} для действия {com.fun.is.activity.gguiduzzi.orariobello/com.fun.is.activity.gguiduzzi.orariobello.SMSActivity }: java.lang.IllegalStateException: не удалось прочитать строку 0, столбец -1 из CursorWindow. Убедитесь, что курсор правильно инициализирован, прежде чем обращаться к его данным.
Может ли кто-нибудь сказать мне, в чем проблема? Я так усердно искал это. Благодарю вас!


person ServantGrunt    schedule 13.05.2015    source источник


Ответы (1)


У вас тут две проблемы, на мой взгляд. Вы используете метод OnClickListener из Button. Вы должны использовать вид.

((Button)findViewById(R.id.cmdApriRubrica)).setOnClickListener( new Button.OnClickListener() { WRONG

((Button)findViewById(R.id.cmdApriRubrica)).setOnClickListener( new View.OnClickListener() { OK

Вторая проблема заключается в том, что вы переопределяете onActivityResult внутри слушателя кнопки, а не активность, поэтому вы не можете использовать super.onActivityResult.

Вы должны поместить этот код (onActivityResult) на тот же уровень, что и onCreate, onDestroy и т. д.

person qmateub    schedule 13.05.2015
comment
Так что я должен переопределить его снаружи, спасибо! Не могли бы вы объяснить мне, пожалуйста, что меняется от использования Button.OnClickListener до View? - person ServantGrunt; 13.05.2015
comment
@ njzk2 Возможно, неправильное слово здесь было неправильным, моя вина, я должен использовать возможное изменение или что-то в этом роде. Он искал решение своей проблемы, и я ответил, что, по моему мнению, он мог бы изменить, чтобы решить ее. В API (developer.android.com/reference/android/widget/Button. html) и в большинстве проектов, в которых я участвовал, используйте Button.OnClickListener, поэтому я и предложил его. - person qmateub; 14.05.2015