Opening large SQLite Databases on Android 11 - android

I need to open a large SQLite Database on Android 11 (api level 30). The Documentation says that "MANAGE_EXTERNAL_STORAGE" is a Problem in the Future.
Therefore, I read the Docs at: https://developer.android.com/training/data-storage/shared/documents-files and used:
public void openDirectory(Uri uriToLoad) {
// Choose a directory using the system's file picker.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 42);
}
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) {
if (requestCode == 42
&& resultCode == Activity.RESULT_OK) {
// The result data contains a URI for the document or directory that
// the user selected.
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
DocumentFile dfile = DocumentFile.fromTreeUri(this, uri);
DocumentFile[] fileList = dfile.listFiles();
}
}
}
If I understand the Documentation right, File is deprecated or can not be used with Files on the SD Card and DocumentFile/URI is the new thing. But to open the Database I use:
SQLiteDatabase.openDatabase(
pFile.getAbsolutePath(),
null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.OPEN_READONLY))
So my Problem is: How to open a large (10Gb or more) Database with an URI or a DocumentFile.
Ps.: The Database is a RasterLite File with map images

Related

Convert File to DocumentFile

I want to convert File (/storage/A54E-14E9/bp.mp4) to DocumentFile
Uri of DocumentFile should be content://com.android.externalstorage.documents/tree/A54E-14E9%3A/document/A54E-14E9%3Abp.mp4
but when I use DocumentFile.fromFile(file).getUri() it returns not correct Uri:
file:///storage/A54E-14E9/bp.mp4
So it's different than when you get it in onActivityResult after calling startActivityForResult(new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), REQUEST_CODE_STORAGE_ACCESS);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_STORAGE_ACCESS && resultCode == RESULT_OK) {
Uri treeUri = data.getData();
mDocumentDir = DocumentFile.fromTreeUri(this, treeUri);
for (DocumentFile file : mDocumentDir.listFiles()) {
// one of them is content://com.android.externalstorage.documents/tree/A54E-14E9%3A/document/A54E-14E9%3Abp.mp4
Log.i(TAG, file.getUri());
}
}
}
or if it's not possible then how to find what equals to File (/storage/A54E-14E9/bp.mp4) in:
// in onActivityResult
for (DocumentFile file : mDocumentDir.listFiles()) {
Log.i(TAG, file.getUri());
}
it's not good idea to just check file names, I need to check absolute paths (if they equals), also file can be placed in subfodler, so it makes things more difficult
My task is to delete File from MicroSD card, it can be done using DocumentFile after requesting storage (ACTION_OPEN_DOCUMENT_TREE) but I need somehow to get the right DocumentFile which equals my File

How to convert a content Uri into a File

I know there are a ton of questions about this exact topic, but after spending two days reading and trying them, none seamed to fix my problem.
This is my code:
I launch the ACTION_GET_CONTENT in my onCreate()
Intent selectIntent = new Intent(Intent.ACTION_GET_CONTENT);
selectIntent.setType("audio/*");
startActivityForResult(selectIntent, AUDIO_REQUEST_CODE);
retrieve the Uri in onActivityResult()
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == AUDIO_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
if ((data != null) && (data.getData() != null)) {
audio = data.getData();
}
}
}
pass the Uri to another activity and retrieve it
Intent debugIntent = new Intent(this, Debug.class);
Bundle bundle = new Bundle();
bundle.putString("audio", audio.toString());
debugIntent.putExtras(bundle);
startActivity(debugIntent);
Intent intent = this.getIntent();
Bundle bundle = intent.getExtras();
audio = Uri.parse((String) bundle.get("audio"));
The I have implemented this method based on another SO answer. To get the actual Path of the Uri
public static String getRealPathFromUri(Activity activity, Uri contentUri) {
String[] proj = { MediaStore.Audio.Media.DATA };
Cursor cursor = activity.managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
and in the Debug activity's onCreate() I try to generate the file:
File audioFile = new File(getRealPathFromUri(this, audio));
This is how the error looks like:
Caused by: java.lang.NullPointerException
at java.io.File.(File.java:262)
at com.dancam.lietome.Debug.onCreate(Debug.java:35)
When I run the app I get a NPE on this last line. The audio Uri, isn't NULL though so I don't understand from what it is caused.
I'd really appreciate if you helped me out.
This is the library I'm trying to work with.
Note: I know exactly what NPE is, but even debugging I couldn't figure out from what it is caused in this specific case.
pass the Uri to another activity and retrieve it
Your other activity does not necessarily have rights to work with the content identified by the Uri. Add FLAG_GRANT_READ_URI_PERMISSION to the Intent used to start that activity, and pass the Uri via the "data" facet of the Intent (setData()), not an extra.
To get the actual Path of the Uri
First, there is no requirement that the Uri that you get back be from the MediaStore.
Second, managedQuery() has been deprecated for six years.
Third, there is no requirement that the path that MediaStore has be one that you can use. For example, the audio file might be on removable storage, and while MediaStore can access it, you cannot.
How to convert a content Uri into a File
On a background thread:
Get a ContentResolver by calling getContentResolver() on a Context
Call openInputStream() on the ContentResolver, passing in the Uri that you obtained from ACTION_GET_CONTENT, to get an InputStream on the content identified by the Uri
Create a FileOutputStream on some File, where you want the content to be stored
Use Java I/O to copy the content from the InputStream to the FileOutputStream, closing both streams when you are done
I ran into same problem for Android Q, so I end up creating a new file and use input stream from content to fill that file
Here's How I do it in kotlin:
private var pdfFile: File? = null
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) {
if (data != null) {
when (requestCode) {
REQUEST_CODE_DOC -> {
data.data?.let {
if (it.scheme.equals("content")) {
val pdfBytes =
(contentResolver?.openInputStream(it))?.readBytes()
pdfFile = File(
getExternalFilesDir(null),
"Lesson ${Calendar.getInstance().time}t.pdf"
)
if (pdfFile!!.exists())
pdfFile!!.delete()
try {
val fos = FileOutputStream(pdfFile!!.path)
fos.write(pdfBytes)
fos.close()
} catch (e: Exception) {
Timber.e("PDF File", "Exception in pdf callback", e)
}
} else {
pdfFile = it.toFile()
}
}
}
}
}
}
}
Daniele, you can get path of file directly from data like below in onActivityResult():
String gilePath = data.getData().getPath();

