Izin Android tidak berfungsi meskipun saya telah menyatakannya

167

Saya mencoba menulis kode untuk mengirim SMS dari aplikasi Android, tetapi ketika saya mencoba mengirim SMS itu mengirim saya kembali kesalahan:

09-17 18:37:29.974  12847-12847/**.**.****E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: **.**.****, PID: 12847
java.lang.SecurityException: Sending SMS message: uid 10092 does not have android.permission.SEND_SMS.
        at android.os.Parcel.readException(Parcel.java:1599)
        at android.os.Parcel.readException(Parcel.java:1552)
        at com.android.internal.telephony.ISms$Stub$Proxy.sendTextForSubscriber(ISms.java:768)
        at android.telephony.SmsManager.sendTextMessageInternal(SmsManager.java:310)
        at android.telephony.SmsManager.sendTextMessage(SmsManager.java:293)
        at **.**.****.MainActivity$3.onClick(MainActivity.java:70)
        at android.view.View.performClick(View.java:5198)
        at android.view.View$PerformClick.run(View.java:21147)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Saya memeriksa tetapi saya memiliki izin dalam manifes, sebagai berikut:

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-feature android:name="android.hardware.telephony"
    android:required="true"/>

<application
    android:exported="true"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

Saya mencari di internet tetapi semua kesalahannya tentang <uses-permission/>sintaksis, bisakah Anda membantu saya?

Nathan Loudjani
sumber
Versi Android apa yang Anda uji?
CommonsWare
Saya sedang menguji di android 6.0
Nathan Loudjani
1
pasti itu akan bekerja pada versi Android di bawah ini. Ada filosofi izin baru di android 6.0
Fakher
Apakah ada sintaks khusus untuk Android 6? Bagaimana saya bisa yakin ini berfungsi pada versi di bawah ini?
Nathan Loudjani
sebelumnya saya targetsdkversiontelah 23diperbarui untuk 27setelah update aplikasi READ_SMSizin tidak bekerja yang sudah diaktifkan. tolong bantu
Sagar

Jawaban:

238

(berikut ini diambil dari posting blog saya tentang ini )

Alasan utama untuk tidak mendapatkan izin Anda saat ini adalah karena proyek Anda memiliki targetSdkVersion23 atau lebih tinggi, dan izin yang Anda minta itu "berbahaya". Di Android 6.0, ini termasuk:

  • ACCESS_COARSE_LOCATION
  • ACCESS_FINE_LOCATION
  • ADD_VOICEMAIL
  • BODY_SENSORS
  • CALL_PHONE
  • CAMERA
  • GET_ACCOUNTS
  • PROCESS_OUTGOING_CALLS
  • READ_CALENDAR
  • READ_CALL_LOG
  • READ_CELL_BROADCASTS
  • READ_CONTACTS
  • READ_EXTERNAL_STORAGE
  • READ_PHONE_STATE
  • READ_SMS
  • RECEIVE_MMS
  • RECEIVE_SMS
  • RECEIVE_WAP_PUSH
  • RECORD_AUDIO
  • SEND_SMS
  • USE_SIP
  • WRITE_CALENDAR
  • WRITE_CALL_LOG
  • WRITE_CONTACTS
  • WRITE_EXTERNAL_STORAGE

Untuk izin ini, tidak hanya targetSdkVersionaplikasi 23+ Anda perlu memiliki <uses-permission>elemen, tetapi Anda juga harus meminta izin tersebut saat runtime dari pengguna di perangkat Android 6.0+, menggunakan metode seperti checkSelfPermission()dan requestPermissions().

Sebagai solusi sementara, jatuhkan di targetSdkVersionbawah 23.

Namun, pada akhirnya, Anda akan memiliki beberapa alasan untuk menginginkan Anda targetSdkVersionmenjadi 23 atau lebih tinggi. Pada saat itu, Anda perlu menyesuaikan aplikasi Anda untuk menggunakan sistem izin runtime baru. Dokumentasi Android memiliki halaman yang didedikasikan untuk topik ini .

CommonsWare
sumber
2
Terima kasih banyak, saya menggunakan metode requestPermissions () dan saya bekerja dengan baik
Nathan Loudjani
Oke, saya sudah mencoba ini sebelumnya tetapi tidak bisa mendapatkan metode ContextCompat.checkSelfPermission dan ActivityCompat.requestPermissions, mereka memberi saya kesalahan 'tidak ditemukan' pada nama metode. Saya kira itu ada hubungannya dengan pustaka yang hilang, sepertinya ada dalam paket v4 tetapi satu-satunya ketergantungan gradle saya adalah compile 'com.android.support:appcompat-v7:22.2.1'. Haruskah saya mengubahnya ke v4?
Ozzy
2
@Ozzy: Anda harus menggunakan pustaka dukungan generasi v23 ( 23.x.y, untuk nilai x dan y saat ini), daripada v22 yang saat ini Anda gunakan.
CommonsWare
Terima kasih, untuk masa depan kurasa. Untuk saat ini saya mengubah target kembali ke v22 dan meskipun penyimpanan kartu SD diatur ke 200MB pada emulator, itu memberi saya kartu SD tidak dipasang kesalahan. Tapi kemudian saya menghubungkan ponsel saya dalam mode pengembang dan semuanya berfungsi. Untuk beberapa alasan penyimpanan kartu SD berfungsi pada emulator yang menjalankan v23 tetapi tidak pada v22.
Ozzy
3
@NathanLoudjani Maukah Anda membagikan kode Anda yang mengimplementasikan ini? Saya berada di kapal yang sama persis dan saya berjuang memasukkan ini ke dalam kegiatan saya.
dschuett
29

Di atas API level 23 Anda akan diberikan secara pragmatis seperti:

    private static final int PERMISSION_REQUEST_CODE = 1;

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {

        if (checkSelfPermission(Manifest.permission.SEND_SMS)
                == PackageManager.PERMISSION_DENIED) {

            Log.d("permission", "permission denied to SEND_SMS - requesting it");
            String[] permissions = {Manifest.permission.SEND_SMS};

            requestPermissions(permissions, PERMISSION_REQUEST_CODE);

        }
    }
pengguna7176550
sumber
7

meminta izin secara pragmatis (setelah API 23)

if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.SEND_SMS)
    != PackageManager.PERMISSION_GRANTED) {
    // Permission is not granted 
    // Ask for permision
    ActivityCompat.requestPermissions(this,new String[] { Manifest.permission.SEND_SMS}, 1); 
} 
else {
// Permission has already been granted
}

"Jika aplikasi memiliki izin, metode checkSelfPermission () mengembalikan PERMISSION_GRANTED, dan aplikasi dapat melanjutkan operasi.

Jika aplikasi tidak memiliki izin, metode mengembalikan PERMISSION_DENIED, dan aplikasi harus secara eksplisit meminta izin kepada pengguna. Anda harus meminta izin kepada pengguna, seperti yang ditunjukkan dalam kode di atas. Memanggil requestPermissions () menampilkan dialog Android standar, yang tidak dapat Anda sesuaikan. "

Dan Alboteanu
sumber
Di mana kita akan meletakkan garis ini? ActivityCompat.requestPermissions (ini, String baru [] {Manifest.permission.SEND_SMS}, 1); dan apa yang dimaksud dengan 1?
LizG
6

Jika Anda menggunakan SDK 23 atau lebih tinggi maka Anda harus memeriksa izin run time.

Dharmendra Pratap
sumber
6

ketika Anda menyatakan permissondalam Manifestdan itu tidak berarti pekerjaan Anda melakukan tugas di MarshMallowdan untuk MarshMallowAnda telah menetapkan permisson diRunTime .

seperti ini

ActivityCompat.requestPermissions();
Harshad Pansuriya
sumber
6

Silakan buka tautan di bawah ini, https://developer.android.com/guide/topics/permissions/overview.html

Beberapa sampel juga tersedia di sana untuk memulai dengan izin.

Untuk membuat android lebih aman sekarang pengembang harus menyebutkan izin dalam manifes serta mereka harus meminta pengguna juga dalam menjalankan waktu untuk menyelesaikan pekerjaan. Izin tersebut dikategorikan dalam bagian izin berbahaya yang disebutkan di bawah ini

KALENDER

READ_CALENDAR

WRITE_CALENDAR

KAMERA

CAMERA

KONTAK

READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS

LOKASI

ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION

MIKROPON

RECORD_AUDIO

TELEPON

READ_PHONE_STATE
READ_PHONE_NUMBERS
CALL_PHONE
ANSWER_PHONE_CALLS (must request at runtime)
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
ANSWER_PHONE_CALLS

SENSOR

BODY_SENSORS

SMS

SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS

PENYIMPANAN

READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
Rishabh Saxena
sumber
2

Saya menambahkan ini ke MainActivity saya, yang menyelesaikan masalah saya

       int MY_PERMISSIONS_REQUEST_READ_CONTACTS=0;
// Here, thisActivity is the current activity
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {

            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

                // Show an expanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.

            } else {

                // No explanation needed, we can request the permission.

                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        MY_PERMISSIONS_REQUEST_READ_CONTACTS);

                // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
                // app-defined int constant. The callback method gets the
                // result of the request.
            }
        }
Masquitos
sumber
2

Jika Anda menggunakan versi Android "23" atau "23+", maka aplikasi akan menunjukkan kesalahan ketika Anda mencoba mengakses apa pun yang memerlukan izin pengguna. Anda harus meminta izin saat run-time walaupun Anda telah menyatakan izin tersebut dalam manifes Android.

Periksa ini: https://developer.android.com/training/permissions/requesting.html

Tetapi jika Anda telah membuat seluruh aplikasi Anda dan tidak ingin berubah di setiap tempat maka sedikit cheat akan cukup.

Buka file "Build.gradle" dan ubah versi Sdk target menjadi kurang dari 23, seperti 22, 21.

Zohaib Hassan
sumber
1

Bersamaan dengan jawaban CommonsWare,

Ada Pengaturan Keamanan (saya memeriksa CM13) untuk mengatur Batas Pesan SMS. Jika Anda mengatur ini ke "Tidak Ada", OS akan memunculkan Dialog untuk setiap SMS, bahkan setelah mendapatkan izin SMS_SEND di saat runtime. Hal terbaik adalah mengatur ini ke maksimum.

Jika maksimum tidak cukup, ada cara untuk meningkatkan tingkat maksimum pada perangkat yang di-rooting.

Dumi Jay
sumber
0

Anda dapat menggunakan kode ini untuk mengakses pesan Anda

Buka Dialog menggunakan kode di bawah ini:

ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    1);

Dapatkan hasil Aktivitas seperti di bawah ini:

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1: {

          // If request is cancelled, the result arrays are empty.
          if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.          
            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
                Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

atau edit file build.gradledan nomor chanche targetSdkVersionkurang dari23
Dan tidak perlu lagi kode di atas

CATATAN
Tentu saja ini tidak terjadi, dan itu hanya aspek pendidikan

Amirhf
sumber
0

Jadi saya harus membuat aplikasi untuk mengirim dan menerima pesan tetapi tindakan pengiriman terhenti setiap kali saya mengklik kirim meskipun izin diberikan. Saya telah meminta izin runtime dan memperbolehkannya, masih saya menghadapi crash bahwa proses tidak memiliki izin yang diminta untuk mengirim SMS. Saya telah memeriksa izin yang diberikan dari:

adb shell dumpsys package <package-name>

Urutan permintaan saya untuk izin adalah

  1. RECEIVE_SMS
  2. KIRIM SMS

Saya mengembalikan urutan permintaan dan berfungsi dengan baik. Ini diuji dengan aplikasi baru yang lengkap (uninstall-> install -> test). Jawabannya mungkin tampak aneh tetapi coba saja.

(Jika berfungsi dengan cara yang ditunjukkan dalam urutan tertentu, maka Android mungkin memiliki bug !!)

Partha Sarathi Murmu
sumber
0

Saya harap solusi untuk menulis ke penyimpanan eksternal akan bermanfaat juga

public  boolean checkPermission() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    == PackageManager.PERMISSION_GRANTED) {
                Timber.tag(LOG_TAG).e("Permission error. You have permission");
                return true;
            } else {
                Timber.tag(LOG_TAG).e("Permission error. You have asked for permission");
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                return false;
            }
        }
        else { 
            // for a stuff below api level 23
            Timber.tag(LOG_TAG).e("Permission error. You already have the permission");
            return true;
        }
    }
SergeyUr
sumber