Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Commit

Permalink
Handle Android API 23 Permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
pbakondy committed Feb 14, 2016
1 parent b9959e3 commit c009c7d
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 22 deletions.
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Additional return values:
* `isNetworkRoaming`: Boolean - true if the device is considered roaming on the current network, for GSM purposes

<sup>1)</sup> Notice: the content of phoneNumber is unreliable (see [this](http://stackoverflow.com/questions/7922734/getting-reliable-msisdn-from-android-phone-voicemailnumber-line1number) and [this](http://stackoverflow.com/questions/25861064/retrieving-line1-number-from-telephonymanager-in-android) article).
Sometimes phoneNumber value is only an empty string.
Sometimes phoneNumber is only an empty string.

### Android Emulator results

Expand Down Expand Up @@ -153,6 +153,35 @@ Sometimes phoneNumber value is only an empty string.
| 4 | `SIM_STATE_NETWORK_LOCKED` | Locked: requires a network PIN to unlock
| 5 | `SIM_STATE_READY` | Ready

### Android 6.0 Permissions

Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.

If the device is running Android 6.0 or higher, **and** your app's target SDK is 23 or higher: The app has to list the permissions in the manifest, **and** it must request each dangerous permission it needs while the app is running. The user can grant or deny each permission, and the app can continue to run with limited capabilities even if the user denies a permission request.

Note: Beginning with Android 6.0 (API level 23), users can revoke permissions from any app at any time, even if the app targets a lower API level. You should test your app to verify that it behaves properly when it's missing a needed permission, regardless of what API level your app targets.

```js
// check permission
function hasReadPermission() {
window.plugins.sim.hasReadPermission(successCallback, errorCallback);
}

// request permission
function requestReadPermission() {
// no callbacks required as this opens a popup which returns async
window.plugins.sim.requestReadPermission();
}
```

This plugin needs `READ_PHONE_STATE` permission for getting the following values:

* `phoneNumber`
* `deviceId`
* `deviceSoftwareVersion`
* `simSerialNumber`
* `subscriberId`


## iOS Quirks

Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "cordova-plugin-sim",
"version": "1.1.0",
"description": "A plugin to get the device's SIM data (carrier name, mcc mnc, country code, telephonenumber, etc)",
"version": "1.2.0",
"description": "A plugin to get the device's SIM data (carrier name, mcc mnc, country code, telephonenumber, imei, etc)",
"cordova": {
"id": "cordova-plugin-sim",
"platforms": [
Expand All @@ -24,6 +24,7 @@
"mcc",
"mnc",
"telephonenumber",
"imei",
"ecosystem:cordova",
"cordova-android",
"cordova-ios",
Expand Down
7 changes: 4 additions & 3 deletions plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="cordova-plugin-sim"
version="1.1.0">
version="1.2.0">
<name>SIM</name>
<description>A plugin to get the device's SIM data (carrier name, mcc mnc, country code, telephonenumber, etc)</description>
<description>A plugin to get the device's SIM data (carrier name, mcc mnc, country code, telephonenumber, imei, etc)</description>
<license>MIT</license>
<keywords>cordova,sim,carrier,mcc,mnc,telephonenumber</keywords>
<repo>https://github.com/pbakondy/cordova-plugin-sim</repo>
Expand All @@ -26,7 +26,8 @@
</feature>
</config-file>

<!-- for method getLine1Number() -->
<framework src="com.android.support:support-v4:+" />

<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
</config-file>
Expand Down
85 changes: 72 additions & 13 deletions src/android/com/pbakondy/Sim.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,54 @@
// class TelephonyManager
// http://developer.android.com/reference/android/telephony/TelephonyManager.html

// permissions
// http://developer.android.com/training/permissions/requesting.html

package com.pbakondy;

import android.app.Activity;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;

import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.Manifest;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.telephony.TelephonyManager;

public class Sim extends CordovaPlugin {

private static final String GET_SIM_INFO = "getSimInfo";
private static final String HAS_READ_PERMISSION = "hasReadPermission";
private static final String REQUEST_READ_PERMISSION = "requestReadPermission";

private CallbackContext callback;

@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if (action.equals("getSimInfo")) {
callback = callbackContext;

if (GET_SIM_INFO.equals(action)) {
Context context = this.cordova.getActivity().getApplicationContext();

TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

String phoneNumber = manager.getLine1Number();
String phoneNumber = "";
String countryCode = manager.getSimCountryIso();
String simOperator = manager.getSimOperator();
String carrierName = manager.getSimOperatorName();

String deviceId = manager.getDeviceId();
String deviceSoftwareVersion = manager.getDeviceSoftwareVersion();
String simSerialNumber = manager.getSimSerialNumber();
String subscriberId = manager.getSubscriberId();
String deviceId = "";
String deviceSoftwareVersion = "";
String simSerialNumber = "";
String subscriberId = "";

int callState = manager.getCallState();
int dataActivity = manager.getDataActivity();
Expand All @@ -46,6 +64,14 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo

boolean isNetworkRoaming = manager.isNetworkRoaming();

if (simPermissionGranted(Manifest.permission.READ_PHONE_STATE)) {
phoneNumber = manager.getLine1Number();
deviceId = manager.getDeviceId();
deviceSoftwareVersion = manager.getDeviceSoftwareVersion();
simSerialNumber = manager.getSimSerialNumber();
subscriberId = manager.getSubscriberId();
}

String mcc = "";
String mnc = "";

Expand All @@ -60,12 +86,6 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo
result.put("countryCode", countryCode);
result.put("mcc", mcc);
result.put("mnc", mnc);
result.put("phoneNumber", phoneNumber);

result.put("deviceId", deviceId);
result.put("deviceSoftwareVersion", deviceSoftwareVersion);
result.put("simSerialNumber", simSerialNumber);
result.put("subscriberId", subscriberId);

result.put("callState", callState);
result.put("dataActivity", dataActivity);
Expand All @@ -75,11 +95,50 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo

result.put("isNetworkRoaming", isNetworkRoaming);

if (simPermissionGranted(Manifest.permission.READ_PHONE_STATE)) {
result.put("phoneNumber", phoneNumber);
result.put("deviceId", deviceId);
result.put("deviceSoftwareVersion", deviceSoftwareVersion);
result.put("simSerialNumber", simSerialNumber);
result.put("subscriberId", subscriberId);
}

callbackContext.success(result);

return true;
} else if (HAS_READ_PERMISSION.equals(action)) {
hasReadPermission();
return true;
} else if (REQUEST_READ_PERMISSION.equals(action)) {
requestReadPermission();
return true;
} else {
return false;
}
}

private void hasReadPermission() {
this.callback.sendPluginResult(new PluginResult(PluginResult.Status.OK,
simPermissionGranted(Manifest.permission.READ_PHONE_STATE)));
}

private void requestReadPermission() {
requestPermission(Manifest.permission.READ_PHONE_STATE);
}

private boolean simPermissionGranted(String type) {
if (Build.VERSION.SDK_INT < 23) {
return true;
}
return (PackageManager.PERMISSION_GRANTED ==
ContextCompat.checkSelfPermission(this.cordova.getActivity(), type));
}

private void requestPermission(String type) {
if (!simPermissionGranted(type)) {
ActivityCompat.requestPermissions(this.cordova.getActivity(), new String[]{type}, 12345);
}
this.callback.success();
}

}
12 changes: 9 additions & 3 deletions www/sim.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
var sim = {
getSimInfo: function (successCallback, errorCallback) {
getSimInfo: function(successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, 'Sim', 'getSimInfo', []);
},
hasReadPermission: function(successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, 'Sim', 'hasReadPermission', []);
},
requestReadPermission: function(successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, 'Sim', 'requestReadPermission', []);
}
}
};

cordova.addConstructor(function () {
cordova.addConstructor(function() {
if (!window.plugins) {
window.plugins = {};
}
Expand Down

0 comments on commit c009c7d

Please sign in to comment.