206 lines
6.8 KiB
Plaintext
206 lines
6.8 KiB
Plaintext
// @ts-nocheck
|
|
import Intent from 'android.content.Intent';
|
|
import ClipData from 'android.content.ClipData';
|
|
import Uri from 'android.net.Uri';
|
|
import InputStream from 'java.io.InputStream';
|
|
import OpenableColumns from 'android.provider.OpenableColumns';
|
|
import Cursor from 'android.database.Cursor';
|
|
import File from 'java.io.File';
|
|
import FileInputStream from 'java.io.FileInputStream';
|
|
import FileOutputStream from 'java.io.FileOutputStream';
|
|
import BufferedOutputStream from 'java.io.BufferedOutputStream';
|
|
import ByteArrayInputStream from 'java.io.ByteArrayInputStream';
|
|
|
|
import { ChooseFileOption, ChooseFile, ChooseFileSuccessCallbackResult } from '../interface'
|
|
import { GeneralCallbackResultImpl } from '../unierror'
|
|
|
|
const REQUEST_CODE_CHOOSE_FILE : Int = 42
|
|
let resultFunction : ((requestCode : Int, resultCode : Int, data ?: Intent) => void) | null = null
|
|
|
|
|
|
class ChooseFileImpl implements ChooseFile {
|
|
name : string = ''
|
|
path : string = ''
|
|
// private _path : string = ''
|
|
size : number = 0
|
|
time : number = 0
|
|
type : string = 'file'
|
|
// private uri : Uri
|
|
private options: ChooseFileOption
|
|
constructor(uri : Uri, options : ChooseFileOption) {
|
|
// this.uri = uri
|
|
this.options = options
|
|
this.time = Date.now()
|
|
this.type = this.getFileTypeFromUri(uri);
|
|
// this._path = uri.getPath() ?? ''
|
|
this.getFileInfoFromUri(uri)
|
|
if (this.isCache(options)) {
|
|
this.copyFileToCache(uri)
|
|
}
|
|
|
|
}
|
|
private isCache(options : ChooseFileOption) : boolean {
|
|
const extension = this.getFileExtension(this.name)
|
|
const extensions = options.extension
|
|
const type = options.type ?? 'all'
|
|
const hasExtension = extensions != null && extension != '' && extensions.includes(extension)
|
|
const isVideoOrImage = ['video', 'image'].includes(type)
|
|
const isFileAndNotVideoOrImage = type == 'file' && !['video', 'image'].includes(this.type);
|
|
if ((type == 'all' || isVideoOrImage || isFileAndNotVideoOrImage) && !hasExtension) {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
private getFileExtension(fileName : string) : string {
|
|
const lastDotIndex = fileName.lastIndexOf(".");
|
|
if (lastDotIndex == -1) {
|
|
return "";
|
|
}
|
|
return fileName.substring(lastDotIndex + 1);
|
|
}
|
|
private copyFileToCache(uri : Uri) {
|
|
const cacheDir = UTSAndroid.getAppCachePath();
|
|
const context = UTSAndroid.getAppContext();
|
|
if(cacheDir != null) {
|
|
const path = new File(cacheDir);
|
|
if (!path.exists()) {
|
|
path.mkdir();
|
|
}
|
|
}
|
|
let fileName = this.name
|
|
if(this.options.filename != null) {
|
|
fileName = this.options.filename!;
|
|
if(this.options.count != null && this.options.count! > 1) {
|
|
fileName = `${fileName}_${Date.now()}`;
|
|
}
|
|
const extension = this.getFileExtension(this.name)
|
|
|
|
fileName = `${fileName}.${extension}`
|
|
}
|
|
const destFile = new File(cacheDir, fileName);
|
|
|
|
try {
|
|
const inputStream = context!.getContentResolver().openInputStream(uri)
|
|
const outputStream = new FileOutputStream(destFile)
|
|
if (inputStream != null) {
|
|
let buffer = ByteArray(1024);
|
|
let c = inputStream.read(buffer)
|
|
while (c > 0) {
|
|
outputStream.write(buffer, 0, c);
|
|
c = inputStream.read(buffer)
|
|
}
|
|
}
|
|
this.path = cacheDir + fileName//this.name
|
|
} catch (e) {
|
|
|
|
}
|
|
}
|
|
private getFileTypeFromUri(uri : Uri) : string {
|
|
const context = UTSAndroid.getAppContext();
|
|
let fileType = 'file'
|
|
let mimeType = context!.getContentResolver().getType(uri);
|
|
if (mimeType != null) {
|
|
if (mimeType.startsWith("video")) {
|
|
fileType = "video";
|
|
} else if (mimeType.startsWith("image")) {
|
|
fileType = "image";
|
|
}
|
|
}
|
|
return fileType;
|
|
}
|
|
private getFileInfoFromUri(uri : Uri) {
|
|
const context = UTSAndroid.getAppContext();
|
|
let cursor = context!.getContentResolver().query(uri, null, null, null, null);
|
|
if (cursor != null && cursor.moveToFirst()) {
|
|
this.name = cursor.getString(cursor.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME))
|
|
const fileSize = cursor.getLong(cursor.getColumnIndexOrThrow(OpenableColumns.SIZE));
|
|
this.size = Number.from(fileSize)
|
|
cursor.close();
|
|
} else if ("file".equals(uri.getScheme())) {
|
|
this.name = uri.getLastPathSegment() ?? '';
|
|
const file = new File(uri.getPath() ?? '');
|
|
const fileSize = file.length();
|
|
this.size = Number.from(fileSize)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
export function chooseFile(options : ChooseFileOption) {
|
|
if (resultFunction != null) {
|
|
UTSAndroid.offAppActivityResult(resultFunction!)
|
|
}
|
|
const type = options.type ?? 'all'
|
|
const intent = new Intent(Intent.ACTION_GET_CONTENT);
|
|
if (type.equals("all") || type.equals("file")) {
|
|
intent.setType("*/*");
|
|
} else if (type.equals("video")) {
|
|
intent.setType("video/*");
|
|
} else if (type.equals("image")) {
|
|
intent.setType("image/*");
|
|
}
|
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, options.count == 1 ? false : true); // 允许多选
|
|
|
|
resultFunction = (requestCode : Int, resultCode : Int, data ?: Intent) => {
|
|
if (requestCode == REQUEST_CODE_CHOOSE_FILE) {
|
|
UTSAndroid.offAppActivityResult(resultFunction!);
|
|
if (resultCode == -1 && data != null) {
|
|
const clipData = data.getClipData();
|
|
const tempFiles : ChooseFile[] = []
|
|
|
|
if (clipData != null) {
|
|
// 多选
|
|
// const itemCount = clipData.getItemCount();
|
|
// if (options.count != null && options.count! > itemCount) {
|
|
// const err = new GeneralCallbackResultImpl(9010002, `选中文件数量超过${options.count}`)
|
|
// options.fail?.(err)
|
|
// options.complete?.(err)
|
|
// return
|
|
// }
|
|
for (let i = 0; i < clipData.getItemCount(); i++) {
|
|
const uri = clipData.getItemAt(i.toInt()).getUri();
|
|
const chooseFile = new ChooseFileImpl(uri, options);
|
|
if(chooseFile.path !=''){
|
|
tempFiles.push(chooseFile)
|
|
}
|
|
}
|
|
} else {
|
|
// 单选
|
|
const uri = data.getData();
|
|
if (uri != null) {
|
|
const chooseFile = new ChooseFileImpl(uri, options)
|
|
if(chooseFile.path !='' ){
|
|
tempFiles.push(chooseFile)
|
|
}
|
|
|
|
}
|
|
}
|
|
const count = options.count ?? Integer.MAX_VALUE // Number.MAX_VALUE
|
|
if(tempFiles.length > 0 && count >= tempFiles.length){
|
|
options.success?.({
|
|
tempFiles,
|
|
errMsg: 'chooseFile:ok'
|
|
} as ChooseFileSuccessCallbackResult)
|
|
} else {
|
|
const err = new GeneralCallbackResultImpl(9010002, `没有可用的文件或文件超过设置数量`)
|
|
options.fail?.(err)
|
|
options.complete?.(err)
|
|
}
|
|
} else {
|
|
const err = new GeneralCallbackResultImpl(9010002, `没有可用的文件`)
|
|
options.fail?.(err)
|
|
options.complete?.(err)
|
|
}
|
|
} else {
|
|
const err = new GeneralCallbackResultImpl(9010002, `没有可用的文件`)
|
|
options.fail?.(err)
|
|
options.complete?.(err)
|
|
}
|
|
}
|
|
|
|
UTSAndroid.onAppActivityResult(resultFunction!)
|
|
UTSAndroid.getUniActivity()!.startActivityForResult(Intent.createChooser(intent, "选择文件"), REQUEST_CODE_CHOOSE_FILE)
|
|
// UTSAndroid.getUniActivity()!.overridePendingTransition((10).toInt(), (0).toInt());
|
|
} |