public void onClick(View view) {
if (view.getId() == R.id.button && ActivityCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
Log.d("STATE", "Call Button DOES NOT WORK");
return;
}
Log.d("STATE", "Call Button DOES WORK");
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:480-240-9255"));
startActivity(callIntent);
This code above keeps logging in the console that it does not work but I have the uses-permission for CALL_PHONE in my manifest file. I am not sure of any other permissions I would need or if the code is just incorrect?
So, if the permission is there then it's ok, but what if the permission is not there ?
Then, you need to request the permissions using requestPermissions()
Something like:-
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, requestCode)
Then, override the method onRequestPermissionsResult(),
to perform the required actions after the permission is granted (here you can start the activity using intent to make a phone call).
So you could do something like :-
int requestCode = 0;
public void onClick(View view)
{
if (view.getId() == R.id.button && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED)
{
Log.d("STATE", "Call Button DOES NOT WORK");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, requestCode);
return;
}
Log.d("STATE", "Call Button DOES WORK");
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:480-240-9255"));
startActivity(callIntent);
}
Then,
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == requestCode)
{
if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:480-240-9255"));
startActivity(callIntent);
}
}
So, this code will give the user a pop-up stating that does the device have access to make or receive phone calls. If you grant the permission, the call manger activity would be started.
I have a weird bug, I have an app that registers a Brodcast whenever I call to a number it pops up a webpage.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerBrodcasts();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CALL_PHONE, Manifest.permission.READ_CALL_LOG},
MY_PERMISSIONS_REQUEST);
} else {
Toast.makeText(this, "Brodcast registered.", Toast.LENGTH_SHORT).show();
finish();
}
}
private void registerBrodcasts(){
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
registerReceiver(new CallReceiver(), filter);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_PERMISSIONS_REQUEST) {
if (grantResults.length > 0) {
boolean phoneLogsPermission = grantResults[1] == PackageManager.PERMISSION_GRANTED;
boolean phoneCallPermision = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (phoneLogsPermission && phoneCallPermision) {
Toast.makeText(this, "Permissions granted, we can call now.", Toast.LENGTH_SHORT).show();
finish();
} else {
Toast.makeText(this, "Please give permissions to the app", Toast.LENGTH_SHORT).show();
}
}
}
}
So, this is how it works, When I open my app it pops up the two permissions I need to request, Phone Call and Phone Logs meanwhile I'm giving access to this permissions registerBrodcasts(); have launched and registered my brodcast.
But here is the bug, If I request the permissions at runtime and try to call after giving this permissions my brodcast does not launch, but, if I go to the app settings and give them manually, the brodcast works without problems.
I dont know why from my app giving this permissions does not register my brodcast but giving them manually does.
This is the brodcast
public class CallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context, "Intercepted call " + phoneNumber, Toast.LENGTH_LONG).show();
if (phoneNumber.equals("123456789")) {
Intent browserIntent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://myweb.com"));
browserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(browserIntent);
}
}
}
I suspect that when I give the permissions to the app, my brodcast has been registered without such permissions, but If I move the registerBrodcasts() method to my onRequestPermissionResults it also does not work
These are all my permissions, which I only need to ask for call_phone and read_call_logs
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.NEW_OUTGOING_CALL" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
Basically what I'm trying to do is create a simple app that uses the default camera app to take a picture, then I want to display that image in a new activity within an ImageView, but everything I've tried has resulted in
java.io.FileNotFoundException: /storage/emulated/0/imageToProcess.jpg: open failed: ENOENT (No such file or directory)
I've included the correct permissions (maybe even too many) in the manifest:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
and I'm also manually requesting permissions if need be in the main activity:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, 1);
}
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
if(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
}
so I don't think the issue is with read/write permissions.
In my main activity's xml file, I've created a button with an onClick listener that calls the following method:
public void openCamera(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(Environment.getExternalStorageDirectory() + File.separator + "imageToProcess.jpg");
imgUri = Uri.fromFile(f);
intent.putExtra("imgUri", imgUri.toString());
startActivityForResult(intent, TAKE_PICTURE);
}
Here's the onActivityResult() method I defined to create a new intent and pass the uri to the new activity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if(requestCode == TAKE_PICTURE && resultCode == Activity.RESULT_OK) {
Intent camResult = new Intent(this, ShowCameraResult.class);
camResult.putExtra("imgUri", imgUri.toString());
startActivity(camResult);
}
}
NOTE: imgUri and TAKE_PICTURE are defined at the top of the class as protected static final int TAKE_PICTURE = 1; and private Uri imgUri;
Lastly, here is my ShowCameraResult activity
public class ShowCameraResult extends AppCompatActivity {
private Bitmap mImageBitmap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_camera_result);
ImageView imageView = (ImageView)findViewById(R.id.imageView);
String filePath = getIntent().getStringExtra("imgUri");
Log.d("ShowCameraResult", "directory: " + filePath);
try {
mImageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(filePath));
imageView.setImageBitmap(mImageBitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
The Log.d method call above returns
ShowCameraResult: directory: file:///storage/emulated/0/imageToProcess.jpg
This leads me to believe that the image result from the camera isn't actually being saved into my imageToProcess.jpg file, but I could be very wrong as this is the first real android project I've worked on.
So my question is: Where did I go wrong?
Any help is greatly appreciated, thank you!
ITs returning a file, not a content resolver uri. Just decode the file with BitmapFactory.
I want to check a permission inside a fragment.
my code:
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
android.Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation 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(getActivity(),
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
1);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
but onRequestPermissionsResult not called after allow or deny.
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
Log.e("test","0");
// 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.
//yes
Log.e("test","1");
Intent intent = new Intent(getActivity(), MapsActivity.class);
intent.putExtra("latitude", 35.694828);
intent.putExtra("longitude", 51.378129);
startActivity(intent);
} else {
utilityFunctions.showSweetAlertWarning(getActivity(),r.getString(R.string.str_warning_title_empty),
r.getString(R.string.str_you_must_allow_this_permission_toast),
r.getString(R.string.str_warning_btn_login));
Log.e("test","2");
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
This is how I did, it works for me. Thanks!
For Activity :
ActivityCompat.requestPermissions(this, permissionsList, REQUEST_CODE);
For Fragment :
requestPermissions(permissionsList, REQUEST_CODE);
Fragment has requestPermissions() and onRequestPermissionsResult() methods, use it.
But checkSelfPermission() is from ActivityCompat (not require Activity, only Context).
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions( //Method of Fragment
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS_CODE_WRITE_STORAGE
);
} else {
downloadImage();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == REQUEST_PERMISSIONS_CODE_WRITE_STORAGE) {
if (permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
proceedWithSdCard();
}
}
}
I have done following to check a permission inside a fragment.
if (ActivityCompat.checkSelfPermission(getContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(getContext(),
android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(getActivity(),
new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION,
android.Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION);
} else {
Log.e("DB", "PERMISSION GRANTED");
}
Update
Since Fragment.requestPermissions is now deprecated, Google advises using registerForActivityResult instead.
I have done the request like this:
val permissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted ->
if (isGranted) {
// Do if the permission is granted
}
else {
// Do otherwise
}
}
permissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
For more documentation on this method you can check this link.
Check Permissions from Fragment (the 2021 way)
The registerForActivityResult() method in fragment is now deprecated. The deprecation message suggests to use registerForActivityResult. So after some trial and errors, here is the 2021 way:
Suppose your fragment's name is AwesomeFragment. Then in the constructor (before the fragment's onCreate method to be precise), you initialize ActivityResultLauncher<String[]> activityResultLauncher.
java version
private ActivityResultLauncher<String[]> activityResultLauncher;
public AwrsomeFragment() {
activityResultLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
#Override
public void onActivityResult(Map<String, Boolean> result) {
Log.e("activityResultLauncher", ""+result.toString());
Boolean areAllGranted = true;
for(Boolean b : result.values()) {
areAllGranted = areAllGranted && b;
}
if(areAllGranted) {
capturePhoto();
}
}
});
}
Then maybe on some button click, you invoke the launch method:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
String[] appPerms;
appPerms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
this.cameraClick.setOnClickListener(v -> {
this.activityResultLauncher.launch(appPerms);
});
}
kotlin version
private var activityResultLauncher: ActivityResultLauncher<Array<String>>
init{
this.activityResultLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()) {result ->
var allAreGranted = true
for(b in result.values) {
allAreGranted = allAreGranted && b
}
if(allAreGranted) {
capturePhoto()
}
}
}
// --- ---
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// ... ... init views / binding... ...
someBtn.setOnClickListener{
val appPerms = arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CAMERA
)
activityResultLauncher.launch(appPerms)
}
}
To handle permissions in a Fragment call requestPermissions method. If you override onRequestPermissionsResult method in both fragment and activity, containing that fragment, make sure to call super.onRequestPermissionsResult(...) in the activity method to propagate call to the onRequestPermissionsResult method in the fragment.
Using Kotlin, you call requestPermissions(arrayOf(Manifest.permission.THE_PERMISSION_CODE_YOU_WANT), PERMISSION_REQUEST_CODE) and add the following override to your fragment
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out kotlin.String>, grantResults: IntArray): Unit {
}
onRequestPermissionsResult is invoked in the activity not the fragment. Try overriding onRequestPermissionsResult in the activity instead.
What worked for me was calling the onRequestPermissionsResult method in the activity inside which fragment is implemented rather than calling it in fragment itself.
Inside onCreateView method in fragment:
Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int permissionCheck = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_MEDIA);
}else{
//Do your work
fetchMethod();
}
}
});
In the Activity which helps to implement fragment, outside of onCreate method:
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_MEDIA:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
fetchMethod();
}else{
Toast.makeText(getApplicationContext(), "Permission not granted!", Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
If you closed your permission of app from settings , you can not open your permission from code or your android version lower than Marshmallow.
You can check this documentation
https://developer.android.com/training/permissions/requesting.html
And this is a example
https://www.learn2crack.com/2015/10/android-marshmallow-permissions.html
I was getting tripped up using checkSelfPermission() in a Fragment and wondering what would be the best approach for Context being null (Kotlin specific)... should I use !! or something else?
I went with something else based on code I found in iosched. Have a look at the sample below, and remember, before the Fragment is attached to an Activity, the Context will be null.
private fun fineLocationPermissionApproved(): Boolean {
val context = context ?: return false
return PackageManager.PERMISSION_GRANTED == checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
)
}
To check permission within a fragment, I did the following.
Before onCreateView in Fragment add the following,
private final int STORAGE_PERMISSION_CODE = 1;
private Activity mActivity;
#Override
public void onAttach(#NotNull Context context) {
super.onAttach(context);
mActivity = (Activity) context;
}
Check the permission,
if ((ContextCompat.checkSelfPermission(mActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED))
{
if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(mActivity)
.setTitle("Permission needed")
.setMessage("Allow "+getResources().getString(R.string.app_name)+" to access your storage?")
.setPositiveButton("ok", (dialog, which) -> ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE)
)
.setNegativeButton("cancel", (dialog, which) -> {
dialog.dismiss();
Toast.makeText(mActivity, "Please allow this permission!", Toast.LENGTH_SHORT).show();
})
.create().show();
} else {
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
}
}
Place the following code in MainActivity to enable permission from the app's settings if the user denied the permission forever.
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == STORAGE_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission GRANTED", Toast.LENGTH_SHORT).show();
} else {
//Now further we check if used denied permanently or not
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// 1. The user has temporarily denied permission.
Toast.makeText(MainActivity.this, "Permission DENIED", Toast.LENGTH_SHORT).show();
} else {
// 2. Permission has been denied.
// From here, you can access theĀ setting's page.
new AlertDialog.Builder(MainActivity.this)
.setTitle("Permission Required")
.setMessage("This permission was already declined by you. Please open settings, go to \"Permissions\", and allow the permission.")
.setPositiveButton("Settings", (dialog, which) -> {
final Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + MainActivity.this.getPackageName()));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
MainActivity.this.startActivity(i);
})
.setNegativeButton("cancel", (dialog, which) -> {
dialog.dismiss();
Toast.makeText(MainActivity.this, "Please allow this permission!", Toast.LENGTH_SHORT).show();
})
.create().show();
}
}
}
}
If anyone is interested in Kotlin call permission.
private fun directCall() {
val numberText = phoneNo
val intent = Intent(Intent.ACTION_CALL)
intent.data = Uri.parse("tel:$numberText")
if (ActivityCompat.checkSelfPermission(requireContext(),Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED)
{
if(ActivityCompat.shouldShowRequestPermissionRationale(requireActivity(), Manifest.permission.CALL_PHONE)){
Toast.makeText(requireContext(), "Permission denied.", Toast.LENGTH_LONG).show()
return //<-- Check user input history if user already denied then second time not request and not ask.
}
else{
requestPermissions(arrayOf(Manifest.permission.CALL_PHONE),1)
return //<--return will call onRequestPermissionsResult and wait for user input.
}
}
startActivity(intent)
}
override fun onRequestPermissionsResult(requestCode: Int,permissions: Array<out String>,grantResults: IntArray) {
if (requestCode == requestPhoneCall && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
directCall()
}else{
Toast.makeText(requireContext(), "Permission denied", Toast.LENGTH_LONG).show()
return
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ContextCompat.checkSelfPermission( getActivity(),Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
its working in my case
checkSelfPermission not working in fragments?? we can try this code
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
ActivityCompat.checkSelfPermission(
getActivity(),Manifest.permission.READ_CONTACTS) !=
PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[].
{Manifest.permission.READ_CONTACTS},
PERMISSIONS_REQUEST_READ_CONTACTS); //After this point you wait for
callback in onRequestPermissionsResult(int, String[], int[]) overriden
method } else { // Android version is lesser than 6.0 or the permission
is already granted. List<String> contacts = getContactNames();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ActivityCompat.checkSelfPermission(getActivity(),Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{
Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
//After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method
} else {
// Android version is lesser than 6.0 or the permission is already granted.
List contacts = getContactNames();
}
To check permissions inside a fragment
we should use requestPermissions instead of ActivityCompat.requestPermissions
// Replace with Permissions you need to check.
requestPermissions(arrayOf(
"android.permission.ACCESS_COARSE_LOCATION",
"android.permission.ACCESS_FINE_LOCATION"
), YOUR_REQUEST_CODE)
Then override onRequestPermissionsResult as uduel
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == YOUR_REQUEST_CODE) {
if (
grantResults.isNotEmpty() &&
grantResults[0] == PackageManager.PERMISSION_GRANTED
) {
// Permission granted
Log.d("onRequestPermissionsResult", "permission granted")
} else {
// Permission was denied. Display an error message.
Log.d("onRequestPermissionsResult", "permission denied")
}
}
}
If the device is running Android 6.0 or higher when im trying to get phone number using getLine1Number():
java.lang.SecurityException: Requires READ_PHONE_STATE: Neither user 10184 nor current process has android.permission.READ_PHONE_STATE.
This is coming out.
I declared permission as :
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
In Android 6.0, you need to explicitly ask the user to grant the permissions. Just declaring it in the manifest isn't enough.
This article in the docs is a great place to start learning the new model, but I'll give a brief summary.
Every time you perform an action that requires a "dangerous permission," you need to check if the permission is currently granted, because the user can revoke it at any time.
This can be done with the checkSelfPermission method.
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
// We do not have this permission. Let's ask the user
}
You can request the permission with the requestPermissions method, as such
ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.READ_PHONE_STATE}, PERMISSION_READ_STATE);
Where PERMISSION_READ_STATE is a constant integer defined by you to check in the callback method later.
You will then override onRequestPermissionsResult in your activity and see if the permission was granted. If it was, you can go ahead and preform the dangerous action.
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_READ_STATE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission granted!
// you may now do the action that requires this permission
} else {
// permission denied
}
return;
}
}
}
public class MainActivity extends AppCompatActivity {
TextView textView;
String device_unique_id,IMEI;
private static final int MY_PERMISSIONS_REQUEST_READ_PHONE_STATE = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.textView);
}
public void GetImei(View view)
{
loadIMEI();
}
public void loadIMEI() {
// Check if the READ_PHONE_STATE permission is already available.
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_PHONE_STATE)) {
// get_imei_data();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE},
MY_PERMISSIONS_REQUEST_READ_PHONE_STATE);
}
} else {
TelephonyManager mngr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
IMEI = mngr.getDeviceId();
device_unique_id = Settings.Secure.getString(this.getContentResolver(),
Settings.Secure.ANDROID_ID);
textView.setText(device_unique_id+"----"+mngr.getDeviceId());
// READ_PHONE_STATE permission is already been granted.
Toast.makeText(this,"Alredy granted",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,#NonNull int[] grantResults) {
if (requestCode == MY_PERMISSIONS_REQUEST_READ_PHONE_STATE) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Toast.makeText(this,"Alredy DONE",Toast.LENGTH_SHORT).show();
TelephonyManager mngr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
IMEI = mngr.getDeviceId();
device_unique_id = Settings.Secure.getString(this.getContentResolver(),Settings.Secure.ANDROID_ID);
textView.setText(device_unique_id+"----"+mngr.getDeviceId());
} else {
Toast.makeText(this,"ehgehfg",Toast.LENGTH_SHORT).show();
}
}
}