Skip to content

Commit 61bcce0

Browse files
author
Russell.H.Sun
committed
add download file temp cache check
1 parent 615a721 commit 61bcce0

File tree

3 files changed

+142
-7
lines changed

3 files changed

+142
-7
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.hstar.reactnative.esayupgrade;
2+
3+
public class IORejectionException extends Exception {
4+
private String code;
5+
6+
public IORejectionException(String code, String message) {
7+
super(message);
8+
this.code = code;
9+
}
10+
11+
public String getCode() {
12+
return code;
13+
}
14+
}

android/src/main/java/org/hstar/reactnative/esayupgrade/RNEasyUpgradeModule.java

Lines changed: 117 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
import android.support.v4.util.LongSparseArray;
1717
import android.util.Log;
1818
import com.facebook.react.bridge.*;
19+
import org.hstar.reactnative.esayupgrade.IORejectionException;
1920

20-
import java.io.File;
21-
import java.io.FileNotFoundException;
21+
import java.io.*;
2222
import java.util.ArrayList;
2323
import java.util.Arrays;
2424
import java.util.HashMap;
@@ -63,7 +63,6 @@ public String getName() {
6363
return "RNEasyUpgrade";
6464
}
6565

66-
6766
BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
6867
@Override
6968
public void onReceive(Context context, Intent intent) {
@@ -87,6 +86,19 @@ public void onReceive(Context context, Intent intent) {
8786
}
8887
};
8988

89+
private Uri getFileUri(String filepath) throws IORejectionException {
90+
Uri uri = Uri.parse(filepath);
91+
if (uri.getScheme() == null) {
92+
// No prefix, assuming that provided path is absolute path to file
93+
File file = new File(filepath);
94+
if (file.isDirectory()) {
95+
throw new IORejectionException("EISDIR", "EISDIR: illegal operation on a directory, read '" + filepath + "'");
96+
}
97+
uri = Uri.parse("file://" + filepath);
98+
}
99+
return uri;
100+
}
101+
90102

91103
@ReactMethod
92104
public void download(String url, ReadableMap headers, ReadableMap config, Callback onDone) {
@@ -163,6 +175,108 @@ public void isFileExists(String filepath, Promise promise) {
163175
}
164176
}
165177

178+
@ReactMethod
179+
public void moveFile(String filepath, String destPath, Promise promise) {
180+
try {
181+
File externalStorageDirectory = Environment.getExternalStorageDirectory();
182+
if (externalStorageDirectory != null && !filepath.contains(externalStorageDirectory.getAbsolutePath())) {
183+
filepath = externalStorageDirectory.getAbsolutePath() + filepath;
184+
destPath = externalStorageDirectory.getAbsolutePath() + destPath;
185+
}
186+
187+
File inFile = new File(filepath);
188+
189+
if (!inFile.renameTo(new File(destPath))) {
190+
copyFile(filepath, destPath);
191+
inFile.delete();
192+
}
193+
194+
promise.resolve(true);
195+
} catch (Exception ex) {
196+
ex.printStackTrace();
197+
reject(promise, filepath, ex);
198+
}
199+
}
200+
201+
@ReactMethod
202+
public void copyFile(String filepath, String destPath, Promise promise) {
203+
try {
204+
copyFile(filepath, destPath);
205+
206+
promise.resolve(null);
207+
} catch (Exception ex) {
208+
ex.printStackTrace();
209+
reject(promise, filepath, ex);
210+
}
211+
}
212+
213+
@ReactMethod
214+
public void unlink(String filepath, Promise promise) {
215+
try {
216+
File file = new File(filepath);
217+
218+
if (!file.exists()) throw new Exception("File does not exist");
219+
220+
DeleteRecursive(file);
221+
222+
promise.resolve(null);
223+
} catch (Exception ex) {
224+
ex.printStackTrace();
225+
reject(promise, filepath, ex);
226+
}
227+
}
228+
229+
private void DeleteRecursive(File fileOrDirectory) {
230+
if (fileOrDirectory.isDirectory()) {
231+
for (File child : fileOrDirectory.listFiles()) {
232+
DeleteRecursive(child);
233+
}
234+
}
235+
236+
fileOrDirectory.delete();
237+
}
238+
239+
private void copyFile(String filepath, String destPath) throws IOException, IORejectionException {
240+
InputStream in = getInputStream(filepath);
241+
OutputStream out = getOutputStream(destPath, false);
242+
243+
byte[] buffer = new byte[1024];
244+
int length;
245+
while ((length = in.read(buffer)) > 0) {
246+
out.write(buffer, 0, length);
247+
}
248+
in.close();
249+
out.close();
250+
}
251+
252+
private InputStream getInputStream(String filepath) throws IORejectionException {
253+
Uri uri = getFileUri(filepath);
254+
InputStream stream;
255+
try {
256+
stream = reactContext.getContentResolver().openInputStream(uri);
257+
} catch (FileNotFoundException ex) {
258+
throw new IORejectionException("ENOENT", "ENOENT: no such file or directory, open '" + filepath + "'");
259+
}
260+
if (stream == null) {
261+
throw new IORejectionException("ENOENT", "ENOENT: could not open an input stream for '" + filepath + "'");
262+
}
263+
return stream;
264+
}
265+
266+
private OutputStream getOutputStream(String filepath, boolean append) throws IORejectionException {
267+
Uri uri = getFileUri(filepath);
268+
OutputStream stream;
269+
try {
270+
stream = reactContext.getContentResolver().openOutputStream(uri, append ? "wa" : "w");
271+
} catch (FileNotFoundException ex) {
272+
throw new IORejectionException("ENOENT", "ENOENT: no such file or directory, open '" + filepath + "'");
273+
}
274+
if (stream == null) {
275+
throw new IORejectionException("ENOENT", "ENOENT: could not open an output stream for '" + filepath + "'");
276+
}
277+
return stream;
278+
}
279+
166280
private void rejectFileNotFound(Promise promise, String filepath) {
167281
promise.reject("ENOENT", "ENOENT: no such file or directory, open '" + filepath + "'");
168282
}

