अगर मैंने इसे घोषित किया है तो भी Android अनुमति काम नहीं करती है


167

मैं एंड्रॉइड ऐप से एक एसएमएस भेजने के लिए कोड लिखने की कोशिश कर रहा हूं, लेकिन जब मैं एसएमएस भेजने की कोशिश करता हूं तो यह मुझे त्रुटि भेजता है:

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)

मैंने जाँच की लेकिन मेरे पास प्रकट में अनुमतियाँ हैं, निम्नानुसार हैं:

<?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>

मैंने इंटरनेट पर खोज की लेकिन सभी त्रुटियाँ <uses-permission/>सिंटैक्स के बारे में थीं , क्या आप मुझे मदद कर सकते हैं?


आप Android के किस संस्करण का परीक्षण कर रहे हैं?
कॉमन्सवेयर सेप

मैं एंड्रॉइड 6.0 पर परीक्षण कर रहा हूं
नाथन लाउडजानी

1
निश्चित रूप से यह एंड्रॉइड के नीचे के संस्करण पर काम करेगा। एंड्रॉइड 6.0
फखर

क्या एंड्रॉइड 6 के लिए एक विशेष वाक्यविन्यास है? मैं कैसे सुनिश्चित कर सकता हूं कि यह नीचे दिए गए संस्करण पर काम करता है?
नाथन लाउडजानी

मेरा पिछला एप्लिकेशन अपडेट की अनुमति के बाद अपडेट किया targetsdkversionगया था जो काम नहीं कर रहा है जो पहले से ही सक्षम है। कृपया मदद करें2327READ_SMS
सागर

जवाबों:


237

( इस बारे में मेरे एक ब्लॉग पोस्ट से निम्नलिखित निकाला गया है )

आजकल आपकी अनुमति नहीं मिलने का बड़ा कारण यह है कि आपकी परियोजना की targetSdkVersionसंख्या 23 या अधिक है, और आप जो अनुरोध कर रहे हैं वह "खतरनाक" है। Android 6.0 में, यह शामिल हैं:

  • 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

इन अनुमतियों के लिए, न केवल आपके targetSdkVersion23+ ऐप में <uses-permission>तत्व (एस) होने की आवश्यकता है, बल्कि आपको एंड्रॉइड 6.0+ उपकरणों पर उपयोगकर्ता से रनटाइम पर उन अनुमतियों के लिए भी पूछना होगा, जैसे तरीकों का उपयोग करके checkSelfPermission()और requestPermissions()

अस्थायी वर्कअराउंड के रूप में, अपने targetSdkVersionनीचे 23 को गिराएं ।

हालांकि, आखिरकार, आपके पास targetSdkVersion23 या उच्चतर होने के लिए कुछ कारण होगा । उस समय, आपको नए रनटाइम अनुमति प्रणाली का उपयोग करने के लिए अपने ऐप को समायोजित करना होगा। Android प्रलेखन में इस विषय के लिए एक पृष्ठ है


2
बहुत-बहुत धन्यवाद, मैंने रिक्वेस्टपेपर्स () मेथड्स का इस्तेमाल किया और मैंने अच्छी तरह से काम किया
नाथन लाउडजानी

ठीक है, मैंने पहले भी यह प्रयास किया था, लेकिन ContextCompat.checkSelfPermission और ActivityCompat.requestPokes विधियाँ प्राप्त नहीं कर सका, वे मुझे विधि के नामों पर 'नहीं मिली' त्रुटि देते हैं। मुझे लगता है कि यह एक लापता पुस्तकालय के साथ करना है, यह एक v4 पैकेज में लगता है, लेकिन मेरी एकमात्र निर्भरता है compile 'com.android.support:appcompat-v7:22.2.1'। क्या मुझे इसे बदलकर v4 करना चाहिए?
ओजस्वी

2
@Ozzy: आपको 23.x.yवर्तमान में उपयोग किए जा रहे v22 के बजाय समर्थन पुस्तकालयों ( , x और y के वर्तमान मूल्यों के लिए) की एक v23 पीढ़ी पर होना चाहिए ।
कॉमन्सवेयर

धन्यवाद, भविष्य के लिए मुझे लगता है। अभी के लिए मैंने लक्ष्य को वापस बदलकर v22 कर दिया और भले ही एमुलेटर पर एसडी कार्ड स्टोरेज 200MB पर सेट किया गया था, इसने मुझे SD कार्ड नहीं माउंटेड एरर दिया। लेकिन फिर मैंने अपने फोन को डेवलपर मोड में जोड़ा और सब कुछ काम करता है। किसी कारण से SD कार्ड स्टोरेज v23 चलाने वाले एमुलेटर पर काम करता है लेकिन v22 नहीं।
ओज़ी

3
@NathanLoudjani क्या आप अपना कोड साझा करना चाहेंगे जो इसे लागू करता है? मैं ठीक उसी नाव में हूं और इसे अपनी गतिविधि में लगा रहा हूं।
3

29

एपीआई स्तर 23 से ऊपर आपको प्रोग्रामेटिक रूप से व्यावहारिक रूप से दिया जाएगा जैसे:

    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);

        }
    }

7

अनुरोध की अनुमति व्यावहारिक रूप से (एपीआई 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
}

"यदि एप्लिकेशन की अनुमति है, तो विधि CheckSelfPermission () PERMISSION_GRANTED लौटाता है, और ऐप ऑपरेशन के साथ आगे बढ़ सकता है।

