share app screenshot without WRITE_EXTERNAL_STORAGE permission? - android

Is it possible to share own app screenshots without adding any permissions ?
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
And this is my others apps code which is works on copy to cache and share
public void sendFile(File paramFile) {
String fileExtension = ".apk";
File temporaryFile;
try {
temporaryFile = File.createTempFile(paramFile.getName(), fileExtension, getApplicationContext().getExternalCacheDir());
copy(paramFile, temporaryFile);
} catch (Exception e) {
temporaryFile = paramFile;
}
Intent localIntent = new Intent();
localIntent.setAction("android.intent.action.SEND");
localIntent.putExtra("android.intent.extra.STREAM", Uri.fromFile(temporaryFile));
localIntent.setType("application/*");
localIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(localIntent, ""));
}

Save your image to internal storage (e.g., getCacheDir()), then use FileProvider to make it available to other apps. See the documentation for more.

You are using getExternalCacheDir()
it absolute the path to youraplication specific directory on the primary
external storage device where the application can place cache
files it owns. These files are internal to the application, and not
typically visible to the user as media.
There is no security enforced with these files.
no need to add the permissions to read or write to the returned path. it's always accessible to the youraplication app. This only applies to paths generated for package name of the youraplication.
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
android.Manifest.permission.READ_EXTERNAL_STORAGE

Related

Flutter image-picker explicitly ask permission

Imagepicker package says
No configuration required - the plugin should work out of the box.
It is no longer required to add
android:requestLegacyExternalStorage="true" as an attribute to the
tag in AndroidManifest.xml, as image_picker has been
updated to make use of scoped storage.
reading images from gallery.
so I think I need to ask some permission from the user as playstore also says this
New package is just working and not asking for any permission.
What permissions I need to explicitly ask
And I don't want to save it on any external directory I just want to upload image to firebase storage
Edit: image picker is not asking any permission from the user is this wrong
Permission needed to read and write files in the android are.
These permission are required to be added to your AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
In your scenario, you don't need to do anything as this is already handled by the library
https://pub.dev/packages/image_picker
Above mentioned library doesn't save the image in external storage.
Note: Images and videos picked using the camera are saved to your
application's local cache, and should therefore be expected to only be
around temporarily. If you require your picked image to be stored
permanently, it is your responsibility to move it to a more permanent
location.
For more info you can refer to this link
https://guides.codepath.com/android/Accessing-the-Camera-and-Stored-Media#accessing-stored-media
Update : How image picking is handled internally in image_picker for Android
For Gallery pick it opens in inbuild file picker intent using ACTION_GET_CONTENT(about action get content)
When opening file using ACTION_GET_CONTENT - Because the user is involved in selecting the files or directories that your app can access, this mechanism doesn't require any system permissions. You can read more about when permission is needed and when not in google docs
Intent pickImageIntent = new Intent(Intent.ACTION_GET_CONTENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
pickImageIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
}
pickImageIntent.setType("image/*");
activity.startActivityForResult(pickImageIntent, REQUEST_CODE_CHOOSE_MULTI_IMAGE_FROM_GALLERY);
and copies the result URI in temp file in cache directory and return the path
String extension = getImageExtension(context, uri);
inputStream = context.getContentResolver().openInputStream(uri);
file = File.createTempFile("image_picker", extension, context.getCacheDir());
file.deleteOnExit();
outputStream = new FileOutputStream(file);
if (inputStream != null) {
copy(inputStream, outputStream);
success = true;
}
For Camera library request the camera permission android.permission.CAMERA from the user and save the camera image in app cache directory.
private void handleCaptureImageResult(int resultCode) {
if (resultCode == Activity.RESULT_OK) {
fileUriResolver.getFullImagePath(
pendingCameraMediaUri != null
? pendingCameraMediaUri
: Uri.parse(cache.retrievePendingCameraMediaUriPath()),
new OnPathReadyListener() {
#Override
public void onPathReady(String path) {
handleImageResult(path, true);
}
});
return;
}
// User cancelled taking a picture.
finishWithSuccess(null);
}
This code is as per version image_picker: ^0.8.4+4 code present on their github page - image picker code
You’ll have to add the above-mentioned permissions to your AndroidManifest.xml file. That is still required to access user storage.

