Following code is working with other APIs but 26
public static boolean cretaeDir()
{
String dir = Environment.getExternalStoragePublicDirectory(Environment.MEDIA_SHARED).getAbsolutePath();
java.io.File folder = new java.io.File(dir + "/SomeFolderName");
if (!folder.exists()) {
try{
if(folder.mkdir()) {
Log.e("Creating Folder", "Success");
return true;
} else {
Log.e("Creating Folder", "Failed");
return false;
}
} catch(Exception e){
e.printStackTrace();
return false;
}
}else{
return true;
}
}
Before some one ask, Yeah the permissions have been granted and also uses-permission present in the Manifest file.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.package.name">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="com.android.vending.BILLING" />
<!-- Required OpenGL ES 2.0. for Maps V2 -->
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<application/>
Test Device is Samsung S8, Running 8.0.0
try this
File fsd = Environment.getExternalStorageDirectory();
String filePath = fsd.getAbsolutePath() + "/SomeFolderName";
File dir = new File(filePath);
if(dir.isDirectory==false || !dir.exists()){
dir.mkdirs();
}
ok, so this worked for me.
RequestPermission Methods, when asking for permission, ask WRITE_EXTERNAL_STORAGE before anything else. Try it...
MainActivity.kt
// First permission to be asked
requestPermissions(arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)
// Then all other permissions
This is working for all API inclusive & levels above 26.
TBH, I don't know how, but it working.
You are not using a valid folder type. You have to choose from the following options
The type of storage directory to return. Should be one of DIRECTORY_MUSIC, DIRECTORY_PODCASTS, DIRECTORY_RINGTONES, DIRECTORY_ALARMS, DIRECTORY_NOTIFICATIONS, DIRECTORY_PICTURES, DIRECTORY_MOVIES, DIRECTORY_DOWNLOADS, DIRECTORY_DCIM, or DIRECTORY_DOCUMENTS. May not be null.
Your code should be something like this
String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath();
I have fixed it by the following way as I have no other option left and I have tried all the suggested solutions. Maybe the error is device dependent or whatever, but it has nothing to do with API 26 as I have upgraded one of my test devices to API 26 and the old function did worked.
The following code is working on all devices.
File file = MyApplication.getInstance().getDir("BUZZ",MODE_PRIVATE);
cacheDir = new File(file.getAbsoluteFile()+File.separator+IMAGE_DIRECTORY_NAME);
Happy Coding :-)
Related
How can I check my own app if there is a newer version available and then update itselfs automatically? The idea is to request an API for a new version and receives the apk file. Then the APK should be stored and the installation/update should start. I don't know how to create this. The request to the API is no big deal, but how can I store and execute the APK file on an Android device?
I only found this but there were too many compiling errors (Context, Java, Buld, Intent, FileProvider could not be found).
Can you gave me some hints how to solve this "problem"?
THANK YOU!
You can uninstall you app by the following code:
var name = this.ApplicationContext.PackageName;
Intent intent = new Intent(Intent.ActionDelete);
intent.SetData(Android.Net.Uri.Parse("package:" + name));
StartActivity(intent);
In addition, don't forget to add the permissions in the AndroidManifest.xml:
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
It is not necessary to uninstall the app. If it is build with the same keystore and signature, it is possible to install one version directly to overwrite the existing.
var context = Android.App.Application.Context;
var path = Path.Combine(Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath, "com.companyname.Testproject.apk");
Java.IO.File file = new Java.IO.File(path);
using (Android.Content.Intent install = new Android.Content.Intent(Android.Content.Intent.ActionView))
{
Android.Net.Uri apkURI = AndroidX.Core.Content.FileProvider.GetUriForFile(context, context.ApplicationContext.PackageName + ".provider", file);
install.SetDataAndType(apkURI, "application/vnd.android.package-archive");
install.AddFlags(Android.Content.ActivityFlags.NewTask);
install.AddFlags(Android.Content.ActivityFlags.GrantReadUriPermission);
install.AddFlags(Android.Content.ActivityFlags.ClearTop);
install.PutExtra(Android.Content.Intent.ExtraNotUnknownSource, true);
Platform.CurrentActivity.StartActivity(install);
}
In the AndroidManifext.xml i added:
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
I'm trying to write a file on a folder outside the app, in the external storage. I have added WRITE_EXTERNAL_STORAGE permission in manifest.
There are similar errors here in Stack Overflow but after trying the solutions (as you will see in my next lines) I'm having the same error.
I tried it in both emulator with Nexus 5X API 27 oreo rom and also in a Huawei real phone with Android 4.4.
In both devices I have the same error:
FileNotFoundException: /storage/sdcard0/Myfile.txt: open failed: EACCES (Permission denied)
This is my code:
String content = "hello world";
File file;
FileOutputStream outputStream;
try {
file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "MyFile.txt");
outputStream = new FileOutputStream(file);
outputStream.write(content.getBytes());
outputStream.close();
} catch (IOException e) {
Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<uses-feature
android:name="android.hardware.location"
android:required="false" />
<uses-feature
android:name="android.hardware.location.gps"
android:required="false" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".activities.Activity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
For devices with Android >=6.0, you have to request permissions at runtime
For android 4, apprently adding android:maxSdkVersion="18" generate this exception, try by removing it
EDIT : For Android 4.4 and above, you don't WRITE_EXTERNAL_STORAGE IF ONLY you want to write to external storage, from the doc :
beginning with Android 4.4 (API level 19), it's no longer necessary
for your app to request the WRITE_EXTERNAL_STORAGE permission when
your app wants to write to its own application-specific directories on
external storage (the directories provided by getExternalFilesDir())
Elsewere, for android < 4.4, you need to add android:maxSdkVersion="18" for own application-specific directories on
external storage
Just try to request permission with this code :
private void requestPermission() {
ActivityCompat.requestPermissions(getActivity() ,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE ,
Manifest.permission.READ_EXTERNAL_STORAGE} ,
PERMISSION_READ_WRITE_REQUEST_CODE);
}
PERMISSION_READ_WRITE_REQUEST_CODE is the custom variable , in my way is 34.
And handle it in
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case PERMISSION_READ_WRITE_REQUEST_CODE : {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
//yeee permission granted
}
}
}
}
Finally yesterday I discovered the same thing that CommonsWare has explained perfectly in the comments:
Get rid of android:maxSdkVersion="18". That is only valid if you are
using getExternalFilesDir(), getExternalCacheDir(), and similar
methods on Context. You are using
Environment.getExternalStorageDirectory(), so you always need
WRITE_EXTERNAL_STORAGE
I'm trying to create folder in internal storage of the device, and have some problems with that. I can't create directory using :
String rootPath=Environment.getExternalStorageDirectory().getPath()+"/test";
File file=new File(rootPath);
if(!file.exists()){
file.mkdir();
}
file.mkdir return false
I have such permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
Thank you very much for answers !
So really, as you all guys said in Android Marshmallow (API 23) or higher we need to ask runtime permissions.
To solve this issue use call :
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
in your onCreate() method
Thanks all for your help !
You can use
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/test");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
I am creating an app in which I would like to read a file from the sd card and then write to another file using info from the other file. When attempting to read the file I get the following error: System.UnauthorizedAccessException: Access to the path 'sdcard/android/data/App1.App1/files/' is denied.
Read Function:
private string ReadFile(string fileName)
{
var path = "sdcard/android/data/App1.App1/files/";
var filePath = Path.Combine(path.ToString(), fileName);
string text = File.ReadAllText(path.ToString());
return text;
}
Android Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="App1.App1" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
<uses-sdk android:minSdkVersion="16" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application android:label="Scout" android:icon="#drawable/Icon" android:theme="#style/CustomActionBarTheme"></application>
</manifest>
I have solved the issue and found that I was trying to read a folder instead of the file itself. When switching out the variable path with filePath int the read all text function the error went away.
Do not forget to add
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
into the manifest. This allows to read and write on SD card.
More details about uses-permission
It can also be a problem with your simulator and your sd card, read this topic
Here is the exact exception that's thrown:
java.io.FileNotFoundException: /mnt/sdcard/example.mp4 (Permission denied)
I literally copied and pasted example code from here. In addition, I also added this little bit of code to format my path correctly:
private String sanitizePath(String path) {
if (!path.startsWith("/")) {
path = "/" + path;
}
if (!path.contains(".")) {
path += ".3gp";
}
return Environment.getExternalStorageDirectory().getAbsolutePath() + path;
}
Here are the permissions included in my manifest:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.STORAGE" />
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.front"/>
Am I missing something completely obvious or is it something more?
You might want to check if the phone is in "Mass Storage Mode".
When USB cable is connected in this mode, you cannot access files on /sdcard.