我的Android应用程序的目标是Android 13(API 33)
我已经从我的列表中生成了一个Excel文件并保存了它,但它没有保存在API 33中,但低于API Android 33保存得很好。
如果需要,这些库已被使用
implementation 'org.apache.poi:poi:4.0.0' implementation 'org.apache.poi:poi-ooxml:4.0.0'
清单权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
检查权限
private void checkPermission() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
if (getApplicationContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(permissions, 1);
} else {
importData();
}
} else {
importData();
}
}
制作excel文件并存储
private void importData() {
//get data from edit text
try {
userList.add(new SheetModel("kawcher", "0181238383", "nmkawcher112@gmail.com"));
userList.add(new SheetModel("shuvo", "0171238383", "demo1@gmail.com"));
userList.add(new SheetModel("hasan", "0161238383", "demo2@gmail.com"));
userList.add(new SheetModel("habib", "0151238383", "demo3@gmail.com"));
userList.add(new SheetModel("selim", "0131238383", "demo4@gmail.com"));
userList.add(new SheetModel("tayeb", "0121238383", "demo5@gmail.com"));
userList.add(new SheetModel("abul kalam", "0191238383", "demo6@gmail.com"));
userList.add(new SheetModel("Kamal", "0101238383", "demo7@gmail.com"));
}catch (Exception e){e.printStackTrace();}
if (userList.size() > 0) {
createXlFile();
} else {
Toast.makeText(this, "list are empty", Toast.LENGTH_SHORT).show();
}
}
private void createXlFile() {
// File filePath = new File(Environment.getExternalStorageDirectory() + "/Demo.xls");
Workbook wb = new HSSFWorkbook();
Cell cell = null;
Sheet sheet = null;
sheet = wb.createSheet("Demo Excel Sheet");
//Now column and row
Row row = sheet.createRow(0);
cell = row.createCell(0);
cell.setCellValue("Person Name");
cell = row.createCell(1);
cell.setCellValue("Phone Number");
cell = row.createCell(2);
cell.setCellValue("Email Address");
//column width
sheet.setColumnWidth(0, (20 * 200));
sheet.setColumnWidth(1, (30 * 200));
sheet.setColumnWidth(2, (30 * 200));
for (int i = 0; i < userList.size(); i++) {
Row row1 = sheet.createRow(i + 1);
cell = row1.createCell(0);
cell.setCellValue(userList.get(i).getName());
cell = row1.createCell(1);
cell.setCellValue((userList.get(i).getPhoneNo()));
// cell.setCellStyle(cellStyle);
cell = row1.createCell(2);
cell.setCellValue(userList.get(i).getEmail());
sheet.setColumnWidth(0, (20 * 200));
sheet.setColumnWidth(1, (30 * 200));
sheet.setColumnWidth(2, (30 * 200));
}
String folderName = "Import Excel";
String fileName = folderName + System.currentTimeMillis() + ".xls";
String path = Environment.getExternalStorageDirectory() + File.separator + folderName + File.separator + fileName;
File file = new File(Environment.getExternalStorageDirectory() + File.separator + folderName);
if (!file.exists()) {
file.mkdirs();
}
// file.deleteOnExit();
FileOutputStream outputStream = null;
try {
//
outputStream = new FileOutputStream(path);
// outputStream = new FileOutputStream(new File(getFilesDir()., path));
wb.write(outputStream);
// ShareViaEmail(file.getParentFile().getName(),file.getName());
Toast.makeText(getApplicationContext(), "Excel Created in " + path, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Not OK", Toast.LENGTH_LONG).show();
try {
outputStream.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
错误logcat:
/System.err: java.io.FileNotFoundException: /storage/emulated/0/Import Excel/Import Excel1681376608447.xls: open
failed: ENOENT (No such file or directory)
at libcore.io.IoBridge.open(IoBridge.java:574)
at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
at java.io.FileOutputStream.<init>(FileOutputStream.java:125)
at com.roomack.amlaak.view.activity.MainActivity.createXlFile(MainActivity.java:1125)
at com.roomack.amlaak.view.activity.MainActivity.importData(MainActivity.java:1051)
at com.roomack.amlaak.view.activity.MainActivity.checkPermission(MainActivity.java:1020)
at com.roomack.amlaak.view.activity.MainActivity.access$300(MainActivity.java:100)
at com.roomack.amlaak.view.activity.MainActivity$18.onClick(MainActivity.java:821)
at android.view.View.performClick(View.java:7560)
at android.view.View.performClickInternal(View.java:7533)
at ndroid.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
at android.view.View$PerformClick.run(View.java:29754)
W/System.err: at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:211)
at android.os.Looper.loop(Looper.java:300)
at android.app.ActivityThread.main(ActivityThread.java:8143)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1028)
Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
at libcore.io.Linux.open(Native Method)
at libcore.io.ForwardingOs.open(ForwardingOs.java:563)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:274)
at libcore.io.ForwardingOs.open(ForwardingOs.java:563)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:8019)
at libcore.io.IoBridge.open(IoBridge.java:560)
您不能在Android 13设备上请求写入权限。
您在所有应用程序特定目录和外部存储上的所有公用目录中自动拥有写入权限。
在HomeFragment.kt的调用方式如下:
binding.btHomeExport.setOnClickListener {
GlobalScope.launch {
exportData(requireActivity())
}
}
Export.kt
它只是一个转换为Kotlin的Java实用程序类,实际上只是为了移出代码:
对象导出{暂停趣味导出数据(activity:activity){
try {
// read again from file?
val listMyDealWithMyClient = doReadFromFile(activity)
val timeZoneDate = SimpleDateFormat("yyyy-MMM-dd_HH-mm-ss", Locale.getDefault())
val formattedDate = timeZoneDate.format( Date())
val workbook = XSSFWorkbook()
val workSheet = workbook.createSheet("MyDeals_$formattedDate")
val colorMap = workbook.stylesSource.indexedColors
val cellStyleHeader = workbook.createCellStyle()
cellStyleHeader.fillForegroundColor = IndexedColors.AQUA.getIndex()
cellStyleHeader.fillPattern = FillPatternType.SOLID_FOREGROUND
cellStyleHeader.font.bold = true
cellStyleHeader.verticalAlignment = VerticalAlignment.CENTER
cellStyleHeader.alignment = HorizontalAlignment.CENTER
cellStyleHeader.setRightBorderColor( XSSFColor(byteArrayOf(0, 0, 0), colorMap))
cellStyleHeader.borderRight = BorderStyle.THIN
val row0 = workSheet.createRow(0)
row0.height = 800
这里有更多的代码,它们是数据处理。。。
// save workbook to file:
val fileName = "data_$formattedDate.xlsx"
val fos: FileOutputStream =
activity.openFileOutput(fileName, Context.MODE_PRIVATE)!!
workbook.write(fos)
workbook.close()
withContext(Dispatchers.IO) {
fos.flush()
fos.close();
};
//need: fos.path, but it is private!
val appPath = activity.application?.filesDir?.absolutePath
// delete old .xlsx files
val dir = appPath?.let { File(it) }
dir?.listFiles()!!.forEach { file ->
run {
if (file.name.endsWith(".xlsx")) {
file.deleteOnExit()
}
}
}
val exportFile = File(appPath, fileName)
val sharingIntent = Intent(Intent.ACTION_SEND)
val fileUri =
FileProvider.getUriForFile(//
activity.applicationContext!!,
activity.packageName + ".fileProvider",
exportFile
);
非常重要的是,".fileProvider"
必须与其他情况相匹配:清单:
<application
android:allowBackup="false"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyAppTheme"
tools:targetApi="33">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="my.package.with.myid.fileProvider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_path"/>
</provider>
<activity
android:name=
不需要读取外部、写入外部权限!不需要!
在res/xml
创建一个文件file_provider_path.xml
粘贴内容:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path
name="files"
path="." />
</paths>
它将被导出的文件,不确定其他应用程序如何访问它。这就是为什么我要共享/发送文件,并让用户选择Intent:
// add provider
sharingIntent.type = "*/*"
sharingIntent.putExtra(Intent.EXTRA_STREAM, fileUri)
sharingIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
activity.startActivity(sharingIntent)
} catch (ex: Exception) {
ex.printStackTrace()
Toast.makeText(activity, ex.message, Toast.LENGTH_LONG).show();
}
}
}
这是Export.kt
的最后一部分
今天(2023年5月22日),它将与Android 33合作…明天可能不会——就像谷歌如何改变他们的API。。。
我不针对其他设备,只针对Android 33,因为它是一款适用于某些人的实用程序。Androi在8号前、8号后、9号前、9号后、10号前、11号前、12号前、13号前和+13号时发生了许多变化花了大约10天的时间把乐高积木拼在一起:)
作为测试,我正在通过蓝牙将.xlsx文件发送到台式电脑(Windowws 10),并在那里检查数据+格式,并且正在工作!