Mercurial > dwindows
changeset 2795:5c61aba17b69
Android: Change dw_file_browse() to return URIs or paths on Android.
Paths will be returned if either DW_DIRECTORY_OPEN or DW_FILE_PATH flags are
specified. Otherwise a URI may be returned. The double string method of
returning both path and URI has been removed. DW_FILE_PATH and DW_FILE_MASK
have been added, but are really only used on Android.
__DW_MOBILE__ will be defined on Mobile platforms such as iOS and Android.
__DW_DESKTOP__ will be defined on most other desktop operating systems.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Fri, 15 Jul 2022 11:50:09 +0000 |
parents | 7ce51a7e8009 |
children | 0c534743b7a9 |
files | android/DWindows.kt android/dw.cpp dw.h |
diffstat | 3 files changed, 90 insertions(+), 87 deletions(-) [+] |
line wrap: on
line diff
--- a/android/DWindows.kt Fri Jul 15 08:15:11 2022 +0000 +++ b/android/DWindows.kt Fri Jul 15 11:50:09 2022 +0000 @@ -6126,7 +6126,6 @@ fun fileBrowseNew(title: String, defpath: String?, ext: String?, flags: Int): String? { var retval: String? = null - var uristr: String? = null var permission = Manifest.permission.WRITE_EXTERNAL_STORAGE var permissions: Int = -1 @@ -6161,57 +6160,61 @@ fileLock.unlock() // Save the URI string for later use - uristr = fileURI.toString() - - if (DocumentsContract.isDocumentUri(this, fileURI)) { - // ExternalStorageProvider - if (fileURI?.authority == "com.android.externalstorage.documents") { - val docId = DocumentsContract.getDocumentId(fileURI) - val split = docId.split(":").toTypedArray() - retval = Environment.getExternalStorageDirectory().toString() + "/" + split[1] - } else if (fileURI?.authority == "com.android.providers.downloads.documents") { - val id = DocumentsContract.getDocumentId(fileURI) - val contentUri = ContentUris.withAppendedId( - Uri.parse("content://downloads/public_downloads"), - java.lang.Long.valueOf(id) - ) - retval = getDataColumn(this, contentUri, null, null) - } else if (fileURI?.authority == "com.android.providers.media.documents") { - val docId = DocumentsContract.getDocumentId(fileURI) - val split = docId.split(":").toTypedArray() - val type = split[0] - var contentUri: Uri? = null - if ("image" == type) { - contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI - } else if ("video" == type) { - contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI - } else if ("audio" == type) { - contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + retval = fileURI.toString() + + // If DW_DIRECTORY_OPEN or DW_FILE_PATH ... use the path not URI + if((flags and 65535) == 2 || ((flags shr 16) and 1) == 1) { + if (DocumentsContract.isDocumentUri(this, fileURI)) { + // ExternalStorageProvider + if (fileURI?.authority == "com.android.externalstorage.documents") { + val docId = DocumentsContract.getDocumentId(fileURI) + val split = docId.split(":").toTypedArray() + retval = Environment.getExternalStorageDirectory() + .toString() + "/" + split[1] + } else if (fileURI?.authority == "com.android.providers.downloads.documents") { + val id = DocumentsContract.getDocumentId(fileURI) + val contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), + java.lang.Long.valueOf(id) + ) + retval = getDataColumn(this, contentUri, null, null) + } else if (fileURI?.authority == "com.android.providers.media.documents") { + val docId = DocumentsContract.getDocumentId(fileURI) + val split = docId.split(":").toTypedArray() + val type = split[0] + var contentUri: Uri? = null + if ("image" == type) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI + } else if ("video" == type) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI + } else if ("audio" == type) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + } + val selection = "_id=?" + val selectionArgs = arrayOf<String?>( + split[1] + ) + retval = getDataColumn(this, contentUri, selection, selectionArgs) } - val selection = "_id=?" - val selectionArgs = arrayOf<String?>( - split[1] - ) - retval = getDataColumn(this, contentUri, selection, selectionArgs) + } else if (fileURI?.scheme == "content") { + retval = getDataColumn(this, fileURI, null, null) + } + // File + else if (fileURI?.scheme == "file") { + retval = fileURI?.path } - } else if (fileURI?.scheme == "content") { - retval = getDataColumn(this, fileURI, null, null) - } - // File - else if (fileURI?.scheme == "file") { - retval = fileURI?.path - } - - // If we are opening a directory DW_DIRECTORY_OPEN - if(retval != null && flags == 2) { - val split = retval.split("/") - val filename = split.last() - - if(filename != null) { - val pathlen = retval.length - val filelen = filename.length - - retval = retval.substring(0, pathlen - filelen - 1) + + // If we are opening a directory DW_DIRECTORY_OPEN + if (retval != null && (flags and 65535) == 2) { + val split = retval.split("/") + val filename = split.last() + + if (filename != null) { + val pathlen = retval.length + val filelen = filename.length + + retval = retval.substring(0, pathlen - filelen - 1) + } } } } else { @@ -6220,9 +6223,6 @@ retval = fileBrowse(title, defpath, ext, flags) } } - if(retval != null && uristr != null) { - return retval + "\n\n" + uristr - } return retval }
--- a/android/dw.cpp Fri Jul 15 08:15:11 2022 +0000 +++ b/android/dw.cpp Fri Jul 15 11:50:09 2022 +0000 @@ -1281,24 +1281,7 @@ { const char *str = env->GetStringUTFChars(jresult, nullptr); if(str) - { - size_t len = strlen(str); - - // Allocate a string with an extra two bytes... so we can - // check for the trailing \n in dw_file_open() without a - // memory violation. - if((retval = (char *)calloc(1, len + 2))) - { - char *tmp; - - strncpy(retval, str, len); - // If we have a URI encoded, find the double \n and replace the - // first \n with NULL so the string still looks like a normal path. - tmp = strstr(retval, "\n\n"); - if (tmp) - *tmp = 0; - } - } + retval = strdup(str); } } return retval; @@ -1306,24 +1289,31 @@ int API dw_file_open(const char *path, int mode) { - JNIEnv *env; int retval = -1; - if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) - { - // dw_file_browse saves a second string with the URI after the path - // So find the end of the string and check for a trailing \n - // The URI will be after that if found. - const char *uri = strchr(path, 0); - jstring jstr = env->NewStringUTF((uri && *(uri+1) == '\n') ? (uri+2) : path); - // First get the class that contains the method you need to call - jclass clazz = _dw_find_class(env, DW_CLASS_NAME); - // Get the method that you want to call - jmethodID fileOpen = env->GetMethodID(clazz, "fileOpen", - "(Ljava/lang/String;I)I"); - // Call the method on the object - retval = (int)env->CallIntMethod(_dw_obj, fileOpen, jstr, (jint)mode); - _dw_jni_check_exception(env); + if(path) + { + JNIEnv *env; + + // If we have no URI we can use the normal open call + if(!strstr(path, "://")) + return open(path, mode); + // If we have a URI, use Android calls to get the URI file descriptor + if ((env = (JNIEnv *) pthread_getspecific(_dw_env_key))) + { + // dw_file_browse saves a second string with the URI after the path + // So find the end of the string and check for a trailing \n + // The URI will be after that if found. + jstring jstr = env->NewStringUTF(path); + // First get the class that contains the method you need to call + jclass clazz = _dw_find_class(env, DW_CLASS_NAME); + // Get the method that you want to call + jmethodID fileOpen = env->GetMethodID(clazz, "fileOpen", + "(Ljava/lang/String;I)I"); + // Call the method on the object + retval = (int) env->CallIntMethod(_dw_obj, fileOpen, jstr, (jint) mode); + _dw_jni_check_exception(env); + } } return retval; }
--- a/dw.h Fri Jul 15 08:15:11 2022 +0000 +++ b/dw.h Fri Jul 15 11:50:09 2022 +0000 @@ -12,6 +12,13 @@ #define DW_MINOR_VERSION 3 #define DW_SUB_VERSION 0 +/* General application type defines */ +#if defined(__IOS__) || defined(__ANDROID__) +#define __DW_MOBILE__ 1 +#else +#define __DW_DESKTOP__ 1 +#endif + #define DW_HOME_URL "http://dwindows.netlabs.org" /* Support for API deprecation in supported compilers */ @@ -1701,6 +1708,12 @@ #define DW_FILE_OPEN 0 #define DW_FILE_SAVE 1 #define DW_DIRECTORY_OPEN 2 +#ifdef __ANDROID__ +#define DW_FILE_PATH (1 << 16) +#else +#define DW_FILE_PATH 0 +#endif +#define DW_FILE_MASK (0x0000FFFF) #define DW_HORZ 0 #define DW_VERT 1