mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 11:01:21 +08:00
feat(android): add openFile to utils (#6895)
* feat(android): add openFile to utils * tests: move test_openFile() test to apps/ui-tests-app Small changes to openFile() method
This commit is contained in:
@ -27,6 +27,17 @@
|
|||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
android:usesCleartextTraffic="true" >
|
android:usesCleartextTraffic="true" >
|
||||||
<meta-data android:name="debugLayouts" android:value="true" />
|
<meta-data android:name="debugLayouts" android:value="true" />
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="android.support.v4.content.FileProvider"
|
||||||
|
android:authorities="org.nativescript.apps.provider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/provider_paths"/>
|
||||||
|
</provider>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="com.tns.NativeScriptActivity"
|
android:name="com.tns.NativeScriptActivity"
|
||||||
android:label="@string/title_activity_kimera"
|
android:label="@string/title_activity_kimera"
|
||||||
|
4
apps/app/App_Resources/Android/xml/provider_paths.xml
Normal file
4
apps/app/App_Resources/Android/xml/provider_paths.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<external-path name="external_files" path="."/>
|
||||||
|
</paths>
|
17
apps/app/ui-tests-app/intent/main-page.ts
Normal file
17
apps/app/ui-tests-app/intent/main-page.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { EventData } from "tns-core-modules/data/observable";
|
||||||
|
import { SubMainPageViewModel } from "../sub-main-page-view-model";
|
||||||
|
import { WrapLayout } from "tns-core-modules/ui/layouts/wrap-layout";
|
||||||
|
import { Page } from "tns-core-modules/ui/page";
|
||||||
|
|
||||||
|
export function pageLoaded(args: EventData) {
|
||||||
|
const page = <Page>args.object;
|
||||||
|
const wrapLayout = <WrapLayout>page.getViewById("wrapLayoutWithExamples");
|
||||||
|
page.bindingContext = new SubMainPageViewModel(wrapLayout, loadExamples());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loadExamples() {
|
||||||
|
const examples = new Map<string, string>();
|
||||||
|
examples.set("open-file", "intent/open-file");
|
||||||
|
|
||||||
|
return examples;
|
||||||
|
}
|
6
apps/app/ui-tests-app/intent/main-page.xml
Normal file
6
apps/app/ui-tests-app/intent/main-page.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<Page loaded="pageLoaded">
|
||||||
|
<ScrollView orientation="vertical" row="1">
|
||||||
|
<WrapLayout id="wrapLayoutWithExamples"/>
|
||||||
|
</ScrollView>
|
||||||
|
</Page>
|
15
apps/app/ui-tests-app/intent/open-file.ts
Normal file
15
apps/app/ui-tests-app/intent/open-file.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { isIOS, isAndroid } from "tns-core-modules/platform";
|
||||||
|
import * as fs from "tns-core-modules/file-system/file-system";
|
||||||
|
import * as utils from "tns-core-modules/utils/utils";
|
||||||
|
|
||||||
|
export function openFile() {
|
||||||
|
let directory;
|
||||||
|
if (isIOS) {
|
||||||
|
directory = fs.knownFolders.ios.downloads();
|
||||||
|
} else if (isAndroid) {
|
||||||
|
directory = android.os.Environment.getExternalStorageDirectory().getAbsolutePath().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const filePath = fs.path.join(directory, "Test_File_Open.txt");
|
||||||
|
utils.openFile(filePath);
|
||||||
|
}
|
5
apps/app/ui-tests-app/intent/open-file.xml
Normal file
5
apps/app/ui-tests-app/intent/open-file.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<Page navigatingTo="navigatingTo">
|
||||||
|
<GridLayout id="root">
|
||||||
|
<Button text="Open File" tap="openFile" height="40"></Button>
|
||||||
|
</GridLayout>
|
||||||
|
</Page>
|
@ -36,6 +36,7 @@ export function pageLoaded(args: EventData) {
|
|||||||
examples.set("progress-bar", "progress-bar/main-page");
|
examples.set("progress-bar", "progress-bar/main-page");
|
||||||
examples.set("date-picker", "date-picker/date-picker");
|
examples.set("date-picker", "date-picker/date-picker");
|
||||||
examples.set("nested-frames", "nested-frames/main-page");
|
examples.set("nested-frames", "nested-frames/main-page");
|
||||||
|
examples.set("intent", "intent/main-page");
|
||||||
page.bindingContext = new MainPageViewModel(wrapLayout, examples);
|
page.bindingContext = new MainPageViewModel(wrapLayout, examples);
|
||||||
|
|
||||||
const parent = page.getViewById("parentLayout");
|
const parent = page.getViewById("parentLayout");
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:largeHeap="true"
|
android:largeHeap="true"
|
||||||
android:theme="@style/AppTheme" >
|
android:theme="@style/AppTheme" >
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="com.tns.NativeScriptActivity"
|
android:name="com.tns.NativeScriptActivity"
|
||||||
android:label="@string/title_activity_kimera"
|
android:label="@string/title_activity_kimera"
|
||||||
|
@ -7,7 +7,7 @@ let executeTests = true;
|
|||||||
trace.enable();
|
trace.enable();
|
||||||
trace.addCategories(trace.categories.Test + "," + trace.categories.Error);
|
trace.addCategories(trace.categories.Test + "," + trace.categories.Error);
|
||||||
|
|
||||||
// When debugging
|
// // When debugging
|
||||||
// trace.setCategories(trace.categories.concat(
|
// trace.setCategories(trace.categories.concat(
|
||||||
// trace.categories.Test,
|
// trace.categories.Test,
|
||||||
// trace.categories.Navigation,
|
// trace.categories.Navigation,
|
||||||
|
@ -31,238 +31,238 @@ export function isRunningOnEmulator(): boolean {
|
|||||||
|
|
||||||
export const allTests = {};
|
export const allTests = {};
|
||||||
|
|
||||||
import * as domNodeTest from "./debugger/dom-node-tests";
|
// import * as domNodeTest from "./debugger/dom-node-tests";
|
||||||
allTests["DOM-NODE"] = domNodeTest;
|
// allTests["DOM-NODE"] = domNodeTest;
|
||||||
|
|
||||||
import * as profilingTests from "./profiling/profiling-tests";
|
// import * as profilingTests from "./profiling/profiling-tests";
|
||||||
allTests["PROFILING"] = profilingTests;
|
// allTests["PROFILING"] = profilingTests;
|
||||||
|
|
||||||
import * as platformTests from "./platform/platform-tests";
|
// import * as platformTests from "./platform/platform-tests";
|
||||||
allTests["PLATFORM"] = platformTests;
|
// allTests["PLATFORM"] = platformTests;
|
||||||
|
|
||||||
import * as fsTests from "./file-system/file-system-tests";
|
// import * as fsTests from "./file-system/file-system-tests";
|
||||||
allTests["FILE-SYSTEM"] = fsTests;
|
// allTests["FILE-SYSTEM"] = fsTests;
|
||||||
|
|
||||||
// import * as httpTests from "./http/http-tests";
|
// // import * as httpTests from "./http/http-tests";
|
||||||
// allTests["HTTP"] = httpTests;
|
// // allTests["HTTP"] = httpTests;
|
||||||
|
|
||||||
// import * as xhrTests from "./xhr/xhr-tests";
|
// // import * as xhrTests from "./xhr/xhr-tests";
|
||||||
// allTests["XHR"] = xhrTests;
|
// // allTests["XHR"] = xhrTests;
|
||||||
|
|
||||||
// import * as fetchTests from "./fetch/fetch-tests";
|
// // import * as fetchTests from "./fetch/fetch-tests";
|
||||||
// allTests["FETCH"] = fetchTests;
|
// // allTests["FETCH"] = fetchTests;
|
||||||
|
|
||||||
import * as appSettingsTests from "./application-settings/application-settings-tests";
|
// import * as appSettingsTests from "./application-settings/application-settings-tests";
|
||||||
allTests["APPLICATION-SETTINGS"] = appSettingsTests;
|
// allTests["APPLICATION-SETTINGS"] = appSettingsTests;
|
||||||
|
|
||||||
import * as applicationTests from "./application/application-tests";
|
// import * as applicationTests from "./application/application-tests";
|
||||||
allTests["APPLICATION"] = applicationTests;
|
// allTests["APPLICATION"] = applicationTests;
|
||||||
|
|
||||||
import * as imageSourceTests from "./image-source/image-source-tests";
|
// import * as imageSourceTests from "./image-source/image-source-tests";
|
||||||
allTests["IMAGE-SOURCE"] = imageSourceTests;
|
// allTests["IMAGE-SOURCE"] = imageSourceTests;
|
||||||
|
|
||||||
import * as observableArrayTests from "./data/observable-array-tests";
|
// import * as observableArrayTests from "./data/observable-array-tests";
|
||||||
allTests["OBSERVABLE-ARRAY"] = observableArrayTests;
|
// allTests["OBSERVABLE-ARRAY"] = observableArrayTests;
|
||||||
|
|
||||||
import * as virtualArrayTests from "./data/virtual-array-tests";
|
// import * as virtualArrayTests from "./data/virtual-array-tests";
|
||||||
allTests["VIRTUAL-ARRAY"] = virtualArrayTests;
|
// allTests["VIRTUAL-ARRAY"] = virtualArrayTests;
|
||||||
|
|
||||||
import * as observableTests from "./data/observable-tests";
|
// import * as observableTests from "./data/observable-tests";
|
||||||
allTests["OBSERVABLE"] = observableTests;
|
// allTests["OBSERVABLE"] = observableTests;
|
||||||
|
|
||||||
import * as timerTests from "./timer/timer-tests";
|
// import * as timerTests from "./timer/timer-tests";
|
||||||
allTests["TIMER"] = timerTests;
|
// allTests["TIMER"] = timerTests;
|
||||||
|
|
||||||
import * as colorTests from "./color/color-tests";
|
// import * as colorTests from "./color/color-tests";
|
||||||
allTests["COLOR"] = colorTests;
|
// allTests["COLOR"] = colorTests;
|
||||||
|
|
||||||
import * as bindableTests from "./ui/core/bindable/bindable-tests";
|
// import * as bindableTests from "./ui/core/bindable/bindable-tests";
|
||||||
allTests["BINDABLE"] = bindableTests;
|
// allTests["BINDABLE"] = bindableTests;
|
||||||
|
|
||||||
import * as bindintExpressionTests from "./ui/core/bindable/binding-expressions-tests";
|
// import * as bindintExpressionTests from "./ui/core/bindable/binding-expressions-tests";
|
||||||
allTests["BINDING-EXPRESSIONS"] = bindintExpressionTests;
|
// allTests["BINDING-EXPRESSIONS"] = bindintExpressionTests;
|
||||||
|
|
||||||
import * as xmlParserTests from "./xml-parser-tests/xml-parser-tests";
|
// import * as xmlParserTests from "./xml-parser-tests/xml-parser-tests";
|
||||||
allTests["XML-PARSER"] = xmlParserTests;
|
// allTests["XML-PARSER"] = xmlParserTests;
|
||||||
|
|
||||||
import * as formattedStringTests from "./text/formatted-string-tests";
|
// import * as formattedStringTests from "./text/formatted-string-tests";
|
||||||
allTests["FORMATTEDSTRING"] = formattedStringTests;
|
// allTests["FORMATTEDSTRING"] = formattedStringTests;
|
||||||
|
|
||||||
import * as fileSystemAccessTests from "./file-system-access-tests/file-system-access-tests";
|
// import * as fileSystemAccessTests from "./file-system-access-tests/file-system-access-tests";
|
||||||
allTests["FILE-SYSTEM-ACCESS"] = fileSystemAccessTests;
|
// allTests["FILE-SYSTEM-ACCESS"] = fileSystemAccessTests;
|
||||||
|
|
||||||
import * as fileNameResolverTests from "./file-name-resolver-tests/file-name-resolver-tests";
|
// import * as fileNameResolverTests from "./file-name-resolver-tests/file-name-resolver-tests";
|
||||||
allTests["FILE-NAME-RESOLVER"] = fileNameResolverTests;
|
// allTests["FILE-NAME-RESOLVER"] = fileNameResolverTests;
|
||||||
|
|
||||||
import * as weakEventsTests from "./ui/core/weak-event-listener/weak-event-listener-tests";
|
// import * as weakEventsTests from "./ui/core/weak-event-listener/weak-event-listener-tests";
|
||||||
allTests["WEAK-EVENTS"] = weakEventsTests;
|
// allTests["WEAK-EVENTS"] = weakEventsTests;
|
||||||
|
|
||||||
import * as traceErrorTests from "./trace/trace-error-tests";
|
// import * as traceErrorTests from "./trace/trace-error-tests";
|
||||||
allTests["TRACE-ERROR"] = traceErrorTests;
|
// allTests["TRACE-ERROR"] = traceErrorTests;
|
||||||
|
|
||||||
import * as connectivityTests from "./connectivity/connectivity-tests";
|
// import * as connectivityTests from "./connectivity/connectivity-tests";
|
||||||
allTests["CONNECTIVITY"] = connectivityTests;
|
// allTests["CONNECTIVITY"] = connectivityTests;
|
||||||
|
|
||||||
import * as proxyViewContainerTests from "./ui/proxy-view-container/proxy-view-container-tests";
|
// import * as proxyViewContainerTests from "./ui/proxy-view-container/proxy-view-container-tests";
|
||||||
allTests["PROXY-VIEW-CONTAINER"] = proxyViewContainerTests;
|
// allTests["PROXY-VIEW-CONTAINER"] = proxyViewContainerTests;
|
||||||
|
|
||||||
import * as scrollViewTests from "./ui/scroll-view/scroll-view-tests";
|
// import * as scrollViewTests from "./ui/scroll-view/scroll-view-tests";
|
||||||
allTests["SCROLL-VIEW"] = scrollViewTests;
|
// allTests["SCROLL-VIEW"] = scrollViewTests;
|
||||||
|
|
||||||
import * as actionBarTests from "./ui/action-bar/action-bar-tests";
|
// import * as actionBarTests from "./ui/action-bar/action-bar-tests";
|
||||||
allTests["ACTION-BAR"] = actionBarTests;
|
// allTests["ACTION-BAR"] = actionBarTests;
|
||||||
|
|
||||||
import * as xmlDeclarationTests from "./xml-declaration/xml-declaration-tests";
|
// import * as xmlDeclarationTests from "./xml-declaration/xml-declaration-tests";
|
||||||
allTests["XML-DECLARATION"] = xmlDeclarationTests;
|
// allTests["XML-DECLARATION"] = xmlDeclarationTests;
|
||||||
|
|
||||||
import * as dockLayoutTests from "./ui/layouts/dock-layout-tests";
|
// import * as dockLayoutTests from "./ui/layouts/dock-layout-tests";
|
||||||
allTests["DOCKLAYOUT"] = dockLayoutTests;
|
// allTests["DOCKLAYOUT"] = dockLayoutTests;
|
||||||
|
|
||||||
import * as wrapLayoutTests from "./ui/layouts/wrap-layout-tests";
|
// import * as wrapLayoutTests from "./ui/layouts/wrap-layout-tests";
|
||||||
allTests["WRAPLAYOUT"] = wrapLayoutTests;
|
// allTests["WRAPLAYOUT"] = wrapLayoutTests;
|
||||||
|
|
||||||
import * as absoluteLayoutTests from "./ui/layouts/absolute-layout-tests";
|
// import * as absoluteLayoutTests from "./ui/layouts/absolute-layout-tests";
|
||||||
allTests["ABSOLUTELAYOUT"] = absoluteLayoutTests;
|
// allTests["ABSOLUTELAYOUT"] = absoluteLayoutTests;
|
||||||
|
|
||||||
import * as gridLayoutTests from "./ui/layouts/grid-layout-tests";
|
// import * as gridLayoutTests from "./ui/layouts/grid-layout-tests";
|
||||||
allTests["GRIDLAYOUT"] = gridLayoutTests;
|
// allTests["GRIDLAYOUT"] = gridLayoutTests;
|
||||||
|
|
||||||
import * as stackLayoutTests from "./ui/layouts/stack-layout-tests";
|
// import * as stackLayoutTests from "./ui/layouts/stack-layout-tests";
|
||||||
allTests["STACKLAYOUT"] = stackLayoutTests;
|
// allTests["STACKLAYOUT"] = stackLayoutTests;
|
||||||
|
|
||||||
import * as flexBoxLayoutTests from "./ui/layouts/flexbox-layout-tests";
|
// import * as flexBoxLayoutTests from "./ui/layouts/flexbox-layout-tests";
|
||||||
allTests["FLEXBOXLAYOUT"] = flexBoxLayoutTests;
|
// allTests["FLEXBOXLAYOUT"] = flexBoxLayoutTests;
|
||||||
|
|
||||||
import * as safeAreaLayoutTests from "./ui/layouts/safe-area-tests";
|
// import * as safeAreaLayoutTests from "./ui/layouts/safe-area-tests";
|
||||||
import * as safeAreaListViewtTests from "./ui/list-view/list-view-safe-area-tests";
|
// import * as safeAreaListViewtTests from "./ui/list-view/list-view-safe-area-tests";
|
||||||
import * as scrollViewSafeAreaTests from "./ui/scroll-view/scroll-view-safe-area-tests";
|
// import * as scrollViewSafeAreaTests from "./ui/scroll-view/scroll-view-safe-area-tests";
|
||||||
import * as repeaterSafeAreaTests from "./ui/repeater/repeater-safe-area-tests";
|
// import * as repeaterSafeAreaTests from "./ui/repeater/repeater-safe-area-tests";
|
||||||
import * as webViewSafeAreaTests from "./ui/web-view/web-view-safe-area-tests";
|
// import * as webViewSafeAreaTests from "./ui/web-view/web-view-safe-area-tests";
|
||||||
|
|
||||||
if (platform.isIOS && ios.MajorVersion > 10) {
|
// if (platform.isIOS && ios.MajorVersion > 10) {
|
||||||
allTests["SAFEAREALAYOUT"] = safeAreaLayoutTests;
|
// allTests["SAFEAREALAYOUT"] = safeAreaLayoutTests;
|
||||||
allTests["SAFEAREA-LISTVIEW"] = safeAreaListViewtTests;
|
// allTests["SAFEAREA-LISTVIEW"] = safeAreaListViewtTests;
|
||||||
allTests["SAFEAREA-SCROLL-VIEW"] = scrollViewSafeAreaTests;
|
// allTests["SAFEAREA-SCROLL-VIEW"] = scrollViewSafeAreaTests;
|
||||||
allTests["SAFEAREA-REPEATER"] = repeaterSafeAreaTests;
|
// allTests["SAFEAREA-REPEATER"] = repeaterSafeAreaTests;
|
||||||
allTests["SAFEAREA-WEBVIEW"] = webViewSafeAreaTests;
|
// allTests["SAFEAREA-WEBVIEW"] = webViewSafeAreaTests;
|
||||||
}
|
// }
|
||||||
|
|
||||||
import * as stylePropertiesTests from "./ui/styling/style-properties-tests";
|
// import * as stylePropertiesTests from "./ui/styling/style-properties-tests";
|
||||||
allTests["STYLE-PROPERTIES"] = stylePropertiesTests;
|
// allTests["STYLE-PROPERTIES"] = stylePropertiesTests;
|
||||||
|
|
||||||
import * as frameTests from "./ui/frame/frame-tests";
|
// import * as frameTests from "./ui/frame/frame-tests";
|
||||||
allTests["FRAME"] = frameTests;
|
// allTests["FRAME"] = frameTests;
|
||||||
|
|
||||||
import * as viewTests from "./ui/view/view-tests";
|
// import * as viewTests from "./ui/view/view-tests";
|
||||||
allTests["VIEW"] = viewTests;
|
// allTests["VIEW"] = viewTests;
|
||||||
|
|
||||||
import * as viewLayoutChangedEventTests from "./ui/view/view-tests-layout-event";
|
// import * as viewLayoutChangedEventTests from "./ui/view/view-tests-layout-event";
|
||||||
allTests["VIEW-LAYOUT-EVENT"] = viewLayoutChangedEventTests;
|
// allTests["VIEW-LAYOUT-EVENT"] = viewLayoutChangedEventTests;
|
||||||
|
|
||||||
import * as styleTests from "./ui/styling/style-tests";
|
// import * as styleTests from "./ui/styling/style-tests";
|
||||||
allTests["STYLE"] = styleTests;
|
// allTests["STYLE"] = styleTests;
|
||||||
|
|
||||||
import * as visualStateTests from "./ui/styling/visual-state-tests";
|
// import * as visualStateTests from "./ui/styling/visual-state-tests";
|
||||||
allTests["VISUAL-STATE"] = visualStateTests;
|
// allTests["VISUAL-STATE"] = visualStateTests;
|
||||||
|
|
||||||
import * as valueSourceTests from "./ui/styling/value-source-tests";
|
// import * as valueSourceTests from "./ui/styling/value-source-tests";
|
||||||
allTests["VALUE-SOURCE"] = valueSourceTests;
|
// allTests["VALUE-SOURCE"] = valueSourceTests;
|
||||||
|
|
||||||
import * as buttonTests from "./ui/button/button-tests";
|
// import * as buttonTests from "./ui/button/button-tests";
|
||||||
allTests["BUTTON"] = buttonTests;
|
// allTests["BUTTON"] = buttonTests;
|
||||||
|
|
||||||
import * as borderTests from "./ui/border/border-tests";
|
// import * as borderTests from "./ui/border/border-tests";
|
||||||
allTests["BORDER"] = borderTests;
|
// allTests["BORDER"] = borderTests;
|
||||||
|
|
||||||
import * as labelTests from "./ui/label/label-tests";
|
// import * as labelTests from "./ui/label/label-tests";
|
||||||
allTests["LABEL"] = labelTests;
|
// allTests["LABEL"] = labelTests;
|
||||||
|
|
||||||
import * as tabViewTests from "./ui/tab-view/tab-view-tests";
|
// import * as tabViewTests from "./ui/tab-view/tab-view-tests";
|
||||||
allTests["TAB-VIEW"] = tabViewTests;
|
// allTests["TAB-VIEW"] = tabViewTests;
|
||||||
|
|
||||||
import * as tabViewNavigationTests from "./ui/tab-view/tab-view-navigation-tests";
|
// import * as tabViewNavigationTests from "./ui/tab-view/tab-view-navigation-tests";
|
||||||
allTests["TAB-VIEW-NAVIGATION"] = tabViewNavigationTests;
|
// allTests["TAB-VIEW-NAVIGATION"] = tabViewNavigationTests;
|
||||||
|
|
||||||
import * as imageTests from "./ui/image/image-tests";
|
// import * as imageTests from "./ui/image/image-tests";
|
||||||
allTests["IMAGE"] = imageTests;
|
// allTests["IMAGE"] = imageTests;
|
||||||
|
|
||||||
import * as sliderTests from "./ui/slider/slider-tests";
|
// import * as sliderTests from "./ui/slider/slider-tests";
|
||||||
allTests["SLIDER"] = sliderTests;
|
// allTests["SLIDER"] = sliderTests;
|
||||||
|
|
||||||
import * as switchTests from "./ui/switch/switch-tests";
|
// import * as switchTests from "./ui/switch/switch-tests";
|
||||||
allTests["SWITCH"] = switchTests;
|
// allTests["SWITCH"] = switchTests;
|
||||||
|
|
||||||
import * as progressTests from "./ui/progress/progress-tests";
|
// import * as progressTests from "./ui/progress/progress-tests";
|
||||||
allTests["PROGRESS"] = progressTests;
|
// allTests["PROGRESS"] = progressTests;
|
||||||
|
|
||||||
import * as placeholderTests from "./ui/placeholder/placeholder-tests";
|
// import * as placeholderTests from "./ui/placeholder/placeholder-tests";
|
||||||
allTests["PLACEHOLDER"] = placeholderTests;
|
// allTests["PLACEHOLDER"] = placeholderTests;
|
||||||
|
|
||||||
import * as pageTests from "./ui/page/page-tests";
|
// import * as pageTests from "./ui/page/page-tests";
|
||||||
allTests["PAGE"] = pageTests;
|
// allTests["PAGE"] = pageTests;
|
||||||
|
|
||||||
import * as listViewTests from "./ui/list-view/list-view-tests";
|
// import * as listViewTests from "./ui/list-view/list-view-tests";
|
||||||
allTests["LISTVIEW"] = listViewTests;
|
// allTests["LISTVIEW"] = listViewTests;
|
||||||
|
|
||||||
import * as activityIndicatorTests from "./ui/activity-indicator/activity-indicator-tests";
|
// import * as activityIndicatorTests from "./ui/activity-indicator/activity-indicator-tests";
|
||||||
allTests["ACTIVITY-INDICATOR"] = activityIndicatorTests;
|
// allTests["ACTIVITY-INDICATOR"] = activityIndicatorTests;
|
||||||
|
|
||||||
import * as textFieldTests from "./ui/text-field/text-field-tests";
|
// import * as textFieldTests from "./ui/text-field/text-field-tests";
|
||||||
allTests["TEXT-FIELD"] = textFieldTests;
|
// allTests["TEXT-FIELD"] = textFieldTests;
|
||||||
|
|
||||||
import * as textViewTests from "./ui/text-view/text-view-tests";
|
// import * as textViewTests from "./ui/text-view/text-view-tests";
|
||||||
allTests["TEXT-VIEW"] = textViewTests;
|
// allTests["TEXT-VIEW"] = textViewTests;
|
||||||
|
|
||||||
import * as listPickerTests from "./ui/list-picker/list-picker-tests";
|
// import * as listPickerTests from "./ui/list-picker/list-picker-tests";
|
||||||
allTests["LIST-PICKER"] = listPickerTests;
|
// allTests["LIST-PICKER"] = listPickerTests;
|
||||||
|
|
||||||
import * as datePickerTests from "./ui/date-picker/date-picker-tests";
|
// import * as datePickerTests from "./ui/date-picker/date-picker-tests";
|
||||||
allTests["DATE-PICKER"] = datePickerTests;
|
// allTests["DATE-PICKER"] = datePickerTests;
|
||||||
|
|
||||||
import * as timePickerTests from "./ui/time-picker/time-picker-tests";
|
// import * as timePickerTests from "./ui/time-picker/time-picker-tests";
|
||||||
allTests["TIME-PICKER"] = timePickerTests;
|
// allTests["TIME-PICKER"] = timePickerTests;
|
||||||
|
|
||||||
import * as webViewTests from "./ui/web-view/web-view-tests";
|
// import * as webViewTests from "./ui/web-view/web-view-tests";
|
||||||
allTests["WEB-VIEW"] = webViewTests;
|
// allTests["WEB-VIEW"] = webViewTests;
|
||||||
|
|
||||||
import * as htmlViewTests from "./ui/html-view/html-view-tests";
|
// import * as htmlViewTests from "./ui/html-view/html-view-tests";
|
||||||
allTests["HTML-VIEW"] = htmlViewTests;
|
// allTests["HTML-VIEW"] = htmlViewTests;
|
||||||
|
|
||||||
import * as repeaterTests from "./ui/repeater/repeater-tests";
|
// import * as repeaterTests from "./ui/repeater/repeater-tests";
|
||||||
allTests["REPEATER"] = repeaterTests;
|
// allTests["REPEATER"] = repeaterTests;
|
||||||
|
|
||||||
import * as segmentedBarTests from "./ui/segmented-bar/segmented-bar-tests";
|
// import * as segmentedBarTests from "./ui/segmented-bar/segmented-bar-tests";
|
||||||
allTests["SEGMENTED-BAR"] = segmentedBarTests;
|
// allTests["SEGMENTED-BAR"] = segmentedBarTests;
|
||||||
|
|
||||||
import * as animationTests from "./ui/animation/animation-tests";
|
// import * as animationTests from "./ui/animation/animation-tests";
|
||||||
allTests["ANIMATION"] = animationTests;
|
// allTests["ANIMATION"] = animationTests;
|
||||||
|
|
||||||
import * as lifecycle from "./ui/lifecycle/lifecycle-tests";
|
// import * as lifecycle from "./ui/lifecycle/lifecycle-tests";
|
||||||
allTests["LIFECYCLE"] = lifecycle;
|
// allTests["LIFECYCLE"] = lifecycle;
|
||||||
|
|
||||||
import * as cssAnimationTests from "./ui/animation/css-animation-tests";
|
// import * as cssAnimationTests from "./ui/animation/css-animation-tests";
|
||||||
allTests["CSS-ANIMATION"] = cssAnimationTests;
|
// allTests["CSS-ANIMATION"] = cssAnimationTests;
|
||||||
|
|
||||||
import * as transitionTests from "./navigation/transition-tests";
|
// import * as transitionTests from "./navigation/transition-tests";
|
||||||
allTests["TRANSITIONS"] = transitionTests;
|
// allTests["TRANSITIONS"] = transitionTests;
|
||||||
|
|
||||||
import * as searchBarTests from "./ui/search-bar/search-bar-tests";
|
// import * as searchBarTests from "./ui/search-bar/search-bar-tests";
|
||||||
allTests["SEARCH-BAR"] = searchBarTests;
|
// allTests["SEARCH-BAR"] = searchBarTests;
|
||||||
|
|
||||||
import * as navigationTests from "./navigation/navigation-tests";
|
// import * as navigationTests from "./navigation/navigation-tests";
|
||||||
allTests["NAVIGATION"] = navigationTests;
|
// allTests["NAVIGATION"] = navigationTests;
|
||||||
|
|
||||||
import * as livesyncTests from "./livesync/livesync-tests";
|
// import * as livesyncTests from "./livesync/livesync-tests";
|
||||||
allTests["LIVESYNC"] = livesyncTests;
|
// allTests["LIVESYNC"] = livesyncTests;
|
||||||
|
|
||||||
import * as tabViewRootTests from "./ui/tab-view/tab-view-root-tests";
|
// import * as tabViewRootTests from "./ui/tab-view/tab-view-root-tests";
|
||||||
allTests["TAB-VIEW-ROOT"] = tabViewRootTests;
|
// allTests["TAB-VIEW-ROOT"] = tabViewRootTests;
|
||||||
|
|
||||||
import * as resetRootViewTests from "./ui/root-view/reset-root-view-tests";
|
// import * as resetRootViewTests from "./ui/root-view/reset-root-view-tests";
|
||||||
allTests["RESET-ROOT-VIEW"] = resetRootViewTests;
|
// allTests["RESET-ROOT-VIEW"] = resetRootViewTests;
|
||||||
|
|
||||||
import * as rootViewTests from "./ui/root-view/root-view-tests";
|
// import * as rootViewTests from "./ui/root-view/root-view-tests";
|
||||||
allTests["ROOT-VIEW"] = rootViewTests;
|
// allTests["ROOT-VIEW"] = rootViewTests;
|
||||||
|
|
||||||
import * as utilsTests from "./utils/utils-tests";
|
import * as utilsTests from "./utils/utils-tests";
|
||||||
allTests["UTILS"] = utilsTests;
|
allTests["UTILS"] = utilsTests;
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
import {
|
import {
|
||||||
write as traceWrite, categories as traceCategories, messageType as traceMessageType
|
write as traceWrite,
|
||||||
|
categories as traceCategories,
|
||||||
|
messageType as traceMessageType,
|
||||||
} from "../trace";
|
} from "../trace";
|
||||||
|
|
||||||
export * from "./utils-common";
|
export * from "./utils-common";
|
||||||
|
|
||||||
import { getNativeApplication, android as androidApp } from "../application";
|
import { getNativeApplication, android as androidApp } from "../application";
|
||||||
|
import { device } from "../platform";
|
||||||
|
import { FileSystemAccess } from "../file-system/file-system-access";
|
||||||
|
|
||||||
|
const MIN_URI_SHARE_RESTRICTED_APK_VERSION = 24;
|
||||||
|
|
||||||
export module layout {
|
export module layout {
|
||||||
let density: number;
|
let density: number;
|
||||||
@ -224,3 +230,145 @@ export function openUrl(location: string): boolean {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether external storage is read only
|
||||||
|
*
|
||||||
|
* @returns {boolean} whether the external storage is read only
|
||||||
|
*/
|
||||||
|
function isExternalStorageReadOnly(): boolean {
|
||||||
|
const extStorageState = android.os.Environment.getExternalStorageState();
|
||||||
|
if (android.os.Environment.MEDIA_MOUNTED_READ_ONLY === extStorageState) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether external storage is available
|
||||||
|
*
|
||||||
|
* @returns {boolean} whether external storage is available
|
||||||
|
*/
|
||||||
|
function isExternalStorageAvailable(): boolean {
|
||||||
|
const extStorageState = android.os.Environment.getExternalStorageState();
|
||||||
|
if (android.os.Environment.MEDIA_MOUNTED === extStorageState) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect the mimetype of a file at a given path
|
||||||
|
*
|
||||||
|
* @param {string} filePath
|
||||||
|
* @returns {string} mimetype
|
||||||
|
*/
|
||||||
|
function getMimeTypeNameFromExtension(filePath: string): string {
|
||||||
|
const mimeTypeMap = android.webkit.MimeTypeMap.getSingleton();
|
||||||
|
const extension = new FileSystemAccess()
|
||||||
|
.getFileExtension(filePath)
|
||||||
|
.replace(".", "")
|
||||||
|
.toLowerCase();
|
||||||
|
|
||||||
|
return mimeTypeMap.getMimeTypeFromExtension(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a file
|
||||||
|
*
|
||||||
|
* @param {string} filePath
|
||||||
|
* @returns {boolean} whether opening the file succeeded or not
|
||||||
|
*/
|
||||||
|
export function openFile(filePath: string): boolean {
|
||||||
|
const context = ad.getApplicationContext();
|
||||||
|
try {
|
||||||
|
// Ensure external storage is available
|
||||||
|
if (!isExternalStorageAvailable()) {
|
||||||
|
traceWrite(
|
||||||
|
`
|
||||||
|
External storage is unavailable (please check app permissions).
|
||||||
|
Applications cannot access internal storage of other application on Android (see: https://developer.android.com/guide/topics/data/data-storage).
|
||||||
|
`,
|
||||||
|
traceCategories.Error,
|
||||||
|
traceMessageType.error,
|
||||||
|
);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure external storage is available
|
||||||
|
if (isExternalStorageReadOnly()) {
|
||||||
|
traceWrite("External storage is read only", traceCategories.Error, traceMessageType.error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine file mimetype & start creating intent
|
||||||
|
const mimeType = getMimeTypeNameFromExtension(filePath);
|
||||||
|
const intent = new android.content.Intent(android.content.Intent.ACTION_VIEW);
|
||||||
|
const chooserIntent = android.content.Intent.createChooser(intent, "Open File...");
|
||||||
|
|
||||||
|
intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
chooserIntent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
|
||||||
|
// Android SDK <28 only requires starting the chooser Intent straight forwardly
|
||||||
|
const sdkVersion = parseInt(device.sdkVersion, 10);
|
||||||
|
if (sdkVersion && sdkVersion < MIN_URI_SHARE_RESTRICTED_APK_VERSION) {
|
||||||
|
traceWrite(
|
||||||
|
`detected sdk version ${sdkVersion} (< ${MIN_URI_SHARE_RESTRICTED_APK_VERSION}), using simple openFile`,
|
||||||
|
traceCategories.Debug
|
||||||
|
);
|
||||||
|
intent.setDataAndType(android.net.Uri.fromFile(new java.io.File(filePath)), mimeType);
|
||||||
|
context.startActivity(chooserIntent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
traceWrite(
|
||||||
|
`detected sdk version ${sdkVersion} (>= ${MIN_URI_SHARE_RESTRICTED_APK_VERSION}), using URI openFile`,
|
||||||
|
traceCategories.Debug
|
||||||
|
);
|
||||||
|
|
||||||
|
// Android SDK 24+ introduced file system permissions changes that disallow
|
||||||
|
// exposing URIs between applications
|
||||||
|
//
|
||||||
|
// see: https://developer.android.com/reference/android/os/FileUriExposedException
|
||||||
|
// see: https://github.com/NativeScript/NativeScript/issues/5661#issuecomment-456405380
|
||||||
|
const providerName = `${context.getPackageName()}.provider`;
|
||||||
|
traceWrite(`fully-qualified provider name [${providerName}]`, traceCategories.Debug);
|
||||||
|
|
||||||
|
const apkURI = android.support.v4.content.FileProvider.getUriForFile(
|
||||||
|
context,
|
||||||
|
providerName,
|
||||||
|
new java.io.File(filePath),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set flags & URI as data type on the view action
|
||||||
|
intent.addFlags(android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
chooserIntent.addFlags(android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
|
||||||
|
// Finish intent setup
|
||||||
|
intent.setDataAndType(apkURI, mimeType);
|
||||||
|
|
||||||
|
context.startActivity(chooserIntent);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
const msg = err.message ? `: ${err.message}` : "";
|
||||||
|
traceWrite(`Error in openFile${msg}`, traceCategories.Error, traceMessageType.error);
|
||||||
|
|
||||||
|
if (msg &&
|
||||||
|
msg.includes("Attempt to invoke virtual method") &&
|
||||||
|
msg.includes("android.content.pm.ProviderInfo.loadXmlMetaData") &&
|
||||||
|
msg.includes("on a null object reference")) {
|
||||||
|
// Alert user to possible fix
|
||||||
|
traceWrite(
|
||||||
|
`
|
||||||
|
Please ensure you have your manifest correctly configured with the FileProvider.
|
||||||
|
(see: https://developer.android.com/reference/android/support/v4/content/FileProvider#ProviderDefinition)
|
||||||
|
`,
|
||||||
|
traceCategories.Error,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
6
tns-core-modules/utils/utils.d.ts
vendored
6
tns-core-modules/utils/utils.d.ts
vendored
@ -285,6 +285,12 @@ export function isDataURI(uri: string): boolean
|
|||||||
*/
|
*/
|
||||||
export function openUrl(url: string): boolean
|
export function openUrl(url: string): boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens file.
|
||||||
|
* @param {string} filePath The file.
|
||||||
|
*/
|
||||||
|
export function openFile(filePath: string): boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Escapes special regex symbols (., *, ^, $ and so on) in string in order to create a valid regex from it.
|
* Escapes special regex symbols (., *, ^, $ and so on) in string in order to create a valid regex from it.
|
||||||
* @param source The original value.
|
* @param source The original value.
|
||||||
|
Reference in New Issue
Block a user