I am trying to request some permission for my app inside the launcher activity. This activity only checks for permissions and prompts the user asking for missing permission. What I want to do is after 1.5 seconds, if the user was prompted and accepted/denied the permissions required, the main activity is started, displaying the dashboard of the application. Now, the problem is that onRequestPermissionResult is not called no matter what I do and I don't understand where the problem comes from. I mention that the permissions are requested successfully, the user being prompted and being able to accept them or deny them, but the callback is not triggered somehow.
Here is my activity code:
public class LauncherActivity extends AppCompatActivity {
public static final String TAG = LauncherActivity.class.getSimpleName();
private boolean permissionsGiven;
private static final String[] REQUIRED_PERMISSIONS =
new String[] {
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.CHANGE_WIFI_STATE,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
};
private static final int REQUEST_CODE_REQUIRED_PERMISSIONS = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launcher);
if (!hasPermissions(this, REQUIRED_PERMISSIONS)) {
permissionsGiven = false;
Log.d(TAG, "onCreate: app does not have all the required permissions. Requesting permissions...");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(
this,
REQUIRED_PERMISSIONS,
REQUEST_CODE_REQUIRED_PERMISSIONS
);
}
} else {
permissionsGiven = true;
}
Runnable enterApplication = new Runnable() {
#Override
public void run() {
while (!permissionsGiven);
SharedPreferences loginPreferences = getApplicationContext().getSharedPreferences("LOGIN_DETAILS", MODE_PRIVATE);
boolean signedIn = loginPreferences.getBoolean("signedIn", false);
if (!signedIn) {
Log.d(TAG, "onCreate: user is not signed in. Sending him to login activity...");
sendUserToLoginActivity();
} else {
sendUserToMainActivity();
}
}
};
Handler launcherHandler = new Handler();
launcherHandler.postDelayed(enterApplication, 1500);
}
private static boolean hasPermissions(Context context, String... permissions) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
#CallSuper
#Override
public void onRequestPermissionsResult(
int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode != REQUEST_CODE_REQUIRED_PERMISSIONS) {
return;
}
permissionsGiven = true;
for (int grantResult : grantResults) {
if (grantResult == PackageManager.PERMISSION_DENIED) {
Toast.makeText(this, "Missing permissions", Toast.LENGTH_LONG).show();
finish();
return;
}
}
recreate();
}
private void sendUserToLoginActivity() {
Log.d(TAG, "sendUserToLoginActivity: starting login activity...");
Intent loginIntent = new Intent(LauncherActivity.this, SignInActivity.class);
loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(loginIntent);
finish();
}
private void sendUserToMainActivity() {
Log.d(TAG, "sendUserToMainActivity: starting main activity...");
Intent mainIntent = new Intent(LauncherActivity.this, MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(mainIntent);
finish();
}
}
Can anyone help me understand what am I doing wrong and how can I trigger onRequestPermissionsResult so I can start the next activity inside the app?
recreate();
I never saw that method.
Dont call it for a test and place a Toast instead.
I wonder how you know that it is not triggered.
Further i would not use a thread that is waiting for a variable to change its value.
Further you dont need threads at all. Just call the code in onCreate or onRequestPermissionsResult. You can place all that code in a function.
Related
I have two activities: a Main, as well a RuntimePermissionManager, which is started first whenever my app is opened.
The app works as expected when the user allows the runtime permission, but when they deny it, instead of the AlertDialog showing up with the permission rationale, the permission dialog is closed completely, and I just get an infinite splash screen (since I have set it to always be on screen during the lifetime of its parent activity).
I have copied the permission logic straight from the RuntimePermissionsBasic example bundled with Android Studio, and just replaced the Snackbar with an AlertDialog, so I don’t see why my app isn’t working.
Here’s the complete RuntimePermissionManager activity for reference.
Thanks.
public class RuntimePermissionManager extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
private static final String TAG = "RuntimePermissionManager";
private static final String PERMISSION = Manifest.permission.WRITE_EXTERNAL_STORAGE;
private static final int PERMISSION_ID = 0;
#Override
protected void onCreate(final Bundle savedInstanceState) {
final SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
super.onCreate(savedInstanceState);
// This ensures no hiccups while the splash screen is active.
splashScreen.setKeepOnScreenCondition(() -> true);
checkRuntimePermissionStatus();
ThreadManager.unpackCriticalAssets(getApplicationContext());
}
#Override
public void onRequestPermissionsResult(final int requestCode, #NonNull final String[] permissions, #NonNull final int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_ID) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Runtime permission has been granted.");
startMainActivity();
} else {
Log.e(TAG, "Runtime permission has been denied.");
}
}
}
private void checkRuntimePermissionStatus() {
if (ActivityCompat.checkSelfPermission(this, PERMISSION) == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Runtime permission has been granted.");
startMainActivity();
} else {
requestRuntimePermission();
}
}
private void requestRuntimePermission() {
System.out.println(ActivityCompat.shouldShowRequestPermissionRationale(this, PERMISSION));
if (ActivityCompat.shouldShowRequestPermissionRationale(this, PERMISSION)) {
System.out.println("HERE1");
showPermissionRationaleDialog(R.string.permission_rationale_title, R.string.permission_rationale_message);
} else {
Log.e(TAG, "Runtime permission has been denied.");
ActivityCompat.requestPermissions(this, new String[]{PERMISSION}, PERMISSION_ID);
}
}
private void showPermissionRationaleDialog(final int title, final int message) {
System.out.println("HERE2");
AlertDialog.Builder builder = new AlertDialog.Builder(RuntimePermissionManager.this);
builder.setTitle(title).setMessage(message).setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(RuntimePermissionManager.this, new String[]{PERMISSION}, PERMISSION_ID);
}
});
builder.create().show();
}
private void startMainActivity() {
Intent intent = new Intent(this, Main.class);
startActivity(intent);
}
}
The code I have written should check the permissions in the OnStart method and regardless of the outcome of whether the user gives access, the same two pieces of code should execute:
Starting my service
Auto-login the user if they have provided credentials before
If I retype my credentials and turn the app on and off then on again - then for around 2-5 minutes it will automatically log me in. If I have the app off for longer than that, the autologin will not work.
OnStart:
#Override
protected void onStart() {
super.onStart();
List<String> permissions = new ArrayList<>();
permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
permissions.add(Manifest.permission.ACTIVITY_RECOGNITION);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
permissions.add(Manifest.permission.SCHEDULE_EXACT_ALARM);
checkPermission(permissions.toArray(new String[0]), INITIAL_REQUESTS_CODE);
}
checkPermission Function:
public void checkPermission(String[] permissions, int requestCode) {
// Checking if permission is not granted
boolean ungrantedPermissions = false;
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_DENIED) {
ungrantedPermissions = true;
break;
}
}
if (ungrantedPermissions)
ActivityCompat.requestPermissions(this, permissions, requestCode);
else{
startStepCounterService();
attemptLoginWithSavedCredentials();
}
}
onRequestPermissionResult:
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode,
permissions,
grantResults);
startStepCounterService();
attemptLoginWithSavedCredentials();
}
startStepCounterService Function:
private void startStepCounterService() {
if(!isMyServiceRunning(StepCounterService.class))
{
Intent newIntent = new Intent(this, StepCounterService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(newIntent);
} else {
startService(newIntent);
}
}
}
attemptLoginWithSavedCredentials Function:
private void attemptLoginWithSavedCredentials() {
String savedUsername = SaveSharedPreference.getUserName(this);
String savedPassword = SaveSharedPreference.getUserPassword(this);
if(!savedUsername.isEmpty() && !savedPassword.isEmpty())
{
LoadingExtensions.showLoadingIcon(loadingIndicator, rootView);
loginManager.login(savedUsername, savedPassword);
}
}
This question already has answers here:
How to make a phone call using intent in Android?
(21 answers)
How to make a phone call programmatically?
(10 answers)
How to make a phone call button in Android for Marshmallow
(3 answers)
How to ask permission to make phone call from Android from Android version Marshmallow onwards?
(7 answers)
Closed 4 years ago.
I used following code for phone call.But the call is not working .can anyone help me? I also given manifest Call Phone permission.
call = (TextView) findViewById(R.id.GuestPhoneNo1);
call.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String no = call.getText().toString();
// Toast.makeText(Accepted_Details.this, no, Toast.LENGTH_SHORT).show();
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" + no));
/*if (ActivityCompat.checkSelfPermission(Accepted_Details.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}*/
startActivity(callIntent);
}
You can use the following code,
I also add the permission popup for above marshmallow.
Uri call = Uri.parse("tel:" + mobile_number);
Intent surf = new Intent(Intent.ACTION_CALL, call);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(TrackActivity.this, Manifest.permission.CALL_PHONE)) {
ActivityCompat.requestPermissions(TrackActivity.this, new String[]{Manifest.permission.CALL_PHONE}, EXTERNAL_STORAGE_PERMISSION_CONSTANT);
} else if (permissionStatus.getBoolean(Manifest.permission.CALL_PHONE, false)) {
AlertDialog.Builder builder = new AlertDialog.Builder(TrackActivity.this);
builder.setTitle("Need call Permission");
builder.setMessage("This app needs call permission.");
builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
Toast.makeText(getBaseContext(), "Go to Permissions to Grant call", Toast.LENGTH_LONG).show();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
} else {
ActivityCompat.requestPermissions(TrackActivity.this, new String[]{Manifest.permission.CALL_PHONE}, EXTERNAL_STORAGE_PERMISSION_CONSTANT);
}
SharedPreferences.Editor editor = permissionStatus.edit();
editor.putBoolean(Manifest.permission.CALL_PHONE, true);
editor.apply();
} else {
startActivity(surf);
}
Even with having added the permissions in the manifest file you need to request for the permission before you run the code that makes the call
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, MAKE_CALL_PERMISSION_REQUEST_CODE);
the whole thing could look like this
public class MainActivity extends AppCompatActivity {
private static final int MAKE_CALL_PERMISSION_REQUEST_CODE = 1;
private Button dial;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dial = (Button) findViewById(R.id.dial);
final EditText numberToDial = (EditText) findViewById(R.id.number);
dial.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String phoneNumber = numberToDial.getText().toString();
if (!TextUtils.isEmpty(phoneNumber)) {
if (checkPermission(Manifest.permission.CALL_PHONE)) {
String dial = "tel:" + phoneNumber;
startActivity(new Intent(Intent.ACTION_CALL, Uri.parse(dial)));
} else {
Toast.makeText(MainActivity.this, "Permission Call Phone denied", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(MainActivity.this, "Enter a phone number", Toast.LENGTH_SHORT).show();
}
}
});
if (checkPermission(Manifest.permission.CALL_PHONE)) {
dial.setEnabled(true);
} else {
dial.setEnabled(false);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, MAKE_CALL_PERMISSION_REQUEST_CODE);
}
}
private boolean checkPermission(String permission) {
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch(requestCode) {
case MAKE_CALL_PERMISSION_REQUEST_CODE :
if (grantResults.length > 0 && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
dial.setEnabled(true);
Toast.makeText(this, "You can call the number by clicking on the button", Toast.LENGTH_SHORT).show();
}
return;
}
}
}
i have method for get runtime permission i searched for that long but still have no answer can anyone help me to modify my code ? cause its never show request dialog for get user permission after user accept permission move to next activity
here my code that i made but some how its never made a request
public class perm extends AppCompatActivity {
private static final int REQUEST_PERMISSION_SETTING = 200;
private View view;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dash);
isPermissionGranted();
}
public boolean isPermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(Manifest.permission.CALL_PHONE)
== PackageManager.PERMISSION_GRANTED) {
Log.v("TAG","Permission is granted");
return true;
} else {
Log.v("TAG","Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, REQUEST_PERMISSION_SETTING);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v("TAG","Permission is granted");
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if(permissions.length == 0){
return;
}
boolean allPermissionsGranted = true;
if(grantResults.length>0){
for(int grantResult: grantResults){
if(grantResult != PackageManager.PERMISSION_GRANTED){
allPermissionsGranted = false;
break;
}
}
}
if(!allPermissionsGranted){
boolean somePermissionsForeverDenied = false;
for(String permission: permissions){
if(ActivityCompat.shouldShowRequestPermissionRationale(this, permission)){
//denied
Log.e("denied", permission);
}else{
if(ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED){
//allowed
Log.e("allowed", permission);
} else{
//set to never ask again
Log.e("set to never ask again", permission);
somePermissionsForeverDenied = true;
}
}
}
if(somePermissionsForeverDenied){
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Permissions Required")
.setMessage("You have forcefully denied some of the required permissions " +
"for this action. Please open settings, go to permissions and allow them.")
.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getPackageName(), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setCancelable(false)
.create()
.show();
}
} else {
switch (requestCode) {
//act according to the request code used while requesting the permission(s).
}
}
}
}
i am making an android app on my music player in which i have populated all the songs in my device using a listview,but in android 6.0 my app crashes as i open it.It doesn't crash anymore when i give it storage permissions manually in app info,and then my songs are displayed.
I have used the android 6.0 request permissions,and it results in asking the user for asking access to storage,but then it doesn't shows the list anymore.I am stuck on this...!
MainActivity.java
public class MainActivity extends AppCompatActivity implements MediaPlayerControl {
private ArrayList<Song> songList;
private ListView songView;
private MusicController controller;
private MusicService musicSrv;
private Intent playIntent;
private boolean musicBound=false;
private boolean paused=false, playbackPaused=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
songView = (ListView) findViewById(R.id.song_list);
songList = new ArrayList<Song>();
//Android 6.0
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
} else {
}
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1002);
}
}
//Android 6.0
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode){
case 1002:
if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
getSongList();
// List songs in Alphabetical Order
Collections.sort(songList, new Comparator<Song>() {
public int compare(Song a, Song b) {
return a.getTitle().compareTo(b.getTitle());
}
});
SongAdapter songAdt = new SongAdapter(this, songList);
songView.setAdapter(songAdt);
setController();
}else{
}
return;
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_shuffle:
musicSrv.setShuffle();
break;
case R.id.action_end:
stopService(playIntent);
musicSrv = null;
System.exit(0);
break;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onStart() {
super.onStart();
if(playIntent==null) {
playIntent = new Intent(this, MusicService.class);
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}
}
#Override
protected void onPause() {
super.onPause();
paused=true;
}
#Override
protected void onResume() {
super.onResume();
if(paused){
setController();
paused=false;
}
}
#Override
protected void onStop() {
controller.hide();
super.onStop();
}
#Override
protected void onDestroy() {
stopService(playIntent);
musicSrv=null;
super.onDestroy();
}
public void songPicked(View view){
musicSrv.setSong(Integer.parseInt(view.getTag().toString()));
musicSrv.playSong();
if(playbackPaused){
setController();
playbackPaused=false;
}controller.show(0);
}
//connect to the service
private ServiceConnection musicConnection = new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.MusicBinder binder = (MusicService.MusicBinder)service;
//get service
musicSrv = binder.getService();
//pass list
musicSrv.setList(songList);
musicBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};
public void getSongList() {
//retrieve song info
ContentResolver musicResolver = getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
if(musicCursor!=null && musicCursor.moveToFirst()){
//get columns
int titleColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.ARTIST);
//add songs to list
do {
long thisId = musicCursor.getLong(idColumn);
String thisTitle = musicCursor.getString(titleColumn);
String thisArtist = musicCursor.getString(artistColumn);
songList.add(new Song(thisId, thisTitle, thisArtist));
}
while (musicCursor.moveToNext());
}
}
You can use this android library for to make handling runtime permissions a whole lot easier.
If your Activity subclasses PermisoActivity, requesting a permission is as simple as:
Permiso.getInstance().requestPermissions(new Permiso.IOnPermissionResult() {
#Override
public void onPermissionResult(Permiso.ResultSet resultSet) {
if (resultSet.areAllPermissionsGranted()) {
// Permission granted!
} else {
// Permission denied.
}
}
#Override
public void onRationaleRequested(Permiso.IOnRationaleProvided callback, String... permissions) {
Permiso.getInstance().showRationaleInDialog("Title", "Message", null, callback);
}
}, Manifest.permission.READ_EXTERNAL_STORAGE);
Gradle
dependencies {
compile 'com.greysonparrelli.permiso:permiso:0.2.0'
}
You can add multiple permissions also please visit link shared. You can get All information in details.
This code will allow you to request permission at run time by checking if the permission has been granted and if not, ask the user to enable the permission.
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, MY_PERMISSION_RESPONSE);
}
The permission being checked for in this case is to do with location services. Just replace ACCESS_COARSE_LOCATION with whatever permission you wish to ask for.