cordova-plugin-mserviceinterface-2.0 1.0.94 → 1.0.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/plugin.xml +1 -4
- package/src/android/mInterface.java +297 -198
package/package.json
CHANGED
package/plugin.xml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
|
3
|
-
xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-mserviceinterface-2.0" version="1.0.
|
|
3
|
+
xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-mserviceinterface-2.0" version="1.0.95">
|
|
4
4
|
<name>mserviceinterface-2.0</name>
|
|
5
5
|
<description>This plugin establishes the connection to the native interface and performs the requested task.</description>
|
|
6
6
|
<author>selfservit@gmail.com</author>
|
|
@@ -47,14 +47,11 @@
|
|
|
47
47
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
|
48
48
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
49
49
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
|
50
|
-
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
|
51
|
-
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
|
52
50
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
|
53
51
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
54
52
|
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
|
55
53
|
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
|
56
54
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
57
|
-
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
|
58
55
|
<queries>
|
|
59
56
|
<intent>
|
|
60
57
|
<action android:name="android.media.action.IMAGE_CAPTURE" />
|
|
@@ -486,11 +486,12 @@ public class mInterface extends CordovaPlugin implements com.google.android.gms.
|
|
|
486
486
|
} else if (action.equals("CheckLocationPermission")) {
|
|
487
487
|
checkLocationPermission(args, callbackContext);
|
|
488
488
|
return true;
|
|
489
|
-
} else if (action.equals("GetMediaImagePermission")) {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
489
|
+
} else if (action.equals("CheckMediaImagePermission") || action.equals("GetMediaImagePermission")) {
|
|
490
|
+
try {
|
|
491
|
+
callbackContext.success("not_required");
|
|
492
|
+
} catch (Exception e) {
|
|
493
|
+
callbackContext.error(e.getMessage());
|
|
494
|
+
}
|
|
494
495
|
return true;
|
|
495
496
|
} else if (action.equals("AppVersion")) {
|
|
496
497
|
appVersion(callbackContext);
|
|
@@ -1606,40 +1607,12 @@ public class mInterface extends CordovaPlugin implements com.google.android.gms.
|
|
|
1606
1607
|
}
|
|
1607
1608
|
}
|
|
1608
1609
|
|
|
1609
|
-
private void checkMediaImagePermission(JSONArray args, CallbackContext
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
Context context = cordova.getActivity().getApplicationContext();
|
|
1615
|
-
String[] permissions = args.optJSONObject(0).optString("permissions").split(",");
|
|
1616
|
-
if (permissions[0].equalsIgnoreCase("android.permission.READ_MEDIA_IMAGES")) {
|
|
1617
|
-
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
|
1618
|
-
checkPermission = false;
|
|
1619
|
-
}
|
|
1620
|
-
}
|
|
1621
|
-
if (checkPermission) {
|
|
1622
|
-
list = new ArrayList<String>(Arrays.asList(permissions));
|
|
1623
|
-
permissions = list.toArray(new String[0]);
|
|
1624
|
-
|
|
1625
|
-
for (int i = 0; i < permissions.length; i++) {
|
|
1626
|
-
if (ActivityCompat.checkSelfPermission(context, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
|
|
1627
|
-
permissionGranted = false;
|
|
1628
|
-
}
|
|
1629
|
-
}
|
|
1630
|
-
if (!permissionGranted) {
|
|
1631
|
-
callback.error("failure");
|
|
1632
|
-
} else {
|
|
1633
|
-
callback.success("success");
|
|
1634
|
-
}
|
|
1635
|
-
} else {
|
|
1636
|
-
callback.success("success");
|
|
1637
|
-
}
|
|
1638
|
-
} catch (Exception e) {
|
|
1639
|
-
e.printStackTrace();
|
|
1640
|
-
}
|
|
1610
|
+
private void checkMediaImagePermission(JSONArray args, CallbackContext cb) {
|
|
1611
|
+
try { cb.success("not_required"); } catch (Exception e) { cb.error(e.getMessage()); }
|
|
1612
|
+
}
|
|
1613
|
+
private void getMediaImagePermission(JSONArray args, CallbackContext cb) {
|
|
1614
|
+
try { cb.success("not_required"); } catch (Exception e) { cb.error(e.getMessage()); }
|
|
1641
1615
|
}
|
|
1642
|
-
|
|
1643
1616
|
|
|
1644
1617
|
private void getLocationPermission(JSONArray args, CallbackContext callbackContext) {
|
|
1645
1618
|
boolean permissionGranted = true;
|
|
@@ -1665,30 +1638,7 @@ public class mInterface extends CordovaPlugin implements com.google.android.gms.
|
|
|
1665
1638
|
e.printStackTrace();
|
|
1666
1639
|
}
|
|
1667
1640
|
}
|
|
1668
|
-
|
|
1669
|
-
boolean permissionGranted = true;
|
|
1670
|
-
List<String> list;
|
|
1671
|
-
try {
|
|
1672
|
-
callback = callbackContext;
|
|
1673
|
-
Context context = cordova.getActivity().getApplicationContext();
|
|
1674
|
-
String[] permissions = args.optJSONObject(0).optString("permissions").split(",");
|
|
1675
|
-
list = new ArrayList<String>(Arrays.asList(permissions));
|
|
1676
|
-
permissions = list.toArray(new String[0]);
|
|
1677
|
-
|
|
1678
|
-
for (int i = 0; i < permissions.length; i++) {
|
|
1679
|
-
if (ActivityCompat.checkSelfPermission(context, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
|
|
1680
|
-
permissionGranted = false;
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
if (!permissionGranted) {
|
|
1684
|
-
PermissionHelper.requestPermissions(this, 111, permissions);
|
|
1685
|
-
} else {
|
|
1686
|
-
callback.success("success");
|
|
1687
|
-
}
|
|
1688
|
-
} catch (Exception e) {
|
|
1689
|
-
e.printStackTrace();
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1641
|
+
|
|
1692
1642
|
private void getPermissions(JSONArray args, CallbackContext callbackContext) {
|
|
1693
1643
|
boolean permissionGranted = true;
|
|
1694
1644
|
List<String> list;
|
|
@@ -1760,29 +1710,33 @@ public class mInterface extends CordovaPlugin implements com.google.android.gms.
|
|
|
1760
1710
|
pluginResult.setKeepCallback(true);
|
|
1761
1711
|
callbackContext.sendPluginResult(pluginResult);
|
|
1762
1712
|
}
|
|
1763
|
-
|
|
1713
|
+
|
|
1714
|
+
void pickImageFromGallery(CallbackContext callbackContext) {
|
|
1764
1715
|
try {
|
|
1765
|
-
Intent
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
1770
|
-
// Use the ACTION_OPEN_DOCUMENT intent for Android 13 and higher
|
|
1771
|
-
openFile = new Intent(MediaStore.ACTION_PICK_IMAGES);
|
|
1772
|
-
openFile.setType("image/*");
|
|
1716
|
+
Intent i;
|
|
1717
|
+
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
|
|
1718
|
+
i = new Intent(MediaStore.ACTION_PICK_IMAGES);
|
|
1719
|
+
i.setType("image/*");
|
|
1773
1720
|
} else {
|
|
1774
|
-
|
|
1775
|
-
|
|
1721
|
+
i = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
|
1722
|
+
i.addCategory(Intent.CATEGORY_OPENABLE);
|
|
1723
|
+
i.setType("image/*");
|
|
1724
|
+
i.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
|
|
1776
1725
|
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
callbackContext.sendPluginResult(
|
|
1726
|
+
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
|
1727
|
+
this.callback = callbackContext;
|
|
1728
|
+
PluginResult pr = new PluginResult(PluginResult.Status.NO_RESULT);
|
|
1729
|
+
pr.setKeepCallback(true);
|
|
1730
|
+
callbackContext.sendPluginResult(pr);
|
|
1731
|
+
cordova.startActivityForResult(this, i, PICK_IMAGE_FROM_GALLERY);
|
|
1732
|
+
|
|
1733
|
+
|
|
1782
1734
|
} catch (Exception e) {
|
|
1783
1735
|
callbackContext.error("pickImageFromGallery failed, exception is : " + e.getMessage());
|
|
1784
1736
|
}
|
|
1785
1737
|
}
|
|
1738
|
+
|
|
1739
|
+
|
|
1786
1740
|
|
|
1787
1741
|
private String getMimeType(String path, Uri uri) {
|
|
1788
1742
|
String mimeType = null;
|
|
@@ -2117,6 +2071,198 @@ public class mInterface extends CordovaPlugin implements com.google.android.gms.
|
|
|
2117
2071
|
return "";
|
|
2118
2072
|
}
|
|
2119
2073
|
|
|
2074
|
+
|
|
2075
|
+
private String safeGetDisplayName(@NonNull ContentResolver cr, @NonNull Uri uri, @NonNull String defaultExt) {
|
|
2076
|
+
String name = null;
|
|
2077
|
+
try (Cursor c = cr.query(uri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null)) {
|
|
2078
|
+
if (c != null && c.moveToFirst()) {
|
|
2079
|
+
int idx = c.getColumnIndex(OpenableColumns.DISPLAY_NAME);
|
|
2080
|
+
if (idx != -1) name = c.getString(idx);
|
|
2081
|
+
}
|
|
2082
|
+
} catch (Throwable t) {
|
|
2083
|
+
android.util.Log.w("mInterface", "safeGetDisplayName query failed: " + t.getMessage());
|
|
2084
|
+
}
|
|
2085
|
+
if (name == null || name.trim().isEmpty()) {
|
|
2086
|
+
String ts = new java.text.SimpleDateFormat("yyyyMMdd_HHmmss").format(new java.util.Date());
|
|
2087
|
+
name = "FILE_" + ts + (defaultExt.startsWith(".") ? defaultExt : "." + defaultExt);
|
|
2088
|
+
}
|
|
2089
|
+
return name;
|
|
2090
|
+
}
|
|
2091
|
+
private void postSuccess(final CallbackContext cb, final org.json.JSONObject out) {
|
|
2092
|
+
if (cb == null) return;
|
|
2093
|
+
final PluginResult pr = new PluginResult(PluginResult.Status.OK, out);
|
|
2094
|
+
pr.setKeepCallback(false);
|
|
2095
|
+
cordova.getActivity().runOnUiThread(new Runnable() {
|
|
2096
|
+
@Override public void run() { cb.sendPluginResult(pr); }
|
|
2097
|
+
});
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
private void postSuccess(final CallbackContext cb, final String s) {
|
|
2101
|
+
if (cb == null) return;
|
|
2102
|
+
final PluginResult pr = new PluginResult(PluginResult.Status.OK, s);
|
|
2103
|
+
pr.setKeepCallback(false);
|
|
2104
|
+
cordova.getActivity().runOnUiThread(new Runnable() {
|
|
2105
|
+
@Override public void run() { cb.sendPluginResult(pr); }
|
|
2106
|
+
});
|
|
2107
|
+
}
|
|
2108
|
+
|
|
2109
|
+
private void postError(final CallbackContext cb, final String msg) {
|
|
2110
|
+
if (cb == null) return;
|
|
2111
|
+
final PluginResult pr = new PluginResult(PluginResult.Status.ERROR, msg);
|
|
2112
|
+
pr.setKeepCallback(false);
|
|
2113
|
+
cordova.getActivity().runOnUiThread(new Runnable() {
|
|
2114
|
+
@Override public void run() { cb.sendPluginResult(pr); }
|
|
2115
|
+
});
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2118
|
+
private int calcInSampleSize(BitmapFactory.Options o, int reqW, int reqH) {
|
|
2119
|
+
int inSample = 1, h = o.outHeight, w = o.outWidth;
|
|
2120
|
+
while ((h / inSample) > reqH || (w / inSample) > reqW) inSample <<= 1;
|
|
2121
|
+
return Math.max(1, inSample);
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
/**
|
|
2125
|
+
* Async version that mirrors the sync behavior:
|
|
2126
|
+
* - "camera"/"gallery": returns base64 string
|
|
2127
|
+
* - "compress": returns JSON { filePath, fileName, fileSize, fileExtension, thumbnail }
|
|
2128
|
+
*/
|
|
2129
|
+
private void convertImageTo64BaseStringAsync(final CallbackContext cb,
|
|
2130
|
+
final String imageSourcePath,
|
|
2131
|
+
final String imgSrcType,
|
|
2132
|
+
final String destinationPath) {
|
|
2133
|
+
cordova.getThreadPool().execute(new Runnable() {
|
|
2134
|
+
@Override public void run() {
|
|
2135
|
+
InputStream srcFileReader = null;
|
|
2136
|
+
OutputStream desFileWriter = null;
|
|
2137
|
+
ByteArrayOutputStream baos = null;
|
|
2138
|
+
Bitmap bitmap = null;
|
|
2139
|
+
try {
|
|
2140
|
+
// Common bits
|
|
2141
|
+
final String[] parts = imageSourcePath.split("/");
|
|
2142
|
+
String baseName = parts.length > 0 ? parts[parts.length - 1] : "IMG";
|
|
2143
|
+
if (baseName.indexOf(".") > 0) {
|
|
2144
|
+
baseName = baseName.substring(0, baseName.lastIndexOf("."));
|
|
2145
|
+
}
|
|
2146
|
+
final String extFromSource = "." + imageSourcePath.substring(imageSourcePath.lastIndexOf(".") + 1).toLowerCase();
|
|
2147
|
+
final String thumbnail = getFileThumbnail(imageSourcePath, extFromSource);
|
|
2148
|
+
|
|
2149
|
+
if ("compress".equalsIgnoreCase(imgSrcType)) {
|
|
2150
|
+
// === COMPRESS: write JPEG to destination and return file properties ===
|
|
2151
|
+
File fileToCompress = new File(imageSourcePath);
|
|
2152
|
+
File compressedImageFile = new Compressor(cordova.getActivity())
|
|
2153
|
+
.setQuality(15)
|
|
2154
|
+
.setCompressFormat(Bitmap.CompressFormat.JPEG)
|
|
2155
|
+
.compressToFile(fileToCompress);
|
|
2156
|
+
|
|
2157
|
+
String timeStamp = new java.text.SimpleDateFormat("yyyyMMdd_HHmmss").format(new java.util.Date());
|
|
2158
|
+
final String baseDir = (destinationPath != null && !destinationPath.isEmpty())
|
|
2159
|
+
? (mInterfaceUtil.rootDirectory + "/" + destinationPath)
|
|
2160
|
+
: (mInterfaceUtil.rootDirectory + "/" + mInterfaceUtil.packageName + "/images");
|
|
2161
|
+
final String outName = baseName + "_" + timeStamp + ".jpg";
|
|
2162
|
+
final String outFullPath = baseDir + "/" + outName;
|
|
2163
|
+
|
|
2164
|
+
File outDir = new File(baseDir);
|
|
2165
|
+
if (!outDir.exists()) outDir.mkdirs();
|
|
2166
|
+
|
|
2167
|
+
// Copy compressed temp → final path
|
|
2168
|
+
if (compressedImageFile.exists()) {
|
|
2169
|
+
srcFileReader = new FileInputStream(compressedImageFile);
|
|
2170
|
+
desFileWriter = new FileOutputStream(new File(outFullPath));
|
|
2171
|
+
byte[] buf = new byte[64 * 1024];
|
|
2172
|
+
int n;
|
|
2173
|
+
while ((n = srcFileReader.read(buf)) > 0) {
|
|
2174
|
+
desFileWriter.write(buf, 0, n);
|
|
2175
|
+
}
|
|
2176
|
+
desFileWriter.flush();
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
// (Optional) load to normalize EXIF rotation like the sync version did
|
|
2180
|
+
try { bitmap = handleImageRotation(outFullPath); } catch (Throwable ignore) {}
|
|
2181
|
+
|
|
2182
|
+
// Build properties
|
|
2183
|
+
File outFile = new File(outFullPath);
|
|
2184
|
+
org.json.JSONObject fileProps = new org.json.JSONObject();
|
|
2185
|
+
fileProps.put("filePath", outFile.getParent());
|
|
2186
|
+
fileProps.put("fileName", outFile.getName());
|
|
2187
|
+
fileProps.put("fileSize", outFile.length());
|
|
2188
|
+
fileProps.put("fileExtension", ".jpg");
|
|
2189
|
+
fileProps.put("thumbnail", thumbnail);
|
|
2190
|
+
|
|
2191
|
+
// Match original behavior: clear attachmentDestPath if you rely on that global
|
|
2192
|
+
try { attachmentDestPath = ""; } catch (Throwable ignore) {}
|
|
2193
|
+
|
|
2194
|
+
postSuccess(cb, fileProps);
|
|
2195
|
+
return;
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
// === CAMERA / GALLERY → return BASE64 string ===
|
|
2199
|
+
// Decode with downsampling and fix rotation
|
|
2200
|
+
BitmapFactory.Options o = new BitmapFactory.Options();
|
|
2201
|
+
o.inJustDecodeBounds = true; BitmapFactory.decodeFile(imageSourcePath, o);
|
|
2202
|
+
o.inSampleSize = calcInSampleSize(o, 1920, 1920);
|
|
2203
|
+
o.inJustDecodeBounds = false;
|
|
2204
|
+
|
|
2205
|
+
// Prefer your rotation-aware helper (handles EXIF)
|
|
2206
|
+
try {
|
|
2207
|
+
bitmap = handleImageRotation(imageSourcePath);
|
|
2208
|
+
if (bitmap == null) bitmap = BitmapFactory.decodeFile(imageSourcePath, o);
|
|
2209
|
+
} catch (Throwable t) {
|
|
2210
|
+
bitmap = BitmapFactory.decodeFile(imageSourcePath, o);
|
|
2211
|
+
}
|
|
2212
|
+
if (bitmap == null) {
|
|
2213
|
+
postError(cb, "decode_failed");
|
|
2214
|
+
return;
|
|
2215
|
+
}
|
|
2216
|
+
|
|
2217
|
+
baos = new ByteArrayOutputStream(1024 * 1024);
|
|
2218
|
+
bitmap.compress(Bitmap.CompressFormat.JPEG, 15, baos);
|
|
2219
|
+
String encodedImage = android.util.Base64.encodeToString(baos.toByteArray(), android.util.Base64.NO_WRAP);
|
|
2220
|
+
|
|
2221
|
+
// Match original behavior: delete camera temp + clear dest flag
|
|
2222
|
+
if ("camera".equalsIgnoreCase(imgSrcType)) {
|
|
2223
|
+
try {
|
|
2224
|
+
File f = new File(imageSourcePath);
|
|
2225
|
+
if (f.exists()) f.delete();
|
|
2226
|
+
} catch (Throwable ignore) {}
|
|
2227
|
+
try { attachmentDestPath = ""; } catch (Throwable ignore) {}
|
|
2228
|
+
} else if ("gallery".equalsIgnoreCase(imgSrcType)) {
|
|
2229
|
+
try { attachmentDestPath = ""; } catch (Throwable ignore) {}
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
postSuccess(cb, encodedImage);
|
|
2233
|
+
} catch (Exception e) {
|
|
2234
|
+
try { attachmentDestPath = ""; } catch (Throwable ignore) {}
|
|
2235
|
+
postError(cb, "convertImageTo64BaseStringAsync failed: " + e.getMessage());
|
|
2236
|
+
} finally {
|
|
2237
|
+
try { if (srcFileReader != null) srcFileReader.close(); } catch (Exception ignore) {}
|
|
2238
|
+
try { if (desFileWriter != null) desFileWriter.close(); } catch (Exception ignore) {}
|
|
2239
|
+
try { if (baos != null) baos.close(); } catch (Exception ignore) {}
|
|
2240
|
+
try { if (bitmap != null) bitmap.recycle(); } catch (Exception ignore) {}
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
});
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
|
|
2247
|
+
private String copyFileFromUriFast(Context ctx, Uri uri, String destName, String destDir) {
|
|
2248
|
+
java.io.File dir = (destDir!=null && !destDir.isEmpty())
|
|
2249
|
+
? new java.io.File(ctx.getFilesDir(), destDir)
|
|
2250
|
+
: ctx.getFilesDir();
|
|
2251
|
+
if (!dir.exists() && !dir.mkdirs()) return null;
|
|
2252
|
+
java.io.File out = new java.io.File(dir, destName);
|
|
2253
|
+
try (java.io.InputStream in = ctx.getContentResolver().openInputStream(uri);
|
|
2254
|
+
java.io.OutputStream os = new java.io.FileOutputStream(out)) {
|
|
2255
|
+
if (in == null) return null;
|
|
2256
|
+
byte[] buf = new byte[64 * 1024];
|
|
2257
|
+
int n; while ((n = in.read(buf)) != -1) os.write(buf, 0, n);
|
|
2258
|
+
os.flush();
|
|
2259
|
+
return out.getAbsolutePath();
|
|
2260
|
+
} catch (Exception e) {
|
|
2261
|
+
android.util.Log.e("mInterface", "copyFileFromUriFast", e);
|
|
2262
|
+
return null;
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
|
|
2120
2266
|
@Override
|
|
2121
2267
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
2122
2268
|
try {
|
|
@@ -2158,136 +2304,89 @@ public class mInterface extends CordovaPlugin implements com.google.android.gms.
|
|
|
2158
2304
|
SCANCODEINT = 0;
|
|
2159
2305
|
callback.error(resultCode);
|
|
2160
2306
|
}
|
|
2161
|
-
}
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
if (new mInterfaceUtil().getPathToNonPrimaryVolume(cordova.getActivity(), tag) != null) {
|
|
2190
|
-
storageDefinition = new mInterfaceUtil().getPathToNonPrimaryVolume(cordova.getActivity(), tag) + "/" + path;
|
|
2191
|
-
file = new File(storageDefinition);
|
|
2192
|
-
if (file.exists() && file.canRead()) {
|
|
2193
|
-
getfilePath = storageDefinition;
|
|
2194
|
-
}
|
|
2195
|
-
}
|
|
2196
|
-
}
|
|
2197
|
-
}
|
|
2198
|
-
} else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) { // DownloadsProvider
|
|
2199
|
-
id = DocumentsContract.getDocumentId(uri);
|
|
2200
|
-
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
|
|
2201
|
-
getfilePath = new mInterfaceUtil().getDataColumn(cordova.getActivity(), contentUri, null, null);
|
|
2202
|
-
} else if ("com.android.providers.media.documents".equals(uri.getAuthority())) { // MediaProvider
|
|
2203
|
-
docId = DocumentsContract.getDocumentId(uri);
|
|
2204
|
-
split = docId.split(":");
|
|
2205
|
-
type = split[0];
|
|
2206
|
-
Uri contentUri = null;
|
|
2207
|
-
if ("image".equals(type)) {
|
|
2208
|
-
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
|
2209
|
-
} else if ("video".equals(type)) {
|
|
2210
|
-
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
|
2211
|
-
} else if ("audio".equals(type)) {
|
|
2212
|
-
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
|
2213
|
-
}
|
|
2214
|
-
final String selection = "_id=?";
|
|
2215
|
-
final String[] selectionArgs = new String[]{
|
|
2216
|
-
split[1]
|
|
2217
|
-
};
|
|
2218
|
-
getfilePath = new mInterfaceUtil().getDataColumn(cordova.getActivity(), contentUri, selection, selectionArgs);
|
|
2219
|
-
}
|
|
2220
|
-
// *** API Level 19 and Above (To Get FileName,FileExtension and FileSize)**** //
|
|
2221
|
-
cursor = cordova.getActivity().getContentResolver().query(uri, null, null, null, null, null);
|
|
2307
|
+
}else if (requestCode == PICK_IMAGE_FROM_GALLERY) {
|
|
2308
|
+
final CallbackContext cb = this.callback;
|
|
2309
|
+
this.callback = null;
|
|
2310
|
+
if (cb == null) return;
|
|
2311
|
+
|
|
2312
|
+
try {
|
|
2313
|
+
if (resultCode != RESULT_OK || data == null) {
|
|
2314
|
+
cb.error("canceled");
|
|
2315
|
+
return;
|
|
2316
|
+
}
|
|
2317
|
+
|
|
2318
|
+
// Photo Picker may return via getData() or ClipData
|
|
2319
|
+
Uri uri = data.getData();
|
|
2320
|
+
if (uri == null && data.getClipData() != null && data.getClipData().getItemCount() > 0) {
|
|
2321
|
+
uri = data.getClipData().getItemAt(0).getUri();
|
|
2322
|
+
}
|
|
2323
|
+
if (uri == null) {
|
|
2324
|
+
cb.error("no_file_selected");
|
|
2325
|
+
return;
|
|
2326
|
+
}
|
|
2327
|
+
|
|
2328
|
+
final Uri selectedUri = uri;
|
|
2329
|
+
final String destPath = attachmentDestPath; // capture current dest
|
|
2330
|
+
final String galleryInd = String.valueOf(galleryAttachmentInd);
|
|
2331
|
+
|
|
2332
|
+
// Offload ALL heavy work (resolver, copy, bitmap/encode) to Cordova thread pool
|
|
2333
|
+
cordova.getThreadPool().execute(new Runnable() {
|
|
2334
|
+
@Override public void run() {
|
|
2222
2335
|
try {
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2336
|
+
ContentResolver cr = cordova.getActivity().getContentResolver();
|
|
2337
|
+
|
|
2338
|
+
String mime = null;
|
|
2339
|
+
try { mime = cr.getType(selectedUri); } catch (Throwable ignore) {}
|
|
2340
|
+
|
|
2341
|
+
String defExt = (mime != null && mime.contains("/"))
|
|
2342
|
+
? mime.substring(mime.indexOf('/') + 1).toLowerCase()
|
|
2343
|
+
: "jpg";
|
|
2344
|
+
|
|
2345
|
+
// Get a display name if provider allows; otherwise build a sane fallback
|
|
2346
|
+
String fileName = safeGetDisplayName(cr, selectedUri, defExt);
|
|
2347
|
+
String ext = fileName.contains(".")
|
|
2348
|
+
? fileName.substring(fileName.lastIndexOf('.')).toLowerCase()
|
|
2349
|
+
: ("." + defExt);
|
|
2350
|
+
|
|
2351
|
+
// Copy the user-selected URI into app-private storage (no READ_MEDIA_* needed)
|
|
2352
|
+
String localPath = copyFileFromUriFast(
|
|
2353
|
+
cordova.getActivity().getApplicationContext(),
|
|
2354
|
+
selectedUri, fileName, destPath);
|
|
2355
|
+
|
|
2356
|
+
if (localPath == null) {
|
|
2357
|
+
cb.error("copy_failed");
|
|
2358
|
+
return;
|
|
2230
2359
|
}
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
};
|
|
2242
|
-
cursor = cordova.getActivity().getContentResolver().query(uri, projection, null, null, null);
|
|
2243
|
-
if (cursor.moveToFirst()) {
|
|
2244
|
-
getfilePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
|
|
2245
|
-
fileName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME));
|
|
2360
|
+
|
|
2361
|
+
// Accept only image-like picks (by MIME or extension)
|
|
2362
|
+
boolean imageLike =
|
|
2363
|
+
(mime != null && mime.startsWith("image/")) ||
|
|
2364
|
+
ext.equals(".jpg") || ext.equals(".jpeg") ||
|
|
2365
|
+
ext.equals(".png") || ext.equals(".heic");
|
|
2366
|
+
|
|
2367
|
+
if (!imageLike) {
|
|
2368
|
+
cb.error("Only JPEG/PNG/HEIC images are allowed.");
|
|
2369
|
+
return;
|
|
2246
2370
|
}
|
|
2247
|
-
cursor.close();
|
|
2248
|
-
// API LEVEL 19 BELOW AND SAMSUNG (TO GET FILE PROPERTIES OF NORMAL FILES(EX:txt,.pdf,etc..,))
|
|
2249
|
-
} else {
|
|
2250
|
-
getfilePath = data.getData().getPath();
|
|
2251
|
-
filePath = getfilePath.substring(0, getfilePath.lastIndexOf(File.separator));
|
|
2252
|
-
getFileName = new File(getfilePath);
|
|
2253
|
-
fileName = getFileName.getName();
|
|
2254
|
-
}
|
|
2255
|
-
}
|
|
2256
|
-
filePath = getfilePath.substring(0, getfilePath.lastIndexOf(File.separator));
|
|
2257
|
-
fileExtension = "." + getfilePath.substring(getfilePath.lastIndexOf(".") + 1).toLowerCase();
|
|
2258
|
-
if (filePath != null) {
|
|
2259
|
-
try {
|
|
2260
|
-
if (fileExtension.equals(".heic")) {
|
|
2261
|
-
if (galleryAttachmentInd.equals("true")) {
|
|
2262
|
-
convertImageTo64BaseString(callback, filePath + "/" + fileName, "compress", attachmentDestPath);
|
|
2263
|
-
} else {
|
|
2264
|
-
convertImageTo64BaseString(callback, filePath + "/" + fileName, "gallery", "");
|
|
2265
|
-
}
|
|
2266
2371
|
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
} else {
|
|
2271
|
-
convertImageTo64BaseString(callback, filePath + "/" + fileName, "gallery", "");
|
|
2272
|
-
}
|
|
2372
|
+
// Run your existing conversion on a worker too (non-blocking)
|
|
2373
|
+
if ("true".equals(galleryInd)) {
|
|
2374
|
+
convertImageTo64BaseStringAsync(cb, localPath, "compress", destPath);
|
|
2273
2375
|
} else {
|
|
2274
|
-
|
|
2376
|
+
convertImageTo64BaseStringAsync(cb, localPath, "gallery", "");
|
|
2275
2377
|
}
|
|
2276
2378
|
} catch (Exception e) {
|
|
2277
|
-
|
|
2379
|
+
cb.error("PICK_IMAGE_FROM_GALLERY: " + e.getMessage());
|
|
2278
2380
|
}
|
|
2279
|
-
} else {
|
|
2280
|
-
callback.error("File path was null");
|
|
2281
2381
|
}
|
|
2282
|
-
}
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
} else {
|
|
2288
|
-
callback.error(resultCode);
|
|
2382
|
+
});
|
|
2383
|
+
return; // IMPORTANT: stop here so no other branch falls through
|
|
2384
|
+
} catch (Exception e) {
|
|
2385
|
+
cb.error("PICK_IMAGE_FROM_GALLERY dispatch failed: " + e.getMessage());
|
|
2386
|
+
return;
|
|
2289
2387
|
}
|
|
2290
|
-
}
|
|
2388
|
+
}
|
|
2389
|
+
else if (requestCode == NEW_FILE_PICK_REQUEST && callback != null) {
|
|
2291
2390
|
try {
|
|
2292
2391
|
Uri uri = data.getData();
|
|
2293
2392
|
String fileName, extension, filePath;
|