Upload Media From Android Gallery to AWS S3 - java

I have been working for a long time on my android app project with Amplify Storage, and I have faced a problem which I didn’t find a solution for.
I want to retrieve an image/video from the gallery and upload it to S3, but I always get an error with “Cursor” it always returns null.
Is there any better way to convert Uri data to a File so I can upload it to S3?
here is my code:
public void openPhotoGallery(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select file to upload "), 8);
}
#Override
protected void onActivityResult(int requestCode, final int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == 8) {
Uri selectedMediaUri = data.getData();
String filePath = getPath(selectedMediaUri);
File file = saveVideoToInternalStorage(filePath);
Amplify.Storage.uploadFile("test/image", file, result -> {
Log.i("MyAmplifyApp", "Successfully uploaded: " + result.getKey());
file.delete();
}, error -> {
Log.e("MyAmplifyApp", "Upload failed", error);
});
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); // Line of error
cursor.moveToFirst();
return cursor.getString(column_index);
}
private File saveVideoToInternalStorage (String filePath) {
File newfile = null;
try {
File currentFile = new File(filePath);
ContextWrapper cw = new ContextWrapper(getApplicationContext());
newfile = new File(this.getFilesDir().getPath().toString() + "/video1.mp4");
if(currentFile.exists()){
InputStream in = new FileInputStream(currentFile);
OutputStream out = new FileOutputStream(newfile);
// Copy the bits from instream to outstream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
Log.v("", "Video file saved successfully.");
} else {
Log.v("", "Video saving failed. Source file missing.");
}
} catch (Exception e) {
e.printStackTrace();
}
return newfile;
}
And I always have this error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.abdulelah.taajerpartners, PID: 24163
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=8, result=-1, data=Intent { dat=content://media/external/images/media/419319 flg=0x1 (has extras) }} to activity {com.abdulelah.taajerpartners/com.ajjerly.partners.TestActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'int android.database.Cursor.getColumnIndexOrThrow(java.lang.String)' on a null object reference
at android.app.ActivityThread.deliverResults(ActivityThread.java:5078)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5120)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
at android.os.Handler.dispatchMessage(Handler.java:112)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'int android.database.Cursor.getColumnIndexOrThrow(java.lang.String)' on a null object reference
at com.ajjerly.partners.TestActivity.getPath(TestActivity.java:114)
at com.ajjerly.partners.TestActivity.onActivityResult(TestActivity.java:72)
at android.app.Activity.dispatchActivityResult(Activity.java:7797)
at android.app.ActivityThread.deliverResults(ActivityThread.java:5071)

As of Android 10, you can only obtain the path for a given Uri if the File is stored within your application directory. Photos from the Gallery do not meet this criteria. See Storage updates in Android for more details on this.
One solution would be to create an InputStream directly from your Uri, like this:
InputStream inStream = getContentResolver().openInputStream(uri);
Then, you can save that to a File, like you are doing in saveVideoToInternalStorage, and then pass the File to Amplify.Storage.uploadFile.
An even better/easier solution would be to use the Amplify.Storage.uploadInputStream API (instead of Amplify.Storage.uploadFile), like this:
InputStream inStream = getContentResolver().openInputStream(uri);
Amplify.Storage.uploadInputStream("test/image", inputStream,
result -> {
Log.i("MyAmplifyApp", "Successfully uploaded: " + result.getKey());
}, error -> {
Log.e("MyAmplifyApp", "Upload failed", error);
}
);
Under the hood, the Amplify library actually does the same thing you are doing - it writes the InputStream to a temp directory as a File, uploads that File, and then deletes it from the temp directory on completion.

Related

Convert android Uri to java File Android Studio

