Open storage directory in android using java - java

We are storing an update of our APK in internal storage of the device. Following is the path of the location:
/storage/emulated/0/Android/data/package_name/files/APK/app_name.apk
We are able to store the updated apk at the above path. But we are unable to install the APK programmatically using java(Because we don’t want to add REQUEST_INSTALL_PACKAGES permission). We decided to atleast open this path so that user can manually install the apk.
SDK level is 32
We have tried multiple ways to open this path, but only Downloads folder is getting opened.
Uri selectedUri = Uri.parse("/storage/emulated/0/Android/data/package_name/files/APK");
intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(selectedUri, "*/*");
intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(intent);
Please suggest a proper way to open the directory.

For similar purpose I'm using below snippet, but be aware thats old app and is still targeting 27, so before e.g. Scoped Storage. Still, afaik, code works well in newer OS versions
public static void sendInstallUpdateIntent(Context ctx, File pendingUpdate) {
Intent intent;
if (Build.VERSION.SDK_INT >= 24) {
Uri uri = FileProvider.getUriForFile(
ctx, ctx.getApplicationContext().getPackageName() + ".fileprovider", pendingUpdate);
intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(uri);
} else {
Uri uri = Uri.fromFile(pendingUpdate);
intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
ctx.startActivity(intent);
}
note you have to implement FileProvider, check out official DOC and some basic configuration on SO

Related

Concerns about the FILES AND MEDIA PERMISSIONS on Android as a developer

I'm developing an app that saves data into a database, I'm trying to backup and restore that database which I am able to do, my issue is with the "ominous" permmission popup on API30+
Allow management of all files
Allow this app to access modify and delete files on your device.....
Allow this app to access, modify and delete files on the device or any connected storage devices? this app may access files without asking you.
I'm not trying to do any of these things, I just want permission to do the backup/restore thing
here's my code for requesting permission:
private void requestStoragePermissionExport(){
if( (Build.VERSION.SDK_INT >= 30 )){
try {
Intent intent = new Intent(Manifest.permission.MANAGE_EXTERNAL_STORAGE);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s",getApplicationContext().getPackageName())));
startActivityForResult(intent, 2296);
} catch (Exception e) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivityForResult(intent, 2296);
}
}else{
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE}, BACKUP_CODE);
}
}
is there a better way to handle this?
Google is restricting use of broad file permissions such as MANAGE_EXTERNAL_STORAGE. You can use Storage Access Framework to gain limited access to certain files or directories.
// Request code for selecting a PDF document.
const val PICK_PDF_FILE = 2
fun openFile(pickerInitialUri: Uri) {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/pdf"
// Optionally, specify a URI for the file that should appear in the
// system file picker when it loads.
putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri)
}
startActivityForResult(intent, PICK_PDF_FILE)
}
Or if you want to access an entire directory;
fun openDirectory(pickerInitialUri: Uri) {
// Choose a directory using the system's file picker.
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
// Optionally, specify a URI for the directory that should be opened in
// the system file picker when it loads.
putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri)
}
startActivityForResult(intent, your-request-code)
}
There are some restrictions to which paths you can access. You can read more about it here
https://developer.android.com/training/data-storage/shared/documents-files
You can just backup your db file to the public Documents directory.
No need for the permissions you mentioned.
Alright so, after a bit of research I found the best solution for myself is as follows:
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + File.separator + "foldername"
this doesn't require permissions and works on below and above API 30

Error parsing package : Whenever trying to install apk after downloading from the server programmatically

