Creating and maintaining a library like this takes a lot of time.
If you would like to thank me, you can do so below:
An Android library that returns real paths from Uri's
Download the demo app here
Add the following in your root build.gradle at the end of repositories:
allprojects { repositories { ... maven { url 'https://jitpack.io' } } }
Then, add the dependency, in your app level build.gradle:
dependencies { implementation 'com.github.HBiSoft:PickiT:2.0.5' }
First, implement PickiT callbacks, as shown below:
public class MainActivity extends Activity implements PickiTCallbacks {
Alt+Enter to implement the methods, we will discuss the methods later in the readme.
Implement pickiT in your onCreate() method, as shown below:
public class MainActivity extends AppCompatActivity implements PickiTCallbacks { //Declare PickiT PickiT pickiT; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Initialize PickiT //context, listener, activity pickiT = new PickiT(this, this, this); } }
You can now select a file as you usually would (have a look at the demo if you don't know how to do this).
Then in onActivityResult, you can pass the path to PickiT, as shown below:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == SELECT_VIDEO_REQUEST) { if (resultCode == RESULT_OK) { pickiT.getPath(data.getData(), Build.VERSION.SDK_INT); } } }
You can check if the Uri is from Dropbox,Google Drive or OneDrive by calling:
if (!pickiT.wasLocalFileSelected(uri)){ // Drive file was selected }
You can check if the Uri is from an unknown provider by calling:
if (pickiT.isUnknownProvider(uri, Build.VERSION.SDK_INT)){ // Uri is from unknown provider }
If the selected file was from Dropbox,Google Drive, OneDrive or an unknown file provider, it will then be copied/created in
Internal Storage - Android - data - your.package.name - files - Temp
It is your responsibility to delete the file when you are done with it, by calling:
pickiT.deleteTemporaryFile(Context);
This can be done in onBackPressed and onDestroy, as shown below:
@Override public void onBackPressed() { pickiT.deleteTemporaryFile(this); super.onBackPressed(); } @Override public void onDestroy() { super.onDestroy(); if (!isChangingConfigurations()) { pickiT.deleteTemporaryFile(this); } }
If you do not call pickiT.deleteTemporaryFile(Context);, the file will remain in the above mentioned folder and will be overwritten each time you select a new file from Dropbox,Google Drive, OneDrive or an unknown file provider.
If you are targeting SDK 29> add android:requestLegacyExternalStorage="true" in your manifest:
<manifest ... > <application android:requestLegacyExternalStorage="true" </application> </manifest>
The reason for this is, in Android 10 file path access was removed and it returned in Android 11.
If you are targiting SDK 29> and you do not add this, you will get EACCES (Permission denied)
//When selecting a file from Google Drive, for example, the Uri will be returned before the file is available(if it has not yet been cached/downloaded). //We are unable to see the progress //Apps like Dropbox will display a dialog inside the picker //This will only be called when selecting a drive file @Override public void PickiTonUriReturned() { //Use to let user know that we are waiting for the application to return the file //See the demo project to see how I used this. } //Called when the file creations starts (similar to onPreExecute) //This will only be called if the selected file is not local or if the file is from an unknown file provider @Override public void PickiTonStartListener() { //Can be used to display a ProgressDialog } //Returns the progress of the file being created (in percentage) //This will only be called if the selected file is not local or if the file is from an unknown file provider @Override public void PickiTonProgressUpdate(int progress) { //Can be used to update the progress of your dialog } //If the selected file was a local file then this will be called directly, returning the path as a String. //String path - returned path //boolean wasDriveFile - check if it was a drive file //boolean wasUnknownProvider - check if it was from an unknown file provider //boolean wasSuccessful - check if it was successful //String reason - the get the reason why wasSuccessful returned false @Override public void PickiTonCompleteListener(String path, boolean wasDriveFile, boolean wasUnknownProvider, boolean wasSuccessful, String reason) { //Dismiss dialog and return the path }
Have a look at the demo project if you have any issues implementing the library.