I have an Intent of ACTION_GET_CONTENT in my app and I need to put the picked file ( there will be different files, ppt, doc...) in a java.io File.
I'm able to get the data and put it into a android.net Uri. Is there a way I ca create a java File from this Uri?
I need it to be a file in order to upload it do google drive using the google drive API
This is the code to upload to the drive, I need to convert the uri to a temporary file in order to pass it as the javaFile of this method
public Task<File> uploadFileWithMetadata(java.io.File javaFile, boolean isSlide, #Nullable final String folderId, PostFileHolder postFileHolder) {
return Tasks.call(mExecutor, () -> {
Log.i("upload file", "chegou" );
String convertTo; // string to convert to gworkspace
if(isSlide){
convertTo = TYPE_GOOGLE_SLIDES;
}
else{
convertTo = TYPE_GOOGLE_DOCS;
}
List<String> folder;
if (folderId == null) {
folder = Collections.singletonList("root");
} else {
folder = Collections.singletonList(folderId);
}
File metadata = new File()
.setParents(Collections.singletonList(folderId))
.setName(postFileHolder.getDisplayName())
.setMimeType(convertTo);
Log.i("convert to: ", convertTo );
// the convert to is the mimeType of the file, withg gworkspace it is a gdoc or gslide, with others is the regular mimetype
FileContent mediaContent = new FileContent(postFileHolder.getConvertTo(), javaFile);
Log.i("media content", "chegou" );
// até aqui com gworkspace chega
File uploadedFile = mDriveService.files().create(metadata, mediaContent)
.setFields("id")
.execute();
Log.i("File ID: " , uploadedFile.getId());
return uploadedFile;
});
}
This is my code to get the Uri
case REQUEST_CODE_FILE_PICKER:
// get uri from file picked
Uri url = data.getData();
break;
}
Solved it!
Here's how I did it:
// my uri
Uri fileUri = Uri.parse(postFileHolder.getFileUri());
// create a null InputSream
InputStream iStream = null;
try {
// create a temporary file
File fileToUpload = File.createTempFile("fileToUpload", null, this.getCacheDir());
iStream = getContentResolver().openInputStream(fileUri);
// use function to get the bytes from the created InputStream
byte[] byteData = getBytes(iStream);
convert byteArray to File
FileOutputStream fos = new FileOutputStream(fileToUpload);
fos.write(byteData);
fos.flush();
fos.close();
if(fileToUpload == null){
Log.i("create file", "null");
}
else{
Log.i("create file", "not null: "+ fileToUpload.getTotalSpace());
getEGDrive(fileToUpload);
}
}
catch (FileNotFoundException e) {
Log.i("error create file uri", e.getLocalizedMessage());
e.printStackTrace();
} catch (IOException e) {
Log.i("error create file uri", e.getLocalizedMessage());
e.printStackTrace();
}
And here's the function to transform the InputStream into byteArray:
public byte[] getBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
Got big part of the answer from: https://stackoverflow.com/a/10297073/14990708

Using SAF File Picker in Android 10 (Q) to copy files from Downloads to local app folder