getExternalFilesDir () doesnot store file to mounted memory card

I am using Nougut 7.1.1 device
When I run the below given code, file is stored in device or internal storage "emulated/0..." but I want to store it in removable memory card.
I logged getExternalStorageState() and it shows mounted.
I tried using Environment.getExternalStorageDirectory() also,stored in "emulated/0...", no result
I have used permissions in manifest file too as below:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Note: However, both internal and external(memory card) storage consist of "Hello World" folder like:
Android/Data/com.example.myapplication/files/Hello World/
but stored file(myData2.txt) is present only in "Hello World" folder of internal storage
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("tag", Environment.getExternalStorageState().toString());
Log.i("tag", getExternalFilesDir(null).toString());
savePrivate();
}
public void savePrivate() {
String info = "Written";
File folder = getExternalFilesDir("Hello World");// Folder Name
File myFile = new File(folder, "myData2.txt");// Filename
writeData(myFile, info);
}
private void writeData(File myFile, String data) {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(myFile);
fileOutputStream.write(data.getBytes());
Toast.makeText(this, "Done" + myFile.getAbsolutePath(), Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Changed my savePrivate() method as below and it worked like a charm!!
As per #CommonsWare suggested,using getExternalFilesDirs() returned available array of locations from which I could select particular storage,In my case folder[0] pointed to "emulated/0.." and folder[1] pointed to removable storage (storage/15C8-119Z/...).
public void savePrivate() {
String info = "Written";
File[] folder = getExternalFilesDirs("backup");// Folder Name
Log.i("tag", String.valueOf(folder[1]).toString());
File myFile = new File(folder[1], "myData2.txt");// Filename
writeData(myFile, info);
}
but stored file(myData2.txt) is present only in "Hello World" folder of internal storage
It is stored in what the Android SDK refers to as external storage. External storage is not removable storage, nor is it what the Android SDK refers to as internal storage.
When I run the below given code, file is stored in device or internal storage "emulated/0..." but I want to store it in removable memory card.
First, you are passing an invalid value to getExternalFilesDir(). Please follow the documentation and pass in a valid value (e.g., Environment.DIRECTORY_MUSIC) or null.
To write to removable storage, replace getExternalFilesDir() with getExternalFilesDirs() and choose a location from the returned array of locations. If that array has 2+ entries, 1+ of them will be on removable storage.
Beginning with Android 4.4 (API level 19), reading or writing files in your app's private external storage directory—accessed using getExternalFilesDir()—does not require the READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE permissions. So if your app supports Android 4.3 (API level 18) and lower, and you want to access only the private external storage directory, you should declare that the permission be requested only on the lower versions of Android by adding the maxSdkVersion attribute:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
</manifest>
Select between multiple storage locations
Sometimes, a device that allocates a partition of the internal memory for use as the external storage also provides an SD card slot. This means that the device has two different external storage directories, so you need to select which one to use when writing "private" files to the external storage.
Beginning with Android 4.4 (API level 19), you can access both locations by calling getExternalFilesDirs(), which returns a File array with entries for each storage location. The first entry in the array is considered the primary external storage, and you should use that location unless it's full or unavailable.
If your app supports Android 4.3 and lower, you should use the support library's static method, ContextCompat.getExternalFilesDirs(). This always returns a File array, but if the device is running Android 4.3 and lower, then it contains just one entry for the primary external storage (if there's a second storage location, you cannot access it on Android 4.3 and lower).
Check official documentation for detailed description.
Hope this helps.
This is a function in context where you could get all mounted storage's
ContextCompat.getExternalFilesDirs(context,Environment.YOUR_DIRECTORY);
So , First is your primary internal storage and second will be your mounted sd-card if mounted . You may use this function that returns the sd-card directory if sd-card mounted else the internal-storage directory
File getDir(Context context){
File[] mountedStorage = ContextCompat.getExternalFilesDirs(context,Environment.DIRECTORY_PICTURES);
return mountedStorage[mountedStorage.length-1];
}
With Kotlin
val dir:File = ContextCompat.getExternalFilesDirs(context,Environment.YOUR_DIRECTORY).last()

Trying to save a file on an android system and make it downloadable by the user

I am sorry I am extremely new to android and I am lost. I successfully found out how to save a file on an android system, but every time I try to search for the file on my Android phone (which is where I have a copy of this app located) I am unable to locate it. I know it is there because the app would not start up with out it. How do you write a file that can be both used by the App AND searched by the user in the File Explorer. I am using a Galaxy Note 3 Android version 5.0 Any help would be appreciated.
private void WriteFile(String FileName, String FileCont, boolean isAppend){
File file = new File(getApplicationContext().getFilesDir().getAbsolutePath() + "/" + FileName);
try {
FileOutputStream stream = new FileOutputStream(file, isAppend);
stream.write(FileCont.getBytes());
stream.close();
}
catch(Exception ex){
}
}
Did set the permissions to write on external space in your manifest.xml?
For reference see
http://developer.android.com/reference/android/Manifest.permission.html
You have to set the "WRITE_EXTERNAL_STORAGE" permission to write on external disk. Just add the following line to your android manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
It will implicitly contain the permission to read external storage as well ;).