I'm trying to update the app which will not be published to the play store since it is for internal use, I've been able to download the file but while launching an intent to install it getting "Error parsing package"
I've tried saving the file in the public directory as mentioned in few links.
I've used FileProvider for getting the URI since the target device is 8.x.
I've checked the apk by installing it manually from the file manager app and also adb to make sure there is no problem with the apk.
I've tried multiple intent actions for installing the app.
All the permissions are given.
--Permissions:
android:name="android.permission.INTERNET"
android:name="android.permission.ACCESS_NETWORK_STATE"
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:name="android.permission.REQUEST_INSTALL_PACKAGES"
--Intent codes that I've tired:
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); intent.setData(FileProvider.getUriForFile(StandardListActivity.this, BuildConfig.APPLICATION_ID+".authorityStr",localFile));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
intent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
startActivity(intent);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getPackageName().toString())); intent.setDataAndType(FileProvider.getUriForFile(StandardListActivity.this, BuildConfig.APPLICATION_ID+".authorityStr"
,localFile), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Intent installIntent = new Intent(Intent.ACTION_VIEW); installIntent.setDataAndType(FileProvider.getUriForFile(StandardListActivity.this,BuildConfig.APPLICATION_ID+".authorityStr",localFile), "application/vnd.android.package-archive");
installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(installIntent);
--Creating a local file for storage:
File rootPath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "/blee");
if (!rootPath.exists()) {
rootPath.mkdirs();
}
final File localFile = new File(rootPath, "test2.apk");
Want to know if there is anything else I can try and please do not redirect me to different threads as probably I've already tried that.

How to do intent that open specific file type in a specific location?

I'm trying to open a specific xlsx file in a specific location via some intent but I don't know how to do it.
I have tried to do something like that:
private void DrawNotfication() {
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent intent=new Intent(Intent.ACTION_OPEN_DOCUMENT,Uri.fromFile(new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "file.xlsx")));
PendingIntent ped= PendingIntent.getActivity(this,0,intent,0);
Notification notification= new Notification.Builder(this).setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("file download comlete")
.setContentIntent(ped).setWhen(System.currentTimeMillis())
.build();
mNotificationManager.notify(0,notification);
}
Someone can help me with the syntax?
I mean to open it in the Excel application
Presumably, Excel supports ACTION_VIEW for this. Replace ACTION_OPEN_DOCUMENT with ACTION_VIEW in your Intent constructor. ACTION_OPEN_DOCUMENT is for displaying what amounts to the file-open dialog you may be used to from other platforms.
Also note that Uri.fromFile() will not work on Android 7.0+, if your targetSdkVersion is 24 or higher. You will need to use FileProvider or something similar, so you can have a Uri with a content scheme instead of a file scheme.

Android Select File Intent

I'm trying to pick a file via an Intent.
What I tryed till now is this:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent, FILE_SELECT_CODE);
But with this, I can only pic Photos with the galery app.
My goal is to pic ANY file via the standard file manager of Android/Samsung.
This didn't work either:
String manufactures = android.os.Build.MANUFACTURER;
if(manufactures.equalsIgnoreCase("samsung"))
{
Intent intent = new Intent("com.sec.android.app.myfiles.PICK_DATA");
intent.putExtra("CONTENT_TYPE", "*/*");
startActivityForResult(intent, FILE_SELECT_CODE);
}
Thx for your help!
My goal is to pic ANY file via the standard file manager of Android/Samsung.
Android does not have a "standard file manager".
If your minSdkVersion is 19 or higher, you are welcome to use the Storage Access Framework (e.g., ACTION_OPEN_DOCUMENT), which is the closest thing that Android now has to a "standard file manager".
Otherwise, you are limited to whatever ACTION_GET_CONTENT-supporting apps that the user has installed, or creating your own file-selection UI, or using one of many existing libraries for selecting files.

How to browse to file explorer in android through code

Hi I want to browse to a file explorer and select a pdf or image present in some directory.
I want the code to do the same.
the below code takes me to gallery and help me choose image but I want to move to file explorer then select file and accordingly I want the code in onactivityResult after selecting.
browsePic.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI
);
startActivityForResult(i, LOAD_IMAGE_RESULTS);
}
});
I believe you can throw out an open intent for a file chooser using the following.
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
try{
startActivityForResult(intent, LOAD_IMAGE_RESULTS);
} catch (ActivityNotFoundException e){
Toast.makeText(YourActivity.this, "There are no file explorer clients installed.", Toast.LENGTH_SHORT).show();
}
The trouble is however, this assumes your user has a file browser open to accepting intents installed on their device, when often no such apps are installed on a device by default.
As in the code above, you may have to throw up a dialog if no Activities exist that can accept this intent, explaining that they need to install a file browser. You could even recommend one that you know works with your application.
I hope this helps.
i think you could do something like this
File strDir = new File("/mnt/"); // where your folder you want to browse inside android
if( strDir.isDirectory()){
//do something
}

Categories