Since Android 10 (API 29) I need to use the Storage Access Framework's File Picker to select GPX (GPS) files to copy from the Downloads folder to my local app folder. I have implemented the file picker and am able to select the GPX file, however the result data URI appears different to the filename (but unique) and I cannot seem to use it to copy the files. The rest of the code is the same "copy" code I used in previous versions of Android. What am I doing wrong and how should I best use the SAF File Picker to copy files? I haven't been able to find a recent (API 29) "file copy" example on the net...
private static final int READ_REQUEST_CODE = 42;
...
public void performFileSearch() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
// intent.setType("application/gpx"); // Filters GPX file but wont let me select them.
intent.setType("*/*");
startActivityForResult(intent, READ_REQUEST_CODE);
}
...
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Uri uri = null;
if (data != null) {
uri = data.getData();
handleDownloadedGPXFiles2(uri);
}
}
...
private void handleDownloadedGPXFiles2(Uri selectedFileUri) {
File sourceFile = new File(selectedFileUri.getPath()); // Returns a unique number or string but NOT filename string???
File destDirectory = new File(this.getExternalFilesDir(null), "Imported");
File destFile = new File(destDirectory, "test.gpx"); // Needs to be same name as original filename.
try {
if (!destFile.exists()) {
destFile.createNewFile();
}
FileInputStream inStream = new FileInputStream(sourceFile);
FileOutputStream outStream = new FileOutputStream(destFile);
FileChannel inChannel = inStream.getChannel();
FileChannel outChannel = outStream.getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
inStream.close();
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "File Import Complete", Toast.LENGTH_LONG).show();
}
File sourceFile = new File(selectedFileUri.getPath());
Remove above line.
FileInputStream inStream = new FileInputStream(sourceFile);
Replace that line by:
InputStream inStream = getContentResolver().openInputStream(selectedFileUri);
Further you can remove
if (!destFile.exists()) {
destFile.createNewFile();
}
as the file will be created by the new FileOutputStream();
Finally: Your last Toast() is on the wrong place. It should be in the try block.
Place a different Toast() in the catch block to inform yourself or the user.
Thanks blackapps. Final code works well...
private void handleDownloadedGPXFiles2(Uri selectedFileUri) {
String displayName = "imported.gpx";
String fileExtension;
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(selectedFileUri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
if (displayName != null && displayName.length() >=4) {
fileExtension = displayName.substring(displayName.length() - 4);
if (!fileExtension.equals(".gpx")){
myCustomToast("Must be a .GPX file!");
return;
}
} else {
myCustomToast("Must be a .GPX file!");
return;
}
}
File destDirectory = new File(this.getExternalFilesDir(null), "Imported");
File destFile = new File(destDirectory, displayName);
FileOutputStream outStream = new FileOutputStream(destFile);
InputStream in = getContentResolver().openInputStream(selectedFileUri);
OutputStream out = outStream;
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
out.flush();
out.close();
Toast.makeText(getApplicationContext(), "File Import Complete", Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "File Import FAILED", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
finally
{
if (cursor != null)
cursor.close();
}
}

FileNotFoundException in onActivityResult

I am trying to browse only two file-types: images or pdf.
Here is the source:
String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE};
myPermissions =new MyPermissions(TestDialog.this, 0, permissions);
MyPermissions.EventHandler permHandler = new MyPermissions.EventHandler() {
#Override
public void handle() {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("application/pdf");
intent.setType("image/jpeg");
startActivityForResult(intent, 0);
}
};
myPermissions.doIfHasPermissions(permHandler);
Here is a my onActivityResult source:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
String url = data.getData().getPath();
File myFile = new File(url);
Log.e("base64 ", getStringFile(myFile));
}
super.onActivityResult(requestCode, resultCode, data);
}
public String getStringFile(File f) {
InputStream inputStream = null;
String encodedFile = "", lastVal;
try {
inputStream = new FileInputStream(f.getAbsolutePath());
byte[] buffer = new byte[10240];//specify the size to allow
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
Base64OutputStream output64 = new Base64OutputStream(output, Base64.DEFAULT);
while ((bytesRead = inputStream.read(buffer)) != -1) {
output64.write(buffer, 0, bytesRead);
}
output64.close();
encodedFile = output.toString();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
lastVal = encodedFile;
return lastVal;
}
I would like to convert the selected file to Base64, but I get a FileNotFoundException. Does anyone have any idea what am I doing wrong?
Have a look at
Uri uri = data.getData();
Then try to log the value of uri.toString().
You will see that it starts with "content//....".
Do not try to find a file.
Instead of a FileInputStream use an InputStream.
InputStream inputStream = getContentResolver().openInputStream(uri);
I try to browse only two type files,images or pdf
Your code has nothing much to do with files. It uses ACTION_GET_CONTENT, which allows the user to choose a piece of content.
String url = data.getData().getPath();
This line is useless, unless the Uri has a scheme of file. Most likely, it has a scheme of content.
Stop using File and FileInputStream. Instead, get an InputStream from a ContentResolver (from getContentResolver()) and its openInputStream() method. You can pass in the Uri, and you will get an InputStream regardless of whether the Uri scheme is file or content.
Also note that your app is likely to crash with an OutOfMemoryError, except for fairly small files, as you will not have enough heap space to perform this conversion.

Access a text file in android

I'm trying to read the contents of a flat file stored in the phone's memory. But when I get the file address through the attempt, and I create the File object this is not readable.
Try to create it by manually passing the file's address and it works.
The problem is that I can not get that address from the uri that gives me the Intent
Here I open the android file browser
btnAdjuntar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("text/plain");
Intent chooser = Intent.createChooser(intent, "Elige App");
if (chooser.resolveActivity(getPackageManager()) != null) {
startActivityForResult(chooser, COD_ABRIR_FICHERO);
}
}
});
Here I receive the Intent
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == COD_ABRIR_FICHERO) {
if (resultCode == RESULT_OK) {
String ruta = data.getData().getPath();
String lectura;
try {
lectura = leerArchivo(ruta);
} catch (Exception e) {
lectura = e.getMessage();
}
Toast.makeText(getApplicationContext(), lectura, Toast.LENGTH_LONG).show();
}
}
}
The exception is thrown and you have this message:
/document/primary:Documents/PruebaArchivo.txt: open failed: ENOENT (No such file or directory)
Method leerArchivo
public String leerArchivo(String ruta) throws FileNotFoundException, IOException {
String cadena;
String lectura = "";
File file = new File(ruta);
FileReader f = new FileReader(file);
BufferedReader b = new BufferedReader(f);
while ((cadena = b.readLine()) != null) {
lectura += cadena;
}
b.close();
return lectura;
}
Already the permissions to read the external memory are accepted
You can open an InputStream from a Uri:
InputStream is = getContentResolver().openInputStream(uri);
Then wrap the input stream to create a BufferedReader:
BufferedReader b = new BufferedReader(new InputStreamReader(is));
while ((cadena = b.readLine()) != null) {
lectura += cadena;
}
b.close();
etc.
This way you never need to get the file's address. You can specify the encoding (e.g. "UTF-8") as a second parameter to the InputStreamReader constructor.
But when I get the file address through the attempt, and I create the File object this is not readable.
You are not getting a file. You are getting content. You are being given a Uri. A Uri is not a file.
String ruta = data.getData().getPath();
That line is only useful if the scheme of the Uri is file. In your case, the scheme is probably content.
Use a ContentResolver and openInputStream() to get an InputStream on the content. This works whether the Uri has a file scheme or a content scheme.