Save a file on Android documents?

I'm creating an excel file directly on Android. The code is working fine, I can verify the .xls has been created and I can check it's content from a rooted phone.
However I want save the excel file in a different folder from the project itself (which is /data/data/mypackage/files/). I want to save it on the normal phone documents, which would be something like "/storage/sdcard0/Documents/test.xls". I get a message saying "Permission denied" when trying to save the .xls file on that folder.
How can I get access to those folders?
Here I'm creating the excel file
WriteExcel test = new WriteExcel();
test.setOutputFile("/data/data/com.example.interfaz/files/test.xls"); // here is where I want to save the file to "/storage/sdcard0/Documents/test.xls"
try {
test.write();
} catch (WriteException e) {
e.printStackTrace();
} catch (IOException e) {
Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
}
Did you add permissions to your manifest?
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
You should also not hard code the SDCard location since it can, and does, changes between devices.
Instead, use Environment.getExternalStorageDirectory()
Check out this page for more info on saving files:
http://developer.android.com/training/basics/data-storage/files.html#GetWritePermission
Make sure you have the permission in your manifest to write files to external storage:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>

It can't access the sdcard after setting "android.uid.system" in my application?

This is a strange problem. My Application can access the sdcard successfully if I don't set android.uid.system to it. But after setting android.uid.system to it, my application can't access the sdcard. At this time, the exception take place:07-13 09:11:24.999: INFO/System.out(9986): create file happen exception--->java.io.IOException: Permission denied. I check I write the right permission in the right place:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />.
Because use forceStopPackage in my application, I need to add android.uid.system to the manifest. And I have written LOCAL_CERTIFICATE := platform in the make file. Who can explain this strange problem. After setting android.uid.system, my application is belong the system process which should have more power to access the sdcard. This is my idea. The following are my code:
public void setPackage(String dir){
System.out.println( "setPackage dir=="+dir );
File share=new File("/mnt/sdcard","test.txt");
if(!share.exists()){
try{
share.createNewFile();
}catch(Exception e){
System.out.println( "creat file happen exception--->" +e.toString() );
}
}
try{
if(share!=null){
System.out.println( "create file is not null" );
FileOutputStream fops=new FileOutputStream(share);
fops.write(dir.getBytes());
fops.flush();
fops.close();
}
}catch(Exception e){
System.out.println( "write Exception-->" +e.toString() );
}
}
And My application run at the emulator and his target version is 2.3. Thank you very much.
Please read this: link1
and this link2
Use Environment.getExternalStorageDirectory().getAbsolutePath() to get the path, NOT "/mnt/sdcard"
Use: File share = new File(Environment.getExternalStorageDirectory().getAbsolutePath(),"test.txt");
This won't work: File share = new File("/mnt/sdcard", "test.txt");
You can see in android source code: frameworks\base\core\java\android\os\Environment.java, it have a function:
private static void throwIfSystem() {
if (Process.myUid() == Process.SYSTEM_UID) {
Log.wtf(TAG, "Static storage paths aren't available from AID_SYSTEM", new Throwable());
}
}
This function would be called getExternalStorageDirectory(), hence app with system uid can't access sdcard if you don't hack aosp.
android.uid.system make your app bind system, but sdcard observered by system also, then if your app delete this, it can access the sdcard. it seems
delete this line in your xml file :android:sharedUserId="android.uid.system"ystem

Categories

Resources