I am developing and android application with emulator of Android Studio 3.6. I am using a virtual device of Nexus 7 with andoird 10.
I have given permission on the manifest file and I have asked for the user to give permission for read write to the external storage.
Although permissions are ok I can not create a folder on the external storage. I attempt to write form a background proccess.
This is the excerpt og manifest file
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
This is the excerpt of my Main Activity where I ask the the user to give permission and call the background proccess: UnitDataUpdater
public class MainActivity extends AppCompatActivity {
public static final String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
public static final int MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE = 1;
// public static String SERVER_API_URL = "http://local.xxxx.xxxxx.eu/index.php?option=com_alumincocc&view=examlist&Itemid=122&format=json&unitCode=";
// public static LinearLayout examList;
public JSONArray uiData;
ListView examsList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkPermissions();
setContentView(R.layout.activity_main);
String url = "http://xxxxx.xxxxx.eu/index.php?option=com_alumincocc&view=examlist&Itemid=122&format=json&unitCode=478050";
String result = "";
examsList = (ListView) findViewById(R.id.examsList);
UnitDataUpdater process = new UnitDataUpdater(this);
try {
result = process.execute(url).get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
........
public void checkPermissions() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED
||
ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String[] permissions,
#NonNull int[] grantResults) {
super
.onRequestPermissionsResult(requestCode,
permissions,
grantResults);
if (requestCode == MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE) {
// Checking whether user granted the permission or not.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Showing the toast message
Toast.makeText(MainActivity.this,
"Write Permission Granted",
Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(MainActivity.this,
"Write Permission Denied",
Toast.LENGTH_SHORT)
.show();
}
}
}
}
And this is the background process where I try to write to the external storage. The method getAppDi is where I am trying to create a new folder. This folder is never created so the rest of the class throws errors.
A strange thing is that at the emulator I don't see the Document folder. I have try the same thing on Downloads folder but still the same.
public class UnitDataUpdater extends AsyncTask<String, Void, String> {
// private static String REMOTE_URL = "http://local.xxxxxx.xxxxx.eu/index.php?option=com_alumincocc&view=examlist&Itemid=122&format=json&unitCode=";
private String data = "";
public static final String REQUEST_METHOD = "GET";
public static final int READ_TIMEOUT = 15000;
public static final int CONNECTION_TIMEOUT = 15000;
private String filePrefix = "i";
private MainActivity mainActivity;
public UnitDataUpdater(Activity mainActivity) {
this.mainActivity = (MainActivity) mainActivity;
}
........
private String getAppDir() {
String externalStoragePublicDirectory = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.getAbsolutePath();
String appDirPath = externalStoragePublicDirectory + "/XXXXUnitData";
File appDir = new File(appDirPath);
if (!appDir.exists()) {
if (!appDir.mkdir()) {
try {
throw new Exception("Storage Error");
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
return appDir.getAbsolutePath();
}
}
Any help is appreciated
On Android Q external storage is not readable and writable. Use getExternalFilesDir(null) instead. You do not need any read write permission then in manifest or at runtime.
Related
I want to create android application where should be a way to upload file on firebase. But Even after giving runtime permissions to storage, somehow Video is not being uploaded.
Here is my MainActivity.java file code
public class MainActivity extends AppCompatActivity implements
ActivityCompat.OnRequestPermissionsResultCallback{
private static final int PERMISSION_REQUEST_STORAGE = 0;
private final String[] REQUIRED_PERMISSIONS = new String[]{
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.INTERNET"
};
FireBaseHandler fb;
private View mLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fb = new FireBaseHandler();
mLayout = findViewById(R.id.main_layout);
// Check if the permission has been granted
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
// Permission is already available, start camera preview
Snackbar.make(mLayout,
"Permission_Available",
Snackbar.LENGTH_SHORT).show();
fb.upload();
} else {
// Permission is missing and must be requested.
requestPermission();
}
/*
if(allPermissionsGranted()){
fb.Upload(); //start upload if permission has been granted by user
} else{
ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS);
}
*/
}
/*
private boolean allPermissionsGranted(){
for(String permission : REQUIRED_PERMISSIONS){
if(ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED){
return false;
}
}
return true;
}
*/
private void requestPermission() {
// Permission has not been granted and must be requested.
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Provide an additional rationale to the user if the permission was not granted
// and the user would benefit from additional context for the use of the permission.
// Display a SnackBar with cda button to request the missing permission.
Snackbar.make(mLayout, "camera_access_required",
Snackbar.LENGTH_INDEFINITE).setAction("OK", new View.OnClickListener() {
#Override
public void onClick(View view) {
// Request the permission
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
PERMISSION_REQUEST_STORAGE);
}
}).show();
} else {
Snackbar.make(mLayout, "Storage_unavailable", Snackbar.LENGTH_SHORT).show();
// Request the permission. The result will be received in onRequestPermissionResult().
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_STORAGE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
// BEGIN_INCLUDE(onRequestPermissionsResult)
if (requestCode == PERMISSION_REQUEST_STORAGE) {
// Request for camera permission.
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission has been granted. Start camera preview Activity.
Snackbar.make(mLayout, "camera_permission_granted",
Snackbar.LENGTH_SHORT)
.show();
fb.upload();
} else {
// Permission request was denied.
Snackbar.make(mLayout, "Storage_permission_denied",
Snackbar.LENGTH_SHORT)
.show();
}
}
// END_INCLUDE(onRequestPermissionsResult)
}
/*
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if(requestCode == REQUEST_CODE_PERMISSIONS){
if(allPermissionsGranted()){
fb.Upload();
} else{
Toast.makeText(this, "Permissions not granted by the user.", Toast.LENGTH_SHORT).show();
this.finish();
}
}
}
*/
}
And here is code for uploading file
public class FireBaseHandler {
private static final String TAG = "MyFirebase";
FirebaseStorage storage; // = FirebaseStorage.getInstance();
// Create a storage reference from our app
StorageReference storageRef; // = storage.getReference();
UploadTask uploadTask;
public FireBaseHandler() {
storage = FirebaseStorage.getInstance();
storageRef = storage.getReference();
}
public void upload(){
Uri file = Uri.fromFile(new File(getWhatsAppVideoDirectory()+"Abc.mp4"));
StorageReference vidRef = storageRef.child("videos/"+file.getLastPathSegment());
uploadTask = vidRef.putFile(file);
// Register observers to listen for when the download is done or if it fails
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
Log.i(TAG,"onFailure");
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc.
// ...
Log.i(TAG,"onSuccess");
}
});
}
private String getWhatsAppVideoDirectory() {
String folder_path = (Environment.getExternalStorageDirectory().getAbsolutePath() +
"/WhatsApp/Media/WhatsApp Video/Sent/");
//new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp/Media");
return folder_path;
}
}
Error is something like Access denied, Kindly tell me where am I doing it wrong way.
I have ran this code using Lower version of android that is 6.0.1 and it is working fine. I don't know if Google has some changes for newer android versions?
I just found that you are not asking permission properly;
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
PERMISSION_REQUEST_STORAGE);
Here you are just asking for reading permission, Read permission is always true when you declare in manifest, but at runtime you should ask for WRITE_EXTERNAL_STORAGE. So there is no meaning of above code, because it will be always true. You have to ask permission like this:
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSION_REQUEST_STORAGE);
I'm trying to write a file to the SD card on android but i cannot get it to work properly. I'm using an Emulator with Android 6.0, where the app manifest has
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
And as far as i understand it, for this to work the user must grant the permission at run time too. I have this code with some explanation inline as comments:
public class AboutPref extends PreferenceFragmentCompat {
private static final int WRITE_REQUEST_CODE = 2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.about_preferences);
Preference export_settings = findPreference("export_settings");
export_settings.setOnPreferenceClickListener(exportSettings());
}
// The export_settings Preference acts like a button, where this is called when it is clicked/tapped
// it basically checks if the permission is already granted, and if so, doesn't bother asking the user for it again
private Preference.OnPreferenceClickListener exportSettings()
{
return new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
//SettingsHelper.ExportSettings(getContext(), getActivity());
int checkVal = getContext().checkCallingOrSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
if(checkVal != PackageManager.PERMISSION_GRANTED) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
askForStoragePermission();
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setMessage(R.string.permission_explained)
.setPositiveButton(R.string.OK, dialogClickListener)
.show();
} else {
doExportSettings();
}
return false;
}
};
}
// This is called if the user had not given permission earlier as shown above
public void askForStoragePermission()
{
List<String> permissionsList = new ArrayList<>();
permissionsList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
String[] permissions = permissionsList.toArray(new String[permissionsList.size()]);
requestPermissions(permissions, WRITE_REQUEST_CODE);
}
// When the user had not given permission earlier this is called after the permission request alert is closed
// which once again checks if permission is granted or not
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case WRITE_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
doExportSettings();
} else {
Toast.makeText(getContext(), "Failed! Need permission", Toast.LENGTH_LONG).show();
}
}
}
// and this is the actualy method that is run when permission is/was granted
private void doExportSettings()
{
// This one is simple for now, but will be used to write application settings to a file
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
File sdcard = Environment.getExternalStorageDirectory();
String exportFileName = "ApplicaitonName/app_settings.pwt";
File file = new File(sdcard, exportFileName);
try {
BufferedWriter out = new BufferedWriter(new FileWriter(file));
out.write(prefs.toString());
} catch (Exception e) {
System.out.println("export error => " + e.getMessage()); // <-- BUT this happens
}
}
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
// .. not used but required
}
}
But as stated i get the following error: export error => /storage/emulated/0/ApplicaitonName/app_settings.pwt: open failed: EACCES (Permission denied)
I must be missing something obvious no?
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
While Reading Device ID etc. I am getting an error in Android 6.
How ever its working fine in all other versions 4.0,5.1 etc..
This is my code:
public class MyDevIDS extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
PackageInfo pInfo = null;
try {
pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
String version = pInfo.versionName;
TextView versionText = (TextView) findViewById(R.id.tv7);
versionText.setText("Version : " + version);
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String imei_id = telephonyManager.getDeviceId();
TextView imei_idT = (TextView) findViewById(R.id.tv9);
String imei_idV = "<b><font color=#008000>" + imei_id + "</b></font>";
imei_idT.setText(Html.fromHtml("IMEI ID : " + imei_idV));
String device_id = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
TextView device_idT = (TextView) findViewById(R.id.tv10);
String device_idV = "<b><font color=#008000>" + device_id + "</b></font>";
device_idT.setText(Html.fromHtml("Device ID : " + device_idV));
}
}
this is error I am getting
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.devid/com.test.devid.MyDevIDS}: java.lang.SecurityException: getDeviceId: Neither user 10102 nor current process has android.permission.READ_PHONE_STATE.
How ever I Have given permission in manifest.. but I need to give Run time permissions in Android 6...
For that I followed this
https://developer.android.com/training/permissions/requesting.html
But I tried but its notworking..
Can any one suggest me how to use Run time permissions in my code..
public class MyDevIDS extends AppCompatActivity {
private static final int REQUEST_READ_PERMISSION = 123;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
if (CheckPermission(this, Manifest.permission.READ_PHONE_STATE)) {
YourStuffHandling();
} else {
RequestPermission(MyDevIDS.this, Manifest.permission.READ_PHONE_STATE, REQUEST_READ_PERMISSION );
}
}
private void YourStuffHandling() {
PackageInfo pInfo = null;
try {
pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
String version = pInfo.versionName;
TextView versionText = (TextView) findViewById(R.id.tv7);
versionText.setText("Version : " + version);
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String imei_id = telephonyManager.getDeviceId();
TextView imei_idT = (TextView) findViewById(R.id.tv9);
String imei_idV = "<b><font color=#008000>" + imei_id + "</b></font>";
imei_idT.setText(Html.fromHtml("IMEI ID : " + imei_idV));
String device_id = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
TextView device_idT = (TextView) findViewById(R.id.tv10);
String device_idV = "<b><font color=#008000>" + device_id + "</b></font>";
device_idT.setText(Html.fromHtml("Device ID : " + device_idV));
}
#Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults) {
switch (permsRequestCode) {
case REQUEST_READ_PERMISSION: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
YourStuffHandling();
} else {
ShowToast(getString(R.string.permission_needed_sms));
}
return;
}
}
}
public void RequestPermission(Activity thisActivity, String Permission, int Code) {
if (ContextCompat.checkSelfPermission(thisActivity,
Permission)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Permission)) {
} else {
ActivityCompat.requestPermissions(thisActivity,
new String[]{Permission},
Code);
}
}
}
public boolean CheckPermission(Context context, String Permission) {
if (ContextCompat.checkSelfPermission(context,
Permission) == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
}
Android sdk has implemented Runtime permission feature from version 6.0 onwards. No matter weather you have given permission in manifest file you need to check that permission before you access.
You can check at runtime using either hasSystemFeature(PackageManager.FEATURE_TELEPHONY) or getPhoneType().
Or you can check by following format I have done for Camera permission
public void getCameraPermission(){
if (!checkPermission()) {
requestPermission();
}
}
private boolean checkPermission(){
int result = ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
private void requestPermission(){
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.CAMERA)){
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE);
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this,"Permission granted",Toast.LENGTH_SHORT).show();
//store permission in shared pref
}
else {
Toast.makeText(MainActivity.this,"Permission denied",Toast.LENGTH_SHORT).show();
//store permission in shared pref
}
break;
}
}
In the below code,getInfoFromDevice is not being executed, I also tried with a Log.d() but it could not be of further help.
In the code I am using runtime permissions to check if the user has granted permission to access external storage and if yes the function getInfoFromDevice() is called. I am not sure if the placement of the function is correct or not ? But this function is not executing. what could be the reason ?
It does not throw any error,
public class MainActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback {
ArrayList<String> listOfSongs = new ArrayList<String>();
ListView liststructure;
final private int REQUEST_CODE_ASK_PERMISSIONS = 123;
String MUSIC_STRING = MediaStore.Audio.Media.IS_MUSIC + "!=0";
String[] STAR = {"*"};
String orderColumns = MediaStore.Audio.AudioColumns.TITLE + " COLLATE LOCALISED ASC";
private final int REQUEST_GRANTED_BY_USER = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkPermissions();
liststructure = (ListView) findViewById(R.id.listView);
SongsList list = new SongsList(MainActivity.this, listOfSongs);
liststructure.setAdapter(list);
}
private void checkPermissions() {
int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_GRANTED_BY_USER);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(requestCode == REQUEST_GRANTED_BY_USER )
{
getInfoFromDevice();
} else {
// Permission Denied
Toast.makeText(MainActivity.this, "EXTERNAL_STORAGE Denied", Toast.LENGTH_SHORT)
.show();
}
}
void getInfoFromDevice() {
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = getContentResolver().query(uri, STAR, MUSIC_STRING, null, null);
if (cursor != null)
{
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));
String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
String albumID = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
listOfSongs.add(album + " " + name + " " + albumID);
} while (cursor.moveToNext());
}
}
}
}
Please let me know if you need more details.
EDIT 1
The code will look for mp3 files with the help of MediaStore library and will check if it has a permission to access external storage and if yes it will call the function getInfoFromDevice()
just change you code like below:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
liststructure = (ListView) findViewById(R.id.listView);
SongsList list = new SongsList(MainActivity.this, listOfSongs);
liststructure.setAdapter(list);
checkPermissions();
}
private void checkPermissions() {
if (Build.VERSION.SDK_INT >= 23) {
int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_GRANTED_BY_USER);
}else{
getInfoFromDevice();
}
}else{
getInfoFromDevice();
}
}
First check permission as below,
public void checkPermission(String permission) {
if (ContextCompat.checkSelfPermission(BaseActivity.this,
permission)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(BaseActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
ActivityCompat.requestPermissions(BaseActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
10);
} else {
ActivityCompat.requestPermissions(BaseActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
10);
}
}
}
then,
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 10: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
// permission granted call your function
getInfoFromDevice();
} else {
// permission denied.
}
return;
}
}
}
You can also use below plugin to easily add run time permission without more effort,
https://android-arsenal.com/details/1/3571
I have a code that runs fine in Lollipop device but don't do anything in Nougat
private ArrayList<PDFDoc> getPDFs() {
File downloadsFolder=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
if (downloadsFolder.exists()) {
//GET ALL FILES IN DOWNLOAD FOLDER
File[] files = downloadsFolder.listFiles();
//LOOP THRU THOSE FILES GETTING NAME AND URI
for (int i = 0; i < files.length; i++) {
File file = files[i];
if (file.getPath().endsWith("pdf")) {
pdfDoc = new PDFDoc();
pdfDoc.setName(file.getName());
pdfDoc.setPath(file.getAbsolutePath());
pdfDocs.add(pdfDoc);
}
}
}
return pdfDocs;
}
This block runs fine with desired result in lollipop but not in Nougat, kindly help me out with genuine changes or addition.
Before calling the method getPDFs() you need to check whether the storage permission is granted by the user or not.
From android marshmallow, only defining the permissions in Manifest file will not work you need to ask for the permission on runtime.
So first you need to check if the device running the app is marshmallow or above. You can do it by using this code.
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
//ask for permission here
}
For asking the runtime permission you can use the following code.
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// 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; request the permission
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
// Permission has already been granted
}
You have to do this for the storage permission. I copied the above code from the Android Developer's Page.
For more details check Requesting App's permission
For this you need to add runtime permissions
private static final int REQUEST_WRITE_PERMISSION = 786;
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_WRITE_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//call func here
}
}
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
} else {
//call func here
}
}
AppConstants
public static final String CAMERA_PERMISSION = CAMERA;
public static final String READ_STORAGE_PERMISSION = READ_EXTERNAL_STORAGE;
public static final String WRITE_STORAGE_PERMISSION = WRITE_EXTERNAL_STORAGE;
public static final String LOCATION_PERMISSION = ACCESS_FINE_LOCATION;
public static final String READ_PHONE_STATE_PERMISSION= READ_PHONE_STATE;
Call this Function From your (Activity OR Fragment OR Button) for checking the permissions
//Getting permission here
public boolean needPermission() {
try {
int readPhoneState = ContextCompat.checkSelfPermission(this, AppConstants.READ_PHONE_STATE_PERMISSION);
int location = ContextCompat.checkSelfPermission(this, AppConstants.LOCATION_PERMISSION);
if (readPhoneState == PackageManager.PERMISSION_GRANTED && location == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
if (readPhoneState != PackageManager.PERMISSION_GRANTED) {
AppGlobal.checkSinglePermission(this, AppConstants.READ_PHONE_STATE_PERMISSION);
} else if (location != PackageManager.PERMISSION_GRANTED) {
AppGlobal.checkSinglePermission(this, AppConstants.LOCATION_PERMISSION);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
This function will check permission type
//Check single permission
public static boolean checkSinglePermission(final Context context, String permissionType) {
ArrayList<String> permissionList = new ArrayList<>();
String type = "";
if (permissionType != null) {
if (permissionType.equals(AppConstants.CAMERA_PERMISSION)) {
type = permissionType;
}
if (permissionType.equals(AppConstants.READ_STORAGE_PERMISSION)) {
type = permissionType;
}
if (permissionType.equals(AppConstants.WRITE_STORAGE_PERMISSION)) {
type = permissionType;
}
if (permissionType.equals(AppConstants.READ_PHONE_STATE_PERMISSION)) {
type = permissionType;
}
if (permissionType.equals(AppConstants.LOCATION_PERMISSION)) {
type = permissionType;
}
int getPermission = ContextCompat.checkSelfPermission(context, type);
if (getPermission != PackageManager.PERMISSION_GRANTED) {
permissionList.add(type);
if (!permissionList.isEmpty()) {
ActivityCompat.requestPermissions((Activity) context, permissionList.toArray
(new String[permissionList.size()]), SINGLE_PERMISSION_REQUEST);
return false;
}
}
}
return true;
}
Then you will get permission success and failure response in this onRequestPermissionsResult()
//Permission request result here
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
for (String permission : permissions) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
AppLog.e("denied" + permission);//denied
needPermission();//needed permission for getting Country code
} else {
if (ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED) {
AppLog.e("allowed" + permission);//allowed
needPermission();//set data
} else {
//set to never ask again
AppLog.e("set to never ask again" + permission);
AppDialog.showAlertDialog(this, null,
getString(R.string.read_phone_state_permission_txt), getString(R.string.txt_ok), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
AppGlobal.permissionSettingView(LoginActivity.this);
}
});
}
}
}
}