How to save picture in memory (not in internal storage)

Please Look at the codes below.
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, PICK_FROM_CAMERA);
This code is for calling camera function.
After I take a picture, the method onActivityResult gives me back Uri so that I can get the absolute path to internal storage of the picture. But, I want to use the picture just for temporary use. that is, I don't want the picture to be stored in internal storage. I need absolute path to make the picture into a File object. So, is there any way to store the picture on memory allocated to my app??
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(resultCode != RESULT_OK)
return;
if(requestCode == PICK_FROM_CAMERA){
imageUri = data.getData();
Log.d("메시지", "uri = "+imageUri);
Cursor c = this.getContentResolver().query(imageUri, null, null, null, null);
c.moveToNext();
absolutePath = c.getString(c.getColumnIndex(MediaStore.MediaColumns.DATA));
}
}
For this you can use Cache Directory:
File storagePath = new File(getCacheDir() + "/" + "YOUR_FILE_NAME.JPG");

filedescriptor use to render pdf file from external storage in android

I have downloaded a pdf file in external storage directory and i want to reder it using pdfrender in android.
i have successfully rendered the pdf saved in my asset folder but now i need to render the file that is saved in external directory. here is the code i am using
String filePath1 = Environment.getExternalStorageDirectory().toString()+"/Mock-up Presentation.pdf";
//filePath1 is the location for file i want to render
File file = new File(filePath1);
mFileDescriptor=getActivity().getAssets().openFd("sample.pdf").getParcelFileDescriptor();//sample pdf is saved in asset folder in project which i have rendered //already
// This is the PdfRenderer we use to render the PDF.
mPdfRenderer = new PdfRenderer(mFileDescriptor);
Any help would be appreciated.
If you faced this problem in project that is targeting android 9+,
Get Complete Code For Solution.from Here
Then you can follow some Steps:
Step 1: Open an Intent for selecting PDF file.
/This Code will help to open Intent../
public final int PDF_REQUEST_CODE =1200;
Intent intent=new Intent();
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/pdf");
startActivityForResult(intent,PDF_REQUEST_CODE);
Step 2: now catch result returned by above intent.
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==PDF_REQUEST_CODE && resultCode == Activity.RESULT_OK)
{
Uri uri=data.getData();
PdfRendererBasicViewModel pdfRendererBasicViewModel =new
ViewModelProvider(this).get(PdfRendererBasicViewModel.class);
pdfRendererBasicViewModel.setUri(uri);
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PdfRendererBasicFragment())
.commitNow();
}
}
Step 3: Need some Modifications on pdfRendererBasicViewModel class.
First of all need to declare methods that set/get file's Uri in viewmodel.
as we called setUri(). in onActivityResult() method.
After That update replace openPdfRenderer() method with
private static Uri uri; `
private void openPdfRenderer() throws IOException {
if(getUri()!=null){
mFileDescriptor =
getApplication().getContentResolver().openFileDescriptor(getUri(), "r");
}
if (mFileDescriptor != null) {
mPdfRenderer = new PdfRenderer(mFileDescriptor);
}
}`
now try to run ...
If You want a complete Solution then you can import from github here

How to create new folder in sd card by using Storage Access Framework?

I would like to know how to use "Storage Access Framework" to create new folder on SD card. If you give me the code it would be very good.
I have already searched other questions and answers but not found how to.
Add some codes that already work per "CommonsWare" answer.
Note that is the only way I found that it can make new folder in sd card on my phone SS A5 with Android OS 5.1.1
public void newFolder(View view)
{
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, NEW_FOLDER_REQUEST_CODE);
}
private static final int NEW_FOLDER_REQUEST_CODE = 43;
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent resultData) {
super.onActivityResult(requestCode, resultCode, resultData);
Uri currentUri = null;
if (resultCode == Activity.RESULT_OK)
{
if (requestCode == NEW_FOLDER_REQUEST_CODE)
{
if (resultData != null) {
currentUri = resultData.getData();
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, currentUri);
DocumentFile newDir = pickedDir.createDirectory("MyFolder");
textView.setText(newDir.getName());
}
}
}
}
You cannot create "create new folder on SD card". You can create a new folder inside some other folder that the user chooses, but you cannot force the user to choose removable storage.
To create a new folder inside of some other folder, this should work:
Start an activity with startActivityForResult() on an ACTION_OPEN_DOCUMENT_TREE Intent, to allow the user to choose a folder. Include FLAG_DIR_SUPPORTS_CREATE to ensure that you can create something new in the folder.
In onActivityResult(), wrap the Uri that you get in a DocumentFile, then call createDirectory() on it to create a new folder as a child of whatever the user chose.

Categories

Resources