Skip to content

Commit

Permalink
Copy file to temp folder if from unknown provider
Browse files Browse the repository at this point in the history
  • Loading branch information
HBiSoft committed Aug 29, 2019
1 parent 1a6221f commit 8e6a18d
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 29 deletions.
8 changes: 5 additions & 3 deletions app/src/main/java/com/hbisoft/pickitexample/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ private void openGallery() {
// Check if permissions was granted
private boolean checkSelfPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MainActivity.PERMISSION_REQ_ID_WRITE_EXTERNAL_STORAGE);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, MainActivity.PERMISSION_REQ_ID_WRITE_EXTERNAL_STORAGE);
return false;
}
return true;
Expand Down Expand Up @@ -195,15 +195,17 @@ public void PickiTonProgressUpdate(int progress) {
}

@Override
public void PickiTonCompleteListener(String path, boolean wasDriveFile, boolean wasSuccessful, String reason) {
public void PickiTonCompleteListener(String path, boolean wasDriveFile, boolean wasUnknownProvider, boolean wasSuccessful, String reason) {

if (mdialog != null && mdialog.isShowing()) {
mdialog.cancel();
}

// Check if it was a Drive file and display a Toast
// Check if it was a Drive/local/unknown provider file and display a Toast
if (wasDriveFile){
showLongToast("Drive file was selected");
}else if (wasUnknownProvider){
showLongToast("File was selected from unknown provider");
}else {
showLongToast("Local file was selected");
}
Expand Down
2 changes: 1 addition & 1 deletion pickit/src/main/java/com/hbisoft/pickit/CallBackTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
interface CallBackTask {
void PickiTonPreExecute();
void PickiTonProgressUpdate(int progress);
void PickiTonPostExecute(String path, boolean wasDriveFile);
void PickiTonPostExecute(String path, boolean wasDriveFile, boolean wasSuccessful, String reason);
}
24 changes: 17 additions & 7 deletions pickit/src/main/java/com/hbisoft/pickit/DownloadAsyncTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,21 @@ class DownloadAsyncTask extends AsyncTask<Uri, Integer, String> {
private Cursor returnCursor;
private InputStream is = null;
private String extension;
private String errorReason = "";

DownloadAsyncTask(Uri uri, Context context, CallBackTask callback) {
DownloadAsyncTask(Uri uri, Context context, CallBackTask callback, String filename) {
this.mUri = uri;
mContext = new WeakReference<>(context);
this.callback = callback;
this.filename = filename;
}

@Override
protected void onPreExecute() {
callback.PickiTonPreExecute();

Context context = mContext.get();
if (context != null) {
folder = context.getExternalFilesDir("Temp");
filename = "tempDriveFile";
returnCursor = context.getContentResolver().query(mUri, null, null, null, null);
final MimeTypeMap mime = MimeTypeMap.getSingleton();
extension = mime.getExtensionFromMimeType(context.getContentResolver().getType(mUri));
Expand Down Expand Up @@ -70,9 +70,14 @@ protected String doInBackground(Uri... params) {
int size = (int) returnCursor.getLong(sizeIndex);
returnCursor.close();

pathPlusName = folder + "/" + filename + "." + extension;
if (extension == null){
pathPlusName = folder + "/" + filename;
file = new File(folder + "/" + filename);
}else {
pathPlusName = folder + "/" + filename + "." + extension;
file = new File(folder + "/" + filename + "." + extension);
}

file = new File(folder + "/" + filename + "." + extension);
BufferedInputStream bis = new BufferedInputStream(is);
FileOutputStream fos = new FileOutputStream(file);

Expand All @@ -91,14 +96,19 @@ protected String doInBackground(Uri... params) {
fos.close();

} catch (IOException e) {
Log.e("Pickit IOException = ", String.valueOf(e));
Log.e("Pickit IOException = ", e.getMessage());
errorReason = e.getMessage();
}

return file.getAbsolutePath();

}

protected void onPostExecute(String result) {
callback.PickiTonPostExecute(pathPlusName, true);
if(result == null){
callback.PickiTonPostExecute(pathPlusName, true, false, errorReason);
}else {
callback.PickiTonPostExecute(pathPlusName, true, true, "");
}
}
}
71 changes: 57 additions & 14 deletions pickit/src/main/java/com/hbisoft/pickit/PickiT.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import android.webkit.MimeTypeMap;

import java.io.File;

public class PickiT implements CallBackTask{
private Context context;
private final PickiTCallbacks pickiTCallbacks;
private String returnedPath = "";
private boolean isDriveFile = false;
private boolean isFromUnknownProvider = false;
private DownloadAsyncTask asyntask;

public PickiT (Context context, PickiTCallbacks listener){
Expand All @@ -19,50 +20,81 @@ public PickiT (Context context, PickiTCallbacks listener){
}

public void getPath(Uri uri, int APILevel){
String returnedPath;
if (APILevel>=19){
// Drive file was selected
if (isOneDrive(uri)||isDropBox(uri)||isGoogleDrive(uri)){
isDriveFile = true;
downloadFile(uri);
}else {
downloadFile(uri, "tempFile");
}
// Local file was selected
else {
returnedPath = Utils.getRealPathFromURI_API19(context, uri);

final MimeTypeMap mime = MimeTypeMap.getSingleton();
String subStringExtension = String.valueOf(returnedPath).substring(String.valueOf(returnedPath).lastIndexOf(".") + 1);
String extensionFromMime = mime.getExtensionFromMimeType(context.getContentResolver().getType(uri));

// Path is null - error occurred
if (returnedPath == null || returnedPath.equals("")){
pickiTCallbacks.PickiTonCompleteListener(returnedPath, false, false, Utils.errorReason());
}else {
pickiTCallbacks.PickiTonCompleteListener(returnedPath, false, true, "");
pickiTCallbacks.PickiTonCompleteListener(returnedPath, false, false, false, Utils.errorReason());
}
// Path is not null
else {
// This can be caused by twe situations
// 1. The file was selected from an unknown provider
// 2. getExtensionFromMimeType returned an unknown mime type for example "audio/mp4"
//
// When this is case we will copy/write the file to the temp folder, same as when a file is selected from Google Drive etc.
// We provide a name by getting the text after the last "/"
// Remember if the extension can't be found, it will not be added, but you will still be able to use the file
//Todo: Add checks for unknown file extensions

if (!subStringExtension.equals(extensionFromMime)) {
String fileName = returnedPath.substring(returnedPath.lastIndexOf("/") + 1);
isFromUnknownProvider = true;
downloadFile(uri, fileName);
return;
}

// Path can be returned, no need to make a "copy"
pickiTCallbacks.PickiTonCompleteListener(returnedPath, false, false, true, "");
}
}
}else{
//Todo: Test API <19
returnedPath = Utils.getRealPathFromURI_BelowAPI19(context, uri);
pickiTCallbacks.PickiTonCompleteListener(returnedPath, false, true, "");
pickiTCallbacks.PickiTonCompleteListener(returnedPath, false, false, true, "");
}

}

private void downloadFile(Uri uri){
asyntask = new DownloadAsyncTask(uri, context, this);
// Create a new file from the Uri that was selected
private void downloadFile(Uri uri, String fileName){
asyntask = new DownloadAsyncTask(uri, context, this, fileName);
asyntask.execute();
}

// End the "copying" of the file
public void cancelTask(){
if (asyntask!=null){
asyntask.cancel(true);
deleteTemporaryFile();
}
}

// Check different providers
private boolean isDropBox(Uri uri) {
return String.valueOf(uri).toLowerCase().contains("content://com.dropbox.android");
}

private boolean isGoogleDrive(Uri uri) {
return String.valueOf(uri).toLowerCase().contains("com.google.android.apps");
}

private boolean isOneDrive(Uri uri){
return String.valueOf(uri).toLowerCase().contains("com.microsoft.skydrive.content");
}

// Listeners
@Override
public void PickiTonPreExecute() {
pickiTCallbacks.PickiTonStartListener();
Expand All @@ -74,12 +106,23 @@ public void PickiTonProgressUpdate(int progress) {
}

@Override
public void PickiTonPostExecute(String path, boolean wasDriveFile) {
if (isDriveFile){
pickiTCallbacks.PickiTonCompleteListener(path, true, true, "");
public void PickiTonPostExecute(String path, boolean wasDriveFile, boolean wasSuccessful, String reason) {
if (wasSuccessful) {
if (isDriveFile) {
pickiTCallbacks.PickiTonCompleteListener(path, true, false, true, "");
} else if (isFromUnknownProvider) {
pickiTCallbacks.PickiTonCompleteListener(path, false, true, true, "");
}
}else {
if (isDriveFile) {
pickiTCallbacks.PickiTonCompleteListener(path, true, false, false, reason);
} else if (isFromUnknownProvider) {
pickiTCallbacks.PickiTonCompleteListener(path, false, true, false, reason);
}
}
}

// Delete the temporary folder
public void deleteTemporaryFile(){
File folder = context.getExternalFilesDir("Temp");
if (folder != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
public interface PickiTCallbacks {
void PickiTonStartListener();
void PickiTonProgressUpdate(int progress);
void PickiTonCompleteListener(String path, boolean wasDriveFile, boolean wasSuccessful, String Reason);
void PickiTonCompleteListener(String path, boolean wasDriveFile, boolean wasUnknownProvider, boolean wasSuccessful, String Reason);
}
50 changes: 47 additions & 3 deletions pickit/src/main/java/com/hbisoft/pickit/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;

import java.io.File;

Expand Down Expand Up @@ -41,11 +42,23 @@ static String getRealPathFromURI_API19(final Context context, final Uri uri) {
return "storage" + "/" + docId.replace(":", "/");
}

}else if (isRawDownloadsDocument(uri)){
String fileName = getFilePath(context, uri);
String subFolderName = getSubFolders(uri);

if (fileName != null) {
return Environment.getExternalStorageDirectory().toString() + "/Download/"+subFolderName + fileName;
}
String id = DocumentsContract.getDocumentId(uri);

final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
else if (isDownloadsDocument(uri)) {
String fileName = getFilePath(context, uri);

if (fileName != null) {
return Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName;
return Environment.getExternalStorageDirectory().toString() + "/Download/"+ fileName;
}
String id = DocumentsContract.getDocumentId(uri);
if (id.startsWith("raw:")) {
Expand Down Expand Up @@ -92,6 +105,31 @@ else if ("file".equalsIgnoreCase(uri.getScheme())) {
return null;
}

private static String getSubFolders(Uri uri) {
String replaceChars = String.valueOf(uri).replace("%2F", "/").replace("%20", " ").replace("%3A",":");
String[] bits = replaceChars.split("/");
String sub5 = bits[bits.length - 2];
String sub4 = bits[bits.length - 3];
String sub3 = bits[bits.length - 4];
String sub2 = bits[bits.length - 5];
String sub1 = bits[bits.length - 6];
if (sub1.equals("Download")){
return sub2+"/"+sub3+"/"+sub4+"/"+sub5+"/";
}
else if (sub2.equals("Download")){
return sub3+"/"+sub4+"/"+sub5+"/";
}
else if (sub3.equals("Download")){
return sub4+"/"+sub5+"/";
}
else if (sub4.equals("Download")){
return sub5+"/";
}
else {
return "";
}
}

static String getRealPathFromURI_BelowAPI19(Context context, Uri contentUri) {
String[] proj = {MediaStore.Video.Media.DATA};
CursorLoader loader = new CursorLoader(context, contentUri, proj, null, null, null);
Expand All @@ -103,6 +141,7 @@ static String getRealPathFromURI_BelowAPI19(Context context, Uri contentUri) {
return result;
}

@SuppressWarnings("TryFinallyCanBeTryWithResources")
private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
Expand All @@ -123,14 +162,15 @@ private static String getDataColumn(Context context, Uri uri, String selection,
}


@SuppressWarnings("TryFinallyCanBeTryWithResources")
private static String getFilePath(Context context, Uri uri) {
Cursor cursor = null;
final String[] projection = {MediaStore.MediaColumns.DISPLAY_NAME};
final String[] projection = {MediaStore.Files.FileColumns.DISPLAY_NAME};
try {
cursor = context.getContentResolver().query(uri, projection, null, null,
null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME);
final int index = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME);
return cursor.getString(index);
}
}catch (Exception e) {
Expand All @@ -152,6 +192,10 @@ private static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

private static boolean isRawDownloadsDocument(Uri uri) {
String uriToString = String.valueOf(uri);
return uriToString.contains("com.android.providers.downloads.documents/document/raw");
}

private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
Expand Down

0 comments on commit 8e6a18d

Please sign in to comment.