यदि एप्लिकेशन के पास अनुमति नहीं है, तो विधि PERMISSION_DENIED लौटाती है, और ऐप को उपयोगकर्ता से अनुमति के लिए स्पष्ट रूप से पूछना होगा। आपको उस अनुमति के लिए उपयोगकर्ता को संकेत देना होगा, जैसा कि उपरोक्त कोड में दिखाया गया है। कॉलिंग अनुरोध () एक मानक Android संवाद लाता है, जिसे आप अनुकूलित नहीं कर सकते। "


हम यह रेखा कहां रखेंगे? एक्टिविटीकम्पॉट। क्रेकपाइप्स (यह, नया स्ट्रिंग [] {मेनिफेस्ट.पेरिशनिंग। END_SMS}, 1); और 1 का क्या उल्लेख है?
LizG


6

जब आप में घोषणा करते permissonहैं Manifestऔर यह काम नहीं करता है तो इसका मतलब है कि आप टास्क में प्रदर्शन कर रहे हैं MarshMallowऔर आपके लिए MarshMallowपरमिशन सेट है RunTime

इस तरह

ActivityCompat.requestPermissions();

6

कृपया नीचे दिए गए लिंक पर जाएं , https://developer.android.com/guide/topics/permissions/overview.html

अनुमतियों के साथ आरंभ करने के लिए कुछ नमूने भी वहां उपलब्ध हैं।

एंड्रॉइड को अधिक सुरक्षित बनाने के लिए अब डेवलपर्स को प्रकट में अनुमति का उल्लेख करना होगा और साथ ही उन्हें उपयोगकर्ता से काम चलाने के लिए समय पूछने के लिए कहना चाहिए। उन्हें खतरनाक अनुमति अनुभाग में वर्गीकृत किया गया है जो नीचे उल्लेखित हैं

पंचांग

READ_CALENDAR

WRITE_CALENDAR

कैमरा

CAMERA

संपर्क

READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS

स्थान

ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION

माइक्रोफोन

RECORD_AUDIO

फ़ोन

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

सेंसर

BODY_SENSORS

एसएमएस

SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS

भंडारण

READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE

2

मैंने इसे अपनी मुख्यता में जोड़ा, जो मेरी समस्या का समाधान करता है

       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.
            }
        }

2

यदि आप एंड्रॉइड संस्करण "23" या "23+" का उपयोग कर रहे हैं, तो ऐप आपको त्रुटियों को दिखाएगा जब आप कुछ भी एक्सेस करने की कोशिश कर रहे हैं जिसके लिए उपयोगकर्ता की अनुमति की आवश्यकता होती है। यदि आपने Android मेनिफ़ेस्ट में उन अनुमतियों को घोषित किया है, तो आपको रन-टाइम पर अनुमति माँगनी होगी।

इसे देखें: https://developer.android.com/training/permissions/requesting.html

लेकिन अगर आपने अपना पूरा एप्लिकेशन बनाया है और हर जगह पर बदलाव नहीं करना चाहते हैं तो थोड़ा धोखा पर्याप्त होगा।

"Build.gradle" फ़ाइल पर जाएं और लक्ष्य Sdk संस्करण को 22, 21 की तरह 23 से कम में बदलें।


1

कॉमन्सवेयर के जवाब के साथ,

एसएमएस संदेश सीमा निर्धारित करने के लिए एक सुरक्षा सेटिंग है (मैंने CM13 पर जाँच की)। यदि आप इसे "नहीं" पर सेट करते हैं, तो रनटाइम में SMS_SEND अनुमति प्राप्त करने के बाद भी, OS हर एसएमएस के लिए एक डायलॉग पॉपअप करेगा। सबसे अच्छी बात यह है कि इसे अधिकतम पर सेट करें।

यदि अधिकतम पर्याप्त नहीं है, तो रूट किए गए डिवाइस पर अधिकतम दर बढ़ाने के तरीके हैं।


0

आप अपने संदेशों तक पहुँचने के लिए इस कोड का उपयोग कर सकते हैं

नीचे दिए गए कोड का उपयोग करके एक डायलॉग खोलें:

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

नीचे दिए गए गतिविधि परिणाम प्राप्त करें:

@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
    }
}

या फ़ाइल build.gradleऔर चांच संख्या से targetSdkVersionकम संपादित करें और 23
अब ऊपर कोड की आवश्यकता नहीं है

ध्यान दें
कि यह मामला नहीं है, और यह सिर्फ एक शैक्षिक पहलू है


0

इसलिए मुझे संदेश भेजने और प्राप्त करने के लिए एक ऐप बनाना था लेकिन जब भी अनुमति दी गई तब भी मैं भेजने पर क्लिक करने पर भेजने की क्रिया क्रैश हो गई। मैंने रनटाइम अनुमतियों का अनुरोध किया था और उन्हें अनुमति दी थी, फिर भी मुझे एक दुर्घटना का सामना करना पड़ा, जिसमें प्रक्रिया को एसएमएस भेजने की अनुमति नहीं है। मैंने निम्नलिखित अनुमतियों की जाँच की थी:

adb shell dumpsys package <package-name>

अनुमति के लिए मेरे अनुरोध का क्रम था

  1. RECEIVE_SMS
  2. संदेश भेजो

मैंने अनुरोध के आदेश को वापस ले लिया और यह ठीक काम करता है। यह एक पूर्ण नए ऐप (अनइंस्टॉल-> इंस्टॉल -> परीक्षण) के साथ परीक्षण किया गया था। जवाब अजीब लग सकता है लेकिन बस इसे एक शॉट दें।

(यदि यह एक निश्चित क्रम में दिखाए गए तरीके से काम करता है, तो एंड्रॉइड में बग हो सकता है !!]


0

मुझे उम्मीद है कि बाहरी भंडारण के लिए लिखने का समाधान भी उपयोगी होगा

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;
        }
    }

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.