Related
I have 8 edittext fields in my android app, I enter the data manually into the same and at the end of the field there is so called "Save" button
What I want is when I click on the save button, a pdf file should be generated with all the values that I have filled in the edittext. Any help is appreciated.. Thanks
You can use itext7 library to do just that. But do look at their licensing as they mention you may need to buy license as soon as you are using it for commercial purpose.
I actually used itext5 which seems deprecated now. But the code should not be much different.
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mContentEditText.getText().toString().isEmpty()){
mContentEditText.setError("Body is empty");
mContentEditText.requestFocus();
return;
}
try {
createPdfWrapper();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
});
The createPdfWrapper() method definition is as follows:
private void createPdfWrapper() throws FileNotFoundException,DocumentException{
int hasWriteStoragePermission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (hasWriteStoragePermission != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {
showMessageOKCancel("You need to allow access to Storage",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_CODE_ASK_PERMISSIONS);
}
}
});
return;
}
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_CODE_ASK_PERMISSIONS);
}
return;
}else {
createPdf();
}
As you can see you will also need WRITE_EXTERNAL_STORAGE permission which should be declared in AndroidManifest.xml .
The permission result can be handled in onRequestPermissionsResult as:
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
try {
createPdfWrapper();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
} else {
// Permission Denied
Toast.makeText(this, "WRITE_EXTERNAL Permission Denied", Toast.LENGTH_SHORT)
.show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
The other functions used here have the following definitions:
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
private void createPdf() throws FileNotFoundException, DocumentException {
File docsFolder = new File(Environment.getExternalStorageDirectory() + "/Documents");
if (!docsFolder.exists()) {
docsFolder.mkdir();
Log.i(TAG, "Created a new directory for PDF");
}
pdfFile = new File(docsFolder.getAbsolutePath(),"HelloWorld.pdf");
OutputStream output = new FileOutputStream(pdfFile);
Document document = new Document();
PdfWriter.getInstance(document, output);
document.open();
document.add(new Paragraph(mContentEditText.getText().toString()));
document.close();
previewPdf();
}
private void previewPdf() {
PackageManager packageManager = getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");
List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (list.size() > 0) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
//Uri uri = Uri.fromFile(pdfFile); //This did not work, SO created a GenericFileProvider, register in xml, created provider_paths.xml
Uri uri = FileProvider.getUriForFile(getApplicationContext(),
getApplicationContext().getPackageName()
+ ".my.package.name.provider", pdfFile);
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
}else{
Toast.makeText(this,"Download a PDF Viewer to see the generated PDF",Toast.LENGTH_SHORT).show();
}
}
The main thing to look for here is the createPdf() method This is where I have created a PDF file with text from my EditText.
If you wish to have a look at the full code that I did you can visit my github respository here.
Good Luck!!!
if (Build.VERSION.SDK_INT >= 23) {
if (checkPermission()) {
Log.e("permission", "Permission already granted.");
} else {
requestPermission();
}
}
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(SolutionBrouchereActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED) {
viewOrDownloadPDF();
return true;
} else {
return false;
}
}
private void requestPermission() {
ActivityCompat.requestPermissions(getParent(), new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE);
}
This functions not worked after denying permission on the splash screen and not able to open permission prompt dialog in another activity.
You can call the shouldShowRequestPermissionRationale method in your new Activity if user did not grant the permission on Splash Screen.
Reference: https://developer.android.com/training/permissions/requesting
If your target SDK version is >=23 then you need to ask for permissions at run time. Otherwise Android will not ask for permission like old Android does.
If this is the case then you should be able to see that no permissions have been granted if you go to Settings > Apps > "Your app" > Permissions.
If you don't want to ask permissions you can reduce your target sdk version to 22 to get the old permission system. You can still compile with sdk version 23 though.
So for >=23 Use this code:
This code will automatically detect which dialog should be shown, because there is a particular limit in android to show that permission dialog. If particular number of attempts made then it will not show permission dialog, and we will have to move user to settings it self.
This code will help you to achieve both scenarios :
CustomPermissionManager.java :
public class CustomPermissionManager {
public static final int STORAGE_PERMISSION = 8;
public HashMap<Integer, ArrayList<PermissionManagerUtil.OnPermissionInterface>> onPermissionInterfaces = new HashMap<>();
public HashMap<Integer, Boolean> hasAlreadyAskedPermission = new HashMap<>();
private MainActivity context;
public void init(MainActivity context) {
this.context = context;
}
private boolean isAskedForFirstTime(String permissionName) {
if (!PreferenceManager.getDefaultSharedPreferences(context).getBoolean(permissionName, false)) {
PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(permissionName, true).commit();
return true;
}
return false;
}
public void requestStoragePermission(Activity activity, boolean showAlertForSettingsIfNeeded, PermissionManagerUtil.OnPermissionInterface onPermissionInterface) {
if (PermissionManagerUtil.instance.checkStoragePermission()) {
onPermissionInterface.onPermissionGranted();
return;
}
boolean isAskedFirstTime = isAskedForFirstTime(Manifest.permission.READ_EXTERNAL_STORAGE);
if (showAlertForSettingsIfNeeded && !isAskedFirstTime && !ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.READ_EXTERNAL_STORAGE)) {
// if user clicked on "never ask again" then popup will not show by android
//https://stackoverflow.com/questions/33224432/android-m-anyway-to-know-if-a-user-has-chosen-never-to-show-the-grant-permissi
showAlertDialogWithAppSettings(activity, Manifest.permission.READ_EXTERNAL_STORAGE);
} else {
if (onPermissionInterfaces.get(STORAGE_PERMISSION) == null) {
onPermissionInterfaces.put(STORAGE_PERMISSION, new ArrayList<>());
}
if (onPermissionInterface != null) {
onPermissionInterfaces.get(STORAGE_PERMISSION).add(onPermissionInterface);
}
if (!hasAlreadyAskedPermission.containsKey(STORAGE_PERMISSION)) {
hasAlreadyAskedPermission.put(STORAGE_PERMISSION, true);
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION);
}
}
}
private void callPermissionManagerCallBack(int requestCode, int[] grantResults) {
if (onPermissionInterfaces.containsKey(requestCode) && onPermissionInterfaces.get(requestCode) != null) {
for (PermissionManagerUtil.OnPermissionInterface onPermissionInterface : onPermissionInterfaces.get(requestCode)) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
onPermissionInterface.onPermissionGranted();
} else {
onPermissionInterface.onPermissionNotGranted();
}
}
hasAlreadyAskedPermission.remove(requestCode);
onPermissionInterfaces.get(requestCode).clear();
}
}
private void showAlertDialogWithAppSettings(String permission) {
showAlertDialogWithAppSettings(context, permission);
}
#SuppressLint("RestrictedApi")
private void showAlertDialogWithAppSettings(Activity context, String permission) {
String title = "Allow permissions";
String message = "Please allow this permission to enable this feature.";
switch (permission) {
case Manifest.permission.WRITE_EXTERNAL_STORAGE:
title = "Allow Storage Permission";
message = "Please allow permission to do.... task";
break;
}
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(title);
builder.setMessage(message);
builder.setPositiveButton("Go to settings", (dialog, which) -> {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromParts("package", context.getPackageName(), null);
intent.setData(uri);
context.startActivity(intent);
});
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss());
builder.show();
}
public boolean checkStoragePermission() {
int resultExternalStorage = PermissionChecker.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
return resultExternalStorage == PackageManager.PERMISSION_GRANTED;
}
}
Call it like this :
CustomPermissionManager customPermissionManager = new CustomPermissionManager();
customPermissionManager.init(context);
customPermissionManager.requestCameraPermission(true, new OnPermissionInterface() {
#Override
public void onPermissionGranted() {
//permission granted
viewOrDownloadPDF();
}
#Override
public void onPermissionNotGranted() {
// permission not granted
}
});
// To check permission is given or not
boolean isGranted = customPermissionManager.checkStoragePermission();
You can add other permission too in future like here STORAGE_PERMISSION is added, by adding same type of method.
Put this function in common file and call whenever you use it will again check
public static boolean checkPermission(final Activity context)
{
int currentAPIVersion = Build.VERSION.SDK_INT;
if(currentAPIVersion>=android.os.Build.VERSION_CODES.M)
{
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED||ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //||ContextCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE)!=PackageManager.PERMISSION_GRANTED
if (ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.READ_EXTERNAL_STORAGE)||ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)||ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.CALL_PHONE)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Permission necessary");
alertBuilder.setMessage("External storage permission is necessary");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
return false;
} else {
return true;
}
} else {
return true;
}
}
I have app that requests runtime permission for call on app start with dialog, but somehow my code doesn't request any permission or work. I need that when the app starts; ask the user for permission to call and in case the user refused, ask again for permission and move to in permissions settings.
Here's my code:
public class MainActivity extends AppCompatActivity {
private FirebaseAnalytics mFirebaseAnalytics;
private AdView mAdView;
private Button button_id;
private Button button_mobily;
private Button button_stc;
private Button button_zain;
private Button button_share;
private Button button_exit;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dash);
NativeExpressAdView adView = (NativeExpressAdView)findViewById(R.id.adView);
AdRequest request = new AdRequest.Builder().build();
adView.loadAd(request);
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
Bundle bundle = new Bundle();
bundle.putString(FirebaseAnalytics.Param.ITEM_ID, "main");
bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, "opened");
bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "image");
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, bundle);
isPermissionGranted();
button_exit = (Button) findViewById(R.id.exit_buton_id);
button_share = (Button) findViewById(R.id.Share_buton);
button_id = (Button) findViewById(R.id.edit_id);
button_mobily = (Button) findViewById(R.id.mobily_buton);
button_stc = (Button) findViewById(R.id.stc_buton);
button_zain = (Button) findViewById(R.id.zain_buton);
button_id.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent myIntent = new Intent(MainActivity.this, NationalId.class);
MainActivity.this.startActivity(myIntent);
}
});
button_share.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
try {
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_SUBJECT, "test");
String sAux = "\n download my app\n\n";
sAux = sAux + "https://play.google.com/store/apps/details?id=Orion.Soft \n\n";
i.putExtra(Intent.EXTRA_TEXT, sAux);
startActivity(Intent.createChooser(i, "share on"));
} catch (Exception e) {
//e.toString();
}
}
});
button_exit.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
close();
}
});
button_mobily.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Intent myIntent = new Intent(MainActivity.this, OpreatorMobily.class);
MainActivity.this.startActivity(myIntent);
}
});
button_stc.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Intent myIntent = new Intent(MainActivity.this, OpreatorSTC.class);
MainActivity.this.startActivity(myIntent);
}
});
button_zain.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Intent myIntent = new Intent(MainActivity.this, OpreatorZain.class);
MainActivity.this.startActivity(myIntent);
}
});
}
public boolean isPermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.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}, 1);
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,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "Permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Permission denied", Toast.LENGTH_SHORT).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
public void close() {
// TODO Auto-generated method stub
finish();
System.exit(0);
}
}
You don't need to check the Android version, Android is smart enough to know what the OS version is on the user's device.
Also if you're trying to get the ability to Call you need to change how the permission is called.
public boolean isPermissionGranted() {
Intent callOfficeIntent = new Intent(Intent.ACTION_CALL);
callOfficeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
callOfficeIntent.setData(Uri.parse("tel:" + mNumberToCall));
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.CALL_PHONE},
10);
return;
} else {
try {
startActivity(callOfficeIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), "No number to call", Toast.LENGTH_SHORT).show();
}
}
}
If you just want to get the permission but not make the call right away place this inside your method. This just asks for permission as a DialogBox.
if(ActivityCompat.checkSelfPermission(getActivity(),Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED){
if(ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),Manifest.permission.READ_PHONE_STATE)){
//Show Information about why you need the permission
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Need Permission");
builder.setMessage("This app needs phone permission.");
builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE},PERMISSION_CALLBACK_CONSTANT);
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
} else if (permissionStatus.getBoolean(Manifest.permission.READ_PHONE_STATE,false)) {
//Previously Permission Request was cancelled with 'Dont Ask Again',
// Redirect to Settings after showing Information about why you need the permission
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Need Permission");
builder.setMessage("This app needs storage permission.");
builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
sentToSettings = true;
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
Toast.makeText(getActivity(), "Go to Permissions to Grant Phone", Toast.LENGTH_LONG).show();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
} else {
//just request the permission
requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE},PERMISSION_CALLBACK_CONSTANT);
}
txtPermissions.setText("Permissions Required");
SharedPreferences.Editor editor = permissionStatus.edit();
editor.putBoolean(Manifest.permission.READ_PHONE_STATE,true);
editor.commit();
} else {
//You already have the permission, just go ahead.
proceedAfterPermission();
}
}
});
}
private void proceedAfterPermission() {
txtPermissions.setText("We've got the permission");
Toast.makeText(getActivity(), "We got All Permissions", Toast.LENGTH_LONG).show();
}
Don't have to use the last method, just change the textView to a toast.
I found a simple Github library developed by "Nabin Bhandari". It is easy to implement and can be customized directly. Github library link...
Please add this dependency to add this library to your code.
implementation 'com.nabinbhandari.android:permissions:3.8'
This allow you to request single permission, multiple permission and do customize your own dialog.
Furthermore,
You can also override other methods like onDenied, onJustBlocked, etc if you want to change the default behaviour.
Dialogue messages and texts can be modified by building the options parameter.
See documentation in the source code for more customizations.
Use this code to ask multiple permissions samuntanely.
String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
Permissions.check(this/*context*/, permissions, null/*rationale*/, null/*options*/, new PermissionHandler() {
#Override
public void onGranted() {
// do your task.
}
});
Use this code if you want to Customized permissions request:
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION};
String rationale = "Please provide location permission so that you can ...";
Permissions.Options options = new Permissions.Options()
.setRationaleDialogTitle("Info")
.setSettingsDialogTitle("Warning");
Permissions.check(this/*context*/, permissions, rationale, options, new PermissionHandler() {
#Override
public void onGranted() {
// do your task.
}
#Override
public void onDenied(Context context, ArrayList<String> deniedPermissions) {
// permission denied, block the feature.
}
});
I am trying to access the users locations and just sorting out the permission side of things. So my understanding is that on 23 and above regardless of the manifest the user must grant permission.
So I have it in the manifest like this for older versions:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
For the newer >= 23 I am testing like this before showing a dialog:
// Check for runtime location permissions
private boolean hasRunTimeLocationPermission() {
int courseLocationPermission = ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.ACCESS_COARSE_LOCATION);
return (courseLocationPermission == PackageManager.PERMISSION_GRANTED );
}
The way I understood it that should return false the first time but it is returning true.
Does the user actually have to disable location services or is it considered 'dangerous" and it have to be approved the first time?
Also I am using a new emulator api 23, when I look into location permissions it says no apps have requested location.
Thanks for your help
Try this.
// Check for runtime location permissions
private boolean hasRunTimeLocationPermission() {
int courseLocationPermission = ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION);
return (courseLocationPermission == PackageManager.PERMISSION_GRANTED );
}
TRY THIS:
private boolean hasRunTimeLocationPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)
{
return false;
}
else
{
return true;
}
}
Check permissions like this :-
Check permissions like this :-
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
//Show Information about why you need the permission
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Need Location Permission");
builder.setMessage("This app needs location permission.");
builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, ACCESS_COARSE_LOCATION_CONSTANT);
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
} else if (permissionStatus.getBoolean(Manifest.permission.ACCESS_COARSE_LOCATION,false)) {
//Previously Permission Request was cancelled with 'Dont Ask Again',
// Redirect to Settings after showing Information about why you need the permission
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Need Location Permission");
builder.setMessage("This app needs location permission.");
builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
sentToSettings = true;
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 Location", Toast.LENGTH_LONG).show();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
} else {
//just request the permission
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, ACCESS_COARSE_LOCATION_CONSTANT);
}
SharedPreferences.Editor editor = permissionStatus.edit();
editor.putBoolean(Manifest.permission.ACCESS_COARSE_LOCATION,true);
editor.commit();
} else {
//You already have the permission, just go ahead.
proceedAfterPermission();
}
Add this to Manifest even for api>23
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
And then ask for runtime permissions like this :-
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
1);
And to handle the restults, use this:-
#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
} else {
// permission denied, boo!
Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
}
return;
}
}
}
When I have a target API of 23 on Android M Preview 3, I cannot seem to acquire the Manifest.permission.WRITE_SETTTINGS permission.
requestPermissions(new String[]{Manifest.permission.WRITE_SETTINGS}, 101);
Request permission doesn't bring up the dialog I would expect, but if I make the following call without this permission,
RingtoneManager.setActualDefaultRingtoneUri(activity, RingtoneManager.TYPE_RINGTONE, ringUri);
The call will except because I don't have the permission.
I'm not sure where to go from here. Is there a new ringtone API for 23? Or did this permission change just make it impossible for any non-system apps to change the ringtone?
To use WRITE_SETTINGS, based on the docs:
Have the <uses-permission> element in the manifest as normal.
Call Settings.System.canWrite() to see if you are eligible to write out settings.
If canWrite() returns false, start up the ACTION_MANAGE_WRITE_SETTINGS activity so the user can agree there to allow your app to actually write to settings.
In other words, writing to settings is now a double-opt-in (agree to install, agree separately in Settings to allow), akin to device admin APIs, accessibility services, etc.
Also note that I have not tried using these yet — this is based on research that I did yesterday on Android 6.0 changes.
In addition to the answer from CommonsWare and the comment from Ogix, here is some dummy code:
private boolean checkSystemWritePermission() {
boolean retVal = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
retVal = Settings.System.canWrite(this);
Log.d(TAG, "Can Write Settings: " + retVal);
if(retVal){
Toast.makeText(this, "Write allowed :-)", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(this, "Write not allowed :-(", Toast.LENGTH_LONG).show();
FragmentManager fm = getFragmentManager();
PopupWritePermission dialogFragment = new PopupWritePermission();
dialogFragment.show(fm, getString(R.string.popup_writesettings_title));
}
}
return retVal;
}
The Fragment PopupwritePermission then gives a window where the situation is explained. A click on the OK Button will open the Android System Menu where the Permission can be granted:
private void openAndroidPermissionsMenu() {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + getActivity().getPackageName()));
startActivity(intent);
}
The previous answers are great, I have just little addition for also getting the result for the permission asking.
public static void youDesirePermissionCode(Activity context){
boolean permission;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
permission = Settings.System.canWrite(context);
} else {
permission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED;
}
if (permission) {
//do your code
} else {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + context.getPackageName()));
context.startActivityForResult(intent, MainActivity.CODE_WRITE_SETTINGS_PERMISSION);
} else {
ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.WRITE_SETTINGS}, MainActivity.CODE_WRITE_SETTINGS_PERMISSION);
}
}
}
And then in the Activity:
#SuppressLint("NewApi")
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == MainActivity.CODE_WRITE_SETTINGS_PERMISSION && Settings.System.canWrite(this)){
Log.d("TAG", "MainActivity.CODE_WRITE_SETTINGS_PERMISSION success");
//do your code
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MainActivity.CODE_WRITE_SETTINGS_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//do your code
}
}
This is a complete example:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.System.canWrite(context) {
// Do stuff here
}
else {
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + getActivity().getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
As of android Marshmellow , you require to use runtime permissions which aims to more security , or use permission when need here is documenatation
and for Write Settings documentation is here
In manifest add
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
In your class
private boolean checkSystemWritePermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(Settings.System.canWrite(context))
return true;
else
openAndroidPermissionsMenu();
}
return false;
}
private void openAndroidPermissionsMenu() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + context.getPackageName()));
context.startActivity(intent);
}
}
And use it like this
try {
if (checkSystemWritePermission()) {
RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, newUri);
Toast.makeText(context, "Set as ringtoon successfully ", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "Allow modify system settings ==> ON ", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Log.i("ringtoon",e.toString());
Toast.makeText(context, "unable to set as Ringtoon ", Toast.LENGTH_SHORT).show();
}
The permission android.permission.WRITE_SETTINGS is now in the group signature|appop|pre23|preinstalled like android.permission.CHANGE_NETWORK_STATE and android.permission.SYSTEM_ALERT_WINDOW
This means you get it on sdk 22 and below. On newer version you have to be an app operator.
I have used bellow like..
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
boolean retVal = true;
retVal = Settings.System.canWrite(this);
if (retVal == false) {
if (!Settings.System.canWrite(getApplicationContext())) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS, Uri.parse("package:" + getPackageName()));
Toast.makeText(getApplicationContext(), "Please, allow system settings for automatic logout ", Toast.LENGTH_LONG).show();
startActivityForResult(intent, 200);
}
}else {
Toast.makeText(getApplicationContext(), "You are not allowed to wright ", Toast.LENGTH_LONG).show();
}
}
Manifest permission
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions" />
• Kotlin Version in Simple Steps
Follow these steps:
1. Add the permission's usage element in the manifest.xml normally:
<uses-permission
android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
2. Where you want to change the settings, check the write access:
if (context.canWriteSettings) {
// change the settings here ...
} else {
startManageWriteSettingsPermission()
}
3. Also add these lines of code in case of requesting the permission:
private fun startManageWriteSettingsPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent(
Settings.ACTION_MANAGE_WRITE_SETTINGS,
Uri.parse("package:${context.packageName}")
).let {
startActivityForResult(it, REQUEST_CODE_WRITE_SETTINGS_PERMISSION)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_CODE_WRITE_SETTINGS_PERMISSION -> {
if (context.canWriteSettings) {
// change the settings here ...
} else {
Toast.makeText(context, "Write settings permission is not granted!", Toast.LENGTH_SHORT).show()
}
}
}
}
val Context.canWriteSettings: Boolean
get() = Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.System.canWrite(this)
companion object {
private const val REQUEST_CODE_WRITE_SETTINGS_PERMISSION = 5
}
Mention below permission in AndroidManifest.xml
In Activity use below if else for changing setting.
if(Settings.System.canWrite(this)){
// change setting here
}
else{
//Migrate to Setting write permission screen.
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + mContext.getPackageName()));
startActivity(intent);
}
In my case i have solved by this way.:
public void checkSystemWriteSettings(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.System.canWrite(context)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS, Uri.parse("package:" + context.getApplicationInfo().packageName));
startActivity(intent);
}else
{
Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 10);
}
}
}