ionic监听外部程序:
android下需要在AndroidManifest.xml添加内容(具体参考ionic native的APP插件),配置例如:
<intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="*/*" />
</intent-filter>
ionic打开文件时的代码如下:
import { App } from '@capacitor/app';
App.addListener('appUrlOpen', (event) => {
const url = event.url;//android下url格式:content://com.android.fileexplorer.myprovider/external_files/test.txt
//拷贝url到Data目录下,用copy方式出错
// Filesystem.copy({ from: readurl, to: 'test.txt', toDirectory: Directory.Data }).then(
// (v) => {
// this.files.push('copy:' + v.uri);
// }
// ).catch(
// (err) => {
// this.files.push('copy_error:' + err);
// }
// );
});
//Filesystem.readFile可以读出内容,但是为字符串,用Filesystem.writeFile也只能写字符串,对于非文本文件无法操作
为了实现拷贝,更改代码,通过downloadFile函数来实现,主要就是读取文件流,然后写入。
android下:
用@capacitor/filesystem的copy函数时,如果拷贝为content://...的文件,会报错,copy不支持content://路径的文件。
修改downloadFile函数,支持本地文件(content://)的下载。
修改capacitor-filesystem的android代码下的Filesystem文件下的downloadFile函数,如下图:
更改后代码如下:
public JSObject downloadFile(PluginCall call, Bridge bridge, HttpRequestHandler.ProgressEmitter emitter)
throws IOException, URISyntaxException, JSONException {
String urlString = call.getString("url", "");
JSObject headers = call.getObject("headers", new JSObject());
JSObject params = call.getObject("params", new JSObject());
Integer connectTimeout = call.getInt("connectTimeout");
Integer readTimeout = call.getInt("readTimeout");
Boolean disableRedirects = call.getBoolean("disableRedirects");
Boolean shouldEncode = call.getBoolean("shouldEncodeUrlParams", true);
Boolean progress = call.getBoolean("progress", false);
String method = call.getString("method", "GET").toUpperCase(Locale.ROOT);
String path = call.getString("path");
String directory = call.getString("directory", Environment.DIRECTORY_DOWNLOADS);
final File file = getFileObject(path, directory);
InputStream connectionInputStream = null;
String contentLength = null;
try {
connectionInputStream = getInputStream(urlString,null);
contentLength = "1024";
} catch (Exception e){}
if (connectionInputStream == null) {
final URL url = new URL(urlString);
HttpRequestHandler.HttpURLConnectionBuilder connectionBuilder = new HttpRequestHandler.HttpURLConnectionBuilder()
.setUrl(url)
.setMethod(method)
.setHeaders(headers)
.setUrlParams(params, shouldEncode)
.setConnectTimeout(connectTimeout)
.setReadTimeout(readTimeout)
.setDisableRedirects(disableRedirects)
.openConnection();
CapacitorHttpUrlConnection connection = connectionBuilder.build();
connection.setSSLSocketFactory(bridge);
connectionInputStream = connection.getInputStream();
contentLength = connection.getHeaderField("content-length");
}
FileOutputStream fileOutputStream = new FileOutputStream(file, false);
int bytes = 0;
int maxBytes = 0;
try {
maxBytes = contentLength != null ? Integer.parseInt(contentLength) : 0;
} catch (NumberFormatException ignored) {}
byte[] buffer = new byte[1024];
int len;
// Throttle emitter to 100ms so it doesn't slow down app
long lastEmitTime = System.currentTimeMillis();
long minEmitIntervalMillis = 100;
while ((len = connectionInputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, len);
bytes += len;
if (progress && null != emitter) {
long currentTime = System.currentTimeMillis();
if (currentTime - lastEmitTime > minEmitIntervalMillis) {
emitter.emit(bytes, maxBytes);
lastEmitTime = currentTime;
}
}
}
if (progress && null != emitter) {
emitter.emit(bytes, maxBytes);
}
connectionInputStream.close();
fileOutputStream.close();
return new JSObject() {
{
put("path", file.getAbsolutePath());
}
};
}
主要更改部分:
更改后,就可以调用downloadfile下载本地文件(拷贝)了,如下所示:
Filesystem.downloadFile(
{
url: "content://com.android.fileexplorer.myprovider/external_files/test.txt",
path: "text.txt",
directory: Directory.Data,
progress: true
}
)
.then(
(v) => {
this.files.push('copy:' + v.path);
}
).catch(
(err) => {
this.files.push('copy_error:' + err);
}
);