質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.92%

java.lang.RuntimeExceptionについて

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 105

tata4179

score 1

Android で電話帳から選択した人の電話番号一覧を取得するプログラムを作成しましたが、
以下のエラーが発生していて原因がわからないです。

ご教授いただきたいです。
よろしくお願いいたします。

■エラーのデバック内容

**E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sample, PID: 20758
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1111, result=-1, data=Intent { dat=content://com.android.contacts/contacts/lookup/258r132-2606083C030D6026260816030D602668/115 flg=0x1 }} to activity {com.example.sample/com.example.sample.MainActivity}: java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://com.android.contacts/data/phones from pid=20758, uid=10344 requires android.permission.READ_CONTACTS, or grantUriPermission()
at android.app.ActivityThread.deliverResults(ActivityThread.java:4382)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4424)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1814)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:280)
at android.app.ActivityThread.main(ActivityThread.java:6706)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://com.android.contacts/data/phones from pid=20758, uid=10344 requires android.permission.READ_CONTACTS, or grantUriPermission()
at android.os.Parcel.createException(Parcel.java:1969)
at android.os.Parcel.readException(Parcel.java:1935)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:418)
at android.content.ContentResolver.query(ContentResolver.java:804)
at android.content.ContentResolver.query(ContentResolver.java:753)
at android.content.ContentResolver.query(ContentResolver.java:711)
at com.example.sample.MainActivity._getPhoneNumbers(MainActivity.java:122)
at com.example.sample.MainActivity.onActivityResult(MainActivity.java:70)
at android.app.Activity.dispatchActivityResult(Activity.java:7454)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4375)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4424)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1814)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:280)
at android.app.ActivityThread.main(ActivityThread.java:6706)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
I/Process: Sending signal. PID: 20758 SIG: 9
■作成したプログラム

ここに言語を入力

package com.example.sample;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
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.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import androidx.core.app.ActivityCompat;

import com.mkyong.android.R;

/**
 * @author peko
 *
 */
public class MainActivity extends Activity implements DialogInterface.OnClickListener {

    private static final String TAG          = "MainActivity";
    private static final int    PICK_CONTACT = 1111;
    private static final int REQUEST_CODE = 1000;

    private AlertDialog.Builder _alertDialogBuilder;
    private TextView            _phoneNumberTextView;
    private String[]            _phoneNumbers;

    /*
     * (non-Javadoc)
     *
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.activity_main);

        this._alertDialogBuilder = new AlertDialog.Builder(this);
        this._phoneNumberTextView = (TextView) this.findViewById(R.id.textView);

        ((Button) this.findViewById(R.id.button)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent pickIntent = new Intent(Intent.ACTION_PICK,
                        ContactsContract.Contacts.CONTENT_URI);
                startActivityForResult(pickIntent, MainActivity.PICK_CONTACT);
            }
        });
    }

    /*
     * (non-Javadoc)
     *
     * @see android.app.Activity#onActivityResult(int, int,
     * android.content.Intent)
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == MainActivity.PICK_CONTACT) {
            if (resultCode == Activity.RESULT_OK) {
                if (null != data) {
                    Uri contactData = data.getData();
                    String displayName = this._getDisplayName(contactData);
                    this._phoneNumbers = this._getPhoneNumbers(displayName);
                    if (this._phoneNumbers.length > 1) {
                        this._createNumberSelectAlertDialog(displayName, this._phoneNumbers);
                    } else if (this._phoneNumbers.length == 1) {
                        this._phoneNumberTextView.setText(this._phoneNumbers[0]);
                    }
                }
            }
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * android.content.DialogInterface.OnClickListener#onClick(android.content
     * .DialogInterface, int)
     */
    @Override
    public void onClick(DialogInterface dialog, int which) {
        String selectedPhoneNumber = this._phoneNumbers[which];
        Uri uri = Uri.parse("tel:" + selectedPhoneNumber);
        Intent i = new Intent(Intent.ACTION_CALL,uri);
        startActivity(i);
    }

    /**
     * コンタクトリストのURIから表示名を取得する
     *
     * @param contactData
     * @return
     */
    private String _getDisplayName(Uri contactData) {
        String displayName = null;
        if (null != contactData) {
            ContentResolver contentResolver = this.getContentResolver();
            Cursor cursor = contentResolver.query(contactData, null, null, null, null);
            cursor.moveToFirst();
            int columnIndex = cursor
                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
            displayName = cursor.getString(columnIndex);
            cursor.close();
        }
        return displayName;
    }

    //
    // コンタクトリストから表示名で検索して、その名前に紐付いている電話番号を取得する
    //
    // @param displayName
    // @return
    //
    private String[] _getPhoneNumbers(String displayName) {
        ContentResolver contentResolver = this.getContentResolver();
        Cursor cursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + "=?",
                new String[] { displayName }, null);
        cursor.moveToFirst();
        String[] names = new String[cursor.getCount()];
        do {
            int index = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
            String number = cursor.getString(index);
            names[cursor.getPosition()] = number;
        } while (cursor.moveToNext());
        cursor.close();

        return names;
    }

    /**
     * 電話番号選択のダイアログを出す
     *
     * @param title
     * @param items
     */
    private void _createNumberSelectAlertDialog(String title, String[] items) {
        this._alertDialogBuilder.setTitle(title);
        this._alertDialogBuilder.setItems(items, this);
        AlertDialog dialog  = this._alertDialogBuilder.create();
        dialog.show();
    }

}


```

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • dodox86

    2020/09/16 12:10

    プログラムのコードやエラーメッセージはマークダウン記法を用いて読みやすくするようにしてください。インデントも崩れ、読みづらいとそれだけで質問を読まれず、回答は離れがちになります。
    https://teratail.com/help/question-tips#questionTips3-5-1
    https://teratail.com/questions/238564
    あたりを参考にしてください。

    キャンセル

  • dodox86

    2020/09/16 12:14

    > 以下のエラーが発生していて原因がわからないです。

    エラーが出てもあわてず思考停止にならず、出力内容をがんばって読んでください。原因のひとつはちゃんとメッセージ内に出ています。

    > java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1111, result=-1, data=Intent { dat=content://com.android.contacts/contacts/lookup/258r132-2606083C030D6026260816030D602668/115 flg=0x1 }} to activity {com.example.sample/com.example.sample.MainActivity}: java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://com.android.contacts/data/phones from pid=20758, uid=10344 requires android.permission.READ_CONTACTS, or grantUriPermission()

    キャンセル

  • tata4179

    2020/09/16 14:22

    >プログラムのコードやエラーメッセージはマークダウン記法を用いて読みやすくするようにしてください。>インデントも崩れ、読みづらいとそれだけで質問を読まれず、回答は離れがちになります。
    すいませんでした。今後、読みやすくするように記載致します。

    原因はわかりました。
    READ_CONTACTSは、android6.0以降、
    ユーザーにパーミッションの許可または拒否を求める必要があったんですね。
    ありがとうございます。

    キャンセル

  • dodox86

    2020/09/16 15:24 編集

    > すいませんでした。今後、読みやすくするように記載致します。
    今、直せばよいと思うのですが。。。

    > 原因はわかりました。
    であれば、原因と解決方法を添えて、自己回答、解決で質問を閉じてください。

    キャンセル

回答 1

check解決した方法

0

READ_CONTACTSは、android6.0以降、
ユーザーにパーミッションの許可または拒否を求める必要があったんですね。
private String[] _getPhoneNumbers(String displayName)に追加しました。
if (ActivityCompat.shouldShowRequestPermissionRationale(
this, Manifest.permission.READ_CONTACTS)) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_CODE);
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る