@nativescript/core 9.0.0-next-09-27-2025-18063560861 → 9.0.0-next-10-06-2025-18277360121
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/platforms/android/include.gradle +51 -0
- package/platforms/android/java/org/nativescript/Process.java +59 -0
- package/platforms/android/java/org/nativescript/widgets/AbsoluteLayout.java +88 -0
- package/platforms/android/java/org/nativescript/widgets/AnimatorHelper.java +61 -0
- package/platforms/android/java/org/nativescript/widgets/Async.java +1356 -0
- package/platforms/android/java/org/nativescript/widgets/BorderDrawable.java +936 -0
- package/platforms/android/java/org/nativescript/widgets/BottomNavigationBar.java +308 -0
- package/platforms/android/java/org/nativescript/widgets/BoxShadowDrawable.java +175 -0
- package/platforms/android/java/org/nativescript/widgets/CSSValue.java +34 -0
- package/platforms/android/java/org/nativescript/widgets/CommonLayoutParams.java +456 -0
- package/platforms/android/java/org/nativescript/widgets/ContentLayout.java +85 -0
- package/platforms/android/java/org/nativescript/widgets/CustomTransition.java +135 -0
- package/platforms/android/java/org/nativescript/widgets/CustomTypefaceSpan.java +44 -0
- package/platforms/android/java/org/nativescript/widgets/Dock.java +15 -0
- package/platforms/android/java/org/nativescript/widgets/DockLayout.java +185 -0
- package/platforms/android/java/org/nativescript/widgets/FileHelper.java +815 -0
- package/platforms/android/java/org/nativescript/widgets/FlexLine.java +177 -0
- package/platforms/android/java/org/nativescript/widgets/FlexboxLayout.java +2769 -0
- package/platforms/android/java/org/nativescript/widgets/FragmentBase.java +14 -0
- package/platforms/android/java/org/nativescript/widgets/GridLayout.java +1172 -0
- package/platforms/android/java/org/nativescript/widgets/GridUnitType.java +10 -0
- package/platforms/android/java/org/nativescript/widgets/HorizontalScrollView.java +256 -0
- package/platforms/android/java/org/nativescript/widgets/ImageView.java +423 -0
- package/platforms/android/java/org/nativescript/widgets/ItemSpec.java +56 -0
- package/platforms/android/java/org/nativescript/widgets/LayoutBase.java +98 -0
- package/platforms/android/java/org/nativescript/widgets/LinearGradientDefinition.java +46 -0
- package/platforms/android/java/org/nativescript/widgets/Orientation.java +9 -0
- package/platforms/android/java/org/nativescript/widgets/OriginPoint.java +74 -0
- package/platforms/android/java/org/nativescript/widgets/ScrollSavedState.java +63 -0
- package/platforms/android/java/org/nativescript/widgets/SegmentedBarColorDrawable.java +27 -0
- package/platforms/android/java/org/nativescript/widgets/StackLayout.java +231 -0
- package/platforms/android/java/org/nativescript/widgets/StyleableTextView.java +50 -0
- package/platforms/android/java/org/nativescript/widgets/TabIconRenderingMode.java +6 -0
- package/platforms/android/java/org/nativescript/widgets/TabItemSpec.java +15 -0
- package/platforms/android/java/org/nativescript/widgets/TabLayout.java +451 -0
- package/platforms/android/java/org/nativescript/widgets/TabStrip.java +294 -0
- package/platforms/android/java/org/nativescript/widgets/TabViewPager.java +64 -0
- package/platforms/android/java/org/nativescript/widgets/TabsBar.java +443 -0
- package/platforms/android/java/org/nativescript/widgets/Utils.java +546 -0
- package/platforms/android/java/org/nativescript/widgets/VerticalScrollView.java +258 -0
- package/platforms/android/java/org/nativescript/widgets/ViewHelper.java +564 -0
- package/platforms/android/java/org/nativescript/widgets/WrapLayout.java +252 -0
- package/platforms/android/java/org/nativescript/widgets/image/AsyncTask.java +679 -0
- package/platforms/android/java/org/nativescript/widgets/image/BitmapOwner.java +17 -0
- package/platforms/android/java/org/nativescript/widgets/image/Cache.java +471 -0
- package/platforms/android/java/org/nativescript/widgets/image/DiskLruCache.java +970 -0
- package/platforms/android/java/org/nativescript/widgets/image/Fetcher.java +747 -0
- package/platforms/android/java/org/nativescript/widgets/image/Utils.java +58 -0
- package/platforms/android/java/org/nativescript/widgets/image/Worker.java +571 -0
- package/platforms/ios/src/TNSWidgets/Info.plist +26 -0
- package/platforms/ios/src/TNSWidgets/NSData+Async.m +42 -0
- package/platforms/ios/src/TNSWidgets/NSFileHandle+Async.m +82 -0
- package/platforms/ios/src/TNSWidgets/NSObject+Swizzling.m +68 -0
- package/platforms/ios/src/TNSWidgets/NSString+Async.m +51 -0
- package/platforms/ios/src/TNSWidgets/TNSLabel.m +42 -0
- package/platforms/ios/src/TNSWidgets/UIImage+TNSBlocks.m +77 -0
- package/platforms/ios/src/TNSWidgets/UIView+PassThroughParent.m +53 -0
- package/platforms/ios/src/TNSWidgets/UIView+PropertyBag.m +72 -0
- package/platforms/ios/src/module.modulemap +5 -0
- package/platforms/android/widgets-release.aar +0 -0
- package/platforms/ios/TNSWidgets.xcframework/Info.plist +0 -102
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/NSCCrypto.h +0 -60
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/TNSProcess.h +0 -29
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Info.plist +0 -0
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Modules/module.modulemap +0 -6
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/TNSWidgets +0 -0
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist +0 -20
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets +0 -0
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/aarch64/TNSWidgets.yml +0 -82
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/NSCCrypto.h +0 -60
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/NSData+Async.h +0 -24
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/NSFileHandle+Async.h +0 -22
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/NSString+Async.h +0 -25
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/TNSLabel.h +0 -16
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/TNSProcess.h +0 -29
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/TNSWidgets.h +0 -25
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h +0 -26
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/UIView+PassThroughParent.h +0 -17
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Modules/module.modulemap +0 -6
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h +0 -17
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h +0 -18
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Resources/Info.plist +0 -52
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/NSCCrypto.h +0 -60
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/NSData+Async.h +0 -24
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/NSFileHandle+Async.h +0 -22
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/NSString+Async.h +0 -25
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/TNSLabel.h +0 -16
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/TNSProcess.h +0 -29
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/TNSWidgets.h +0 -25
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/UIImage+TNSBlocks.h +0 -26
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/UIView+PassThroughParent.h +0 -17
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Modules/module.modulemap +0 -6
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/PrivateHeaders/NSObject+Swizzling.h +0 -17
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/PrivateHeaders/UIView+PropertyBag.h +0 -18
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Resources/Info.plist +0 -52
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/TNSWidgets +0 -0
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/NSCCrypto.h +0 -60
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/NSData+Async.h +0 -24
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/NSFileHandle+Async.h +0 -22
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/NSString+Async.h +0 -25
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/TNSLabel.h +0 -16
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/TNSProcess.h +0 -29
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/TNSWidgets.h +0 -25
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/UIImage+TNSBlocks.h +0 -26
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/UIView+PassThroughParent.h +0 -17
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Modules/module.modulemap +0 -6
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/PrivateHeaders/NSObject+Swizzling.h +0 -17
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/PrivateHeaders/UIView+PropertyBag.h +0 -18
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Resources/Info.plist +0 -52
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/TNSWidgets +0 -0
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist +0 -20
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets +0 -0
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/aarch64/TNSWidgets.yml +0 -82
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/x86_64/TNSWidgets.yml +0 -82
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSCCrypto.h +0 -60
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSData+Async.h +0 -24
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSFileHandle+Async.h +0 -22
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSString+Async.h +0 -25
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSLabel.h +0 -16
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSProcess.h +0 -29
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSWidgets.h +0 -25
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h +0 -26
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIView+PassThroughParent.h +0 -17
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Info.plist +0 -0
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Modules/module.modulemap +0 -6
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h +0 -17
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h +0 -18
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/TNSWidgets +0 -0
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/_CodeSignature/CodeResources +0 -223
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist +0 -20
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets +0 -0
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/aarch64/TNSWidgets.yml +0 -82
- package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/x86_64/TNSWidgets.yml +0 -82
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/NSCCrypto.h +0 -60
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/NSData+Async.h +0 -24
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/NSFileHandle+Async.h +0 -22
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/NSString+Async.h +0 -25
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/TNSLabel.h +0 -16
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/TNSProcess.h +0 -29
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/TNSWidgets.h +0 -25
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h +0 -26
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/UIView+PassThroughParent.h +0 -17
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Info.plist +0 -0
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Modules/module.modulemap +0 -6
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h +0 -17
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h +0 -18
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/TNSWidgets +0 -0
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist +0 -20
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets +0 -0
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/aarch64/TNSWidgets.yml +0 -82
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSCCrypto.h +0 -60
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSData+Async.h +0 -24
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSFileHandle+Async.h +0 -22
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSString+Async.h +0 -25
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSLabel.h +0 -16
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSProcess.h +0 -29
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSWidgets.h +0 -25
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h +0 -26
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIView+PassThroughParent.h +0 -17
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Info.plist +0 -0
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Modules/module.modulemap +0 -6
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h +0 -17
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h +0 -18
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/TNSWidgets +0 -0
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/_CodeSignature/CodeResources +0 -223
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist +0 -20
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets +0 -0
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/aarch64/TNSWidgets.yml +0 -82
- package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/x86_64/TNSWidgets.yml +0 -82
- /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/NSData+Async.h +0 -0
- /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/NSFileHandle+Async.h +0 -0
- /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/PrivateHeaders → src/TNSWidgets}/NSObject+Swizzling.h +0 -0
- /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/NSString+Async.h +0 -0
- /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/TNSLabel.h +0 -0
- /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/TNSWidgets.h +0 -0
- /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/UIImage+TNSBlocks.h +0 -0
- /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/UIView+PassThroughParent.h +0 -0
- /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/PrivateHeaders → src/TNSWidgets}/UIView+PropertyBag.h +0 -0
|
@@ -0,0 +1,1356 @@
|
|
|
1
|
+
package org.nativescript.widgets;
|
|
2
|
+
|
|
3
|
+
import android.content.ContentValues;
|
|
4
|
+
import android.content.Context;
|
|
5
|
+
import android.content.res.Resources;
|
|
6
|
+
import android.graphics.Bitmap;
|
|
7
|
+
import android.graphics.BitmapFactory;
|
|
8
|
+
import android.graphics.drawable.BitmapDrawable;
|
|
9
|
+
import android.net.Uri;
|
|
10
|
+
import android.os.Build;
|
|
11
|
+
import android.os.Looper;
|
|
12
|
+
import android.util.Base64;
|
|
13
|
+
import android.util.Log;
|
|
14
|
+
|
|
15
|
+
import java.io.BufferedInputStream;
|
|
16
|
+
import java.io.ByteArrayOutputStream;
|
|
17
|
+
import java.io.Closeable;
|
|
18
|
+
import java.io.DataInputStream;
|
|
19
|
+
import java.io.File;
|
|
20
|
+
import java.io.FileInputStream;
|
|
21
|
+
import java.io.FileNotFoundException;
|
|
22
|
+
import java.io.FileOutputStream;
|
|
23
|
+
import java.io.IOException;
|
|
24
|
+
import java.io.InputStream;
|
|
25
|
+
import java.io.InputStreamReader;
|
|
26
|
+
import java.io.OutputStream;
|
|
27
|
+
import java.io.OutputStreamWriter;
|
|
28
|
+
import java.io.UnsupportedEncodingException;
|
|
29
|
+
import java.net.CookieHandler;
|
|
30
|
+
import java.net.CookieManager;
|
|
31
|
+
import java.net.HttpURLConnection;
|
|
32
|
+
import java.net.URL;
|
|
33
|
+
import java.nio.ByteBuffer;
|
|
34
|
+
import java.nio.CharBuffer;
|
|
35
|
+
import java.nio.channels.FileChannel;
|
|
36
|
+
import java.nio.channels.ReadableByteChannel;
|
|
37
|
+
import java.nio.channels.WritableByteChannel;
|
|
38
|
+
import java.util.ArrayList;
|
|
39
|
+
import java.util.List;
|
|
40
|
+
import java.util.Locale;
|
|
41
|
+
import java.util.Map;
|
|
42
|
+
import java.util.Stack;
|
|
43
|
+
import java.util.concurrent.LinkedBlockingQueue;
|
|
44
|
+
import java.util.concurrent.ThreadFactory;
|
|
45
|
+
import java.util.concurrent.ThreadPoolExecutor;
|
|
46
|
+
import java.util.concurrent.TimeUnit;
|
|
47
|
+
import java.util.zip.GZIPInputStream;
|
|
48
|
+
|
|
49
|
+
public class Async {
|
|
50
|
+
static final String TAG = "Async";
|
|
51
|
+
static ThreadPoolExecutor executor = null;
|
|
52
|
+
|
|
53
|
+
static ThreadPoolExecutor threadPoolExecutor() {
|
|
54
|
+
if (executor == null) {
|
|
55
|
+
int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
|
|
56
|
+
ThreadFactory backgroundPriorityThreadFactory = new PriorityThreadFactory(android.os.Process.THREAD_PRIORITY_BACKGROUND);
|
|
57
|
+
|
|
58
|
+
executor = new ThreadPoolExecutor(
|
|
59
|
+
NUMBER_OF_CORES * 2,
|
|
60
|
+
NUMBER_OF_CORES * 2,
|
|
61
|
+
60L,
|
|
62
|
+
TimeUnit.SECONDS,
|
|
63
|
+
new LinkedBlockingQueue<Runnable>(),
|
|
64
|
+
backgroundPriorityThreadFactory
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return executor;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public interface CompleteCallback {
|
|
72
|
+
void onComplete(Object result, Object tag);
|
|
73
|
+
|
|
74
|
+
void onError(String error, Object tag);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static class PriorityThreadFactory implements ThreadFactory {
|
|
78
|
+
private final int mThreadPriority;
|
|
79
|
+
|
|
80
|
+
public PriorityThreadFactory(int threadPriority) {
|
|
81
|
+
mThreadPriority = threadPriority;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@Override
|
|
85
|
+
public Thread newThread(final Runnable runnable) {
|
|
86
|
+
Runnable wrapperRunnable = new Runnable() {
|
|
87
|
+
@Override
|
|
88
|
+
public void run() {
|
|
89
|
+
try {
|
|
90
|
+
android.os.Process.setThreadPriority(mThreadPriority);
|
|
91
|
+
} catch (Throwable t) {
|
|
92
|
+
|
|
93
|
+
}
|
|
94
|
+
runnable.run();
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
return new Thread(wrapperRunnable);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public static class Image {
|
|
102
|
+
/*
|
|
103
|
+
* The request id parameter is needed for the sake of the JavaScript implementation.
|
|
104
|
+
* Because we want to use only one extend of the CompleteCallback interface (for the sake of better performance)
|
|
105
|
+
* we use this id to detect the initial request, which result is currently received in the complete callback.
|
|
106
|
+
* When the async task completes it will pass back this id to JavaScript.
|
|
107
|
+
*/
|
|
108
|
+
public static void fromResource(final String name, final Context context, final int requestId, final CompleteCallback callback) {
|
|
109
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
110
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
111
|
+
@Override
|
|
112
|
+
public void run() {
|
|
113
|
+
final LoadImageFromResourceTask task = new LoadImageFromResourceTask(context, requestId, callback);
|
|
114
|
+
final Bitmap result = task.doInBackground(name);
|
|
115
|
+
mHandler.post(new Runnable() {
|
|
116
|
+
@Override
|
|
117
|
+
public void run() {
|
|
118
|
+
task.onPostExecute(result);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public static void fromFile(final String fileName, final int requestId, final CompleteCallback callback) {
|
|
126
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
127
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
128
|
+
@Override
|
|
129
|
+
public void run() {
|
|
130
|
+
final LoadImageFromFileTask task = new LoadImageFromFileTask(requestId, callback);
|
|
131
|
+
final Bitmap result = task.doInBackground(fileName);
|
|
132
|
+
mHandler.post(new Runnable() {
|
|
133
|
+
@Override
|
|
134
|
+
public void run() {
|
|
135
|
+
task.onPostExecute(result);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public static void fromBase64(final String source, final int requestId, final CompleteCallback callback) {
|
|
143
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
144
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
145
|
+
@Override
|
|
146
|
+
public void run() {
|
|
147
|
+
final LoadImageFromBase64StringTask task = new LoadImageFromBase64StringTask(requestId, callback);
|
|
148
|
+
final Bitmap result = task.doInBackground(source);
|
|
149
|
+
mHandler.post(new Runnable() {
|
|
150
|
+
@Override
|
|
151
|
+
public void run() {
|
|
152
|
+
task.onPostExecute(result);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
public static void download(final String url, final CompleteCallback callback, final Object context) {
|
|
160
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
161
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
162
|
+
@Override
|
|
163
|
+
public void run() {
|
|
164
|
+
final DownloadImageTask task = new DownloadImageTask(callback, context);
|
|
165
|
+
final Bitmap result = task.doInBackground(url);
|
|
166
|
+
mHandler.post(new Runnable() {
|
|
167
|
+
@Override
|
|
168
|
+
public void run() {
|
|
169
|
+
task.onPostExecute(result);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
static class DownloadImageTask {
|
|
177
|
+
private final CompleteCallback callback;
|
|
178
|
+
private final Object context;
|
|
179
|
+
|
|
180
|
+
public DownloadImageTask(CompleteCallback callback, Object context) {
|
|
181
|
+
this.callback = callback;
|
|
182
|
+
this.context = context;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
protected Bitmap doInBackground(String... params) {
|
|
186
|
+
InputStream stream = null;
|
|
187
|
+
try {
|
|
188
|
+
stream = new java.net.URL(params[0]).openStream();
|
|
189
|
+
Bitmap bmp = BitmapFactory.decodeStream(stream);
|
|
190
|
+
return bmp;
|
|
191
|
+
} catch (Throwable t) {
|
|
192
|
+
Log.e(TAG, "Failed to decode stream, Throwable: " + t.getMessage());
|
|
193
|
+
return null;
|
|
194
|
+
} finally {
|
|
195
|
+
if (stream != null) {
|
|
196
|
+
try {
|
|
197
|
+
stream.close();
|
|
198
|
+
} catch (IOException e) {
|
|
199
|
+
Log.e(TAG, "Failed to close stream, IOException: " + e.getMessage());
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
protected void onPostExecute(final Bitmap result) {
|
|
206
|
+
if (result != null) {
|
|
207
|
+
this.callback.onComplete(result, this.context);
|
|
208
|
+
} else {
|
|
209
|
+
this.callback.onError("DownloadImageTask returns no result.", this.context);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
static class LoadImageFromResourceTask {
|
|
215
|
+
private final CompleteCallback callback;
|
|
216
|
+
private final Context context;
|
|
217
|
+
private final int requestId;
|
|
218
|
+
|
|
219
|
+
public LoadImageFromResourceTask(Context context, int requestId, CompleteCallback callback) {
|
|
220
|
+
this.callback = callback;
|
|
221
|
+
this.context = context;
|
|
222
|
+
this.requestId = requestId;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
protected Bitmap doInBackground(String... params) {
|
|
226
|
+
String name = params[0];
|
|
227
|
+
Resources res = this.context.getResources();
|
|
228
|
+
int id = res.getIdentifier(name, "drawable", context.getPackageName());
|
|
229
|
+
|
|
230
|
+
if (id > 0) {
|
|
231
|
+
BitmapDrawable result = (BitmapDrawable) res.getDrawable(id);
|
|
232
|
+
return result.getBitmap();
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
protected void onPostExecute(final Bitmap result) {
|
|
239
|
+
if (result != null) {
|
|
240
|
+
this.callback.onComplete(result, this.requestId);
|
|
241
|
+
} else {
|
|
242
|
+
this.callback.onError("LoadImageFromResourceTask returns no result.", this.requestId);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
static class LoadImageFromFileTask {
|
|
248
|
+
private final CompleteCallback callback;
|
|
249
|
+
private final int requestId;
|
|
250
|
+
|
|
251
|
+
public LoadImageFromFileTask(int requestId, CompleteCallback callback) {
|
|
252
|
+
this.callback = callback;
|
|
253
|
+
this.requestId = requestId;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
protected Bitmap doInBackground(String... params) {
|
|
257
|
+
String fileName = params[0];
|
|
258
|
+
return BitmapFactory.decodeFile(fileName);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
protected void onPostExecute(final Bitmap result) {
|
|
262
|
+
if (result != null) {
|
|
263
|
+
this.callback.onComplete(result, this.requestId);
|
|
264
|
+
} else {
|
|
265
|
+
this.callback.onError("LoadImageFromFileTask returns no result.", this.requestId);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
static class LoadImageFromBase64StringTask {
|
|
271
|
+
private final CompleteCallback callback;
|
|
272
|
+
private final int requestId;
|
|
273
|
+
|
|
274
|
+
public LoadImageFromBase64StringTask(int requestId, CompleteCallback callback) {
|
|
275
|
+
this.callback = callback;
|
|
276
|
+
this.requestId = requestId;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
protected Bitmap doInBackground(String... params) {
|
|
280
|
+
String source = params[0];
|
|
281
|
+
byte[] bytes = Base64.decode(source, Base64.DEFAULT);
|
|
282
|
+
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
protected void onPostExecute(final Bitmap result) {
|
|
286
|
+
if (result != null) {
|
|
287
|
+
this.callback.onComplete(result, this.requestId);
|
|
288
|
+
} else {
|
|
289
|
+
this.callback.onError("LoadImageFromBase64StringTask returns no result.", this.requestId);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
public static class Http {
|
|
296
|
+
private static final String GET_METHOD = "GET";
|
|
297
|
+
private static final String HEAD_METHOD = "HEAD";
|
|
298
|
+
private static CookieManager cookieManager;
|
|
299
|
+
|
|
300
|
+
public static void setCookieManager(CookieManager manager) {
|
|
301
|
+
if(manager == null) return;
|
|
302
|
+
|
|
303
|
+
cookieManager = manager;
|
|
304
|
+
if (CookieHandler.getDefault() == null) {
|
|
305
|
+
CookieHandler.setDefault(manager);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
public static CookieManager initializeCookieManager() {
|
|
310
|
+
if (cookieManager == null) {
|
|
311
|
+
CookieHandler defaultHandler = CookieHandler.getDefault();
|
|
312
|
+
if (defaultHandler instanceof CookieManager) {
|
|
313
|
+
cookieManager = (CookieManager) defaultHandler;
|
|
314
|
+
} else {
|
|
315
|
+
cookieManager = new CookieManager();
|
|
316
|
+
CookieHandler.setDefault(cookieManager);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return cookieManager;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
public static void MakeRequest(final RequestOptions options, final CompleteCallback callback, final Object context) {
|
|
324
|
+
if (cookieManager == null) {
|
|
325
|
+
initializeCookieManager();
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
329
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
330
|
+
@Override
|
|
331
|
+
public void run() {
|
|
332
|
+
final HttpRequestTask task = new HttpRequestTask(callback, context);
|
|
333
|
+
final RequestResult result = task.doInBackground(options);
|
|
334
|
+
mHandler.post(new Runnable() {
|
|
335
|
+
@Override
|
|
336
|
+
public void run() {
|
|
337
|
+
task.onPostExecute(result);
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
public static class KeyValuePair {
|
|
345
|
+
public String key;
|
|
346
|
+
public String value;
|
|
347
|
+
|
|
348
|
+
public KeyValuePair(String key, String value) {
|
|
349
|
+
this.key = key;
|
|
350
|
+
this.value = value;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
public static class RequestOptions {
|
|
355
|
+
public String url;
|
|
356
|
+
public String method;
|
|
357
|
+
public ArrayList<KeyValuePair> headers;
|
|
358
|
+
public Object content;
|
|
359
|
+
public int timeout = -1;
|
|
360
|
+
public int screenWidth = -1;
|
|
361
|
+
public int screenHeight = -1;
|
|
362
|
+
public boolean dontFollowRedirects = false;
|
|
363
|
+
|
|
364
|
+
public void addHeaders(HttpURLConnection connection) {
|
|
365
|
+
if (this.headers == null) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
boolean hasAcceptHeader = false;
|
|
369
|
+
|
|
370
|
+
for (KeyValuePair pair : this.headers) {
|
|
371
|
+
String key = pair.key;
|
|
372
|
+
connection.addRequestProperty(key, pair.value);
|
|
373
|
+
if (key.toLowerCase().contentEquals("accept-encoding")) {
|
|
374
|
+
hasAcceptHeader = true;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// If the user hasn't added an Accept-Encoding header, we add gzip as something we accept
|
|
379
|
+
if (!hasAcceptHeader) {
|
|
380
|
+
connection.addRequestProperty("Accept-Encoding", "gzip");
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
public void writeContent(HttpURLConnection connection, Stack<Closeable> openedStreams) throws IOException {
|
|
385
|
+
if (this.content == null) {
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
OutputStream outStream = connection.getOutputStream();
|
|
390
|
+
openedStreams.push(outStream);
|
|
391
|
+
|
|
392
|
+
if (this.content instanceof String) {
|
|
393
|
+
OutputStreamWriter writer = new OutputStreamWriter(outStream);
|
|
394
|
+
openedStreams.push(writer);
|
|
395
|
+
|
|
396
|
+
writer.write((String) this.content);
|
|
397
|
+
} else {
|
|
398
|
+
outStream.write(((java.nio.ByteBuffer) this.content).array());
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
public static class RequestResult {
|
|
404
|
+
public ByteArrayOutputStream raw;
|
|
405
|
+
public ArrayList<KeyValuePair> headers = new ArrayList<KeyValuePair>();
|
|
406
|
+
public int statusCode;
|
|
407
|
+
public String responseAsString;
|
|
408
|
+
public Bitmap responseAsImage;
|
|
409
|
+
public Exception error;
|
|
410
|
+
public String url;
|
|
411
|
+
public String statusText;
|
|
412
|
+
|
|
413
|
+
public void getHeaders(HttpURLConnection connection) {
|
|
414
|
+
Map<String, List<String>> headers = connection.getHeaderFields();
|
|
415
|
+
if (headers == null) {
|
|
416
|
+
// no headers, this may happen if there is no internet connection currently available
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
int size = headers.size();
|
|
421
|
+
if (size == 0) {
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
|
426
|
+
String key = entry.getKey();
|
|
427
|
+
for (String value : entry.getValue()) {
|
|
428
|
+
this.headers.add(new KeyValuePair(key, value));
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
public void readResponseStream(HttpURLConnection connection, Stack<Closeable> openedStreams, RequestOptions options) throws IOException {
|
|
434
|
+
int contentLength = connection.getContentLength();
|
|
435
|
+
|
|
436
|
+
InputStream inStream =
|
|
437
|
+
this.statusCode >= 400
|
|
438
|
+
? connection.getErrorStream()
|
|
439
|
+
: connection.getInputStream();
|
|
440
|
+
|
|
441
|
+
if (inStream == null) {
|
|
442
|
+
// inStream is null when receiving status code 401 or 407
|
|
443
|
+
// see this thread for more information http://stackoverflow.com/a/24986433
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// In the event we don't have a null stream, and we have gzip as part of the encoding
|
|
448
|
+
// then we will use gzip to decode the stream
|
|
449
|
+
// Ignore gzip encoding for 204 'No Content' status to prevent java.io.EOFException
|
|
450
|
+
String encodingHeader = connection.getHeaderField("Content-Encoding");
|
|
451
|
+
if (encodingHeader != null && encodingHeader.toLowerCase().contains("gzip") && this.statusCode != 204) {
|
|
452
|
+
inStream = new GZIPInputStream(inStream);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
openedStreams.push(inStream);
|
|
456
|
+
|
|
457
|
+
BufferedInputStream buffer = new BufferedInputStream(inStream, 4096);
|
|
458
|
+
openedStreams.push(buffer);
|
|
459
|
+
|
|
460
|
+
ByteArrayOutputStream2 responseStream = contentLength != -1 ? new ByteArrayOutputStream2(contentLength) : new ByteArrayOutputStream2();
|
|
461
|
+
openedStreams.push(responseStream);
|
|
462
|
+
|
|
463
|
+
byte[] buff = new byte[4096];
|
|
464
|
+
int read = -1;
|
|
465
|
+
while ((read = buffer.read(buff, 0, buff.length)) != -1) {
|
|
466
|
+
responseStream.write(buff, 0, read);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
this.raw = responseStream;
|
|
470
|
+
buff = null;
|
|
471
|
+
|
|
472
|
+
// make the byte array conversion here, not in the JavaScript
|
|
473
|
+
// world for better performance
|
|
474
|
+
// since we do not have some explicit way to determine whether
|
|
475
|
+
// the content-type is image
|
|
476
|
+
try {
|
|
477
|
+
// TODO: Generally this approach will not work for very
|
|
478
|
+
// large files
|
|
479
|
+
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
|
|
480
|
+
bitmapOptions.inJustDecodeBounds = true;
|
|
481
|
+
|
|
482
|
+
// check the size of the bitmap first
|
|
483
|
+
BitmapFactory.decodeByteArray(responseStream.buf(), 0, responseStream.size(), bitmapOptions);
|
|
484
|
+
if (bitmapOptions.outWidth > 0 && bitmapOptions.outHeight > 0) {
|
|
485
|
+
int scale = 1;
|
|
486
|
+
final int height = bitmapOptions.outHeight;
|
|
487
|
+
final int width = bitmapOptions.outWidth;
|
|
488
|
+
|
|
489
|
+
if ((options.screenWidth > 0 && bitmapOptions.outWidth > options.screenWidth) ||
|
|
490
|
+
(options.screenHeight > 0 && bitmapOptions.outHeight > options.screenHeight)) {
|
|
491
|
+
final int halfHeight = height / 2;
|
|
492
|
+
final int halfWidth = width / 2;
|
|
493
|
+
|
|
494
|
+
// scale down the image since it is larger than the
|
|
495
|
+
// screen resolution
|
|
496
|
+
while ((halfWidth / scale) > options.screenWidth && (halfHeight / scale) > options.screenHeight) {
|
|
497
|
+
scale *= 2;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
bitmapOptions.inJustDecodeBounds = false;
|
|
502
|
+
bitmapOptions.inSampleSize = scale;
|
|
503
|
+
this.responseAsImage = BitmapFactory.decodeByteArray(responseStream.buf(), 0, responseStream.size(), bitmapOptions);
|
|
504
|
+
}
|
|
505
|
+
} catch (Throwable t) {
|
|
506
|
+
Log.e(TAG, "Failed to decode byte array, Throwable: " + t.getMessage());
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
if (this.responseAsImage == null) {
|
|
510
|
+
// convert to string
|
|
511
|
+
this.responseAsString = responseStream.toString();
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
public static final class ByteArrayOutputStream2 extends ByteArrayOutputStream {
|
|
516
|
+
public ByteArrayOutputStream2() {
|
|
517
|
+
super();
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
public ByteArrayOutputStream2(int size) {
|
|
521
|
+
super(size);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Returns the internal buffer of this ByteArrayOutputStream, without copying.
|
|
526
|
+
*/
|
|
527
|
+
public synchronized byte[] buf() {
|
|
528
|
+
return this.buf;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
static class HttpRequestTask {
|
|
534
|
+
private final CompleteCallback callback;
|
|
535
|
+
private final Object context;
|
|
536
|
+
|
|
537
|
+
public HttpRequestTask(CompleteCallback callback, Object context) {
|
|
538
|
+
this.callback = callback;
|
|
539
|
+
this.context = context;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
protected RequestResult doInBackground(RequestOptions... params) {
|
|
543
|
+
RequestResult result = new RequestResult();
|
|
544
|
+
Stack<Closeable> openedStreams = new Stack<Closeable>();
|
|
545
|
+
|
|
546
|
+
try {
|
|
547
|
+
RequestOptions options = params[0];
|
|
548
|
+
URL url = new URL(options.url);
|
|
549
|
+
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
|
550
|
+
|
|
551
|
+
// set the request method
|
|
552
|
+
String requestMethod = options.method != null ? options.method.toUpperCase(Locale.ENGLISH) : GET_METHOD;
|
|
553
|
+
connection.setRequestMethod(requestMethod);
|
|
554
|
+
|
|
555
|
+
// add the headers
|
|
556
|
+
options.addHeaders(connection);
|
|
557
|
+
|
|
558
|
+
// apply timeout
|
|
559
|
+
if (options.timeout > 0) {
|
|
560
|
+
connection.setConnectTimeout(options.timeout);
|
|
561
|
+
connection.setReadTimeout(options.timeout);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// don't follow redirect (30x) responses; by default, HttpURLConnection follows them.
|
|
565
|
+
if (options.dontFollowRedirects) {
|
|
566
|
+
connection.setInstanceFollowRedirects(false);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
options.writeContent(connection, openedStreams);
|
|
570
|
+
|
|
571
|
+
// close the opened streams (saves copy-paste implementation
|
|
572
|
+
// in each method that throws IOException)
|
|
573
|
+
this.closeOpenedStreams(openedStreams);
|
|
574
|
+
|
|
575
|
+
connection.connect();
|
|
576
|
+
|
|
577
|
+
// build the result
|
|
578
|
+
result.getHeaders(connection);
|
|
579
|
+
result.url = options.url;
|
|
580
|
+
result.statusCode = connection.getResponseCode();
|
|
581
|
+
result.statusText = connection.getResponseMessage();
|
|
582
|
+
if (!requestMethod.equals(HEAD_METHOD)) {
|
|
583
|
+
result.readResponseStream(connection, openedStreams, options);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// close the opened streams (saves copy-paste implementation
|
|
587
|
+
// in each method that throws IOException)
|
|
588
|
+
this.closeOpenedStreams(openedStreams);
|
|
589
|
+
|
|
590
|
+
connection.disconnect();
|
|
591
|
+
|
|
592
|
+
return result;
|
|
593
|
+
} catch (Exception e) // TODO: Catch all exceptions?
|
|
594
|
+
{
|
|
595
|
+
result.error = e;
|
|
596
|
+
|
|
597
|
+
return result;
|
|
598
|
+
} finally {
|
|
599
|
+
try {
|
|
600
|
+
this.closeOpenedStreams(openedStreams);
|
|
601
|
+
} catch (IOException e) {
|
|
602
|
+
Log.e(TAG, "Failed to close opened streams, IOException: " + e.getMessage());
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
protected void onPostExecute(final RequestResult result) {
|
|
608
|
+
if (result != null) {
|
|
609
|
+
this.callback.onComplete(result, this.context);
|
|
610
|
+
} else {
|
|
611
|
+
this.callback.onError("HttpRequestTask returns no result.", this.context);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
private void closeOpenedStreams(Stack<Closeable> streams) throws IOException {
|
|
616
|
+
while (streams.size() > 0) {
|
|
617
|
+
Closeable stream = streams.pop();
|
|
618
|
+
stream.close();
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
public static class File {
|
|
625
|
+
|
|
626
|
+
static void updateValue(Context context, Uri uri) {
|
|
627
|
+
try {
|
|
628
|
+
ContentValues values = new ContentValues();
|
|
629
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
630
|
+
context.getContentResolver().update(uri, values, null);
|
|
631
|
+
} else {
|
|
632
|
+
context.getContentResolver().update(uri, values, null, null);
|
|
633
|
+
}
|
|
634
|
+
} catch (Exception exception){
|
|
635
|
+
Log.e(TAG, "Failed to updateValue: " + exception.getMessage());
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
public static void append(final String path, final byte[] content, final CompleteCallback callback, final Object context) {
|
|
641
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
642
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
643
|
+
@Override
|
|
644
|
+
public void run() {
|
|
645
|
+
final AppendTask task = new AppendTask(callback, context);
|
|
646
|
+
final boolean result = task.doInBackground(path, content);
|
|
647
|
+
mHandler.post(new Runnable() {
|
|
648
|
+
@Override
|
|
649
|
+
public void run() {
|
|
650
|
+
task.onPostExecute(result);
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
public static void appendBuffer(final String path, final ByteBuffer content, final CompleteCallback callback, final Object context) {
|
|
658
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
659
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
660
|
+
@Override
|
|
661
|
+
public void run() {
|
|
662
|
+
final AppendBufferTask task = new AppendBufferTask(callback, context);
|
|
663
|
+
final boolean result = task.doInBackground(path, content);
|
|
664
|
+
mHandler.post(new Runnable() {
|
|
665
|
+
@Override
|
|
666
|
+
public void run() {
|
|
667
|
+
task.onPostExecute(result);
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
public static void appendText(final String path, final String content, final String encoding, final CompleteCallback callback, final Object context) {
|
|
675
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
676
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
677
|
+
@Override
|
|
678
|
+
public void run() {
|
|
679
|
+
final AppendTextTask task = new AppendTextTask(callback, context);
|
|
680
|
+
final boolean result = task.doInBackground(path, content, encoding);
|
|
681
|
+
mHandler.post(new Runnable() {
|
|
682
|
+
@Override
|
|
683
|
+
public void run() {
|
|
684
|
+
task.onPostExecute(result);
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
public static boolean copySync(final String src, final String dest, final Context context) throws Exception {
|
|
692
|
+
InputStream is;
|
|
693
|
+
OutputStream os;
|
|
694
|
+
boolean requiresUpdate = false;
|
|
695
|
+
if(src.startsWith("content://")){
|
|
696
|
+
is = context.getContentResolver().openInputStream(Uri.parse(src));
|
|
697
|
+
}else is = new FileInputStream(new java.io.File(src));
|
|
698
|
+
|
|
699
|
+
if(dest.startsWith("content://")){
|
|
700
|
+
os = context.getContentResolver().openOutputStream(Uri.parse(dest));
|
|
701
|
+
requiresUpdate = true;
|
|
702
|
+
}else os = new FileOutputStream(new java.io.File(dest));
|
|
703
|
+
|
|
704
|
+
boolean ret = copySync(is, os, context);
|
|
705
|
+
|
|
706
|
+
if(ret && requiresUpdate){
|
|
707
|
+
updateValue(context, Uri.parse(dest));
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
return ret;
|
|
711
|
+
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
public static boolean copySync(final InputStream src, final OutputStream dest, final Object context) throws Exception {
|
|
715
|
+
ReadableByteChannel isc = java.nio.channels.Channels.newChannel(src);
|
|
716
|
+
WritableByteChannel osc = java.nio.channels.Channels.newChannel(dest);
|
|
717
|
+
|
|
718
|
+
int size = src.available();
|
|
719
|
+
|
|
720
|
+
int written = fastChannelCopy(isc, osc);
|
|
721
|
+
|
|
722
|
+
return size == written;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
public static void copy(final String src, final String dest, final CompleteCallback callback, final Context context) {
|
|
726
|
+
try {
|
|
727
|
+
InputStream is;
|
|
728
|
+
OutputStream os;
|
|
729
|
+
|
|
730
|
+
boolean requiresUpdate = false;
|
|
731
|
+
|
|
732
|
+
if(src.startsWith("content://")){
|
|
733
|
+
is = context.getContentResolver().openInputStream(Uri.parse(src));
|
|
734
|
+
}else is = new FileInputStream(new java.io.File(src));
|
|
735
|
+
|
|
736
|
+
if(dest.startsWith("content://")){
|
|
737
|
+
requiresUpdate = true;
|
|
738
|
+
os = context.getContentResolver().openOutputStream(Uri.parse(dest));
|
|
739
|
+
}else os = new FileOutputStream(new java.io.File(dest));
|
|
740
|
+
|
|
741
|
+
boolean finalRequiresUpdate = requiresUpdate;
|
|
742
|
+
copy(is, os, new CompleteCallback() {
|
|
743
|
+
@Override
|
|
744
|
+
public void onComplete(Object result, Object tag) {
|
|
745
|
+
if(finalRequiresUpdate){
|
|
746
|
+
updateValue(context, Uri.parse(dest));
|
|
747
|
+
}
|
|
748
|
+
callback.onComplete(result, tag);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
@Override
|
|
752
|
+
public void onError(String error, Object tag) {
|
|
753
|
+
callback.onError(error, tag);
|
|
754
|
+
}
|
|
755
|
+
}, context);
|
|
756
|
+
|
|
757
|
+
}catch (Exception exception){
|
|
758
|
+
callback.onError(exception.getMessage(), context);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
private static int fastChannelCopy(final ReadableByteChannel src,
|
|
763
|
+
final WritableByteChannel dest) throws IOException {
|
|
764
|
+
int written = 0;
|
|
765
|
+
final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
|
|
766
|
+
while (src.read(buffer) != -1) {
|
|
767
|
+
// prepare the buffer to be drained
|
|
768
|
+
buffer.flip();
|
|
769
|
+
// write to the channel, may block
|
|
770
|
+
written += dest.write(buffer);
|
|
771
|
+
// If partial transfer, shift remainder down
|
|
772
|
+
// If buffer is empty, same as doing clear()
|
|
773
|
+
buffer.compact();
|
|
774
|
+
}
|
|
775
|
+
// EOF will leave buffer in fill state
|
|
776
|
+
buffer.flip();
|
|
777
|
+
// make sure the buffer is fully drained.
|
|
778
|
+
while (buffer.hasRemaining()) {
|
|
779
|
+
written += dest.write(buffer);
|
|
780
|
+
}
|
|
781
|
+
return written;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
public static void copy(final InputStream src, final OutputStream dest, final CompleteCallback callback, final Object context) {
|
|
785
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
786
|
+
threadPoolExecutor().execute((Runnable) () -> {
|
|
787
|
+
|
|
788
|
+
boolean done = false;
|
|
789
|
+
Exception error = null;
|
|
790
|
+
try (InputStream is = src; OutputStream os = dest){
|
|
791
|
+
ReadableByteChannel isc = java.nio.channels.Channels.newChannel(is);
|
|
792
|
+
WritableByteChannel osc = java.nio.channels.Channels.newChannel(os);
|
|
793
|
+
|
|
794
|
+
int size = src.available();
|
|
795
|
+
|
|
796
|
+
int written = fastChannelCopy(isc, osc);
|
|
797
|
+
|
|
798
|
+
done = size == written;
|
|
799
|
+
|
|
800
|
+
} catch (Exception e) {
|
|
801
|
+
error = e;
|
|
802
|
+
|
|
803
|
+
}finally {
|
|
804
|
+
if (error != null){
|
|
805
|
+
Exception finalError = error;
|
|
806
|
+
mHandler.post(() -> callback.onError(finalError.getMessage(), context));
|
|
807
|
+
}else {
|
|
808
|
+
boolean finalDone = done;
|
|
809
|
+
mHandler.post(() -> callback.onComplete(finalDone, context));
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
public static void readText(final String path, final String encoding, final CompleteCallback callback, final Object context) {
|
|
816
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
817
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
818
|
+
@Override
|
|
819
|
+
public void run() {
|
|
820
|
+
final ReadTextTask task = new ReadTextTask(callback, context);
|
|
821
|
+
final String result = task.doInBackground(path, encoding);
|
|
822
|
+
mHandler.post(new Runnable() {
|
|
823
|
+
@Override
|
|
824
|
+
public void run() {
|
|
825
|
+
task.onPostExecute(result);
|
|
826
|
+
}
|
|
827
|
+
});
|
|
828
|
+
}
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
public static void read(final String path, final CompleteCallback callback, final Object context) {
|
|
833
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
834
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
835
|
+
@Override
|
|
836
|
+
public void run() {
|
|
837
|
+
final ReadTask task = new ReadTask(callback, context);
|
|
838
|
+
final byte[] result = task.doInBackground(path);
|
|
839
|
+
mHandler.post(new Runnable() {
|
|
840
|
+
@Override
|
|
841
|
+
public void run() {
|
|
842
|
+
task.onPostExecute(result);
|
|
843
|
+
}
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
public static void readBuffer(final String path, final CompleteCallback callback, final Object context) {
|
|
850
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
851
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
852
|
+
@Override
|
|
853
|
+
public void run() {
|
|
854
|
+
final ReadBufferTask task = new ReadBufferTask(callback, context);
|
|
855
|
+
final ByteBuffer result = task.doInBackground(path);
|
|
856
|
+
mHandler.post(new Runnable() {
|
|
857
|
+
@Override
|
|
858
|
+
public void run() {
|
|
859
|
+
task.onPostExecute(result);
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
public static void writeText(final String path, final String content, final String encoding, final CompleteCallback callback, final Object context) {
|
|
867
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
868
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
869
|
+
@Override
|
|
870
|
+
public void run() {
|
|
871
|
+
final WriteTextTask task = new WriteTextTask(callback, context);
|
|
872
|
+
final boolean result = task.doInBackground(path, content, encoding);
|
|
873
|
+
mHandler.post(new Runnable() {
|
|
874
|
+
@Override
|
|
875
|
+
public void run() {
|
|
876
|
+
task.onPostExecute(result);
|
|
877
|
+
}
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
public static void write(final String path, final byte[] content, final CompleteCallback callback, final Object context) {
|
|
884
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
885
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
886
|
+
@Override
|
|
887
|
+
public void run() {
|
|
888
|
+
final WriteTask task = new WriteTask(callback, context);
|
|
889
|
+
final boolean result = task.doInBackground(path, content);
|
|
890
|
+
mHandler.post(new Runnable() {
|
|
891
|
+
@Override
|
|
892
|
+
public void run() {
|
|
893
|
+
task.onPostExecute(result);
|
|
894
|
+
}
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
public static void writeBuffer(final String path, final ByteBuffer content, final CompleteCallback callback, final Object context) {
|
|
901
|
+
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
|
902
|
+
threadPoolExecutor().execute(new Runnable() {
|
|
903
|
+
@Override
|
|
904
|
+
public void run() {
|
|
905
|
+
final WriteBufferTask task = new WriteBufferTask(callback, context);
|
|
906
|
+
final boolean result = task.doInBackground(path, content);
|
|
907
|
+
mHandler.post(new Runnable() {
|
|
908
|
+
@Override
|
|
909
|
+
public void run() {
|
|
910
|
+
task.onPostExecute(result);
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
static class ReadTextTask {
|
|
918
|
+
private final CompleteCallback callback;
|
|
919
|
+
private final Object context;
|
|
920
|
+
|
|
921
|
+
public ReadTextTask(CompleteCallback callback, Object context) {
|
|
922
|
+
this.callback = callback;
|
|
923
|
+
this.context = context;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
protected String doInBackground(String... params) {
|
|
927
|
+
java.io.File javaFile = new java.io.File(params[0]);
|
|
928
|
+
FileInputStream stream = null;
|
|
929
|
+
|
|
930
|
+
try {
|
|
931
|
+
stream = new FileInputStream(javaFile);
|
|
932
|
+
|
|
933
|
+
InputStreamReader reader = new InputStreamReader(stream, params[1]);
|
|
934
|
+
|
|
935
|
+
CharBuffer buffer = CharBuffer.allocate(81920);
|
|
936
|
+
StringBuilder sb = new StringBuilder();
|
|
937
|
+
|
|
938
|
+
while (reader.read(buffer) != -1) {
|
|
939
|
+
buffer.flip();
|
|
940
|
+
sb.append(buffer);
|
|
941
|
+
buffer.clear();
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
reader.close();
|
|
945
|
+
|
|
946
|
+
return sb.toString();
|
|
947
|
+
} catch (FileNotFoundException e) {
|
|
948
|
+
Log.e(TAG, "Failed to read file, FileNotFoundException: " + e.getMessage());
|
|
949
|
+
return null;
|
|
950
|
+
} catch (UnsupportedEncodingException e) {
|
|
951
|
+
Log.e(TAG, "Failed to read file, UnsupportedEncodingException: " + e.getMessage());
|
|
952
|
+
return null;
|
|
953
|
+
} catch (IOException e) {
|
|
954
|
+
Log.e(TAG, "Failed to read file, IOException: " + e.getMessage());
|
|
955
|
+
return null;
|
|
956
|
+
} finally {
|
|
957
|
+
if (stream != null) {
|
|
958
|
+
try {
|
|
959
|
+
stream.close();
|
|
960
|
+
} catch (IOException e) {
|
|
961
|
+
Log.e(TAG, "Failed to close stream, IOException: " + e.getMessage());
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
protected void onPostExecute(final String result) {
|
|
968
|
+
if (result != null) {
|
|
969
|
+
this.callback.onComplete(result, this.context);
|
|
970
|
+
} else {
|
|
971
|
+
this.callback.onError("ReadTextTask returns no result.", this.context);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
static class ReadTask {
|
|
977
|
+
private final CompleteCallback callback;
|
|
978
|
+
private final Object context;
|
|
979
|
+
|
|
980
|
+
public ReadTask(CompleteCallback callback, Object context) {
|
|
981
|
+
this.callback = callback;
|
|
982
|
+
this.context = context;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
protected byte[] doInBackground(String... params) {
|
|
986
|
+
java.io.File javaFile = new java.io.File(params[0]);
|
|
987
|
+
FileInputStream stream = null;
|
|
988
|
+
|
|
989
|
+
try {
|
|
990
|
+
stream = new FileInputStream(javaFile);
|
|
991
|
+
|
|
992
|
+
byte[] result = new byte[(int) javaFile.length()];
|
|
993
|
+
|
|
994
|
+
DataInputStream dataInputStream = new DataInputStream(stream);
|
|
995
|
+
dataInputStream.readFully(result);
|
|
996
|
+
|
|
997
|
+
return result;
|
|
998
|
+
} catch (FileNotFoundException e) {
|
|
999
|
+
Log.e(TAG, "Failed to read file, FileNotFoundException: " + e.getMessage());
|
|
1000
|
+
return null;
|
|
1001
|
+
} catch (IOException e) {
|
|
1002
|
+
Log.e(TAG, "Failed to read file, IOException: " + e.getMessage());
|
|
1003
|
+
return null;
|
|
1004
|
+
} finally {
|
|
1005
|
+
if (stream != null) {
|
|
1006
|
+
try {
|
|
1007
|
+
stream.close();
|
|
1008
|
+
} catch (IOException e) {
|
|
1009
|
+
Log.e(TAG, "Failed to close stream, IOException: " + e.getMessage());
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
protected void onPostExecute(final byte[] result) {
|
|
1016
|
+
if (result != null) {
|
|
1017
|
+
this.callback.onComplete(result, this.context);
|
|
1018
|
+
} else {
|
|
1019
|
+
this.callback.onError("ReadTask returns no result.", this.context);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
static class ReadBufferTask {
|
|
1025
|
+
private final CompleteCallback callback;
|
|
1026
|
+
private final Object context;
|
|
1027
|
+
|
|
1028
|
+
public ReadBufferTask(CompleteCallback callback, Object context) {
|
|
1029
|
+
this.callback = callback;
|
|
1030
|
+
this.context = context;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
protected ByteBuffer doInBackground(String... params) {
|
|
1034
|
+
java.io.File javaFile = new java.io.File(params[0]);
|
|
1035
|
+
FileInputStream stream = null;
|
|
1036
|
+
|
|
1037
|
+
try {
|
|
1038
|
+
stream = new FileInputStream(javaFile);
|
|
1039
|
+
|
|
1040
|
+
ByteBuffer buffer = ByteBuffer.allocateDirect((int) javaFile.length());
|
|
1041
|
+
|
|
1042
|
+
FileChannel channel = stream.getChannel();
|
|
1043
|
+
channel.read(buffer);
|
|
1044
|
+
buffer.rewind();
|
|
1045
|
+
|
|
1046
|
+
return buffer;
|
|
1047
|
+
} catch (FileNotFoundException e) {
|
|
1048
|
+
Log.e(TAG, "Failed to read file, FileNotFoundException: " + e.getMessage());
|
|
1049
|
+
return null;
|
|
1050
|
+
} catch (IOException e) {
|
|
1051
|
+
Log.e(TAG, "Failed to read file, IOException: " + e.getMessage());
|
|
1052
|
+
return null;
|
|
1053
|
+
} finally {
|
|
1054
|
+
if (stream != null) {
|
|
1055
|
+
try {
|
|
1056
|
+
stream.close();
|
|
1057
|
+
} catch (IOException e) {
|
|
1058
|
+
Log.e(TAG, "Failed to close stream, IOException: " + e.getMessage());
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
protected void onPostExecute(final ByteBuffer result) {
|
|
1065
|
+
if (result != null) {
|
|
1066
|
+
this.callback.onComplete(result, this.context);
|
|
1067
|
+
} else {
|
|
1068
|
+
this.callback.onError("ReadTask returns no result.", this.context);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
static class WriteTextTask {
|
|
1074
|
+
private final CompleteCallback callback;
|
|
1075
|
+
private final Object context;
|
|
1076
|
+
|
|
1077
|
+
public WriteTextTask(CompleteCallback callback, Object context) {
|
|
1078
|
+
this.callback = callback;
|
|
1079
|
+
this.context = context;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
protected boolean doInBackground(String... params) {
|
|
1083
|
+
java.io.File javaFile = new java.io.File(params[0]);
|
|
1084
|
+
FileOutputStream stream = null;
|
|
1085
|
+
try {
|
|
1086
|
+
stream = new FileOutputStream(javaFile);
|
|
1087
|
+
|
|
1088
|
+
OutputStreamWriter writer = new OutputStreamWriter(stream, params[2]);
|
|
1089
|
+
writer.write(params[1]);
|
|
1090
|
+
writer.close();
|
|
1091
|
+
|
|
1092
|
+
return true;
|
|
1093
|
+
} catch (FileNotFoundException e) {
|
|
1094
|
+
Log.e(TAG, "Failed to write file, FileNotFoundException: " + e.getMessage());
|
|
1095
|
+
return false;
|
|
1096
|
+
} catch (UnsupportedEncodingException e) {
|
|
1097
|
+
Log.e(TAG, "Failed to write file, UnsupportedEncodingException: " + e.getMessage());
|
|
1098
|
+
return false;
|
|
1099
|
+
} catch (IOException e) {
|
|
1100
|
+
Log.e(TAG, "Failed to write file, IOException: " + e.getMessage());
|
|
1101
|
+
return false;
|
|
1102
|
+
} finally {
|
|
1103
|
+
if (stream != null) {
|
|
1104
|
+
try {
|
|
1105
|
+
stream.close();
|
|
1106
|
+
} catch (IOException e) {
|
|
1107
|
+
Log.e(TAG, "Failed to close stream, IOException: " + e.getMessage());
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
protected void onPostExecute(final boolean result) {
|
|
1114
|
+
if (result) {
|
|
1115
|
+
this.callback.onComplete(null, this.context);
|
|
1116
|
+
} else {
|
|
1117
|
+
this.callback.onError("WriteTextTask returns no result.", this.context);
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
static class WriteTask {
|
|
1123
|
+
private final CompleteCallback callback;
|
|
1124
|
+
private final Object context;
|
|
1125
|
+
|
|
1126
|
+
public WriteTask(CompleteCallback callback, Object context) {
|
|
1127
|
+
this.callback = callback;
|
|
1128
|
+
this.context = context;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
protected boolean doInBackground(Object... params) {
|
|
1132
|
+
java.io.File javaFile = new java.io.File((String) params[0]);
|
|
1133
|
+
FileOutputStream stream = null;
|
|
1134
|
+
byte[] content = (byte[]) params[1];
|
|
1135
|
+
|
|
1136
|
+
try {
|
|
1137
|
+
stream = new FileOutputStream(javaFile);
|
|
1138
|
+
stream.write(content, 0, content.length);
|
|
1139
|
+
|
|
1140
|
+
return true;
|
|
1141
|
+
} catch (FileNotFoundException e) {
|
|
1142
|
+
Log.e(TAG, "Failed to write file, FileNotFoundException: " + e.getMessage());
|
|
1143
|
+
return false;
|
|
1144
|
+
} catch (IOException e) {
|
|
1145
|
+
Log.e(TAG, "Failed to write file, IOException: " + e.getMessage());
|
|
1146
|
+
return false;
|
|
1147
|
+
} finally {
|
|
1148
|
+
if (stream != null) {
|
|
1149
|
+
try {
|
|
1150
|
+
stream.close();
|
|
1151
|
+
} catch (IOException e) {
|
|
1152
|
+
Log.e(TAG, "Failed to close stream, IOException: " + e.getMessage());
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
protected void onPostExecute(final boolean result) {
|
|
1159
|
+
if (result) {
|
|
1160
|
+
this.callback.onComplete(null, this.context);
|
|
1161
|
+
} else {
|
|
1162
|
+
this.callback.onError("WriteTask returns no result.", this.context);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
static class WriteBufferTask {
|
|
1168
|
+
private final CompleteCallback callback;
|
|
1169
|
+
private final Object context;
|
|
1170
|
+
|
|
1171
|
+
public WriteBufferTask(CompleteCallback callback, Object context) {
|
|
1172
|
+
this.callback = callback;
|
|
1173
|
+
this.context = context;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
protected boolean doInBackground(Object... params) {
|
|
1177
|
+
java.io.File javaFile = new java.io.File((String) params[0]);
|
|
1178
|
+
FileOutputStream stream = null;
|
|
1179
|
+
ByteBuffer content = (ByteBuffer) params[1];
|
|
1180
|
+
|
|
1181
|
+
try {
|
|
1182
|
+
stream = new FileOutputStream(javaFile);
|
|
1183
|
+
FileChannel channel = stream.getChannel();
|
|
1184
|
+
content.rewind();
|
|
1185
|
+
channel.write(content);
|
|
1186
|
+
content.rewind();
|
|
1187
|
+
return true;
|
|
1188
|
+
} catch (FileNotFoundException e) {
|
|
1189
|
+
Log.e(TAG, "Failed to write file, FileNotFoundException: " + e.getMessage());
|
|
1190
|
+
return false;
|
|
1191
|
+
} catch (IOException e) {
|
|
1192
|
+
Log.e(TAG, "Failed to write file, IOException: " + e.getMessage());
|
|
1193
|
+
return false;
|
|
1194
|
+
} finally {
|
|
1195
|
+
if (stream != null) {
|
|
1196
|
+
try {
|
|
1197
|
+
stream.close();
|
|
1198
|
+
} catch (IOException e) {
|
|
1199
|
+
Log.e(TAG, "Failed to close stream, IOException: " + e.getMessage());
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
protected void onPostExecute(final boolean result) {
|
|
1206
|
+
if (result) {
|
|
1207
|
+
this.callback.onComplete(null, this.context);
|
|
1208
|
+
} else {
|
|
1209
|
+
this.callback.onError("WriteTask returns no result.", this.context);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
static class AppendTask {
|
|
1215
|
+
private final CompleteCallback callback;
|
|
1216
|
+
private final Object context;
|
|
1217
|
+
|
|
1218
|
+
public AppendTask(CompleteCallback callback, Object context) {
|
|
1219
|
+
this.callback = callback;
|
|
1220
|
+
this.context = context;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
protected boolean doInBackground(Object... params) {
|
|
1224
|
+
java.io.File javaFile = new java.io.File((String) params[0]);
|
|
1225
|
+
FileOutputStream stream = null;
|
|
1226
|
+
byte[] content = (byte[]) params[1];
|
|
1227
|
+
|
|
1228
|
+
try {
|
|
1229
|
+
stream = new FileOutputStream(javaFile, true);
|
|
1230
|
+
stream.write(content, 0, content.length);
|
|
1231
|
+
|
|
1232
|
+
return true;
|
|
1233
|
+
} catch (FileNotFoundException e) {
|
|
1234
|
+
Log.e(TAG, "Failed to append file, FileNotFoundException: " + e.getMessage());
|
|
1235
|
+
return false;
|
|
1236
|
+
} catch (IOException e) {
|
|
1237
|
+
Log.e(TAG, "Failed to write file, IOException: " + e.getMessage());
|
|
1238
|
+
return false;
|
|
1239
|
+
} finally {
|
|
1240
|
+
if (stream != null) {
|
|
1241
|
+
try {
|
|
1242
|
+
stream.close();
|
|
1243
|
+
} catch (IOException e) {
|
|
1244
|
+
Log.e(TAG, "Failed to close stream, IOException: " + e.getMessage());
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
protected void onPostExecute(final boolean result) {
|
|
1251
|
+
if (result) {
|
|
1252
|
+
this.callback.onComplete(null, this.context);
|
|
1253
|
+
} else {
|
|
1254
|
+
this.callback.onError("AppendTask returns no result.", this.context);
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
static class AppendBufferTask {
|
|
1260
|
+
private final CompleteCallback callback;
|
|
1261
|
+
private final Object context;
|
|
1262
|
+
|
|
1263
|
+
public AppendBufferTask(CompleteCallback callback, Object context) {
|
|
1264
|
+
this.callback = callback;
|
|
1265
|
+
this.context = context;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
protected boolean doInBackground(Object... params) {
|
|
1269
|
+
java.io.File javaFile = new java.io.File((String) params[0]);
|
|
1270
|
+
FileOutputStream stream = null;
|
|
1271
|
+
ByteBuffer content = (ByteBuffer) params[1];
|
|
1272
|
+
|
|
1273
|
+
try {
|
|
1274
|
+
stream = new FileOutputStream(javaFile, true);
|
|
1275
|
+
FileChannel channel = stream.getChannel();
|
|
1276
|
+
content.rewind();
|
|
1277
|
+
channel.write(content);
|
|
1278
|
+
content.rewind();
|
|
1279
|
+
return true;
|
|
1280
|
+
} catch (FileNotFoundException e) {
|
|
1281
|
+
Log.e(TAG, "Failed to append to file, FileNotFoundException: " + e.getMessage());
|
|
1282
|
+
return false;
|
|
1283
|
+
} catch (IOException e) {
|
|
1284
|
+
Log.e(TAG, "Failed to append file, IOException: " + e.getMessage());
|
|
1285
|
+
return false;
|
|
1286
|
+
} finally {
|
|
1287
|
+
if (stream != null) {
|
|
1288
|
+
try {
|
|
1289
|
+
stream.close();
|
|
1290
|
+
} catch (IOException e) {
|
|
1291
|
+
Log.e(TAG, "Failed to close stream, IOException: " + e.getMessage());
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
protected void onPostExecute(final boolean result) {
|
|
1298
|
+
if (result) {
|
|
1299
|
+
this.callback.onComplete(null, this.context);
|
|
1300
|
+
} else {
|
|
1301
|
+
this.callback.onError("AppendTask returns no result.", this.context);
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
static class AppendTextTask {
|
|
1307
|
+
private final CompleteCallback callback;
|
|
1308
|
+
private final Object context;
|
|
1309
|
+
|
|
1310
|
+
public AppendTextTask(CompleteCallback callback, Object context) {
|
|
1311
|
+
this.callback = callback;
|
|
1312
|
+
this.context = context;
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
protected boolean doInBackground(String... params) {
|
|
1316
|
+
java.io.File javaFile = new java.io.File(params[0]);
|
|
1317
|
+
FileOutputStream stream = null;
|
|
1318
|
+
try {
|
|
1319
|
+
stream = new FileOutputStream(javaFile, true);
|
|
1320
|
+
|
|
1321
|
+
OutputStreamWriter writer = new OutputStreamWriter(stream, params[2]);
|
|
1322
|
+
writer.write(params[1]);
|
|
1323
|
+
writer.close();
|
|
1324
|
+
|
|
1325
|
+
return true;
|
|
1326
|
+
} catch (FileNotFoundException e) {
|
|
1327
|
+
Log.e(TAG, "Failed to append file, FileNotFoundException: " + e.getMessage());
|
|
1328
|
+
return false;
|
|
1329
|
+
} catch (UnsupportedEncodingException e) {
|
|
1330
|
+
Log.e(TAG, "Failed to append file, UnsupportedEncodingException: " + e.getMessage());
|
|
1331
|
+
return false;
|
|
1332
|
+
} catch (IOException e) {
|
|
1333
|
+
Log.e(TAG, "Failed to append file, IOException: " + e.getMessage());
|
|
1334
|
+
return false;
|
|
1335
|
+
} finally {
|
|
1336
|
+
if (stream != null) {
|
|
1337
|
+
try {
|
|
1338
|
+
stream.close();
|
|
1339
|
+
} catch (IOException e) {
|
|
1340
|
+
Log.e(TAG, "Failed to close stream, IOException: " + e.getMessage());
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
protected void onPostExecute(final boolean result) {
|
|
1347
|
+
if (result) {
|
|
1348
|
+
this.callback.onComplete(null, this.context);
|
|
1349
|
+
} else {
|
|
1350
|
+
this.callback.onError("AppendTextTask returns no result.", this.context);
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
}
|
|
1356
|
+
}
|