├── .npmignore
├── README.md
├── background-task.android.js
├── background-task.ios.js
├── demo
├── app
│ ├── App_Resources
│ │ ├── Android
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── app.gradle
│ │ │ ├── drawable-hdpi
│ │ │ │ ├── background.png
│ │ │ │ ├── icon.png
│ │ │ │ └── logo.png
│ │ │ ├── drawable-ldpi
│ │ │ │ ├── background.png
│ │ │ │ ├── icon.png
│ │ │ │ └── logo.png
│ │ │ ├── drawable-mdpi
│ │ │ │ ├── background.png
│ │ │ │ ├── icon.png
│ │ │ │ └── logo.png
│ │ │ ├── drawable-nodpi
│ │ │ │ ├── splash_screen.xml
│ │ │ │ └── splashscreen.9.png
│ │ │ ├── drawable-xhdpi
│ │ │ │ ├── background.png
│ │ │ │ ├── icon.png
│ │ │ │ └── logo.png
│ │ │ ├── drawable-xxhdpi
│ │ │ │ ├── background.png
│ │ │ │ ├── icon.png
│ │ │ │ └── logo.png
│ │ │ ├── drawable-xxxhdpi
│ │ │ │ ├── background.png
│ │ │ │ ├── icon.png
│ │ │ │ └── logo.png
│ │ │ ├── values-v21
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ └── values
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ └── iOS
│ │ │ ├── Assets.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon-29.png
│ │ │ │ ├── icon-29@2x.png
│ │ │ │ ├── icon-29@3x.png
│ │ │ │ ├── icon-40.png
│ │ │ │ ├── icon-40@2x.png
│ │ │ │ ├── icon-40@3x.png
│ │ │ │ ├── icon-50.png
│ │ │ │ ├── icon-50@2x.png
│ │ │ │ ├── icon-57.png
│ │ │ │ ├── icon-57@2x.png
│ │ │ │ ├── icon-60@2x.png
│ │ │ │ ├── icon-60@3x.png
│ │ │ │ ├── icon-72.png
│ │ │ │ ├── icon-72@2x.png
│ │ │ │ ├── icon-76.png
│ │ │ │ ├── icon-76@2x.png
│ │ │ │ └── icon-83.5@2x.png
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.launchimage
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Default-568h@2x.png
│ │ │ │ ├── Default-667h@2x.png
│ │ │ │ ├── Default-736h@3x.png
│ │ │ │ ├── Default-Landscape.png
│ │ │ │ ├── Default-Landscape@2x.png
│ │ │ │ ├── Default-Landscape@3x.png
│ │ │ │ ├── Default-Portrait.png
│ │ │ │ ├── Default-Portrait@2x.png
│ │ │ │ ├── Default.png
│ │ │ │ └── Default@2x.png
│ │ │ ├── LaunchScreen.AspectFill.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── LaunchScreen-AspectFill.png
│ │ │ │ └── LaunchScreen-AspectFill@2x.png
│ │ │ └── LaunchScreen.Center.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── LaunchScreen-Center.png
│ │ │ │ └── LaunchScreen-Center@2x.png
│ │ │ ├── Default-568h@2x.png
│ │ │ ├── Default-667h@2x.png
│ │ │ ├── Default-736h@3x.png
│ │ │ ├── Default-Landscape-568h@2x.png
│ │ │ ├── Default-Landscape-667h@2x.png
│ │ │ ├── Default-Landscape.png
│ │ │ ├── Default-Landscape@2x.png
│ │ │ ├── Default-Landscape@3x.png
│ │ │ ├── Default-Portrait.png
│ │ │ ├── Default-Portrait@2x.png
│ │ │ ├── Default.png
│ │ │ ├── Default@2x.png
│ │ │ ├── Icon-Small-50.png
│ │ │ ├── Icon-Small-50@2x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ ├── Info.plist
│ │ │ ├── LaunchScreen.storyboard
│ │ │ ├── build.xcconfig
│ │ │ ├── icon-40.png
│ │ │ ├── icon-40@2x.png
│ │ │ ├── icon-60.png
│ │ │ ├── icon-60@2x.png
│ │ │ ├── icon-72.png
│ │ │ ├── icon-72@2x.png
│ │ │ ├── icon-76.png
│ │ │ ├── icon-76@2x.png
│ │ │ ├── icon.png
│ │ │ └── icon@2x.png
│ ├── app.css
│ ├── app.js
│ ├── main-page.js
│ ├── main-page.xml
│ ├── package.json
│ └── res
│ │ ├── big_buck_bunny.mp4
│ │ └── mobilemind.png
└── package.json
├── index.js
├── native-src
├── android
│ ├── NativescriptBackgroundTask.iml
│ ├── NativescriptBackgroundTask
│ │ └── .idea
│ │ │ └── workspace.xml
│ ├── android.iml
│ ├── app
│ │ ├── .gitignore
│ │ ├── app.iml
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ ├── release
│ │ │ └── MobileMindNSTaskPlugin.aar
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java
│ │ │ └── br
│ │ │ └── com
│ │ │ └── mobilemind
│ │ │ └── ns
│ │ │ └── task
│ │ │ ├── CompleteCallback.java
│ │ │ ├── CopyFilesTask.java
│ │ │ ├── DbInsertBatchTask.java
│ │ │ ├── HttpPostData.java
│ │ │ ├── HttpPostDataTask.java
│ │ │ ├── HttpPostFileFormDataTask.java
│ │ │ ├── HttpPostFileTask.java
│ │ │ ├── HttpRequestToFileTask.java
│ │ │ ├── LargeFilePersisterTask.java
│ │ │ ├── SplitFilesTask.java
│ │ │ ├── UnzipTask.java
│ │ │ └── sql
│ │ │ └── DBHelper.java
│ ├── build.gradle
│ ├── compile
│ ├── gradle.properties
│ ├── local.properties
│ └── settings.gradle
├── ios
│ ├── NSBackgroundTask.h
│ ├── NSBackgroundTaskCopyFiles.m
│ ├── NSBackgroundTaskHttpRequestToFile.m
│ ├── NSBackgroundTaskUnzipTask.m
│ └── NativeScriptBackgroundTask.podspec
└── server-mock
│ ├── app.js
│ ├── bin
│ └── www
│ ├── package.json
│ ├── public
│ └── stylesheets
│ │ └── style.css
│ ├── routes
│ ├── index.js
│ └── users.js
│ └── views
│ ├── error.pug
│ ├── index.pug
│ └── layout.pug
├── package-lock.json
├── package.json
└── platforms
├── android
├── AndroidManifest.xml
├── MobileMindNSTaskPlugin.aar
└── include.gradle
└── ios
├── Podfile
└── headers
└── module.modulemap
/.npmignore:
--------------------------------------------------------------------------------
1 | # Exclude the native source code. The native libraries are included in the push-plugin as compiled resources (i.e. jar & framework)
2 | native-src/
3 | demo/
4 | demo_old/
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # nativescript-background-task
2 |
3 | Run background task
4 |
5 | **Attention!!** this plugin not is registered on npm. To use you should add the repository directly on your package.json:
6 |
7 | ```
8 | dependencies: {
9 | "nativescript-background-task": "https://github.com/mobilemindtec/nativescript-background-task.git"
10 | }
11 | ```
12 |
13 | ## Features
14 |
15 | * unzip file
16 | * download big files, supports partial/resume download
17 | * move many files
18 | * save large file
19 | * post large file base64 gzip json or form data (base64 gzip)
20 | * split large file
21 | * run sql batch (insert, update, delete)
22 |
23 | ** IOS Pod code at http://github.com/mobilemindtec/nativescript-background-task-ios-source
24 |
25 | ## Configs
26 | ### Android
27 | Add at app.gradle
28 |
29 | ```
30 | allprojects {
31 | repositories {
32 | jcenter()
33 | mavenCentral()
34 | maven {
35 | url "https://raw.githubusercontent.com/mobilemindtec/m2/master"
36 | }
37 | }
38 | }
39 |
40 | android {
41 | useLibrary 'org.apache.http.legacy'
42 | }
43 | dependencies{
44 | compile('br.com.mobilemind.api:mobilemind-droid-util:1.4', {
45 | exclude group: 'com.google.android', module: 'android'
46 | exclude group: 'com.google.android', module: 'support-v4'
47 | exclude group: 'br.com.mobilemind.api', module: 'mobilemind-utils'
48 | })
49 | compile 'br.com.mobilemind.api:mobilemind-utils:1.3'
50 | }
51 |
52 | ```
53 | ## Using
54 |
55 | ```
56 |
57 | var BackgroundTask = require("nativescript-background-task")
58 |
59 | ```
60 | ### Unzip file
61 |
62 | ```
63 | BackgroundTask.unzip({
64 | fromFile: zipFile,
65 | toFile: extractPath,
66 | doneCallback: function(){
67 | // done
68 | },
69 | errorCallback: function(error){
70 | // error
71 | },
72 | })
73 |
74 | ```
75 |
76 | ### Download to file
77 |
78 | if you set `checkPartialDownload: true` the plugin will test, using `HEAD` request to know if server accepts (header Accept-Ranges: bytes). If server supports, the plugin make partial download of `partBytesSize` bytes (default is 2MB). Partial download enable resume download if some part of download already done. The server can supports `HEAD` request to work.
79 |
80 | ```
81 | BackgroundTask.getFile({
82 | url: 'http://www.mobilemind.com.br/makeyourself/coollife/images-2.1.zip',
83 | toFile: destinationFile,
84 | identifier: 1,
85 | partBytesSize: 0, // use default 2MB
86 | checkPartialDownload: true,
87 | headers: [
88 | { 'CustonHeader': 'Custon Value' }
89 | ],
90 | doneCallback: function(identifier){
91 | // done
92 | },
93 | errorCallback: function(error){
94 | var identifier = error[0]
95 | var message = error[1]
96 | // error
97 | },
98 | })
99 | ```
100 |
101 | ### Copy many files to destination directory
102 |
103 | ```
104 | BackgroundTask.copyFiles({
105 | fromFile: extractPath,
106 | toFile: movePath,
107 | doneCallback: function(){
108 | // done
109 | },
110 | errorCallback: function(){
111 | // error
112 | },
113 | })
114 | ```
115 |
116 | ### Save a or copy a large file or Image to destination.
117 |
118 | You can set Image or file source
119 |
120 | ```
121 | var files = []
122 | files.push({
123 | image: image, // to save android Bitmap, ios UIImage or nativescript Image
124 | fileDst: fileDst, // destination file path
125 | fileSrc: doc.fileSrc, // to pdf or another doc.. copy to destination
126 | quality: 30 // quality if is bitmap
127 | })
128 | BackgroundTask.saveLargeFiles({
129 | files: files
130 | doneCallback: function(){
131 | // done
132 | },
133 | errorCallback: function(error){
134 | // error
135 | }
136 | })
137 |
138 | ```
139 |
140 | ### Post files
141 |
142 | Post a file using json format or form data.
143 |
144 | * JSON format - To post json files, you need provide a key that the content will be stored in json object. For example, if you set `jsonKey: 'photo'` the plugin make a json `{ photo: 'photo content' }` and add in `photo content` the file content using Base64 and, if you want GZip.
145 |
146 | * Form Data - To post Form Data, you need provide a key that the content will be stored in form data. For example, if you set `jsonKey: 'photo'` the plugin make a form data `dataform[jsonKey] = 'photo content'` and add in `photo content` the file content using Base64 and, if you want GZip.
147 |
148 | The file always will be store in `jsonKey` field, and not in post content. The server need supports this logic.
149 |
150 | ```
151 | BackgroundTask.postFiles({
152 | url: apiUrl, // api url
153 | formData: false, // use form data to post. default is json
154 | gzip: true, // use base64 gzip
155 | items: [{
156 | fileSrc: fileSrc, // file origin path
157 | jsonKey: jsonKey, // internally post data[jsonKey] = file content
158 | identifier: identifier, // identifier to result
159 | data: { // you json object to post + data[jsonKey] = file content
160 | Id: 1
161 | }
162 | }],
163 | headers: [
164 | { 'X-Auth-Token': token }
165 | ],
166 | doneCallback: function(dataPostList) {
167 |
168 | // to ios use array converter
169 | // var utils require("utils/utils")
170 | // if(application.ios)
171 | // dataPostList = utils.ios.collections.nsArrayToJSArray(dataPostList)
172 |
173 | for(var i in dataPostList){
174 | var postData = dataPostList[i]
175 | var data = JSON.parse(postData.result)
176 | var identifier = postData.identifier
177 | // get response headers names postData.getHeaderNames()
178 | // get response header value postData.getHeaderValue("name")
179 | // get response headers postData.getHeaders()
180 | // get response object postData.response
181 | // process result
182 | }
183 | },
184 | errorCallback: function(error){
185 | // error
186 | }
187 | })
188 | ```
189 |
190 | ### SQL Batch
191 |
192 | Execute sql back in background.
193 |
194 | ```
195 | // sql batch
196 | var items = []
197 |
198 | // insert / update / delete
199 | items.push({
200 | query: 'insert into foo name values(?)',
201 | args: ['john']
202 | })
203 |
204 | // to insert or update
205 | items.push({
206 | insertQuery: 'insert into foo name values(?)',
207 | updateQuery: 'update foo set name = ? where id = ?',
208 | tableName: 'foo',
209 | updateKey: 'id',
210 | updateKeyValue: '1',
211 | args: ['john']
212 | })
213 |
214 | BackgroundTask.dbBatch({
215 | dbName: dbName,
216 | items: items,
217 | doneCallback: function(){
218 | // done
219 | },
220 | errorCallback: function(error){
221 | // error
222 | }
223 | })
224 |
225 | ```
226 |
227 | ### Split large file and save parts
228 |
229 | ```
230 | BackgroundTask.splitFiles({
231 | files: [{
232 | fileSrc: "/file/to/split.mp4"
233 | filePartPath: "/path/to/save/part/"
234 | fileParthName: "FileName"
235 | fileParteSufix: "part" // create FileName.part
236 | filePartMaxSize: 3 // 3MB
237 | }],
238 | doneCallback: function(data){
239 |
240 | var files = []
241 | for(i in data){
242 | for(filePath in data[i].fileParts)
243 | files.push(it) // get name of parts
244 | }
245 | },
246 | errorCallback: function(error){
247 | // error
248 | }
249 | })
250 |
251 | ```
252 |
--------------------------------------------------------------------------------
/background-task.android.js:
--------------------------------------------------------------------------------
1 | var Application = require("@nativescript/core").Application
2 |
3 | /*
4 | args = {
5 |
6 | url:
7 | toFile: - file path to save
8 |
9 | }
10 | */
11 | exports.getFile = function(args){
12 | var callback = createCallback(args)
13 | var toFile = args.toFile
14 | var url = args.url
15 | var identifier = args.identifier + ""
16 | var partBytesSize = args.partBytesSize
17 | var checkPartialDownload = args.checkPartialDownload
18 |
19 | var task = new br.com.mobilemind.ns.task.HttpRequestToFileTask(callback, url, toFile, identifier)
20 | task.setCheckPartialDownload(checkPartialDownload == undefined ? false : checkPartialDownload)
21 | task.setPartBytesSize( partBytesSize || 0)
22 |
23 | if(args.headers){
24 | for(var i in args.headers){
25 | var header = args.headers[i]
26 | for(var key in header){
27 | task.addHeader(key, header[key])
28 | }
29 | }
30 | }
31 |
32 | task.executeOnExecutor(android.os.AsyncTask.THREAD_POOL_EXECUTOR, null)
33 | }
34 |
35 | exports.isPartialDownloadCompleted = function(args) {
36 | return br.com.mobilemind.ns.task.HttpRequestToFileTask.isCompletedDownload(args.toFile)
37 | }
38 |
39 | /*
40 |
41 | args = {
42 | fromFile:
43 | toFile:
44 | }
45 |
46 | */
47 | exports.unzip = function(args){
48 | var callback = createCallback(args)
49 | var toFile = args.toFile
50 | var fromFile = args.fromFile
51 | br.com.mobilemind.ns.task.UnzipTask.doIt(callback, fromFile, toFile);
52 | }
53 |
54 | /*
55 |
56 | args = {
57 | fromFile:
58 | toFile:
59 | }
60 |
61 | */
62 | exports.copyFiles = function(args){
63 | var callback = createCallback(args)
64 | var toFile = args.toFile
65 | var fromFile = args.fromFile
66 | br.com.mobilemind.ns.task.CopyFilesTask.doIt(callback, fromFile, toFile);
67 | }
68 |
69 | /*
70 | args = {
71 | files: [
72 | {
73 | image: // bitmap or uiimage
74 | fileDst:
75 | fileSrc:
76 | quality:
77 | }
78 | ]
79 | }
80 |
81 | */
82 | exports.saveLargeFiles = function(args){
83 |
84 | var callback = createCallback(args)
85 |
86 | try{
87 |
88 | if(!args.files || args.files.length == 0){
89 | if(args.doneCallback){
90 | args.doneCallback()
91 | return
92 | }
93 | }
94 |
95 | var largeFiles = []
96 |
97 | for(var i in args.files) {
98 |
99 | var item = args.files[i]
100 | var large = new br.com.mobilemind.ns.task.LargeFilePersisterTask.LargeFile()
101 | large.bitmap = item.image.android || item.image
102 | large.fileDst = item.fileDst
103 | large.fileSrc = item.fileSrc
104 | large.quality = item.quality
105 |
106 | largeFiles.push(large)
107 |
108 | }
109 |
110 | br.com.mobilemind.ns.task.LargeFilePersisterTask.doIt(callback, largeFiles);
111 | }catch(error){
112 | console.log("BackgroundTask.saveLargeFiles error=" + error)
113 | if(args.errorCallback)
114 | args.errorCallback(error)
115 | }
116 |
117 | }
118 |
119 | /*
120 | args = {
121 | files: [
122 | {
123 | fileSrc:
124 | filePartPath:
125 | filePartName:
126 | filePartSufix: default is "part"
127 | filePartMaxSize: default is 5 (5MB)
128 | }
129 | ]
130 | }
131 |
132 | */
133 |
134 | exports.splitFiles = function(args){
135 |
136 | var callback = createCallback(args)
137 |
138 | try{
139 |
140 | if(!args.files || args.files.length == 0){
141 | if(args.doneCallback){
142 | args.doneCallback()
143 | return
144 | }
145 | }
146 |
147 | var splitFiles = []
148 |
149 | for(var i in args.files) {
150 |
151 | var item = args.files[i]
152 | var splitFile = new br.com.mobilemind.ns.task.SplitFilesTask.SplitFile()
153 |
154 | splitFile.fileSrc = item.fileSrc
155 | splitFile.filePartPath = item.filePartPath
156 | splitFile.filePartMaxSize = item.filePartMaxSize || splitFile.filePartMaxSize
157 | splitFile.filePartName = item.filePartName
158 | splitFile.filePartSufix = item.filePartSufix || splitFile.filePartSufix
159 |
160 | splitFiles.push(splitFile)
161 |
162 | }
163 |
164 | br.com.mobilemind.ns.task.SplitFilesTask.doIt(callback, splitFiles);
165 |
166 | }catch(error){
167 | console.log("BackgroundTask.splitFiles error=" + error)
168 | if(args.errorCallback)
169 | args.errorCallback(error)
170 | }
171 |
172 | }
173 |
174 | /*
175 |
176 | args = {
177 | url:
178 | items: [
179 | {
180 | jsonKey:
181 | fileSrc:
182 | data: - json data
183 | }
184 | ]
185 | headers: [
186 | {}
187 | ]
188 | }
189 |
190 | */
191 |
192 | exports.postFiles = function(args){
193 |
194 | var callback = createCallback(args)
195 |
196 | try{
197 |
198 | var httpPostFileTask
199 |
200 | if(args.formData){
201 | httpPostFileTask = new br.com.mobilemind.ns.task.HttpPostFileFormDataTask(args.url, callback)
202 | } else {
203 | httpPostFileTask = new br.com.mobilemind.ns.task.HttpPostFileTask(args.url, callback)
204 | }
205 |
206 | for(var i in args.items){
207 | var jsonItem = args.items[i]
208 | var fileSrc = jsonItem.fileSrc
209 | var jsonKey = jsonItem.jsonKey
210 | var jsonData = jsonItem.data
211 |
212 | var httpPostData = new br.com.mobilemind.ns.task.HttpPostData(fileSrc, jsonKey)
213 | httpPostData.identifier = jsonItem.identifier
214 |
215 | for(var key in jsonData){
216 | httpPostData.addJsonValue(key, jsonData[key])
217 | }
218 |
219 | httpPostFileTask.addData(httpPostData)
220 |
221 | }
222 |
223 | if(args.gzip)
224 | httpPostFileTask.setUseGzip(args.gzip)
225 |
226 | if(args.headers){
227 | for(var i in args.headers){
228 | var header = args.headers[i]
229 | for(var key in header){
230 | httpPostFileTask.addHeader(key, header[key])
231 | }
232 | }
233 | }
234 |
235 | httpPostFileTask.executeOnExecutor(android.os.AsyncTask.THREAD_POOL_EXECUTOR, null)
236 | }catch(error){
237 | console.log("BackgroundTask.postFiles error=" + error)
238 |
239 | if(args.errorCallback)
240 | args.errorCallback(error)
241 | }
242 | }
243 |
244 | exports.postData = function(args){
245 |
246 | var callback = createCallback(args)
247 |
248 | try{
249 |
250 | var task = new br.com.mobilemind.ns.task.HttpPostDataTask(args.url, callback)
251 |
252 |
253 | for(var i in args.items){
254 | var jsonItem = args.items[i]
255 | var fileSrc = jsonItem.fileSrc
256 | var jsonKey = jsonItem.jsonKey
257 | var jsonData = jsonItem.data
258 |
259 | var httpPostData = new br.com.mobilemind.ns.task.HttpPostData(fileSrc, jsonKey)
260 | httpPostData.identifier = jsonItem.identifier
261 |
262 | for(var key in jsonData){
263 | httpPostData.addJsonValue(key, jsonData[key])
264 | }
265 |
266 | task.addData(httpPostData)
267 |
268 | }
269 |
270 | if(args.gzip)
271 | task.setUseGzip(args.gzip)
272 |
273 | if(args.splitMaxSize > 0)
274 | task.setSplitMaxSize(args.splitMaxSize)
275 |
276 |
277 | if(args.headers){
278 | for(var i in args.headers){
279 | var header = args.headers[i]
280 | for(var key in header){
281 | task.addHeader(key, header[key])
282 | }
283 | }
284 | }
285 |
286 | task.executeOnExecutor(android.os.AsyncTask.THREAD_POOL_EXECUTOR, null)
287 |
288 | }catch(error){
289 | console.log("BackgroundTask.postFiles error=" + error)
290 |
291 | if(args.errorCallback)
292 | args.errorCallback(error)
293 | }
294 | }
295 |
296 | /*
297 |
298 | insert/update/delete
299 |
300 | args = {
301 | dbName
302 | items: [
303 | {
304 | query:
305 | args
306 | }
307 | ]
308 | }
309 |
310 | insert or update
311 |
312 | args = {
313 | dbName
314 | items: [
315 | {
316 | insertQuery:
317 | updateQuery:
318 | tableName:
319 | updateKey: // where column name
320 | updateKeyValue: // where column value
321 | params:
322 | }
323 | ]
324 | }
325 |
326 | */
327 | exports.dbBatch = function(args){
328 | var callback = createCallback(args)
329 |
330 | try{
331 | var context = Application.android.foregroundActivity || Application.android.startActivity
332 | var dbName = args.dbName
333 |
334 | var dbInsertBatchTask = new br.com.mobilemind.ns.task.DbInsertBatchTask(context, dbName, callback)
335 |
336 | for(var i in args.items){
337 | var item = args.items[i]
338 | if(item.query)
339 | dbInsertBatchTask.addQuery(item.query, item.args)
340 | else
341 | dbInsertBatchTask.addInsertOrUpdateQuery(item.insertQuery, item.updateQuery, item.tableName, item.updateKey + "", item.updateKeyValue, item.args)
342 | }
343 |
344 | dbInsertBatchTask.executeOnExecutor(android.os.AsyncTask.THREAD_POOL_EXECUTOR, null)
345 |
346 | }catch(error){
347 | console.log("BackgroundTask.dbBatchInsert error=" + error)
348 |
349 | if(args.errorCallback)
350 | args.errorCallback(error)
351 | }
352 |
353 | }
354 |
355 | function createCallback(args){
356 |
357 | var doneCallback = args.doneCallback
358 | var errorCallback = args.errorCallback
359 |
360 | var callback = new br.com.mobilemind.ns.task.CompleteCallback({
361 | onComplete: function(result){
362 | if(doneCallback)
363 | doneCallback(result)
364 | },
365 | onError: function(e){
366 | if(errorCallback)
367 | errorCallback(e)
368 | }
369 | })
370 |
371 | return callback
372 |
373 | }
374 |
--------------------------------------------------------------------------------
/background-task.ios.js:
--------------------------------------------------------------------------------
1 | var fs = require("@nativescript/core/file-system")
2 |
3 | exports.getFile = function(args){
4 |
5 | var CompleteCallback = createCallback(args)
6 |
7 | var toFile = args.toFile
8 | var url = args.url
9 | var identifier = args.identifier + ""
10 | var partBytesSize = args.partBytesSize
11 | var checkPartialDownload = args.checkPartialDownload
12 | var debug = args.debug
13 |
14 |
15 | var task = NSBackgroundTaskHttpRequestToFile.alloc().initWithUrlToFileIdentifier(url, toFile, identifier)
16 |
17 | task.setCheckPartialDownload(checkPartialDownload == undefined ? false : checkPartialDownload)
18 | task.setPartBytesSize(partBytesSize || 0)
19 | task.setDebug(debug == undefined ? false : debug)
20 |
21 | if(args.headers){
22 | for(var i in args.headers){
23 | var header = args.headers[i]
24 | for(var key in header){
25 | task.addHeaderWithNameAndValue(key, header[key])
26 | }
27 | }
28 | }
29 |
30 | task.delegate = CompleteCallback.new()
31 | task.runTask();
32 | }
33 |
34 | exports.unzip = function(args){
35 |
36 | var CompleteCallback = createCallback(args)
37 |
38 | var task = NSBackgroundTaskUnzipTask.alloc().initWithFromFileToFile(args.fromFile, args.toFile)
39 | task.delegate = CompleteCallback.new()
40 | task.runTask();
41 | }
42 |
43 | exports.copyFiles = function(args){
44 |
45 | var CompleteCallback = createCallback(args)
46 |
47 | var task = NSBackgroundTaskCopyFiles.alloc().initWithFromFileToFile(args.fromFile, args.toFile)
48 | task.delegate = CompleteCallback.new()
49 | task.runTask();
50 | }
51 |
52 | /*
53 | args = {
54 | files: [
55 | {
56 | image:
57 | fileDst:
58 | fileSrc:
59 | quality:
60 | }
61 | ]
62 | }
63 |
64 | */
65 | exports.saveLargeFiles = function(args){
66 |
67 | var CompleteCallback = createCallback(args)
68 |
69 | try{
70 |
71 | if(!args.files || args.files.length == 0){
72 | if(args.doneCallback){
73 | args.doneCallback()
74 | return
75 | }
76 | }
77 |
78 | var task = NSLargeFilePersisterTask.new()
79 | task.delegate = CompleteCallback.new()
80 |
81 | for(var i in args.files) {
82 |
83 | var item = args.files[i]
84 | var largeFile = NSLargeFile.new()
85 |
86 | if (item.image instanceof UIImage)
87 | largeFile.image = item.image
88 | else if(item.image && item.image.ios)
89 | largeFile.image = item.image.ios
90 |
91 | largeFile.fileDst = item.fileDst
92 | largeFile.fileSrc = item.fileSrc
93 | largeFile.quality = item.quality || 0
94 |
95 | task.addLargeFile(largeFile)
96 | }
97 |
98 | task.runTask()
99 |
100 | }catch(error){
101 | console.log("BackgroundTask.saveLargeFiles error=" + error)
102 | if(args.errorCallback)
103 | args.errorCallback(error)
104 | }
105 |
106 | }
107 |
108 | /*
109 | args = {
110 | files: [
111 | {
112 | fileSrc:
113 | filePartPath:
114 | fileParthName:
115 | fileParteSufix: default is "part"
116 | filePartMaxSize: default is 5 (5MB)
117 | }
118 | ]
119 | }
120 |
121 | */
122 |
123 | exports.splitFiles = function(args){
124 |
125 | var CompleteCallback = createCallback(args)
126 |
127 | try{
128 |
129 | if(!args.files || args.files.length == 0){
130 | if(args.doneCallback)
131 | args.doneCallback()
132 | }
133 |
134 | var task = NSSplitFileTask.new()
135 | task.delegate = CompleteCallback.new()
136 |
137 | for(var i in args.files) {
138 |
139 | var item = args.files[i]
140 |
141 | var splitFile = NSSplitFile.new()
142 | splitFile.fileSrc = item.fileSrc
143 | splitFile.filePartPath = item.filePartPath
144 | splitFile.filePartMaxSize = item.filePartMaxSize || splitFile.filePartMaxSize
145 | splitFile.filePartName = item.filePartName
146 | splitFile.filePartSufix = item.filePartSufix || splitFile.filePartSufix
147 |
148 | task.addSplitFile(splitFile)
149 | }
150 |
151 | task.runTask()
152 |
153 | }catch(error){
154 | console.log("BackgroundTask.splitFiles error=" + error)
155 | if(args.errorCallback)
156 | args.errorCallback(error)
157 | }
158 |
159 | }
160 |
161 | /*
162 |
163 | args = {
164 | url:
165 | items: [
166 | {
167 | jsonKey:
168 | fileSrc:
169 | data: - json data
170 | }
171 | ]
172 | headers: [
173 | {}
174 | ]
175 | }
176 |
177 | */
178 |
179 | exports.postFiles = function(args){
180 |
181 | var CompleteCallback = createCallback(args)
182 |
183 | try{
184 |
185 | var task = NSHttpPostFileTask.alloc().initWithUrl(args.url)
186 | task.delegate = CompleteCallback.new()
187 |
188 | if(args.formData){
189 | task.setUseFormData(true)
190 | }
191 |
192 | if(args.gzip){
193 | task.setUseGzip(true)
194 | }
195 |
196 | if(args.debug)
197 | task.setDebug(true)
198 |
199 | for(var i in args.items){
200 | var jsonItem = args.items[i]
201 | var fileSrc = jsonItem.fileSrc
202 | var jsonKey = jsonItem.jsonKey
203 | var jsonData = jsonItem.data
204 |
205 | var httpPostFile = NSHttpPostFile.alloc().initWithFileSrcJsonKey(fileSrc, jsonKey)
206 | httpPostFile.identifier = jsonItem.identifier
207 |
208 | for(var key in jsonData){
209 | httpPostFile.addJsonKeyValue(key, jsonData[key])
210 | }
211 |
212 | task.addPostFile(httpPostFile)
213 |
214 | }
215 |
216 | if(args.gzip == false)
217 | task.setUseGzip(false)
218 |
219 | if(args.headers){
220 | for(var i in args.headers){
221 | var header = args.headers[i]
222 | for(var key in header){
223 | task.addHeaderWithNameAndValue(key, header[key])
224 | }
225 | }
226 | }
227 |
228 | task.runTask()
229 |
230 |
231 | }catch(error){
232 | console.log("BackgroundTask.postFiles error=" + error)
233 |
234 | if(args.errorCallback)
235 | args.errorCallback(error)
236 | }
237 | }
238 |
239 |
240 | /*
241 |
242 | insert/update/delete
243 |
244 | args = {
245 | dbName
246 | items: [
247 | {
248 | query:
249 | args
250 | }
251 | ]
252 | }
253 |
254 | insert or update
255 |
256 | args = {
257 | dbName
258 | items: [
259 | {
260 | insertQuery:
261 | updateQuery:
262 | tableName:
263 | updateKey: // where column name
264 | updateKeyValue: // where column value
265 | params:
266 | }
267 | ]
268 | }
269 |
270 | */
271 | exports.dbBatch = function(args){
272 | var CompleteCallback = createCallback(args)
273 |
274 | var dbPath = fs.path.join(fs.knownFolders.documents().path, args.dbName)
275 |
276 | try{
277 |
278 | var task = NSDbBatchTask.alloc().initWithDbPath(dbPath)
279 | task.delegate = CompleteCallback.new()
280 |
281 | if(args.debug)
282 | task.setDebug(true)
283 |
284 | for(var i in args.items){
285 | var item = args.items[i]
286 |
287 | var query = NSQuery.new()
288 |
289 | if(item.query){
290 | query.query = item.query
291 | query.params = item.args
292 | } else {
293 | query.insertQuery = item.insertQuery
294 | query.updateQuery = item.updateQuery
295 | query.tableName = item.tableName
296 | query.updateKey = item.updateKey + ""
297 | query.updateKeyValue = item.updateKeyValue + ""
298 | query.updateKeyDataType = item.updateKeyDataType || "text"
299 | query.params = item.args
300 | }
301 |
302 | task.addQuery(query)
303 |
304 | }
305 |
306 | task.runTask()
307 |
308 | }catch(error){
309 | console.log("BackgroundTask.dbBatchInsert error=" + error)
310 |
311 | if(args.errorCallback)
312 | args.errorCallback(error)
313 | }
314 |
315 | }
316 |
317 | function createCallback(args){
318 |
319 | var CompleteCallback = (function(_super){
320 | __extends(CompleteCallback, _super);
321 | function CompleteCallback(){
322 | _super.apply(this, arguments);
323 | }
324 |
325 | CompleteCallback.prototype.onComplete = function(result){
326 | if(args.doneCallback)
327 | invokeOnRunLoop(()=>{
328 | args.doneCallback(result)
329 | })
330 | }
331 |
332 | CompleteCallback.prototype.onError = function(message){
333 | if(args.errorCallback)
334 | invokeOnRunLoop(()=>{
335 | args.errorCallback(message)
336 | })
337 | }
338 |
339 | CompleteCallback.ObjCProtocols = [NSBackgroundTaskCompleteCallback]
340 |
341 | return CompleteCallback
342 |
343 | }(NSObject))
344 |
345 | return CompleteCallback
346 | }
347 |
348 | let invokeOnRunLoop = (function() {
349 | var runloop = CFRunLoopGetMain();
350 | return function(func) {
351 | CFRunLoopPerformBlock(runloop, kCFRunLoopDefaultMode, func);
352 | CFRunLoopWakeUp(runloop);
353 | }
354 | }());
355 |
356 | exports.invokeOnRunLoop = invokeOnRunLoop
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
27 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/app.gradle:
--------------------------------------------------------------------------------
1 | // Add your native dependencies here:
2 |
3 | // Uncomment to add recyclerview-v7 dependency
4 | //dependencies {
5 | // compile 'com.android.support:recyclerview-v7:+'
6 | //}
7 |
8 | android {
9 | defaultConfig {
10 | generatedDensities = []
11 | }
12 | aaptOptions {
13 | additionalParameters "--no-version-vectors"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-hdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-hdpi/background.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-hdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-hdpi/logo.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-ldpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-ldpi/background.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-ldpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-ldpi/icon.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-ldpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-ldpi/logo.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-mdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-mdpi/background.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-mdpi/icon.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-mdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-mdpi/logo.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-nodpi/splash_screen.xml:
--------------------------------------------------------------------------------
1 |
2 | -
3 |
4 |
5 | -
6 |
7 |
8 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-nodpi/splashscreen.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-nodpi/splashscreen.9.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-xhdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-xhdpi/background.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-xhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-xhdpi/icon.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-xhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-xhdpi/logo.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-xxhdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-xxhdpi/background.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-xxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-xxhdpi/icon.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-xxhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-xxhdpi/logo.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-xxxhdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-xxxhdpi/background.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-xxxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-xxxhdpi/icon.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/drawable-xxxhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/Android/drawable-xxxhdpi/logo.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/values-v21/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3d5afe
4 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
14 |
15 |
16 |
19 |
20 |
23 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #F5F5F5
4 | #757575
5 | #33B5E5
6 | #272734
7 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
18 |
19 |
21 |
22 |
23 |
31 |
32 |
34 |
35 |
36 |
42 |
43 |
45 |
46 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "29x29",
5 | "idiom" : "iphone",
6 | "filename" : "icon-29.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "29x29",
11 | "idiom" : "iphone",
12 | "filename" : "icon-29@2x.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "icon-29@3x.png",
19 | "scale" : "3x"
20 | },
21 | {
22 | "size" : "40x40",
23 | "idiom" : "iphone",
24 | "filename" : "icon-40@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "icon-40@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "57x57",
35 | "idiom" : "iphone",
36 | "filename" : "icon-57.png",
37 | "scale" : "1x"
38 | },
39 | {
40 | "size" : "57x57",
41 | "idiom" : "iphone",
42 | "filename" : "icon-57@2x.png",
43 | "scale" : "2x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "icon-60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "icon-60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "29x29",
59 | "idiom" : "ipad",
60 | "filename" : "icon-29.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "29x29",
65 | "idiom" : "ipad",
66 | "filename" : "icon-29@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "40x40",
71 | "idiom" : "ipad",
72 | "filename" : "icon-40.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "40x40",
77 | "idiom" : "ipad",
78 | "filename" : "icon-40@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "50x50",
83 | "idiom" : "ipad",
84 | "filename" : "icon-50.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "50x50",
89 | "idiom" : "ipad",
90 | "filename" : "icon-50@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "72x72",
95 | "idiom" : "ipad",
96 | "filename" : "icon-72.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "72x72",
101 | "idiom" : "ipad",
102 | "filename" : "icon-72@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "76x76",
107 | "idiom" : "ipad",
108 | "filename" : "icon-76.png",
109 | "scale" : "1x"
110 | },
111 | {
112 | "size" : "76x76",
113 | "idiom" : "ipad",
114 | "filename" : "icon-76@2x.png",
115 | "scale" : "2x"
116 | },
117 | {
118 | "size" : "83.5x83.5",
119 | "idiom" : "ipad",
120 | "filename" : "icon-83.5@2x.png",
121 | "scale" : "2x"
122 | }
123 | ],
124 | "info" : {
125 | "version" : 1,
126 | "author" : "xcode"
127 | }
128 | }
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "extent" : "full-screen",
5 | "idiom" : "iphone",
6 | "subtype" : "736h",
7 | "filename" : "Default-736h@3x.png",
8 | "minimum-system-version" : "8.0",
9 | "orientation" : "portrait",
10 | "scale" : "3x"
11 | },
12 | {
13 | "extent" : "full-screen",
14 | "idiom" : "iphone",
15 | "subtype" : "736h",
16 | "filename" : "Default-Landscape@3x.png",
17 | "minimum-system-version" : "8.0",
18 | "orientation" : "landscape",
19 | "scale" : "3x"
20 | },
21 | {
22 | "extent" : "full-screen",
23 | "idiom" : "iphone",
24 | "subtype" : "667h",
25 | "filename" : "Default-667h@2x.png",
26 | "minimum-system-version" : "8.0",
27 | "orientation" : "portrait",
28 | "scale" : "2x"
29 | },
30 | {
31 | "orientation" : "portrait",
32 | "idiom" : "iphone",
33 | "filename" : "Default@2x.png",
34 | "extent" : "full-screen",
35 | "minimum-system-version" : "7.0",
36 | "scale" : "2x"
37 | },
38 | {
39 | "extent" : "full-screen",
40 | "idiom" : "iphone",
41 | "subtype" : "retina4",
42 | "filename" : "Default-568h@2x.png",
43 | "minimum-system-version" : "7.0",
44 | "orientation" : "portrait",
45 | "scale" : "2x"
46 | },
47 | {
48 | "orientation" : "portrait",
49 | "idiom" : "ipad",
50 | "filename" : "Default-Portrait.png",
51 | "extent" : "full-screen",
52 | "minimum-system-version" : "7.0",
53 | "scale" : "1x"
54 | },
55 | {
56 | "orientation" : "landscape",
57 | "idiom" : "ipad",
58 | "filename" : "Default-Landscape.png",
59 | "extent" : "full-screen",
60 | "minimum-system-version" : "7.0",
61 | "scale" : "1x"
62 | },
63 | {
64 | "orientation" : "portrait",
65 | "idiom" : "ipad",
66 | "filename" : "Default-Portrait@2x.png",
67 | "extent" : "full-screen",
68 | "minimum-system-version" : "7.0",
69 | "scale" : "2x"
70 | },
71 | {
72 | "orientation" : "landscape",
73 | "idiom" : "ipad",
74 | "filename" : "Default-Landscape@2x.png",
75 | "extent" : "full-screen",
76 | "minimum-system-version" : "7.0",
77 | "scale" : "2x"
78 | },
79 | {
80 | "orientation" : "portrait",
81 | "idiom" : "iphone",
82 | "filename" : "Default.png",
83 | "extent" : "full-screen",
84 | "scale" : "1x"
85 | },
86 | {
87 | "orientation" : "portrait",
88 | "idiom" : "iphone",
89 | "filename" : "Default@2x.png",
90 | "extent" : "full-screen",
91 | "scale" : "2x"
92 | },
93 | {
94 | "orientation" : "portrait",
95 | "idiom" : "iphone",
96 | "filename" : "Default-568h@2x.png",
97 | "extent" : "full-screen",
98 | "subtype" : "retina4",
99 | "scale" : "2x"
100 | },
101 | {
102 | "orientation" : "portrait",
103 | "idiom" : "ipad",
104 | "extent" : "to-status-bar",
105 | "scale" : "1x"
106 | },
107 | {
108 | "orientation" : "portrait",
109 | "idiom" : "ipad",
110 | "filename" : "Default-Portrait.png",
111 | "extent" : "full-screen",
112 | "scale" : "1x"
113 | },
114 | {
115 | "orientation" : "landscape",
116 | "idiom" : "ipad",
117 | "extent" : "to-status-bar",
118 | "scale" : "1x"
119 | },
120 | {
121 | "orientation" : "landscape",
122 | "idiom" : "ipad",
123 | "filename" : "Default-Landscape.png",
124 | "extent" : "full-screen",
125 | "scale" : "1x"
126 | },
127 | {
128 | "orientation" : "portrait",
129 | "idiom" : "ipad",
130 | "extent" : "to-status-bar",
131 | "scale" : "2x"
132 | },
133 | {
134 | "orientation" : "portrait",
135 | "idiom" : "ipad",
136 | "filename" : "Default-Portrait@2x.png",
137 | "extent" : "full-screen",
138 | "scale" : "2x"
139 | },
140 | {
141 | "orientation" : "landscape",
142 | "idiom" : "ipad",
143 | "extent" : "to-status-bar",
144 | "scale" : "2x"
145 | },
146 | {
147 | "orientation" : "landscape",
148 | "idiom" : "ipad",
149 | "filename" : "Default-Landscape@2x.png",
150 | "extent" : "full-screen",
151 | "scale" : "2x"
152 | }
153 | ],
154 | "info" : {
155 | "version" : 1,
156 | "author" : "xcode"
157 | }
158 | }
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-568h@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-667h@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchScreen-AspectFill.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchScreen-AspectFill@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchScreen-Center.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchScreen-Center@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Default-568h@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Default-667h@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Default-736h@3x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Default-Landscape-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Default-Landscape-568h@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Default-Landscape-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Default-Landscape-667h@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Default-Landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Default-Landscape.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Default-Landscape@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Default-Landscape@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Default-Landscape@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Default-Landscape@3x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Default-Portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Default-Portrait.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Default-Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Default-Portrait@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Default.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Default@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Icon-Small-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Icon-Small-50.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Icon-Small-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Icon-Small-50@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Icon-Small.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/Icon-Small@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIconFile
12 | icon.png
13 | CFBundleIcons
14 |
15 | CFBundlePrimaryIcon
16 |
17 | CFBundleIconFiles
18 |
19 | icon-40
20 | icon-60
21 | icon-72
22 | icon-76
23 | Icon-Small
24 | Icon-Small-50
25 |
26 | UIPrerenderedIcon
27 |
28 |
29 |
30 | CFBundleInfoDictionaryVersion
31 | 6.0
32 | CFBundleName
33 | ${PRODUCT_NAME}
34 | CFBundlePackageType
35 | APPL
36 | CFBundleShortVersionString
37 | 1.0
38 | CFBundleSignature
39 | ????
40 | CFBundleVersion
41 | 1.0
42 | LSRequiresIPhoneOS
43 |
44 | UILaunchStoryboardName
45 | LaunchScreen
46 | UIRequiresFullScreen
47 |
48 | UIRequiredDeviceCapabilities
49 |
50 | armv7
51 |
52 | UISupportedInterfaceOrientations
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationLandscapeLeft
56 | UIInterfaceOrientationLandscapeRight
57 |
58 | UISupportedInterfaceOrientations~ipad
59 |
60 | UIInterfaceOrientationPortrait
61 | UIInterfaceOrientationPortraitUpsideDown
62 | UIInterfaceOrientationLandscapeLeft
63 | UIInterfaceOrientationLandscapeRight
64 |
65 |
66 | NSAppTransportSecurity
67 |
68 | NSAllowsArbitraryLoads
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/build.xcconfig:
--------------------------------------------------------------------------------
1 | // You can add custom settings here
2 | // for example you can uncomment the following line to force distribution code signing
3 | // CODE_SIGN_IDENTITY = iPhone Distribution
4 | // ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
5 | // ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = Brand Assets;
6 |
7 | DEVELOPMENT_TEAM = QVUFUDQE96
8 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/icon-40.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/icon-40@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/icon-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/icon-60.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/icon-60@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/icon-72.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/icon-72@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/icon-76.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/icon-76@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/icon.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/App_Resources/iOS/icon@2x.png
--------------------------------------------------------------------------------
/demo/app/app.css:
--------------------------------------------------------------------------------
1 | .title {
2 | font-size: 30;
3 | horizontal-align: center;
4 | }
5 |
6 |
7 | StackLayout{
8 | padding: 20;
9 | }
10 |
11 | button {
12 | font-size: 15;
13 | margin-top: 15;
14 | horizontal-align: center;
15 | width: 100%;
16 | background-color: #2980b9;
17 | color: #FFFFFF;
18 | }
19 |
20 | .message {
21 | font-size: 20;
22 | color: #284848;
23 | horizontal-align: center;
24 | margin: 0 20;
25 | text-align: center;
26 | }
27 |
--------------------------------------------------------------------------------
/demo/app/app.js:
--------------------------------------------------------------------------------
1 | var application = require("application");
2 | application.start({ moduleName: "main-page" });
3 |
--------------------------------------------------------------------------------
/demo/app/main-page.js:
--------------------------------------------------------------------------------
1 |
2 | var observableModule = require("data/observable");
3 | var fs = require("file-system");
4 | var BackgroundTask = require("nativescript-background-task")
5 | var dialogs = require("ui/dialogs");
6 | var imageSource = require("image-source")
7 | var orm = require("nativescript-db-orm");
8 | var Model = orm.Model
9 | var application = require("application")
10 |
11 | var viewModel = new observableModule.Observable({
12 | 'message': '',
13 | 'loading': false
14 | })
15 |
16 | //var server = "http://192.168.0.4:3000/"
17 | var server = "http://10.0.0.102:3000/"
18 |
19 | var Person = (function(_super){
20 |
21 | __extends(Person, _super);
22 |
23 | function Person(params){
24 | _super.apply(this, params);
25 |
26 | params = params || {}
27 |
28 | this.clazz = Person
29 | this.tableName = "person"
30 | this.columns = [
31 | { name: 'id', key: true },
32 | { name: 'name', type: 'string' }
33 | ]
34 |
35 | this.attrs = {}
36 |
37 | for(i in this.columns){
38 | this.attrs[this.columns[i].name] = params[this.columns[i].name]
39 | }
40 |
41 | Model.prototype._init.call(this, this, this.attrs)
42 | }
43 |
44 | return Person
45 |
46 | })(Model)
47 |
48 | exports.loaded = function(args) {
49 | var page = args.object;
50 | page.bindingContext = viewModel;
51 |
52 | var DbChecker = orm.DbChecker
53 | var dbChecker = new DbChecker()
54 |
55 | //dbChecker.onDebug(true)
56 |
57 | dbChecker.createOrUpdate(true, "demo.db", [
58 | new Person()
59 | ], function(){
60 | console.log("orm init successful")
61 | }, function (error) {
62 | console.log("error orm init " + error)
63 | })
64 |
65 | //console.log("---------------------------------")
66 | //console.log(android.database.sqlite.SQLiteDatabase.openOrCreateDatabase("test.db", {}))
67 | //console.log("---------------------------------")
68 |
69 | }
70 |
71 | exports.onUnzip = function(){
72 |
73 | var temp = fs.knownFolders.temp();
74 | var extractPath = fs.path.join(temp.path, 'unziped_files')
75 | var zipFile = fs.path.join(temp.path, "images-2.1.zip")
76 |
77 | if(!fs.File.exists(zipFile)){
78 | showAlert('Zip file does not exists.. do zip download.')
79 | return
80 | }
81 |
82 | viewModel.set('loading', true)
83 |
84 | BackgroundTask.unzip({
85 | fromFile: zipFile,
86 | toFile: extractPath,
87 | doneCallback: function(){
88 | // done
89 |
90 | fs.Folder.fromPath(extractPath).getEntities().then(function(entities){
91 | viewModel.set('loading', false)
92 | showAlert("Unziped " + entities.length + " files to " + extractPath)
93 |
94 | }).then(function(error){
95 | viewModel.set('loading', false)
96 | showAlert('Error on list directory ' + extractPath + ': ' + error)
97 | })
98 | },
99 | errorCallback: function(error){
100 | // error
101 | viewModel.set('loading', false)
102 | showAlert('Error on extract zip: ' + error)
103 | },
104 | })
105 | }
106 |
107 | exports.onGetWebFile = function(){
108 |
109 | var temp = fs.knownFolders.temp().path;
110 | var destinationFile = fs.path.join(temp, "images-2.1.zip")
111 |
112 | viewModel.set('loading', true)
113 |
114 | BackgroundTask.getFile({
115 | url: 'http://mobilemind.com.br/makeyourself/coollife/images-2.1.zip',
116 | toFile: destinationFile,
117 | headers: [
118 | { 'CustonHeader': 'Custon Value' }
119 | ],
120 | doneCallback: function(){
121 | // done
122 | viewModel.set('loading', false)
123 |
124 | if(fs.File.exists(destinationFile)){
125 | showAlert("download success in path " + destinationFile);
126 | }else{
127 | showAlert("ops.. file not downloaded");
128 | }
129 |
130 | },
131 | errorCallback: function(message){
132 | // error
133 | viewModel.set('loading', false)
134 | showAlert("Ops.. download error: " + message);
135 | },
136 | })
137 | }
138 |
139 | exports.onGetPartialWebFile = function() {
140 | var temp = fs.knownFolders.temp().path;
141 | var destinationFile = fs.path.join(temp, "large_file.pdf")
142 |
143 | viewModel.set('loading', true)
144 |
145 | BackgroundTask.getFile({
146 | url: server + 'partial-download',
147 | toFile: destinationFile,
148 | partBytesSize: 0, // use default
149 | checkPartialDownload: true,
150 | headers: [
151 |
152 | ],
153 | doneCallback: function(){
154 | // done
155 | viewModel.set('loading', false)
156 |
157 | if(fs.File.exists(destinationFile)){
158 | showAlert("download success in path " + destinationFile);
159 | }else{
160 | showAlert("ops.. file not downloaded");
161 | }
162 |
163 | },
164 | errorCallback: function(obj){
165 | // error
166 | viewModel.set('loading', false)
167 | showAlert("Ops.. download error: " + obj[1]);
168 | },
169 | })
170 | }
171 |
172 | exports.onCopyFiles = function(){
173 | var temp = fs.knownFolders.temp().path;
174 | var extractPath = fs.path.join(temp, 'unziped_files')
175 | var movePath = fs.path.join(temp, "moved_files")
176 |
177 | if(!fs.Folder.exists(extractPath)){
178 | showAlert('Unziped folder does not exists.. do unzip file.')
179 | return
180 | }
181 |
182 | viewModel.set('loading', true)
183 |
184 | BackgroundTask.copyFiles({
185 | fromFile: extractPath,
186 | toFile: movePath,
187 | doneCallback: function(){
188 | viewModel.set('loading', false)
189 | // done
190 | fs.Folder.fromPath(movePath).getEntities().then(function(entities){
191 | showAlert("Moved " + entities.length + " files to " + movePath)
192 | }).then(function(error){
193 | showAlert('Error on list directory ' + movePath + ': ' + error)
194 | })
195 | },
196 | errorCallback: function(error){
197 | // error
198 | viewModel.set('loading', false)
199 | showAlert('Error on move files: ' + error)
200 | },
201 | })
202 | }
203 |
204 |
205 | exports.onSaveLargeFile = function(){
206 | var current = fs.knownFolders.currentApp()
207 | var videoPath = fs.path.join(current.path, 'res/big_buck_bunny.mp4')
208 | var imagePath = fs.path.join(current.path, 'res/mobilemind.png')
209 | var temp = fs.knownFolders.temp().path;
210 |
211 | viewModel.set('loading', true)
212 |
213 | var img = imageSource.fromFile(imagePath);
214 |
215 | BackgroundTask.saveLargeFiles({
216 | files: [{
217 | fileSrc: videoPath,
218 | fileDst: fs.path.join(temp, "big_buck_bunny.mp4")
219 | },{
220 | image: img,
221 | fileDst: fs.path.join(temp, "image.png")
222 | }],
223 | doneCallback: function(result){
224 | viewModel.set('loading', false)
225 | showAlert('large file saved')
226 | },
227 | errorCallback: function(error){
228 | viewModel.set('loading', false)
229 | showAlert('Error on save large file: ' + error)
230 | }
231 | })
232 | }
233 |
234 | exports.onPostFile = function(){
235 |
236 | var current = fs.knownFolders.currentApp()
237 | var videoPath = fs.path.join(current.path, 'res/big_buck_bunny.mp4')
238 |
239 | viewModel.set('loading', true)
240 |
241 | BackgroundTask.postFiles({
242 | url: server,
243 | formData: false,
244 | gzip: true,
245 | items: [{
246 | fileSrc: videoPath,
247 | jsonKey: 'video',
248 | identifier: '10',
249 | data: {
250 | name: 'jonh',
251 | age: '33'
252 | }
253 | }],
254 | headers: [
255 | { 'X-Auth-Toke': 'token' },
256 | {'Content-Type': 'application/json'}
257 | ],
258 | doneCallback: function(results) {
259 | viewModel.set('loading', false)
260 | showAlert('post result: ' + results[0].result)
261 | },
262 | errorCallback: function(error) {
263 | viewModel.set('loading', false)
264 | showAlert('Error post file file: ' + error)
265 | }
266 | })
267 | }
268 |
269 | exports.onPostData = function(){
270 |
271 | var current = fs.knownFolders.currentApp()
272 | var videoPath = fs.path.join(current.path, 'res/big_buck_bunny.mp4')
273 |
274 | viewModel.set('loading', true)
275 |
276 | BackgroundTask.postData({
277 | url: server + 'raw',
278 | formData: false,
279 | gzip: true,
280 | items: [{
281 | fileSrc: videoPath,
282 | identifier: '10',
283 | }],
284 | headers: [
285 | {"Content-Type": "application/octet-stream"}
286 | ],
287 | doneCallback: function(results) {
288 | viewModel.set('loading', false)
289 | showAlert('post result: ' + results[0].result)
290 | },
291 | errorCallback: function(error) {
292 | viewModel.set('loading', false)
293 | showAlert('Error post file file: ' + error)
294 | }
295 | })
296 | }
297 |
298 | exports.onDbBatch = function () {
299 |
300 | var items = []
301 |
302 | for(var i = 0; i < 1000; i++){
303 | items.push({
304 | query: "insert into person (name) values (?)",
305 | args: ["Person " + i]
306 | })
307 | }
308 |
309 | viewModel.set('loading', true)
310 |
311 | BackgroundTask.dbBatch({
312 | dbName: "demo.db",
313 | items: items,
314 | doneCallback: function(){
315 |
316 | viewModel.set('loading', false)
317 |
318 | var model = new Person()
319 |
320 | model.count(function(err, result){
321 | showAlert('data count after batch insert: ' + result)
322 | })
323 |
324 | },
325 | errorCallback: function (error) {
326 | viewModel.set('loading', false)
327 | showAlert('Error db batch: ' + error)
328 | }
329 | })
330 |
331 | }
332 |
333 | exports.onSplitFile = function () {
334 |
335 | var current = fs.knownFolders.currentApp()
336 | var videoPath = fs.path.join(current.path, 'res/big_buck_bunny.mp4')
337 | var temp = fs.knownFolders.temp().path;
338 |
339 | viewModel.set('loading', true)
340 |
341 | BackgroundTask.splitFiles({
342 | files: [{
343 | fileSrc: videoPath,
344 | filePartPath: temp,
345 | filePartName: 'video_',
346 | filePartSufix: 'part',
347 | filePartMaxSize: 1 // 1MB
348 | }],
349 | doneCallback: function(result){
350 | viewModel.set('loading', false)
351 | console.log(result[0].fileParts)
352 | showAlert('Split OK. Parts: ' + result[0].fileParts)
353 | },
354 | errorCallback: function(error){
355 | viewModel.set('loading', false)
356 | showAlert('Error on split file: ' + error)
357 | }
358 | })
359 | }
360 |
361 | function showAlert(message) {
362 | var options = {
363 | title: "Background Tasks",
364 | message: message,
365 | okButtonText: "OK"
366 | }
367 |
368 | dialogs.alert(options)
369 | }
370 |
371 |
372 |
373 |
--------------------------------------------------------------------------------
/demo/app/main-page.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/demo/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "android": {
3 | "v8Flags": "--expose_gc"
4 | },
5 | "main": "app.js",
6 | "name": "tns-template-hello-world",
7 | "version": "2.5.0"
8 | }
--------------------------------------------------------------------------------
/demo/app/res/big_buck_bunny.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/res/big_buck_bunny.mp4
--------------------------------------------------------------------------------
/demo/app/res/mobilemind.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/demo/app/res/mobilemind.png
--------------------------------------------------------------------------------
/demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "NativeScript Application",
3 | "license": "SEE LICENSE IN ",
4 | "readme": "NativeScript Application",
5 | "repository": "",
6 | "nativescript": {
7 | "id": "org.nativescript.demo",
8 | "tns-android": {
9 | "version": "3.4.0"
10 | }
11 | },
12 | "dependencies": {
13 | "moment": "^2.12.0",
14 | "nativescript-background-task": "file:../",
15 | "nativescript-db-orm": "https://github.com/mobilemindtec/nativescript-db-orm.git",
16 | "nativescript-sqlite": "^1.1.2",
17 | "nativescript-theme-core": "~1.0.2",
18 | "tns-core-modules": "^3.4.0"
19 | },
20 | "devDependencies": {
21 | "babel-traverse": "6.26.0",
22 | "babel-types": "6.26.0",
23 | "babylon": "6.18.0",
24 | "lazy": "1.0.11",
25 | "nativescript-dev-android-snapshot": "^0.*.*"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 |
2 | export * from "./background-task"
--------------------------------------------------------------------------------
/native-src/android/NativescriptBackgroundTask.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/native-src/android/android.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/native-src/android/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/native-src/android/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | generateDebugSources
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/native-src/android/app/build.gradle:
--------------------------------------------------------------------------------
1 |
2 | apply plugin: 'com.android.library'
3 |
4 |
5 | android {
6 | compileSdkVersion 25
7 | buildToolsVersion "25.0.2"
8 |
9 | defaultConfig {
10 | minSdkVersion 17
11 | targetSdkVersion 25
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | lintOptions {
20 | abortOnError false
21 | }
22 | useLibrary 'org.apache.http.legacy'
23 | }
24 |
25 | dependencies {
26 |
27 | compile('br.com.mobilemind.api:mobilemind-droid-util:2.1', {
28 | exclude group: 'com.google.android', module: 'android'
29 | exclude group: 'com.google.android', module: 'support-v4'
30 | // exclude group: 'br.com.mobilemind.api', module: 'mobilemind-utils'
31 | })
32 | //compile 'br.com.mobilemind.api:mobilemind-utils:1.3'
33 | compile fileTree(dir: 'libs', include: ['*.jar'])
34 | }
35 |
36 | // task to delete the old jar
37 | task deleteOldJar(type: Delete) {
38 | delete 'release/MobileMindNSTaskPlugin.aar'
39 | }
40 |
41 | // task to export contents as jar
42 | task exportJar(type: Copy) {
43 | from('build/outputs/aar')
44 | into('release')
45 | include('app-release.aar')
46 | // name the plugin
47 | rename('app-release.aar','MobileMindNSTaskPlugin.aar')
48 | }
49 |
50 | exportJar.dependsOn(deleteOldJar, build)
51 |
--------------------------------------------------------------------------------
/native-src/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /opt/android-studio/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/native-src/android/app/release/MobileMindNSTaskPlugin.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/native-src/android/app/release/MobileMindNSTaskPlugin.aar
--------------------------------------------------------------------------------
/native-src/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/native-src/android/app/src/main/java/br/com/mobilemind/ns/task/CompleteCallback.java:
--------------------------------------------------------------------------------
1 | package br.com.mobilemind.ns.task;
2 |
3 | /**
4 | * Created by ricardo on 3/22/16.
5 | */
6 | public interface CompleteCallback {
7 |
8 | void onComplete(Object result);
9 |
10 | void onError(Object error);
11 | }
12 |
--------------------------------------------------------------------------------
/native-src/android/app/src/main/java/br/com/mobilemind/ns/task/CopyFilesTask.java:
--------------------------------------------------------------------------------
1 | package br.com.mobilemind.ns.task;
2 |
3 | import android.os.AsyncTask;
4 | import android.util.Log;
5 | import java.io.BufferedInputStream;
6 | import java.io.File;
7 | import java.io.FileInputStream;
8 | import java.io.FileOutputStream;
9 | import java.io.IOException;
10 |
11 |
12 | /**
13 | * Created by ricardo on 3/22/16.
14 | */
15 | public class CopyFilesTask extends AsyncTask {
16 |
17 | private CompleteCallback callback;
18 | private File toFile;
19 | private File fromFile;
20 |
21 |
22 | public CopyFilesTask(CompleteCallback callback,String fromFile, String toFile)
23 | {
24 | Log.i("CopyFilesTask", "toFile=" + toFile);
25 | Log.i("CopyFilesTask", "fromFile=" + fromFile);
26 |
27 | this.callback = callback;
28 | this.toFile = new File(toFile);
29 | this.fromFile = new File(fromFile);
30 | }
31 |
32 | @Override
33 | protected Object doInBackground(Object[] params) {
34 |
35 | try
36 | {
37 | copyDirectoryOneLocationToAnotherLocation(this.fromFile, this.toFile);
38 | }
39 | catch(Exception e)
40 | {
41 | Log.e("CopyFileTask", e.getMessage(), e);
42 | return e;
43 | }
44 |
45 | return null;
46 | }
47 |
48 | @Override
49 | protected void onPostExecute(Object o) {
50 | super.onPostExecute(o);
51 |
52 | if(o instanceof Exception){
53 | if (callback != null) {
54 | callback.onError(((Exception) o).getMessage());
55 | }
56 | }else {
57 | if (callback != null) {
58 | Log.i("CopyFileTask", "done callback");
59 | callback.onComplete(o);
60 | } else {
61 | Log.i("CopyFileTask", "done null callback");
62 | }
63 | }
64 | }
65 |
66 | public static void doIt(CompleteCallback callback, String fromFile, String toFile){
67 | new CopyFilesTask(callback, fromFile, toFile).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
68 | }
69 |
70 |
71 | public void copyDirectoryOneLocationToAnotherLocation(File sourceLocation, File targetLocation) throws IOException {
72 |
73 |
74 | //Log.i("CopyFileTask", "copy " + sourceLocation + " to " + targetLocation);
75 |
76 | if (sourceLocation.isDirectory()) {
77 |
78 | if(targetLocation.exists() && targetLocation.isFile()){
79 |
80 | targetLocation.delete();
81 | }
82 |
83 | if (!targetLocation.exists()) {
84 |
85 | targetLocation.mkdir();
86 | }
87 |
88 | String[] children = sourceLocation.list();
89 |
90 |
91 | for (int i = 0; i < sourceLocation.listFiles().length; i++) {
92 | File newsource = new File(sourceLocation, children[i]);
93 | File newtarget = new File(targetLocation, children[i]);
94 | copyDirectoryOneLocationToAnotherLocation(newsource, newtarget);
95 | }
96 | } else {
97 |
98 | if(targetLocation.exists())
99 | targetLocation.delete();
100 |
101 | BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceLocation));
102 | FileOutputStream fout = new FileOutputStream(targetLocation);
103 | int count = 0;
104 | byte buffer[] = new byte[1024];
105 | while ((count = bis.read(buffer)) != -1) {
106 | fout.write(buffer, 0, count);
107 | }
108 |
109 | fout.close();
110 | bis.close();
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/native-src/android/app/src/main/java/br/com/mobilemind/ns/task/DbInsertBatchTask.java:
--------------------------------------------------------------------------------
1 | package br.com.mobilemind.ns.task;
2 |
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteDatabase;
5 | import android.os.AsyncTask;
6 | import android.util.Log;
7 |
8 | import java.util.ArrayList;
9 | import java.util.Arrays;
10 | import java.util.LinkedList;
11 | import java.util.List;
12 |
13 | import br.com.mobilemind.ns.task.sql.DBHelper;
14 |
15 | /**
16 | * Created by ricardo on 1/25/17.
17 | */
18 |
19 | public class DbInsertBatchTask extends AsyncTask {
20 |
21 | private CompleteCallback callback;
22 | private DBHelper helper;
23 | private Context context;
24 | private String dbName;
25 | private List sqls;
26 |
27 | class Query {
28 | String query;
29 | String insertQuery;
30 | String updateQuery;
31 | Object[] params;
32 | String tableName;
33 | String updateKey;
34 | String updateKeyValue;
35 |
36 | public Query(String query, Object[] params) {
37 | this.query = query;
38 | this.params = params;
39 | }
40 |
41 | public Query(String insertQuery, String updateQuery, String tableName, String updateKey, String updateKeyValue, Object[] params) {
42 | this.insertQuery = insertQuery;
43 | this.updateQuery = updateQuery;
44 | this.tableName = tableName;
45 | this.updateKey = updateKey;
46 | this.updateKeyValue = updateKeyValue;
47 | this.params = params;
48 | }
49 | }
50 |
51 | public DbInsertBatchTask(Context context, String dbName, CompleteCallback callback) {
52 | this.callback = callback;
53 | this.context = context;
54 | this.dbName = dbName;
55 | sqls = new LinkedList();
56 | }
57 |
58 | public void addQuery(String sql, Object[] params) {
59 | sqls.add(new Query(sql, params));
60 | }
61 |
62 | public void addInsertOrUpdateQuery(String insertQuery, String updateQuery, String tableName, String updateKey, String updateKeyValue, Object[] params) {
63 | sqls.add(new Query(insertQuery, updateQuery, tableName, updateKey, updateKeyValue, params));
64 | }
65 |
66 | @Override
67 | protected Object doInBackground(Object[] params) {
68 | SQLiteDatabase db = null;
69 | try {
70 | Log.i("DbInsertBatchTask", "## open database " + this.dbName);
71 | helper = new DBHelper(context, this.dbName, 1);
72 | db = helper.getReadableDatabase();
73 |
74 | Log.i("DbInsertBatchTask", "## database " + this.dbName + " is isOpen=" + db.isOpen());
75 |
76 | db.beginTransaction();
77 |
78 |
79 | for (Query q : sqls) {
80 | if (q.query != null) {
81 | //Log.i("DbInsertBatchTask", "## execute insert [" + q.query + "]");
82 | helper.executeQuery(q.query, q.params, db);
83 | } else {
84 | Long id = helper.getDataId("select id from " + q.tableName + " where " + q.updateKey + " = ?", new String[]{q.updateKeyValue});
85 | if(id == null){
86 | //Log.i("DbInsertBatchTask", "## execute insert tableName="+q.tableName+", updateKeyValue = " + q.updateKeyValue);
87 | helper.executeQuery(q.insertQuery, q.params, db);
88 | } else {
89 | //Log.i("DbInsertBatchTask", "## execute update tableName="+q.tableName+", updateKeyValue = " + q.updateKeyValue);
90 | List args = new LinkedList(Arrays.asList(q.params));
91 | args.add(q.updateKeyValue);
92 | q.params = args.toArray();
93 | helper.executeQuery(q.updateQuery + " where " + q.updateKey + " = ?", q.params, db);
94 | }
95 | }
96 | }
97 | db.setTransactionSuccessful();
98 | } catch (Exception e) {
99 | Log.e("DbInsertBatchTask", e.getMessage(), e);
100 | return e;
101 | } finally {
102 | if (db != null) {
103 | db.endTransaction();
104 | db.close();
105 | }
106 |
107 | if(helper != null)
108 | helper.close();
109 | }
110 |
111 | return null;
112 | }
113 |
114 | @Override
115 | protected void onPostExecute(Object o) {
116 | super.onPostExecute(o);
117 |
118 | if(o instanceof Exception){
119 | if (callback != null) {
120 | callback.onError(((Exception) o).getMessage());
121 | }
122 | }else {
123 | if (callback != null) {
124 | Log.i("DbInsertBatchTask", "done callback");
125 | callback.onComplete(o);
126 | } else {
127 | Log.i("DbInsertBatchTask", "done null callback");
128 | }
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/native-src/android/app/src/main/java/br/com/mobilemind/ns/task/HttpPostData.java:
--------------------------------------------------------------------------------
1 | package br.com.mobilemind.ns.task;
2 |
3 | import java.util.Map;
4 | import java.util.HashMap;
5 | import java.util.Set;
6 | import java.io.Serializable;
7 |
8 | public class HttpPostData implements Serializable{
9 | public String identifier;
10 | public String fileSrc;
11 | public String result;
12 | public String jsonKey;
13 | protected Map json;
14 | protected Map responseHeaders;
15 |
16 |
17 | public HttpPostData(String fileSrc, String jsonKey) {
18 | this.fileSrc = fileSrc;
19 | this.jsonKey = jsonKey;
20 | this.responseHeaders = new HashMap();
21 | json = new HashMap();
22 | }
23 |
24 | public HttpPostData addJsonValue(String key, String value) {
25 | json.put(key, value);
26 | return this;
27 | }
28 |
29 | public String[] getHeaderNames() {
30 | Set names = this.responseHeaders.keySet();
31 | return names.toArray(new String[names.size()]);
32 | }
33 |
34 | public String getHeaderValue(String name) {
35 | return this.responseHeaders.get(name);
36 | }
37 |
38 | public Map getHeaders() {
39 | return this.responseHeaders;
40 | }
41 |
42 | }
--------------------------------------------------------------------------------
/native-src/android/app/src/main/java/br/com/mobilemind/ns/task/HttpPostDataTask.java:
--------------------------------------------------------------------------------
1 | package br.com.mobilemind.ns.task;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.os.AsyncTask;
6 | import android.util.Log;
7 |
8 | import org.apache.http.Header;
9 | import org.apache.http.HttpEntity;
10 | import org.apache.http.HttpResponse;
11 | import org.apache.http.NameValuePair;
12 | import org.apache.http.client.HttpClient;
13 | import org.apache.http.client.entity.UrlEncodedFormEntity;
14 | import org.apache.http.client.methods.HttpPost;
15 | import org.apache.http.conn.ConnectTimeoutException;
16 | import org.apache.http.conn.HttpHostConnectException;
17 | import org.apache.http.entity.ByteArrayEntity;
18 | import org.apache.http.entity.InputStreamEntity;
19 | import org.apache.http.impl.client.DefaultHttpClient;
20 | import org.apache.http.message.BasicNameValuePair;
21 | import org.json.JSONObject;
22 |
23 | import java.io.BufferedReader;
24 | import java.io.ByteArrayInputStream;
25 | import java.io.ByteArrayOutputStream;
26 | import java.io.FileInputStream;
27 | import java.io.IOException;
28 | import java.io.InputStream;
29 | import java.io.InputStreamReader;
30 | import java.util.ArrayList;
31 | import java.util.HashMap;
32 | import java.util.List;
33 | import java.util.Map;
34 | import java.util.Set;
35 |
36 | import br.com.mobilemind.api.droidutil.rest.RestException;
37 | import br.com.mobilemind.api.rest.RestStatus;
38 | import br.com.mobilemind.api.rest.RestTools;
39 | import br.com.mobilemind.api.security.key.Base64;
40 |
41 | /**
42 | * Created by ricardo on 1/23/17.
43 | */
44 |
45 | public class HttpPostDataTask extends AsyncTask {
46 |
47 | private CompleteCallback callback;
48 | private ArrayList postDataFiles;
49 | private Map httpHeaders;
50 | private String url;
51 | private boolean useGzip;
52 | public int splitMaxSize;
53 | private boolean resultToUtf8 = true;
54 | private String charset = RestTools.CHARSET_UTF8;
55 |
56 | public HttpPostDataTask(String url, CompleteCallback callback) {
57 | this.httpHeaders = new HashMap();
58 | this.callback = callback;
59 | this.postDataFiles = new ArrayList();
60 | this.url = url;
61 | }
62 |
63 | public HttpPostDataTask addData(HttpPostData data){
64 | this.postDataFiles.add(data);
65 | return this;
66 | }
67 |
68 | public void setUseGzip(boolean useGzip) {
69 | this.useGzip = useGzip;
70 | }
71 |
72 |
73 | public void setSplitMaxSize(int splitMaxSize) {
74 | this.splitMaxSize = splitMaxSize;
75 | }
76 |
77 | public HttpPostDataTask addHeader(String key, String value) {
78 | this.httpHeaders.put(key, value);
79 | return this;
80 | }
81 |
82 | @Override
83 | protected Object doInBackground(Object[] params) {
84 |
85 | String imgs[] = new String[]{".png", ".jpeg", ".jpg"};
86 |
87 | try {
88 | for (HttpPostData postData : this.postDataFiles) {
89 |
90 | boolean isImg = false;
91 |
92 | for (String s : imgs) {
93 | if (postData.fileSrc.toLowerCase().endsWith(s)) {
94 | isImg = true;
95 | break;
96 | }
97 | }
98 | ByteArrayOutputStream bStream = new ByteArrayOutputStream();
99 |
100 | if (isImg) {
101 |
102 | BitmapFactory.Options options = new BitmapFactory.Options();
103 | options.inJustDecodeBounds = true;
104 |
105 | BitmapFactory.decodeFile(postData.fileSrc, options);
106 | options.inSampleSize = calculateInSampleSize(options, 500, 500);
107 | options.inJustDecodeBounds = false;
108 | options.inPreferredConfig = Bitmap.Config.RGB_565;
109 |
110 | Bitmap bitmap = BitmapFactory.decodeFile(postData.fileSrc, options);
111 |
112 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bStream);
113 | bitmap.recycle();
114 | } else {
115 | FileInputStream ios = new FileInputStream(postData.fileSrc);
116 | byte[] buffer = new byte[4096];
117 | int read = 0;
118 | while ((read = ios.read(buffer)) != -1) {
119 | bStream.write(buffer, 0, read);
120 | }
121 | buffer = null;
122 | ios.close();
123 | }
124 |
125 | bStream.flush();
126 |
127 | boolean isJson = false, isFormData = false, isBinary = false, isMultiPart = false;
128 |
129 | if(!this.httpHeaders.containsKey("Content-Type") && !this.httpHeaders.containsKey("content-type")){
130 | this.httpHeaders.put("Content-Type", "application/json");
131 | }
132 |
133 | String contentType = this.httpHeaders.get("Content-Type");
134 |
135 | if(contentType.toLowerCase().endsWith("binary/octet-stream") || contentType .toLowerCase().endsWith("application/octet-stream")){
136 | isBinary = true;
137 | }else if(contentType .toLowerCase().endsWith("application/json")){
138 | isJson = true;
139 | } else if(contentType.toLowerCase().endsWith("application/x-www-form-urlencoded") || contentType.toLowerCase().endsWith("application/form-data")){
140 | isFormData = true;
141 | }
142 |
143 |
144 | final int contentSize = bStream.size();
145 | final int splitSize = this.splitMaxSize;
146 | final int mb = 1048576;
147 | final int kb = 1024 * 4;
148 | int partSize = mb * splitSize;
149 | int len = 0;
150 | int partCount = 0;
151 |
152 | if(partSize > 0){
153 | partCount = contentSize / partSize;
154 |
155 | if(contentSize % partSize > 0)
156 | partCount++;
157 |
158 | }else{
159 | partSize = contentSize;
160 | partCount = 1;
161 | }
162 |
163 | for(int i = 0; i < partCount; i++) {
164 | byte[] buf = null;
165 | HttpClient httpclient = new DefaultHttpClient();
166 | HttpPost httppost = new HttpPost(this.url);
167 |
168 | if(contentSize % partSize > 0 && i == partCount - 1){
169 | len = contentSize % partSize;
170 | }else{
171 | len = partSize;
172 | }
173 |
174 | if(partCount == 1){
175 | buf = bStream.toByteArray();
176 | }else{
177 | buf = new byte[partSize];
178 | bStream.write(buf, i * partSize, len);
179 | }
180 |
181 | String contentData = null;
182 | if(this.useGzip){
183 | contentData = Base64.encodeBytes(buf, Base64.GZIP);
184 | }else{
185 | contentData = Base64.encodeBytes(buf);
186 | }
187 |
188 | if(isJson || isFormData){
189 | postData.json.put(postData.jsonKey, contentData);
190 | }
191 |
192 | int postLength = contentData.length();
193 |
194 | if(isFormData){
195 |
196 | Set keys = postData.json.keySet();
197 | List nameValuePairs = new ArrayList(keys.size());
198 |
199 | for (String key : keys) {
200 | nameValuePairs.add(new BasicNameValuePair(key, postData.json.get(key)));
201 | }
202 |
203 | httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
204 |
205 | postLength = new JSONObject(postData.json).toString().length();
206 |
207 | Log.i("HttpPostDataTask", "post form-data content");
208 |
209 | }else if(isJson){
210 |
211 | String postDataStr = new JSONObject(postData.json).toString();
212 | httppost.setEntity(new ByteArrayEntity(postDataStr.getBytes(
213 | charset)));
214 |
215 | postLength = postDataStr.length();
216 | Log.i("HttpPostDataTask", "post json content");
217 | }
218 | else if(isBinary){
219 | httppost.setEntity(new ByteArrayEntity(buf));
220 | }
221 |
222 | for (String key : this.httpHeaders.keySet())
223 | httppost.setHeader(key, this.httpHeaders.get(key));
224 |
225 |
226 | //httppost.setHeader("Content-Length", postLength + "");
227 |
228 | Log.i("HttpPostDataTask", "post binary content");
229 | execute(httpclient, httppost, postData);
230 |
231 |
232 |
233 | bStream.close();
234 | bStream = null;
235 |
236 |
237 | Runtime.getRuntime().gc();
238 | System.gc();
239 | Thread.sleep(100);
240 |
241 | }
242 | }
243 | } catch (Exception e) {
244 | Log.e("HttpPostDataTask", e.getMessage(), e);
245 | return e;
246 | }
247 |
248 | return null;
249 | }
250 |
251 | private void execute(HttpClient httpclient, HttpPost httppost, HttpPostData postData){
252 |
253 | HttpResponse response = null;
254 |
255 | try {
256 | response = httpclient.execute(httppost);
257 | } catch (HttpHostConnectException e) {
258 | if (e.getMessage().contains("refused")) {
259 | throw new RestException(RestStatus.HTTP_CONNECTION_REFUSED, "conneciton refused");
260 | } else {
261 | throw new RestException(e.getMessage(), e);
262 | }
263 | } catch (ConnectTimeoutException e) {
264 | throw new RestException(RestStatus.HTTP_CONNECTION_TIME_OUT, "connection timeout");
265 | } catch (Exception e) {
266 | throw new RestException(e.getMessage(), e);
267 | }
268 |
269 |
270 | Header headers[] = response.getAllHeaders();
271 |
272 | for(Header header : headers)
273 | postData.responseHeaders.put(header.getName(), header.getValue());
274 |
275 | HttpEntity httpEntity = response.getEntity();
276 | InputStream instream = null;
277 | String result = null;
278 |
279 | if (httpEntity != null) {
280 | try {
281 | instream = httpEntity.getContent();
282 | result = convertStreamToString(instream);
283 | postData.result = result;
284 | Log.i("HttpPostDataTask", "result = [" + result + "]");
285 | } catch (Exception e) {
286 | throw new RestException(e.getMessage(), e);
287 | } finally {
288 | if (instream != null) {
289 | try {
290 | instream.close();
291 | } catch (IOException io) {
292 | }
293 | }
294 | }
295 | }else {
296 | Log.i("HttpPostDataTask", "httpEntity is null");
297 | }
298 |
299 | if(response.getStatusLine().getStatusCode() != RestStatus.OK){
300 | Log.i("HttpPostDataTask", "response code = [" + response.getStatusLine().getStatusCode() + "]");
301 | Log.i("HttpPostDataTask", "response reason = [" + response.getStatusLine().getReasonPhrase() + "]");
302 | throw new RestException(response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), result);
303 | }
304 | }
305 |
306 | @Override
307 | protected void onPostExecute(Object o) {
308 | super.onPostExecute(o);
309 |
310 | try{
311 | if(o instanceof RestException){
312 | JSONObject json = new JSONObject();
313 | json.put("statusCode", ((RestException)o).getHttpSatatus());
314 | json.put("content", ((RestException)o).getContent());
315 | json.put("message", ((RestException)o).getMessage());
316 | Log.i("HttpPostDataTask", "done with error " + json.toString());
317 | if (callback != null) {
318 | callback.onError(json.toString());
319 | }else {
320 | Log.i("HttpPostDataTask", "done null callback");
321 | }
322 | }else if(o instanceof Exception){
323 | if (callback != null) {
324 | callback.onError(((Exception) o).getMessage());
325 | } else {
326 | Log.i("HttpPostDataTask", "done null callback");
327 | }
328 | }else {
329 | if (callback != null) {
330 | Log.i("HttpPostDataTask", "done callback");
331 | callback.onComplete(this.postDataFiles.toArray());
332 | } else {
333 | Log.i("HttpPostDataTask", "done null callback");
334 | }
335 | }
336 | }catch(Exception e){
337 | Log.e("HttpPostDataTask", "error on callback call: " + e.getMessage(), e);
338 | }
339 | }
340 |
341 | public static int calculateInSampleSize(
342 | BitmapFactory.Options options, int reqWidth, int reqHeight) {
343 | // Raw height and width of image
344 | final int height = options.outHeight;
345 | final int width = options.outWidth;
346 | int inSampleSize = 1;
347 |
348 | if (height > reqHeight || width > reqWidth) {
349 |
350 | final int halfHeight = height / 2;
351 | final int halfWidth = width / 2;
352 |
353 | // Calculate the largest inSampleSize value that is a power of 2 and keeps both
354 | // height and width larger than the requested height and width.
355 | while ((halfHeight / inSampleSize) >= reqHeight
356 | && (halfWidth / inSampleSize) >= reqWidth) {
357 | inSampleSize *= 2;
358 | }
359 | }
360 |
361 | return inSampleSize;
362 | }
363 |
364 | public String convertStreamToString(InputStream is)
365 | throws IOException {
366 | /*
367 | * To convert the InputStream to String we use the
368 | * BufferedReader.readLine() method. We iterate until the BufferedReader
369 | * return null which means there's no more data to read. Each line will
370 | * appended to a StringBuilder and returned as String.
371 | */
372 | BufferedReader reader = null;
373 |
374 | if (resultToUtf8) {
375 | reader = new BufferedReader(new InputStreamReader(is,
376 | "UTF-8"));
377 | } else {
378 | reader = new BufferedReader(new InputStreamReader(is));
379 | }
380 |
381 | StringBuilder sb = new StringBuilder();
382 |
383 | String line = null;
384 | while ((line = reader.readLine()) != null) {
385 | sb.append(line).append("\n");
386 | }
387 |
388 | return sb.toString();
389 | }
390 | }
391 |
--------------------------------------------------------------------------------
/native-src/android/app/src/main/java/br/com/mobilemind/ns/task/HttpPostFileFormDataTask.java:
--------------------------------------------------------------------------------
1 | package br.com.mobilemind.ns.task;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.os.AsyncTask;
6 | import android.util.Log;
7 |
8 | import org.apache.http.Header;
9 | import org.apache.http.HttpEntity;
10 | import org.apache.http.HttpResponse;
11 | import org.apache.http.NameValuePair;
12 | import org.apache.http.client.HttpClient;
13 | import org.apache.http.client.entity.UrlEncodedFormEntity;
14 | import org.apache.http.client.methods.HttpPost;
15 | import org.apache.http.conn.ConnectTimeoutException;
16 | import org.apache.http.conn.HttpHostConnectException;
17 | import org.apache.http.impl.client.DefaultHttpClient;
18 | import org.apache.http.message.BasicNameValuePair;
19 | import org.json.JSONObject;
20 |
21 | import java.io.BufferedReader;
22 | import java.io.ByteArrayOutputStream;
23 | import java.io.FileInputStream;
24 | import java.io.IOException;
25 | import java.io.InputStream;
26 | import java.io.InputStreamReader;
27 | import java.util.ArrayList;
28 | import java.util.HashMap;
29 | import java.util.List;
30 | import java.util.Map;
31 | import java.util.Set;
32 |
33 | import br.com.mobilemind.api.droidutil.rest.RestException;
34 | import br.com.mobilemind.api.rest.RestStatus;
35 | import br.com.mobilemind.api.security.key.Base64;
36 |
37 | /**
38 | * Created by ricardo on 1/23/17.
39 | */
40 |
41 | public class HttpPostFileFormDataTask extends AsyncTask {
42 |
43 | private CompleteCallback callback;
44 | private ArrayList postDataFiles;
45 | private Map httpHeaders;
46 | private String url;
47 | private boolean useGzip;
48 | private boolean resultToUtf8 = true;
49 |
50 | public HttpPostFileFormDataTask(String url, CompleteCallback callback) {
51 | this.httpHeaders = new HashMap();
52 | this.callback = callback;
53 | this.postDataFiles = new ArrayList();
54 | this.url = url;
55 | }
56 |
57 | public HttpPostFileFormDataTask addData(HttpPostData data){
58 | this.postDataFiles.add(data);
59 | return this;
60 | }
61 |
62 | public void setUseGzip(boolean useGzip) {
63 | this.useGzip = useGzip;
64 | }
65 |
66 | public HttpPostFileFormDataTask addHeader(String key, String value) {
67 | this.httpHeaders.put(key, value);
68 | return this;
69 | }
70 |
71 | @Override
72 | protected Object doInBackground(Object[] params) {
73 |
74 | String imgs[] = new String[]{".png", ".jpeg", ".jpg"};
75 |
76 | try {
77 | for (HttpPostData postData : this.postDataFiles) {
78 |
79 | boolean isImg = false;
80 |
81 | for (String s : imgs) {
82 | if (postData.fileSrc.toLowerCase().endsWith(s)) {
83 | isImg = true;
84 | break;
85 | }
86 | }
87 | ByteArrayOutputStream bStream = new ByteArrayOutputStream();
88 |
89 | if (isImg) {
90 |
91 | BitmapFactory.Options options = new BitmapFactory.Options();
92 | options.inJustDecodeBounds = true;
93 |
94 | BitmapFactory.decodeFile(postData.fileSrc, options);
95 | options.inSampleSize = calculateInSampleSize(options, 500, 500);
96 | options.inJustDecodeBounds = false;
97 | options.inPreferredConfig = Bitmap.Config.RGB_565;
98 |
99 | Bitmap bitmap = BitmapFactory.decodeFile(postData.fileSrc, options);
100 |
101 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bStream);
102 | bitmap.recycle();
103 | } else {
104 | FileInputStream ios = new FileInputStream(postData.fileSrc);
105 | byte[] buffer = new byte[4096];
106 | int read = 0;
107 | while ((read = ios.read(buffer)) != -1) {
108 | bStream.write(buffer, 0, read);
109 | }
110 | buffer = null;
111 | ios.close();
112 | }
113 |
114 | bStream.flush();
115 |
116 | if(this.useGzip)
117 | postData.json.put(postData.jsonKey, Base64.encodeBytes(bStream.toByteArray(), Base64.GZIP));
118 | else
119 | postData.json.put(postData.jsonKey, Base64.encodeBytes(bStream.toByteArray()));
120 |
121 | bStream.close();
122 | bStream = null;
123 |
124 | Log.i("HttpPostFileFormDataTask", "ULR=" + this.url);
125 | Log.i("HttpPostFileFormDataTask", "FILE LEN=" + postData.json.get(postData.jsonKey).length());
126 |
127 | HttpClient httpclient = new DefaultHttpClient();
128 | HttpPost httppost = new HttpPost(this.url);
129 |
130 | Set keys = postData.json.keySet();
131 | List nameValuePairs = new ArrayList(keys.size());
132 |
133 | for(String key : keys){
134 | nameValuePairs.add(new BasicNameValuePair(key, postData.json.get(key)));
135 | }
136 |
137 | httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
138 |
139 | for (String key : this.httpHeaders.keySet())
140 | httppost.addHeader(key, this.httpHeaders.get(key));
141 |
142 |
143 | HttpResponse response = null;
144 |
145 |
146 | try {
147 | postData.json.put(postData.jsonKey, null);
148 | response = httpclient.execute(httppost);
149 | } catch (HttpHostConnectException e) {
150 | if (e.getMessage().contains("refused")) {
151 | throw new RestException(RestStatus.HTTP_CONNECTION_REFUSED, "conneciton refused");
152 | } else {
153 | throw new RestException(e.getMessage(), e);
154 | }
155 | } catch (ConnectTimeoutException e) {
156 | throw new RestException(RestStatus.HTTP_CONNECTION_TIME_OUT, "connection timeout");
157 | } catch (Exception e) {
158 | throw new RestException(e.getMessage(), e);
159 | }
160 |
161 |
162 | Header headers[] = response.getAllHeaders();
163 |
164 | for(Header header : headers)
165 | postData.responseHeaders.put(header.getName(), header.getValue());
166 |
167 | HttpEntity httpEntity = response.getEntity();
168 | InputStream instream = null;
169 | String result = null;
170 |
171 | if (httpEntity != null) {
172 | try {
173 | instream = httpEntity.getContent();
174 | result = convertStreamToString(instream);
175 | postData.result = result;
176 | Log.i("HttpPostFileFormDataTask", "result = [" + result + "]");
177 | } catch (Exception e) {
178 | throw new RestException(e.getMessage(), e);
179 | } finally {
180 | if (instream != null) {
181 | try {
182 | instream.close();
183 | } catch (IOException io) {
184 | }
185 | }
186 | }
187 | }else {
188 | Log.i("HttpPostFileFormDataTask", "httpEntity is null");
189 | }
190 |
191 | if(response.getStatusLine().getStatusCode() != RestStatus.OK){
192 | Log.i("HttpPostFileFormDataTask", "response code = [" + response.getStatusLine().getStatusCode() + "]");
193 | Log.i("HttpPostFileFormDataTask", "response reason = [" + response.getStatusLine().getReasonPhrase() + "]");
194 | throw new RestException(response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), result);
195 | }
196 |
197 |
198 | Runtime.getRuntime().gc();
199 | System.gc();
200 | Thread.sleep(1000);
201 | }
202 | } catch (Exception e) {
203 | Log.e("HttpPostFileFormDataTask", e.getMessage(), e);
204 | return e;
205 | }
206 |
207 | return null;
208 | }
209 |
210 | @Override
211 | protected void onPostExecute(Object o) {
212 | super.onPostExecute(o);
213 |
214 | try{
215 | if(o instanceof RestException){
216 | JSONObject json = new JSONObject();
217 | json.put("statusCode", ((RestException)o).getHttpSatatus());
218 | json.put("content", ((RestException)o).getContent());
219 | json.put("message", ((RestException)o).getMessage());
220 | Log.i("HttpPostFileFormDataTask", "done with error " + json.toString());
221 | if (callback != null) {
222 | callback.onError(json.toString());
223 | }else {
224 | Log.i("HttpPostFileFormDataTask", "done null callback");
225 | }
226 | }else if(o instanceof Exception){
227 | if (callback != null) {
228 | callback.onError(((Exception) o).getMessage());
229 | } else {
230 | Log.i("HttpPostFileFormDataTask", "done null callback");
231 | }
232 | }else {
233 | if (callback != null) {
234 | Log.i("HttpPostFileFormDataTask", "done callback");
235 | callback.onComplete(this.postDataFiles.toArray());
236 | } else {
237 | Log.i("HttpPostFileFormDataTask", "done null callback");
238 | }
239 | }
240 | }catch(Exception e){
241 | Log.e("HttpPostFileFormDataTask", "error on callback call: " + e.getMessage(), e);
242 | }
243 | }
244 |
245 | public static int calculateInSampleSize(
246 | BitmapFactory.Options options, int reqWidth, int reqHeight) {
247 | // Raw height and width of image
248 | final int height = options.outHeight;
249 | final int width = options.outWidth;
250 | int inSampleSize = 1;
251 |
252 | if (height > reqHeight || width > reqWidth) {
253 |
254 | final int halfHeight = height / 2;
255 | final int halfWidth = width / 2;
256 |
257 | // Calculate the largest inSampleSize value that is a power of 2 and keeps both
258 | // height and width larger than the requested height and width.
259 | while ((halfHeight / inSampleSize) >= reqHeight
260 | && (halfWidth / inSampleSize) >= reqWidth) {
261 | inSampleSize *= 2;
262 | }
263 | }
264 |
265 | return inSampleSize;
266 | }
267 |
268 | public String convertStreamToString(InputStream is)
269 | throws IOException {
270 | /*
271 | * To convert the InputStream to String we use the
272 | * BufferedReader.readLine() method. We iterate until the BufferedReader
273 | * return null which means there's no more data to read. Each line will
274 | * appended to a StringBuilder and returned as String.
275 | */
276 | BufferedReader reader = null;
277 |
278 | if (resultToUtf8) {
279 | reader = new BufferedReader(new InputStreamReader(is,
280 | "UTF-8"));
281 | } else {
282 | reader = new BufferedReader(new InputStreamReader(is));
283 | }
284 |
285 | StringBuilder sb = new StringBuilder();
286 |
287 | String line = null;
288 | while ((line = reader.readLine()) != null) {
289 | sb.append(line).append("\n");
290 | }
291 |
292 | return sb.toString();
293 | }
294 | }
295 |
--------------------------------------------------------------------------------
/native-src/android/app/src/main/java/br/com/mobilemind/ns/task/HttpPostFileTask.java:
--------------------------------------------------------------------------------
1 | package br.com.mobilemind.ns.task;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.os.AsyncTask;
6 | import android.util.Log;
7 |
8 | import org.json.JSONObject;
9 |
10 | import java.io.ByteArrayOutputStream;
11 | import java.io.FileInputStream;
12 | import java.util.ArrayList;
13 | import java.util.HashMap;
14 | import java.util.Map;
15 |
16 | import br.com.mobilemind.api.droidutil.rest.WsExecutor;
17 | import br.com.mobilemind.api.security.key.Base64;
18 | import br.com.mobilemind.api.droidutil.rest.RestException;
19 | /**
20 | * Created by ricardo on 1/23/17.
21 | */
22 |
23 | public class HttpPostFileTask extends AsyncTask {
24 |
25 | private CompleteCallback callback;
26 | private ArrayList postDataFiles;
27 | private Map httpHeaders;
28 | private String url;
29 | private boolean useGzip;
30 |
31 | public HttpPostFileTask(String url, CompleteCallback callback) {
32 | this.httpHeaders = new HashMap();
33 | this.callback = callback;
34 | this.postDataFiles = new ArrayList();
35 | this.url = url;
36 | }
37 |
38 | public HttpPostFileTask addData(HttpPostData data){
39 | this.postDataFiles.add(data);
40 | return this;
41 | }
42 |
43 | public void setUseGzip(boolean useGzip) {
44 | this.useGzip = useGzip;
45 | }
46 |
47 | public HttpPostFileTask addHeader(String key, String value) {
48 | this.httpHeaders.put(key, value);
49 | return this;
50 | }
51 |
52 | @Override
53 | protected Object doInBackground(Object[] params) {
54 |
55 | String imgs[] = new String[]{".png", ".jpeg", ".jpg"};
56 |
57 | try {
58 | for (HttpPostData postData : this.postDataFiles) {
59 |
60 | boolean isImg = false;
61 |
62 | for (String s : imgs) {
63 | if (postData.fileSrc.toLowerCase().endsWith(s)) {
64 | isImg = true;
65 | break;
66 | }
67 | }
68 | ByteArrayOutputStream bStream = new ByteArrayOutputStream();
69 |
70 | if (isImg) {
71 |
72 | BitmapFactory.Options options = new BitmapFactory.Options();
73 | options.inJustDecodeBounds = true;
74 |
75 | BitmapFactory.decodeFile(postData.fileSrc, options);
76 | options.inSampleSize = calculateInSampleSize(options, 500, 500);
77 | options.inJustDecodeBounds = false;
78 | options.inPreferredConfig = Bitmap.Config.RGB_565;
79 |
80 | Bitmap bitmap = BitmapFactory.decodeFile(postData.fileSrc, options);
81 |
82 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bStream);
83 | bitmap.recycle();
84 | } else {
85 | FileInputStream ios = new FileInputStream(postData.fileSrc);
86 | byte[] buffer = new byte[4096];
87 | int read = 0;
88 | while ((read = ios.read(buffer)) != -1) {
89 | bStream.write(buffer, 0, read);
90 | }
91 | buffer = null;
92 | ios.close();
93 | }
94 |
95 | bStream.flush();
96 |
97 | if(this.useGzip)
98 | postData.json.put(postData.jsonKey, Base64.encodeBytes(bStream.toByteArray(), Base64.GZIP));
99 | else
100 | postData.json.put(postData.jsonKey, Base64.encodeBytes(bStream.toByteArray()));
101 |
102 | bStream.close();
103 | bStream = null;
104 |
105 | String postDataStr = new JSONObject(postData.json).toString();
106 | int fileLength = postData.json.get(postData.jsonKey).length();
107 | int postLength = postDataStr.length();
108 |
109 |
110 | Log.i("HttpPostFileTask", "ULR=" + this.url);
111 | Log.i("HttpPostFileTask", "FILE LEN=" + fileLength);
112 | Log.i("HttpPostFileTask", "POST LEN=" + postLength);
113 |
114 | WsExecutor httpService = new WsExecutor(null, 30000);
115 |
116 | httpService.setBaseUrl(this.url)
117 | .setEntity(postDataStr);
118 |
119 |
120 | for (String key : this.httpHeaders.keySet())
121 | httpService.addHeaderParam(key, this.httpHeaders.get(key));
122 |
123 | //httpService.addHeaderParam("Content-Length", postLength + "");
124 |
125 | try {
126 | postData.json.put(postData.jsonKey, null);
127 | postData.result = httpService.executePostAsString();
128 | } finally {
129 | Runtime.getRuntime().gc();
130 | System.gc();
131 | Thread.sleep(1000);
132 | }
133 |
134 | Log.i("HttpPostFileTask", "FILE RESULT=" + postData.result);
135 |
136 | Map resHeaders = httpService.getResponseHeaders();
137 |
138 | for(String name : resHeaders.keySet())
139 | postData.responseHeaders.put(name, resHeaders.get(name));
140 |
141 | httpService = null;
142 |
143 | }
144 | } catch (Exception e) {
145 | Log.e("HttpPostFileTask", e.getMessage(), e);
146 | return e;
147 | }
148 |
149 | return null;
150 | }
151 |
152 | @Override
153 | protected void onPostExecute(Object o) {
154 | super.onPostExecute(o);
155 |
156 | try{
157 | if(o instanceof RestException){
158 | JSONObject json = new JSONObject();
159 | json.put("statusCode", ((RestException)o).getHttpSatatus());
160 | json.put("content", ((RestException)o).getContent());
161 | json.put("message", ((RestException)o).getMessage());
162 | Log.i("HttpPostFileTask", "done with error " + json.toString());
163 | if (callback != null) {
164 | callback.onError(json.toString());
165 | }else {
166 | Log.i("HttpPostFileTask", "done null callback");
167 | }
168 | }else if(o instanceof Exception){
169 | if (callback != null) {
170 | callback.onError(((Exception) o).getMessage());
171 | } else {
172 | Log.i("HttpPostFileTask", "done null callback");
173 | }
174 | }else {
175 | if (callback != null) {
176 | callback.onComplete(this.postDataFiles.toArray());
177 | } else {
178 | Log.i("HttpPostFileTask", "done null callback");
179 | }
180 | }
181 | }catch(Exception e){
182 | Log.e("HttpPostFileFormDataTask", "error on callback call: " + e.getMessage(), e);
183 | }
184 | }
185 |
186 | public static int calculateInSampleSize(
187 | BitmapFactory.Options options, int reqWidth, int reqHeight) {
188 | // Raw height and width of image
189 | final int height = options.outHeight;
190 | final int width = options.outWidth;
191 | int inSampleSize = 1;
192 |
193 | if (height > reqHeight || width > reqWidth) {
194 |
195 | final int halfHeight = height / 2;
196 | final int halfWidth = width / 2;
197 |
198 | // Calculate the largest inSampleSize value that is a power of 2 and keeps both
199 | // height and width larger than the requested height and width.
200 | while ((halfHeight / inSampleSize) >= reqHeight
201 | && (halfWidth / inSampleSize) >= reqWidth) {
202 | inSampleSize *= 2;
203 | }
204 | }
205 |
206 | return inSampleSize;
207 | }
208 | }
209 |
--------------------------------------------------------------------------------
/native-src/android/app/src/main/java/br/com/mobilemind/ns/task/HttpRequestToFileTask.java:
--------------------------------------------------------------------------------
1 | package br.com.mobilemind.ns.task;
2 |
3 | import android.os.AsyncTask;
4 | import android.util.Log;
5 |
6 | import java.io.BufferedInputStream;
7 | import java.io.FileOutputStream;
8 | import java.io.ByteArrayOutputStream;
9 | import java.io.InputStream;
10 | import java.io.File;
11 | import java.net.HttpURLConnection;
12 | import java.net.URL;
13 | import java.util.HashMap;
14 | import java.util.Map;
15 | import java.util.List;
16 |
17 | /**
18 | * Created by ricardo on 3/22/16.
19 | */
20 | public class HttpRequestToFileTask extends AsyncTask {
21 |
22 |
23 |
24 | private CompleteCallback callback;
25 | private String toFile;
26 | private String url;
27 | private String identifier;
28 | private boolean checkPartialDownload;
29 | private int partBytesSize = 1024 * 1024 * 2; // 2MB
30 | private Map httpHeaders;
31 |
32 |
33 | public HttpRequestToFileTask(CompleteCallback callback, String url, String toFile, String identifier)
34 | {
35 | this.callback = callback;
36 | this.toFile = toFile;
37 | this.url = url;
38 | this.identifier = identifier;
39 | this.httpHeaders = new HashMap();
40 | }
41 |
42 | public void addHeader(String name, String value){
43 | this.httpHeaders.put(name, value);
44 | }
45 |
46 | public void setCheckPartialDownload(boolean checkPartialDownload){
47 | this.checkPartialDownload = checkPartialDownload;
48 | }
49 |
50 | public void setPartBytesSize(int partBytesSize){
51 | if(partBytesSize > 0)
52 | this.partBytesSize = partBytesSize;
53 | }
54 |
55 | @Override
56 | protected Object doInBackground(Object[] params) {
57 |
58 | try {
59 |
60 | boolean supportsPartialDownload = false;
61 | long fileDownloadedSize = 0;
62 |
63 |
64 | if(this.checkPartialDownload){
65 | supportsPartialDownload = checkServerSupportPartialDownload();
66 | }
67 |
68 | Log.i("HttpRequestToFileTask", "supportsPartialDownload=" + supportsPartialDownload);
69 |
70 | while(true){
71 |
72 | URL url = new URL(this.url);
73 |
74 | Log.i("HttpRequestToFileTask", "ULR=" + this.url);
75 | Log.i("HttpRequestToFileTask", "toFile=" + this.toFile);
76 |
77 | HttpURLConnection connection = (HttpURLConnection) url.openConnection();
78 |
79 | for (String name : this.httpHeaders.keySet()){
80 | connection.setRequestProperty(name, this.httpHeaders.get(name));
81 | }
82 |
83 | if(supportsPartialDownload){
84 |
85 | File destinationFile = new File(this.toFile + ".part");
86 |
87 | if(destinationFile.exists()){
88 | fileDownloadedSize = destinationFile.length();
89 | }
90 |
91 | long rangeStart = fileDownloadedSize;
92 | long rangeEnd = fileDownloadedSize + partBytesSize;
93 |
94 | connection.setRequestProperty("Content-Range", "bytes " + rangeStart + "-" + rangeEnd + "/*");
95 |
96 | }
97 |
98 | int statusCode = connection.getResponseCode();
99 |
100 | if (statusCode >= 400) {
101 | String errorMessage = errorToString(connection.getErrorStream());
102 | throw new Exception("Download error. StatusCode: " + statusCode + ", Message: " + errorMessage);
103 | }
104 |
105 | InputStream inStream = connection.getInputStream();
106 |
107 |
108 | Log.i("HttpRequestToFileTask", "statusCode=" + statusCode);
109 |
110 | String fileDestinationName = this.toFile;
111 |
112 | if(supportsPartialDownload){
113 | fileDestinationName += ".part";
114 | }
115 |
116 | BufferedInputStream bis = new BufferedInputStream(inStream);
117 | FileOutputStream fos = new FileOutputStream(fileDestinationName, supportsPartialDownload);
118 |
119 |
120 | int BUFFER_SIZE = 20 * 1024;
121 | byte[] buffer = new byte[BUFFER_SIZE];
122 | int actual = 0;
123 | int totalRead = 0;
124 |
125 | while (actual != -1) {
126 | fos.write(buffer, 0, actual);
127 | actual = bis.read(buffer, 0, BUFFER_SIZE);
128 |
129 | if(actual > 0)
130 | totalRead += actual;
131 | }
132 |
133 | //Log.i("HttpRequestToFileTask", "totalRead=" + totalRead);
134 |
135 | fos.flush();
136 | fos.close();
137 | bis.close();
138 | inStream.close();
139 | connection.disconnect();
140 |
141 | if(!supportsPartialDownload){
142 | break;
143 | } else {
144 |
145 | if(totalRead < partBytesSize){
146 | // end of download
147 | File file = new File(fileDestinationName);
148 | File newfile = new File(this.toFile);
149 |
150 | //Log.i("HttpRequestToFileTask", "FILE DESTINATION LEN=" + file.length());
151 |
152 | if (newfile.exists())
153 | newfile.delete();
154 |
155 | boolean success = file.renameTo(newfile);
156 |
157 | if(!success)
158 | throw new Exception("error rename partial download to " + this.toFile);
159 |
160 | break;
161 | }
162 | }
163 | }
164 | }catch (Exception e){
165 | Log.e("HttpRequestToFileTask", e.getMessage(), e);
166 | return e;
167 | }
168 | return this.identifier;
169 | }
170 |
171 | private boolean checkServerSupportPartialDownload(){
172 | try{
173 | URL url = new URL(this.url);
174 |
175 | HttpURLConnection connection = (HttpURLConnection) url.openConnection();
176 |
177 | for (String name : this.httpHeaders.keySet())
178 | connection.setRequestProperty(name, this.httpHeaders.get(name));
179 |
180 | connection.setRequestMethod("HEAD");
181 |
182 | int statusCode = connection.getResponseCode();
183 |
184 | if(statusCode != 200){
185 | String errorMessage = errorToString(connection.getErrorStream());
186 | Log.i("HttpRequestToFileTask", "server error on get HEAD: status: " + statusCode + ", message: " + errorMessage);
187 | return false;
188 | }
189 |
190 | Map> map = connection.getHeaderFields();
191 |
192 | if(map.containsKey("Accept-Ranges") && !map.get("Accept-Ranges").isEmpty()){
193 |
194 | Log.i("HttpRequestToFileTask", "server acceps partial download: " + map.get("Accept-Ranges").get(0));
195 |
196 | if(map.get("Accept-Ranges") != null)
197 | return "bytes".equals(map.get("Accept-Ranges").get(0).trim());
198 |
199 | } else {
200 | Log.i("HttpRequestToFileTask", "server does not acceps partial download");
201 | }
202 | }catch(Exception e){
203 | Log.e("HttpRequestToFileTask", e.getMessage(), e);
204 | }
205 |
206 | return false;
207 |
208 | }
209 |
210 | private String errorToString(InputStream inStream) throws Exception{
211 | BufferedInputStream bis = new BufferedInputStream(inStream);
212 | ByteArrayOutputStream buf = new ByteArrayOutputStream();
213 | int result = bis.read();
214 | while(result != -1) {
215 | buf.write((byte) result);
216 | result = bis.read();
217 | }
218 | return buf.toString("UTF-8");
219 | }
220 |
221 | public static boolean isCompletedDownload(String destinationFile){
222 | File completeFile = new File(destinationFile);
223 | File partialFile = new File(destinationFile + ".part");
224 |
225 | if(partialFile.exists())
226 | return false;
227 |
228 | return completeFile.exists();
229 | }
230 |
231 |
232 | @Override
233 | protected void onPostExecute(Object o) {
234 | super.onPostExecute(o);
235 |
236 | if(o instanceof Exception){
237 | if (callback != null) {
238 | callback.onError(new Object[]{identifier, ((Exception) o).getMessage()});
239 | }
240 | }else {
241 | if (callback != null) {
242 | Log.i("HttpRequestToFileTask", "done callback");
243 | callback.onComplete(o);
244 | } else {
245 | Log.i("HttpRequestToFileTask", "done null callback");
246 | }
247 | }
248 | }
249 | }
250 |
--------------------------------------------------------------------------------
/native-src/android/app/src/main/java/br/com/mobilemind/ns/task/LargeFilePersisterTask.java:
--------------------------------------------------------------------------------
1 | package br.com.mobilemind.ns.task;
2 |
3 | import android.graphics.Bitmap;
4 | import android.os.AsyncTask;
5 | import android.util.Log;
6 |
7 | import java.io.ByteArrayOutputStream;
8 | import java.io.File;
9 | import java.io.FileInputStream;
10 | import java.io.FileOutputStream;
11 | import java.io.InputStream;
12 |
13 | /**
14 | * Created by ricardo on 1/23/17.
15 | */
16 |
17 | public class LargeFilePersisterTask extends AsyncTask {
18 |
19 | private CompleteCallback callback;
20 | private LargeFile largeFiles[];
21 |
22 | public static class LargeFile{
23 | public Bitmap bitmap;
24 | public String fileDst;
25 | public String fileSrc;
26 | public int quality = 80;
27 | }
28 |
29 | public LargeFilePersisterTask(CompleteCallback callback, LargeFile largeFiles[])
30 | {
31 | this.callback = callback;
32 | this.largeFiles = largeFiles;
33 | }
34 |
35 | @Override
36 | protected Object doInBackground(Object[] params) {
37 |
38 | String imgs[] = new String[]{".png", ".jpeg", ".jpg"};
39 |
40 | try {
41 |
42 | for (LargeFile file: largeFiles) {
43 |
44 | boolean isImg = false;
45 |
46 | for(String s : imgs){
47 | if(file.fileDst.toLowerCase().endsWith(s)){
48 | isImg = true;
49 | break;
50 | }
51 | }
52 |
53 | ByteArrayOutputStream bStream = new ByteArrayOutputStream();
54 |
55 | if(isImg && file.bitmap != null) {
56 | Bitmap.CompressFormat format = Bitmap.CompressFormat.JPEG;
57 |
58 | if (file.fileDst.toLowerCase().endsWith(".png")) {
59 | format = Bitmap.CompressFormat.PNG;
60 | }
61 |
62 | file.bitmap.compress(format, file.quality, bStream );
63 |
64 | } else {
65 |
66 | File src = new File(file.fileSrc);
67 |
68 | if(!src.exists()){
69 | throw new RuntimeException("file " + file.fileSrc + " not found to copy");
70 | }
71 |
72 | InputStream in = new FileInputStream(src);
73 | byte[] buf = new byte[1024];
74 | int len;
75 | while ((len = in.read(buf)) > 0) {
76 | bStream .write(buf, 0, len);
77 | }
78 | in.close();
79 | }
80 |
81 | Log.i("LargeFilePersisterTask", "save file at " + file.fileDst);
82 |
83 | File imageFile = new File(file.fileDst);
84 |
85 | if (imageFile.exists()) {
86 | Log.i("LargeFilePersisterTask", "delete file " + file.fileDst);
87 | imageFile.delete();
88 | }
89 |
90 | FileOutputStream fo = new FileOutputStream(imageFile);
91 | fo.write(bStream.toByteArray());
92 | fo.flush();
93 | fo.close();
94 | bStream.close();
95 | Runtime.getRuntime().gc();
96 | System.gc();
97 | Thread.sleep(1000);
98 |
99 | Log.i("LargeFilePersisterTask", "file saved at " + file.fileDst);
100 | }
101 |
102 | }catch (Exception e){
103 | Log.e("LargeFilePersisterTask", e.getMessage(), e);
104 | return e;
105 | }
106 |
107 | return null;
108 | }
109 |
110 | @Override
111 | protected void onPostExecute(Object o) {
112 | super.onPostExecute(o);
113 |
114 | if(o instanceof Exception){
115 | if (callback != null) {
116 | callback.onError(((Exception) o).getMessage());
117 | }
118 | }else {
119 | if (callback != null) {
120 | Log.i("LargeFilePersisterTask", "done callback");
121 | callback.onComplete(o);
122 | } else {
123 | Log.i("LargeFilePersisterTask", "done null callback");
124 | }
125 | }
126 | }
127 |
128 | public static void doIt(CompleteCallback callback, LargeFile largeFiles[]){
129 | new LargeFilePersisterTask(callback, largeFiles).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/native-src/android/app/src/main/java/br/com/mobilemind/ns/task/SplitFilesTask.java:
--------------------------------------------------------------------------------
1 | package br.com.mobilemind.ns.task;
2 |
3 | import android.graphics.Bitmap;
4 | import android.os.AsyncTask;
5 | import android.util.Log;
6 |
7 | import java.io.ByteArrayOutputStream;
8 | import java.io.File;
9 | import java.io.FileInputStream;
10 | import java.io.FileOutputStream;
11 | import java.io.InputStream;
12 |
13 | /**
14 | * Created by ricardo on 1/23/17.
15 | */
16 |
17 | public class SplitFilesTask extends AsyncTask {
18 |
19 | private CompleteCallback callback;
20 | private SplitFile splitFiles[];
21 |
22 | public static class SplitFile{
23 | public String fileSrc;
24 | public String filePartPath;
25 | //MB
26 | public int filePartMaxSize = 5;
27 | public String fileParthName;
28 | public String fileParteSufix = "part";
29 | public int filePartCount;
30 | public String[] fileParts;
31 | }
32 |
33 | public SplitFilesTask(CompleteCallback callback, SplitFile splitFiles[])
34 | {
35 | this.callback = callback;
36 | this.splitFiles = splitFiles;
37 | }
38 |
39 | @Override
40 | protected Object doInBackground(Object[] params) {
41 |
42 | try {
43 |
44 | for (SplitFile file: splitFiles) {
45 |
46 |
47 | File src = new File(file.fileSrc);
48 | InputStream in = new FileInputStream(src);
49 |
50 | if(!src.exists()){
51 | throw new RuntimeException("file " + file.fileSrc + " not found to split");
52 | }
53 |
54 | final int mb = 1048576;
55 | final int kb = 1024 * 4;
56 | final int partSize = mb * file.filePartMaxSize;
57 | byte[] buf = new byte[kb];
58 | int len = 0;
59 |
60 | int partCount = in.available() / partSize;
61 |
62 | if(in.available() % partSize > 0)
63 | partCount++;
64 |
65 | file.fileParts = new String[partCount];
66 | file.filePartCount = partCount;
67 |
68 | for(int i = 0; i < partCount; i++){
69 |
70 | ByteArrayOutputStream bStream = new ByteArrayOutputStream();
71 | int read = 0;
72 |
73 | while ((len = in.read(buf)) > 0) {
74 |
75 | read += len;
76 |
77 | bStream .write(buf, 0, len);
78 |
79 | if(read >= partSize){
80 | read = 0;
81 | break;
82 | }
83 | }
84 |
85 | File fileSrc = new File(file.filePartPath, file.fileParthName + "_" + (i + 1) + "." + file.fileParteSufix);
86 | Log.i("SplitFilesTask", "save part file at " + fileSrc.getAbsolutePath());
87 |
88 | file.fileParts[i] = fileSrc.getAbsolutePath();
89 |
90 |
91 | if (fileSrc.exists()) {
92 | Log.i("SplitFilesTask", "delete file before create " + fileSrc.getAbsolutePath());
93 | fileSrc.delete();
94 | }
95 |
96 | FileOutputStream fo = new FileOutputStream(fileSrc);
97 | fo.write(bStream.toByteArray());
98 | fo.flush();
99 | fo.close();
100 | bStream.close();
101 | }
102 |
103 | in.close();
104 |
105 | Runtime.getRuntime().gc();
106 | System.gc();
107 | Thread.sleep(1000);
108 |
109 | }
110 |
111 | }catch (Exception e){
112 | Log.e("SplitFilesTask", e.getMessage(), e);
113 | return e;
114 | }
115 |
116 | return null;
117 | }
118 |
119 | @Override
120 | protected void onPostExecute(Object o) {
121 | super.onPostExecute(o);
122 |
123 | if(o instanceof Exception){
124 | if (callback != null) {
125 | callback.onError(((Exception) o).getMessage());
126 | }
127 | }else {
128 | if (callback != null) {
129 | Log.i("SplitFilesTask", "done callback");
130 | callback.onComplete(this.splitFiles);
131 | } else {
132 | Log.i("SplitFilesTask", "done null callback");
133 | }
134 | }
135 | }
136 |
137 | public static void doIt(CompleteCallback callback, SplitFile splitFiles[]){
138 | new SplitFilesTask(callback, splitFiles).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/native-src/android/app/src/main/java/br/com/mobilemind/ns/task/UnzipTask.java:
--------------------------------------------------------------------------------
1 | package br.com.mobilemind.ns.task;
2 |
3 | import android.os.AsyncTask;
4 | import android.util.Log;
5 |
6 | import java.io.BufferedInputStream;
7 | import java.io.File;
8 | import java.io.FileInputStream;
9 | import java.io.FileOutputStream;
10 | import java.io.InputStream;
11 | import java.util.zip.ZipEntry;
12 | import java.util.zip.ZipInputStream;
13 |
14 | /**
15 | * Created by ricardo on 3/22/16.
16 | */
17 | public class UnzipTask extends AsyncTask {
18 |
19 | private CompleteCallback callback;
20 | private String toFile;
21 | private String fromFile;
22 |
23 |
24 | public UnzipTask(CompleteCallback callback,String fromFile, String toFile)
25 | {
26 | this.callback = callback;
27 | this.toFile = toFile;
28 | this.fromFile = fromFile;
29 |
30 | if(!this.toFile.endsWith("/"))
31 | this.toFile += "/";
32 | }
33 |
34 | @Override
35 | protected Object doInBackground(Object[] params) {
36 |
37 | InputStream is;
38 | ZipInputStream zis;
39 | try
40 | {
41 | String filename;
42 | is = new FileInputStream(this.fromFile);
43 | zis = new ZipInputStream(new BufferedInputStream(is));
44 | ZipEntry ze;
45 | byte[] buffer = new byte[1024];
46 | int count;
47 |
48 | while ((ze = zis.getNextEntry()) != null)
49 | {
50 | // zapis do souboru
51 | filename = ze.getName();
52 |
53 | //Log.i("UnzipTask", "zip file name " + filename);
54 |
55 | // Need to create directories if not exists, or
56 | // it will generate an Exception...
57 | if (ze.isDirectory()) {
58 | File fmd = new File(this.toFile + filename);
59 | fmd.mkdirs();
60 | continue;
61 | }
62 |
63 | File file = new File(this.toFile + filename);
64 | FileOutputStream fout = new FileOutputStream(file);
65 |
66 | // cteni zipu a zapis
67 | while ((count = zis.read(buffer)) != -1)
68 | {
69 | fout.write(buffer, 0, count);
70 | }
71 |
72 | fout.close();
73 | zis.closeEntry();
74 | }
75 |
76 | zis.close();
77 | }
78 | catch(Exception e)
79 | {
80 | Log.e("UnzipTask", e.getMessage(), e);
81 | return e;
82 | }
83 |
84 | return null;
85 | }
86 |
87 | @Override
88 | protected void onPostExecute(Object o) {
89 | super.onPostExecute(o);
90 |
91 | if(o instanceof Exception){
92 | if (callback != null) {
93 | callback.onError(((Exception) o).getMessage());
94 | }
95 | }else {
96 | if (callback != null) {
97 | Log.i("UnzipTask", "done callback");
98 | callback.onComplete(o);
99 | } else {
100 | Log.i("UnzipTask", "done null callback");
101 | }
102 | }
103 | }
104 |
105 | public static void doIt(CompleteCallback callback, String fromFile, String toFile){
106 | new UnzipTask(callback, fromFile, toFile).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/native-src/android/app/src/main/java/br/com/mobilemind/ns/task/sql/DBHelper.java:
--------------------------------------------------------------------------------
1 | package br.com.mobilemind.ns.task.sql;
2 |
3 | import android.content.Context;
4 | import android.database.Cursor;
5 | import android.database.sqlite.SQLiteDatabase;
6 | import android.database.sqlite.SQLiteOpenHelper;
7 |
8 | public class DBHelper extends SQLiteOpenHelper {
9 |
10 | public DBHelper(Context context, String dbName, int dbVersion)
11 | {
12 | super(context, dbName , null, dbVersion);
13 | }
14 |
15 | @Override
16 | public void onCreate(SQLiteDatabase db) {
17 | }
18 |
19 | @Override
20 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
21 | }
22 |
23 | public Cursor getData(String query){
24 | SQLiteDatabase db = this.getReadableDatabase();
25 | Cursor cursor = db.rawQuery(query, null);
26 | return cursor;
27 | }
28 |
29 | public Long getDataId(String query, String[] args){
30 | SQLiteDatabase db = this.getReadableDatabase();
31 | Cursor cursor = db.rawQuery(query, args);
32 |
33 | try{
34 |
35 | if (cursor.moveToFirst())
36 | return cursor.getLong(0);
37 |
38 | }finally{
39 | cursor.close();
40 | }
41 |
42 | return null;
43 | }
44 |
45 | public void executeQuery(String query, Object[] args, SQLiteDatabase db){
46 | db.execSQL(query, args);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/native-src/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.3.3'
9 | // NOTE: Do not place your application dependencies here; they belong
10 | // in the individual module build.gradle files
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | jcenter()
17 | mavenCentral()
18 | maven {
19 | url "https://raw.githubusercontent.com/mobilemindtec/m2/master"
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/native-src/android/compile:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ./gradlew exportJar
4 |
5 | cp app/release/MobileMindNSTaskPlugin.aar ../../platforms/android
6 |
--------------------------------------------------------------------------------
/native-src/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/native-src/android/local.properties:
--------------------------------------------------------------------------------
1 | ## This file is automatically generated by Android Studio.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 | #
7 | # Location of the SDK. This is only used by Gradle.
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | #Fri Apr 22 19:56:40 BRT 2016
11 | android.library=true
12 | #sdk.dir=/opt/android-sdk
13 |
--------------------------------------------------------------------------------
/native-src/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/native-src/ios/NSBackgroundTask.h:
--------------------------------------------------------------------------------
1 |
2 |
3 | @protocol NSBackgroundTaskCompleteCallback
4 |
5 | -(void) onComplete;
6 | -(void) onError:(NSString *) message;
7 |
8 | @end
9 |
10 |
11 | @interface NSBackgroundTaskCopyFiles : NSObject{
12 | NSString *_toFile;
13 | NSString *_fromFile;
14 | }
15 |
16 | @property (nonatomic, retain) id delegate;
17 |
18 | -(void) runTask;
19 |
20 | -(id) initWithFromFile:(NSString *) fromFile toFile: (NSString *) toFile;
21 |
22 | @end
23 |
24 | @interface NSBackgroundTaskHttpRequestToFile : NSObject{
25 | NSString *_url;
26 | NSString *_toFile;
27 | }
28 |
29 | @property (nonatomic, retain) id delegate;
30 |
31 | -(void) runTask;
32 |
33 | -(id) initWithUrl:(NSString *) url toFile: (NSString *) toFile;
34 |
35 | @end
36 |
37 | @interface NSBackgroundTaskUnzipTask : NSObject{
38 |
39 | NSString *_toFile;
40 | NSString *_fromFile;
41 |
42 | }
43 |
44 | @property (nonatomic, retain) id delegate;
45 |
46 | -(void) runTask;
47 |
48 | -(id) initWithFromFile:(NSString *) fromFile toFile: (NSString *) toFile;
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/native-src/ios/NSBackgroundTaskCopyFiles.m:
--------------------------------------------------------------------------------
1 |
2 | #import "NSBackgroundTask.h"
3 |
4 |
5 | @implementation NSBackgroundTaskCopyFiles
6 |
7 | @synthesize delegate;
8 |
9 | -(void) runTask{
10 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
11 |
12 | @try{
13 |
14 | NSFileManager *fileManager = [NSFileManager defaultManager];
15 |
16 | NSError *moveError;
17 |
18 | NSLog(@"move file %@ to %@", _fromFile, _toFile);
19 |
20 | [fileManager moveItemAtPath: _fromFile toPath: _toFile error: &moveError];
21 |
22 | if(moveError)
23 | [self.delegate onError: [moveError description]];
24 | else
25 | [self.delegate onComplete];
26 |
27 | }@catch(NSException *exception){
28 | [self.delegate onError: [exception reason]];
29 | }
30 |
31 | });
32 | }
33 |
34 |
35 | -(id) initWithFromFile:(NSString *) fromFile toFile: (NSString *) toFile{
36 | self = [super init];
37 | _toFile = toFile;
38 | _fromFile = fromFile;
39 | return self;
40 | }
41 |
42 | @end
--------------------------------------------------------------------------------
/native-src/ios/NSBackgroundTaskHttpRequestToFile.m:
--------------------------------------------------------------------------------
1 |
2 | #import "NSBackgroundTask.h"
3 | #import "AFNetworking.h"
4 |
5 |
6 | @implementation NSBackgroundTaskHttpRequestToFile
7 |
8 | @synthesize delegate;
9 |
10 | -(void) runTask{
11 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
12 |
13 |
14 | NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
15 | AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
16 | NSFileManager *fileManager = [NSFileManager defaultManager];
17 | NSURL *url = [[NSURL alloc] initWithString: _url];
18 |
19 | NSURLRequest *request = [NSURLRequest requestWithURL:url];
20 |
21 | NSString *destination = _toFile;
22 |
23 | //NSArray *listItems = [destination componentsSeparatedByString:@", "];
24 |
25 | //NSString *fileName = (NSString *)[listItems lastObject];
26 | //NSString *destinationFile = [destination stringByAppendingPathComponent: fileName];
27 |
28 | if([fileManager fileExistsAtPath: destination ] == YES){
29 | NSLog(@"deleting destination file %@ before download..", destination);
30 | NSError *deleteError;
31 | [fileManager removeItemAtPath: destination error:&deleteError];
32 |
33 | if(deleteError){
34 | NSLog(@"error on delete file to %@ -> %@", destination, deleteError);
35 | [self.delegate onError: [deleteError description]];
36 | return;
37 | }
38 |
39 | }
40 |
41 | NSLog(@"dowload file from %@", _url);
42 |
43 |
44 | NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
45 | NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
46 | return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
47 | } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
48 |
49 | if(error){
50 | NSLog(@"dowload error %@", error);
51 | [self.delegate onError: [error description]];
52 | }else{
53 | NSLog(@"dowload error success!");
54 | NSError *moveError;
55 | [fileManager moveItemAtPath: filePath toPath: destination error: &moveError];
56 |
57 | if(moveError){
58 | NSLog(@"error dowload move %@ to %@ -> %@", filePath, destination, moveError);
59 | [self.delegate onError: [moveError description]];
60 | }else{
61 | NSLog(@"success dowload move %@ to %@", filePath, destination);
62 | [self.delegate onComplete];
63 | }
64 | }
65 | }];
66 |
67 | [downloadTask resume];
68 |
69 | });
70 | }
71 |
72 |
73 | -(id) initWithUrl:(NSString *) url toFile: (NSString *) toFile{
74 | self = [super init];
75 | _toFile = toFile;
76 | _url = url;
77 | return self;
78 | }
79 |
80 | @end
--------------------------------------------------------------------------------
/native-src/ios/NSBackgroundTaskUnzipTask.m:
--------------------------------------------------------------------------------
1 |
2 | #import "NSBackgroundTask.h"
3 | #import "SSZipArchive.h"
4 |
5 | @implementation NSBackgroundTaskUnzipTask
6 |
7 | @synthesize delegate;
8 |
9 | -(void) runTask{
10 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
11 |
12 | @try{
13 | NSFileManager *fileManager = [NSFileManager defaultManager];
14 | NSLog(@"unzip file %@ to %@", _fromFile, _toFile);
15 |
16 | /*
17 | if([fileManager fileExistsAtPath: destination ] == NO){
18 | NSError *createError;
19 | [fileManager createDirectoryAtPath:destination withIntermediateDirectories:NO
20 | attributes:nil
21 | error:&createError];
22 | if(createError){
23 | NSLog(@"create path error %@", createError);
24 | return;
25 | }
26 | }*/
27 |
28 | [SSZipArchive unzipFileAtPath:_fromFile toDestination:_toFile];
29 | [self.delegate onComplete];
30 | }@catch(NSException *exception){
31 | NSLog(@"move file error %@", exception);
32 | [self.delegate onError: [exception reason]];
33 | }
34 |
35 | });
36 | }
37 |
38 |
39 | -(id) initWithFromFile:(NSString *) fromFile toFile: (NSString *) toFile{
40 | self = [super init];
41 | _toFile = toFile;
42 | _fromFile = fromFile;
43 | return self;
44 | }
45 |
46 | @end
--------------------------------------------------------------------------------
/native-src/ios/NativeScriptBackgroundTask.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "NativeScriptBackgroundTask"
3 | s.version = "0.0.1"
4 | s.summary = "NativeScript background task ios sources."
5 | s.description = "NativeScript background task ios sources."
6 | s.homepage = "https://github.com/mobilemindtec/nativescript-background-task-ios-source"
7 | s.license = { :type => 'MIT', :file => 'LICENSE' }
8 | s.author = { "orta" => 'ricardo@mobilemind.com.br' }
9 | s.source = { :git => "https://github.com/mobilemindtec/nativescript-background-task-ios-source.git", :tag => s.version.to_s }
10 | s.platform = :ios, '8.0'
11 | s.source_files = '*.{h,m}'
12 | s.resources = '*.{png}'
13 | s.requires_arc = true
14 |
15 | s.dependency 'SSZipArchive'
16 | s.dependency 'AFNetworking'
17 |
18 | end
--------------------------------------------------------------------------------
/native-src/server-mock/app.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var path = require('path');
3 | var favicon = require('serve-favicon');
4 | var logger = require('morgan');
5 | var cookieParser = require('cookie-parser');
6 | var bodyParser = require('body-parser');
7 | var getRawBody = require('raw-body')
8 | var index = require('./routes/index');
9 | var users = require('./routes/users');
10 |
11 | var app = express();
12 |
13 | // view engine setup
14 | app.set('views', path.join(__dirname, 'views'));
15 | app.set('view engine', 'pug');
16 |
17 | // uncomment after placing your favicon in /public
18 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
19 | app.use(logger('dev'));
20 | app.use(bodyParser.json({limit: '50mb'}));
21 | app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
22 | app.use(cookieParser());
23 | app.use(express.static(path.join(__dirname, 'public')));
24 |
25 | app.use(function (req, res, next) {
26 | console.log('octet-stream')
27 | if (req.headers['content-type'] === 'application/octet-stream') {
28 | getRawBody(req, {
29 | length: req.headers['content-length'],
30 | encoding: this.charset
31 | }, function (err, string) {
32 | if (err)
33 | return next(err)
34 |
35 | req.body = string
36 | next()
37 | })
38 | }
39 | else {
40 | next()
41 | }
42 |
43 | })
44 |
45 | app.use('/', index);
46 | app.use('/users', users);
47 |
48 | // catch 404 and forward to error handler
49 | app.use(function(req, res, next) {
50 | var err = new Error('Not Found');
51 | err.status = 404;
52 | next(err);
53 | });
54 |
55 | // error handler
56 | app.use(function(err, req, res, next) {
57 | // set locals, only providing error in development
58 | res.locals.message = err.message;
59 | res.locals.error = req.app.get('env') === 'development' ? err : {};
60 |
61 | // render the error page
62 | res.status(err.status || 500);
63 | res.render('error');
64 | });
65 |
66 |
67 |
68 | module.exports = app;
69 |
--------------------------------------------------------------------------------
/native-src/server-mock/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 |
7 | var app = require('../app');
8 | var debug = require('debug')('app-icons:server');
9 | var http = require('http');
10 |
11 | /**
12 | * Get port from environment and store in Express.
13 | */
14 |
15 | var port = normalizePort(process.env.PORT || '3000');
16 | app.set('port', port);
17 |
18 | /**
19 | * Create HTTP server.
20 | */
21 |
22 | var server = http.createServer(app);
23 |
24 | /**
25 | * Listen on provided port, on all network interfaces.
26 | */
27 |
28 | server.listen(port);
29 | server.on('error', onError);
30 | server.on('listening', onListening);
31 |
32 | /**
33 | * Normalize a port into a number, string, or false.
34 | */
35 |
36 | function normalizePort(val) {
37 | var port = parseInt(val, 10);
38 |
39 | if (isNaN(port)) {
40 | // named pipe
41 | return val;
42 | }
43 |
44 | if (port >= 0) {
45 | // port number
46 | return port;
47 | }
48 |
49 | return false;
50 | }
51 |
52 | /**
53 | * Event listener for HTTP server "error" event.
54 | */
55 |
56 | function onError(error) {
57 | if (error.syscall !== 'listen') {
58 | throw error;
59 | }
60 |
61 | var bind = typeof port === 'string'
62 | ? 'Pipe ' + port
63 | : 'Port ' + port;
64 |
65 | // handle specific listen errors with friendly messages
66 | switch (error.code) {
67 | case 'EACCES':
68 | console.error(bind + ' requires elevated privileges');
69 | process.exit(1);
70 | break;
71 | case 'EADDRINUSE':
72 | console.error(bind + ' is already in use');
73 | process.exit(1);
74 | break;
75 | default:
76 | throw error;
77 | }
78 | }
79 |
80 | /**
81 | * Event listener for HTTP server "listening" event.
82 | */
83 |
84 | function onListening() {
85 | var addr = server.address();
86 | var bind = typeof addr === 'string'
87 | ? 'pipe ' + addr
88 | : 'port ' + addr.port;
89 | debug('Listening on ' + bind);
90 | }
91 |
--------------------------------------------------------------------------------
/native-src/server-mock/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server-mock",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "node ./bin/www"
7 | },
8 | "dependencies": {
9 | "body-parser": "~1.16.0",
10 | "cookie-parser": "~1.4.3",
11 | "debug": "~2.6.0",
12 | "express": "~4.14.1",
13 | "morgan": "~1.7.0",
14 | "pug": "~2.0.0-beta10",
15 | "serve-favicon": "~2.3.2"
16 | },
17 | "devDependencies": {
18 | "memorystream": "^0.3.1",
19 | "slice-file": "^1.0.0",
20 | "slice-stream": "^1.0.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/native-src/server-mock/public/stylesheets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 50px;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | }
5 |
6 | a {
7 | color: #00B7FF;
8 | }
9 |
--------------------------------------------------------------------------------
/native-src/server-mock/routes/index.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 | var path = require('path');
4 | var mime = require('mime');
5 | var fs = require("fs");
6 | var path = require('path');
7 |
8 | /* GET home page. */
9 | router.get('/', function(req, res, next) {
10 |
11 | console.log('on get')
12 |
13 | console.log("*********************** headers")
14 | console.log(JSON.stringify(req.headers))
15 | console.log("*********************** headers")
16 |
17 |
18 | res.render('index', { title: 'Express' });
19 | });
20 |
21 |
22 | router.post('/', function(req, res, next){
23 |
24 | console.log('on post')
25 |
26 | console.log("*********************** body size")
27 | console.log(req.body.length)
28 | console.log("*********************** body size")
29 |
30 | //console.log(req.body.name)
31 |
32 | console.log("*********************** headers")
33 | console.log(JSON.stringify(req.headers))
34 | console.log("*********************** headers")
35 |
36 | res.json({
37 | message: 'OK'
38 | })
39 |
40 | })
41 |
42 | router.post('/raw', function(req, res, next){
43 | console.log('on post raw')
44 |
45 | console.log("*********************** body size")
46 | console.log(req.body.length)
47 | console.log("*********************** body size")
48 |
49 | //console.log(req.body.name)
50 |
51 | console.log("*********************** headers")
52 | console.log(JSON.stringify(req.headers))
53 | console.log("*********************** headers")
54 |
55 |
56 |
57 | res.json({
58 | message: 'OK'
59 | })
60 | })
61 |
62 | router.get('/partial-download', function(req, res, next) {
63 |
64 | console.log('on get partial-download')
65 |
66 | console.log("*********************** headers")
67 | console.log(JSON.stringify(req.headers))
68 | console.log("*********************** headers")
69 |
70 | var file = '/home/ricardo/Downloads/larg-file.pdf';
71 |
72 | if(req.method == 'GET'){
73 | if(req.headers['content-range']){
74 | readcontent(file, serveWithRanges, req, res)
75 | }else{
76 | console.log('range header not set')
77 | res.status(500).send('range header not set')
78 | }
79 | } else {
80 | console.log("HEAD")
81 | res.set("Accept-Ranges", "bytes")
82 | res.end()
83 | }
84 |
85 |
86 | });
87 |
88 |
89 | function serveWithRanges(request, response, content, file) {
90 |
91 | var filename = path.basename(file);
92 | var mimetype = mime.lookup(file);
93 |
94 |
95 | var range = request.headers['content-range'];
96 | var total = fs.statSync(file).size;
97 | var parts = range.replace("bytes", "").split("/")[0].trim().split("-");
98 |
99 | console.log("total=" + total)
100 | console.log(parts)
101 |
102 | var partialstart = parts[0];
103 | var partialend = parts[1];
104 |
105 | var start = parseInt(partialstart, 10);
106 | var end = partialend ? parseInt(partialend, 10) : total;
107 | var chunksize = (end-start);
108 |
109 |
110 | response.set('Content-disposition', 'attachment; filename=' + filename)
111 | response.set("Content-Range", "bytes " + start + "-" + end + "/" + total)
112 | response.set("Accept-Ranges", "bytes")
113 | response.set("Content-Length", chunksize)
114 | response.set("Content-Type", mimetype)
115 |
116 |
117 |
118 |
119 | if(start > total){
120 | console.log("start > total")
121 | response.set("Content-Length", 0)
122 | response.end()
123 | }
124 | else{
125 |
126 | if(end > total){
127 | end = start + (total-start)
128 | console.log("end > total. new end ="+end)
129 | }
130 |
131 | response.set("Content-Length", end-start)
132 |
133 | try{
134 | response.end(content.slice(start, end));
135 | }catch(e){
136 | console.log('error ' + e)
137 | }
138 | }
139 |
140 | }
141 |
142 | function readcontent(file, callback, request, response) {
143 | var toreturn;
144 | fs.exists(file, function(exists) {
145 | if (exists) {
146 | fs.readFile(file, function(error, content) {
147 | if (error) {
148 | response.writeHead(500);
149 | response.end("500, internal error.
");
150 | toreturn = undefined;
151 | }
152 | else {
153 | callback(request, response, content, file);
154 | }
155 | });
156 | } else {
157 | response.writeHead(404);
158 | response.end("404, not found.
");
159 | toreturn = undefined;
160 | }
161 | });
162 | return toreturn;
163 | }
164 |
165 |
166 | module.exports = router;
167 |
--------------------------------------------------------------------------------
/native-src/server-mock/routes/users.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 |
4 | /* GET users listing. */
5 | router.get('/', function(req, res, next) {
6 | res.send('respond with a resource');
7 | });
8 |
9 | module.exports = router;
10 |
--------------------------------------------------------------------------------
/native-src/server-mock/views/error.pug:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | h1= message
5 | h2= error.status
6 | pre #{error.stack}
7 |
--------------------------------------------------------------------------------
/native-src/server-mock/views/index.pug:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | h1= title
5 | p Welcome to #{title}
6 |
--------------------------------------------------------------------------------
/native-src/server-mock/views/layout.pug:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title= title
5 | link(rel='stylesheet', href='/stylesheets/style.css')
6 | body
7 | block content
8 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nativescript-background-task",
3 | "version": "0.0.1",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "tns-core-modules": {
8 | "version": "3.4.1",
9 | "resolved": "http://registry.npmjs.org/tns-core-modules/-/tns-core-modules-3.4.1.tgz",
10 | "integrity": "sha512-sz/yTmoW7WyDPpr4JEC+trlfiEI14X365jGF//tMCT/G6ISzANr43wc17fgbGH1UA1XbKzujbAl0xPNssRHVUA==",
11 | "dev": true,
12 | "requires": {
13 | "tns-core-modules-widgets": "3.4.0"
14 | }
15 | },
16 | "tns-core-modules-widgets": {
17 | "version": "3.4.0",
18 | "resolved": "https://registry.npmjs.org/tns-core-modules-widgets/-/tns-core-modules-widgets-3.4.0.tgz",
19 | "integrity": "sha512-WEtjDRTjjKB+C1NhY1CJSNyhK9DPCYzBgM+yKgq5AmphK/QdQEMAP1U2ttOv8yWWfsvLZGOnzyLCzcyeoG0Gfw==",
20 | "dev": true
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nativescript-background-task",
3 | "main": "index.js",
4 | "version": "0.0.1",
5 | "nativescript": {
6 | "platforms": {
7 | "ios": "3.4.0",
8 | "android": "3.4.0"
9 | }
10 | },
11 | "devDependencies": {
12 | "tns-core-modules": "^3.4.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/platforms/android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/platforms/android/MobileMindNSTaskPlugin.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobilemindtec/nativescript-background-task/d580b3711e47c4d52b7bb2fba6ff65badd5fc1d0/platforms/android/MobileMindNSTaskPlugin.aar
--------------------------------------------------------------------------------
/platforms/android/include.gradle:
--------------------------------------------------------------------------------
1 | allprojects {
2 | repositories {
3 | jcenter()
4 | mavenCentral()
5 | maven {
6 | url "https://raw.githubusercontent.com/mobilemindtec/m2/master"
7 | }
8 | }
9 | }
10 |
11 | dependencies {
12 | implementation('br.com.mobilemind.api:mobilemind-droid-util:2.1', {
13 | exclude group: 'com.google.android', module: 'android'
14 | exclude group: 'com.google.android', module: 'support-v4'
15 | //exclude group: 'br.com.mobilemind.api', module: 'mobilemind-utils'
16 | })
17 | //implementation 'br.com.mobilemind.api:mobilemind-utils:1.3'
18 | implementation fileTree(dir: 'libs', include: ['*.jar'])
19 | }
--------------------------------------------------------------------------------
/platforms/ios/Podfile:
--------------------------------------------------------------------------------
1 |
2 | pod 'NSBackgroundTask', :git => "https://github.com/mobilemindtec/nativescript-background-task-ios-source.git"
3 |
--------------------------------------------------------------------------------
/platforms/ios/headers/module.modulemap:
--------------------------------------------------------------------------------
1 | module NativeScriptBackgroundTask {
2 | umbrella "../../../../../platforms/ios/Pods/Headers/Public"
3 | export *
4 | }
--------------------------------------------------------------------------------