index.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const defaults = {
1919
downloadDestDirectory: DocumentDirectoryPath,
2020
downloadApkName: DEFAULT_DOWNLOAD_APK_NAME,
2121
downloadApkEnd: path => RNEasyUpgrade.installApk(path),
22+
shouldCheckApkHasDownloaded: true,
2223
onError: () => {}
2324
};
2425

@@ -73,10 +74,13 @@ class AppUpgrade {
7374
return;
7475
}
7576

77+
const tempDownloadApkName = 'temp_download.apk';
78+
const tempDownloadPath = this.downloadDestDirectory + '/' + tempDownloadApkName;
79+
7680
const downloadConf = {
7781
downloadTitle: this.options.downloadTitle,
7882
downloadDescription: this.options.downloadDescription,
79-
saveAsName: this.options.downloadApkName,
83+
saveAsName: this.options.shouldCheckApkHasDownloaded ? tempDownloadApkName : this.options.downloadApkName,
8084
allowedInRoaming: true,
8185
allowedInMetered: true,
8286
showInDownloads: true,
@@ -85,8 +89,11 @@ class AppUpgrade {
8589
};
8690
jobId = 1;
8791
download(apkUrl, downloadConf)
88-
.then(res => {
92+
.then(async res => {
8993
jobId = -1;
94+
if (this.options.shouldCheckApkHasDownloaded) {
95+
await RNEasyUpgrade.moveFile(tempDownloadPath, this.downloadDestPath);
96+
}
9097
this.options.downloadApkEnd(this.downloadDestPath);
9198
})
9299
.catch(err => {
@@ -132,9 +139,9 @@ class AppUpgrade {
132139
RNEasyUpgrade.openURL(trackViewUrl || this.trackViewUrl);
133140
}
134141

135-
startAppUpdate(apkUrl, appStoreUrl = this.trackViewUrl, options = { checkApkHasDownloaded: true }) {
142+
startAppUpdate(apkUrl, appStoreUrl = this.trackViewUrl) {
136143
if (isAndroid) {
137-
if (options.checkApkHasDownloaded) {
144+
if (this.options.shouldCheckApkHasDownloaded) {
138145
this.checkApkHasDownloaded().then(async hasDownloaded => {
139146
if (hasDownloaded) {
140147
this.options.downloadApkEnd(this.downloadDestPath);

0 commit comments

Comments
 (0)