How can i share apk file in my app (send app itself)

I am trying to use this code to send my application apk file to another device:
public static void sendAppItself(Activity paramActivity) throws IOException {
PackageManager pm = paramActivity.getPackageManager();
ApplicationInfo appInfo;
try {
appInfo = pm.getApplicationInfo(paramActivity.getPackageName(),
PackageManager.GET_META_DATA);
Intent sendBt = new Intent(Intent.ACTION_SEND);
sendBt.setType("*/*");
sendBt.putExtra(Intent.EXTRA_STREAM,
Uri.parse("file://" + appInfo.publicSourceDir));
paramActivity.startActivity(Intent.createChooser(sendBt,
"Share it using"));
} catch (PackageManager.NameNotFoundException e1) {
e1.printStackTrace();
}
}
This code works very well.
But the name of the apk file shared with this code is base.apk
How can I change it?
Copy the file from the source directory to a new directory.
Rename the file while copying and share the copied file.
Delete the temp file after share is complete.
private void shareApplication() {
ApplicationInfo app = getApplicationContext().getApplicationInfo();
String filePath = app.sourceDir;
Intent intent = new Intent(Intent.ACTION_SEND);
// MIME of .apk is "application/vnd.android.package-archive".
// but Bluetooth does not accept this. Let's use "*/*" instead.
intent.setType("*/*");
// Append file and send Intent
File originalApk = new File(filePath);
try {
//Make new directory in new location
File tempFile = new File(getExternalCacheDir() + "/ExtractedApk");
//If directory doesn't exists create new
if (!tempFile.isDirectory())
if (!tempFile.mkdirs())
return;
//Get application's name and convert to lowercase
tempFile = new File(tempFile.getPath() + "/" + getString(app.labelRes).replace(" ","").toLowerCase() + ".apk");
//If file doesn't exists create new
if (!tempFile.exists()) {
if (!tempFile.createNewFile()) {
return;
}
}
//Copy file to new location
InputStream in = new FileInputStream(originalApk);
OutputStream out = new FileOutputStream(tempFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
System.out.println("File copied.");
//Open share dialog
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
startActivity(Intent.createChooser(intent, "Share app via"));
} catch (IOException e) {
e.printStackTrace();
}
}
Update: this method does not work anymore and throws exception if you implement it. Since android N, we should use content providers if we want to have access to files in memory(like the apk file). For more information please visit this Guide. Although the whole idea of copying and renaming and sharing the copied version is still valid.
You can use this function, test on api 22 and 27
private void shareApplication() {
ApplicationInfo app = getApplicationContext().getApplicationInfo();
String filePath = app.sourceDir;
Intent intent = new Intent(Intent.ACTION_SEND);
// MIME of .apk is "application/vnd.android.package-archive".
// but Bluetooth does not accept this. Let's use "*/*" instead.
intent.setType("*/*");
// Append file and send Intent
File originalApk = new File(filePath);
try {
//Make new directory in new location=
File tempFile = new File(getExternalCacheDir() + "/ExtractedApk");
//If directory doesn't exists create new
if (!tempFile.isDirectory())
if (!tempFile.mkdirs())
return;
//Get application's name and convert to lowercase
tempFile = new File(tempFile.getPath() + "/" + getString(app.labelRes).replace(" ","").toLowerCase() + ".apk");
//If file doesn't exists create new
if (!tempFile.exists()) {
if (!tempFile.createNewFile()) {
return;
}
}
//Copy file to new location
InputStream in = new FileInputStream(originalApk);
OutputStream out = new FileOutputStream(tempFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
System.out.println("File copied.");
//Open share dialog
// intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
Uri photoURI = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", tempFile);
// intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
intent.putExtra(Intent.EXTRA_STREAM, photoURI);
startActivity(Intent.createChooser(intent, "Share app via"));
} catch (IOException e) {
e.printStackTrace();
}
}
This only happens because it is saved by base.apk name.
To share it as per your need you have to just copy this file into another directory path and rename it over there. Then use new file to share.
This file path[file:///data/app/com.yourapppackagename/base.apk] in data folder is having only read permissions so you can't rename .apk file over there.
2021 Kotlin way
First we need to set a file provider
In AndroidManifest.xml create a File provider
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true"
>
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"
/>
</provider>
If you don't have file_path.xml the create one in res/xml (create xml folder if it doesn't exist)
and in file_path.xml add
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path
name="apk"
path="cache/ExtractedApk/" />
</paths>
Now add the code to share the apk
private fun shareAppAsAPK(context: Context) {
val app: ApplicationInfo = context.applicationInfo
val originalApk = app.publicSourceDir
try {
//Make new directory in new location
var tempFile: File = File(App.instance.getExternalCacheDir().toString() + "/ExtractedApk")
//If directory doesn't exists create new
if (!tempFile.isDirectory) if (!tempFile.mkdirs()) return
//rename apk file to app name
tempFile = File(tempFile.path + "/" + getString(app.labelRes).replace(" ", "") + ".apk")
//If file doesn't exists create new
if (!tempFile.exists()) {
if (!tempFile.createNewFile()) {
return
}
}
//Copy file to new location
val inp: InputStream = FileInputStream(originalApk)
val out: OutputStream = FileOutputStream(tempFile)
val buf = ByteArray(1024)
var len: Int
while (inp.read(buf).also { len = it } > 0) {
out.write(buf, 0, len)
}
inp.close()
out.close()
//Open share dialog
val intent = Intent(Intent.ACTION_SEND)
//MIME type for apk, might not work in bluetooth sahre as it doesn't support apk MIME type
intent.type = "application/vnd.android.package-archive"
intent.putExtra(
Intent.EXTRA_STREAM, FileProvider.getUriForFile(
context, BuildConfig.APPLICATION_ID + ".fileprovider", File(tempFile.path)
)
)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(intent)
} catch (e: IOException) {
e.printStackTrace()
}
}
If someone trying to generate apk from fragment they may need to change few lines from #sajad's answer as below
Replace
File tempFile = new File(getExternalCacheDir() + "/ExtractedApk");
with
File tempFile = new File(getActivity().getExternalCacheDir() + "/ExtractedApk");
2.while importing BuildConfig for below line
import androidx.multidex.BuildConfig // DO NOT DO THIS!!! , use your app BuildConfig.
and if you're getting below EXCEPTION
Couldn't find meta-data for provider with authority
Look for provider info in manifest file
then look for "provider"s name and authority in your manifest file and if it's androidx.core.content.FileProvider then
Replace
Uri photoURI = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", tempFile);
With
Uri photoURI = FileProvider.getUriForFile(getActivity(), BuildConfig.APPLICATION_ID + ".fileprovider", tempFile);

Categories

Resources