Android kotlin语言实现删除文件的解决方案

2025-02-05 04:50

本文主要是介绍Android kotlin语言实现删除文件的解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的...

一、前言

在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的这种操作就显得尤为重要了。但是在android11+的操作系统中,权限声明变得复杂了起来,而且大多数的解决方案多为Java语言,kotlin语言的解决方案甚少,而且大多数的解决方案也没有用。

本人也是寻求多日无果后尝试多种解决方案拼合最终发现的本解决方案,在这里给广大开发者同志们提供一个模板,各位同志可以在本模版的基础上进行改写,从而减少无谓查询资料工作。

二、适用环境

语言:kotlin

操作系统版本:Android7+(本方案已经对Android11+和Android7-10进行了区分,可以放心使用)

三、模板内容

1.权限申请

首先在AndroidManifest.XML中必须注册这三项权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
        android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />

完整的AndroidManifest.xml示例如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <application
        android:allowBackup="true"
        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.AbstractFunctionDemo"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission
        android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />
</manifest>

2.Activity中的模板

本人在模板中按步骤写了注释了,广大开发者同志在复制走后,按照注释的流程消化,然后进行简单的改写即可。

完整模板(MainActivity.kt)如下:

package com.example.abstractfunctiondemo
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import android.Manifest
import android.app.Activity
import android.content.ContentUris
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.provider.Settings
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
import android.provider.OpenableColumns
import android.util.Log
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.documentfile.provider.DocumentFile
import com.google.android.material.button.MaterialButton
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.OutputStream
class MainActivity : AppCompatActivity() {
    /**
     * 1.定义选择器的公共变量
     *
     * 定义这个全局变量是因为必须在onCreate的时候就注册,
     * 不可以现用现注册
     */
    http://www.chinasem.cnprivate lateinit var filePickerLauncher: androidx.activity.result.ActivityResultLauncher<Intent>
    private var onFilePicked: ((String) -> Unit)? = null
    /**
     * 定义目标文件路径的公共变量
     */
    private var sourceFilePath: String? = null
    override fun onjavascriptCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
        /**
         * 5.注册文件选择器
         */
        filePickerLauncher =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                if (result.resultCode == Activity.RESULT_OK) {
                    val uri: Uri? = result.data?.data
                    if (uri != null) {
                        Log.e("选取文件", "选择的文件 URI: $uri")
                        onFilePicked?.invoke(uri.toString()) // ✅ 直接返回 `Uri`
                        deleteFileByUri(urwww.chinasem.cni) // ✅ 直接用 `Uri` 删除
                        Log.e("选取文件", "执行结束")
                    } else {
                        Toast.makeText(this, "无法获取文件", Toast.LENGTH_SHORT).show()
                    }
                } else {
                    Toast.makeText(this, "未选择文件", Toast.LENGTH_SHORT).show()
                }
            }
        val testButton2: MaterialButton = findViewById(R.id.testButton2)
        testButton2.setOnClickListener {
            /**
             * 6.调用
             */
            if (checkAndRequestPermissions()) {
                pickFile()
            }
        }
    }
    /**
     * 2.定义文件选择器激活函数
     */
    private fun pickFile() {
        filePickerLauncher.launch(Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "*/*"
        })
    }
    /**
     * 3.定义URI解析函数
     */
    private fun getFilePathFromUri(uri: Uri): String? {
        val context = applicationContext
        var filePath: String? = null
        if (uri.scheme == "content") {
            val projection = arrayOf(MediaStore.Files.FileColumns.DATA)
            context.contentResolver.query(uri, projection, null, null, null)?.use { cursor ->
                if (cursor.moveToFirst()) {
                    val columnIndex =
                        cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA)
                    filePath = cursor.getString(columnIndex)
                }
            }
        }
        return filePath
    }
    /**
     * 4.定义文件删除函数
     */
    private fun deleteFileByUri(uri: Uri) {
        try {
            if (Build.VERSION.SDK_INT >www.chinasem.cn;= Build.VERSION_CODES.Q) {
                // ✅ Android 10+ 需要用 `DocumentsContract.deleteDocument()`
                val deleted = DocumentsContract.deleteDocument(contentResolver, uri)
                if (deleted) {
                    Log.e("删除文件", "文件删除www.chinasem.cn成功: $uri")
                    Toast.makeText(this, "文件删除成功", Toast.LENGTH_SHORT).show()
                } else {
                    Log.e("删除文件", "文件删除失败: $uri")
                    Toast.makeText(this, "无法删除文件", Toast.LENGTH_SHORT).show()
                }
            } else {
                // ✅ Android 9 及以下,尝试转换为文件路径
                val filePath = getFilePathFromUri(uri)
                if (filePath != null) {
                    val file = File(filePath)
                    if (file.exists() && file.delete()) {
                        Log.e("删除文件", "文件删除成功: $filePath")
                        Toast.makeText(this, "文件删除成功", Toast.LENGTH_SHORT).show()
                    } else {
                        Log.e("删除文件", "文件删除失败: $filePath")
                        Toast.makeText(this, "无法删除文件", Toast.LENGTH_SHORT).show()
                    }
                } else {
                    Toast.makeText(this, "无法获取文件路径,尝试手动删除", Toast.LENGTH_SHORT).show()
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Toast.makeText(this, "删除文件出错: ${e.message}", Toast.LENGTH_SHORT).show()
        }
    }
}

以上就是Android kotlin语言实现删除文件的解决方案的详细内容,更多关于Android kotlin删除文件的资料请关注China编程(www.chinasem.cn)其它相关文章!

这篇关于Android kotlin语言实现删除文件的解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1153297

相关文章

Spring IOC的三种实现方式详解

《SpringIOC的三种实现方式详解》:本文主要介绍SpringIOC的三种实现方式,在Spring框架中,IOC通过依赖注入来实现,而依赖注入主要有三种实现方式,构造器注入、Setter注入... 目录1. 构造器注入(Cons编程tructor Injection)2. Setter注入(Setter

Spring IOC控制反转的实现解析

《SpringIOC控制反转的实现解析》:本文主要介绍SpringIOC控制反转的实现,IOC是Spring的核心思想之一,它通过将对象的创建、依赖注入和生命周期管理交给容器来实现解耦,使开发者... 目录1. IOC的基本概念1.1 什么是IOC1.2 IOC与DI的关系2. IOC的设计目标3. IOC

Python实现文件下载、Cookie以及重定向的方法代码

《Python实现文件下载、Cookie以及重定向的方法代码》本文主要介绍了如何使用Python的requests模块进行网络请求操作,涵盖了从文件下载、Cookie处理到重定向与历史请求等多个方面,... 目录前言一、下载网络文件(一)基本步骤(二)分段下载大文件(三)常见问题二、requests模块处理

Linux内存泄露的原因排查和解决方案(内存管理方法)

《Linux内存泄露的原因排查和解决方案(内存管理方法)》文章主要介绍了运维团队在Linux处理LB服务内存暴涨、内存报警问题的过程,从发现问题、排查原因到制定解决方案,并从中学习了Linux内存管理... 目录一、问题二、排查过程三、解决方案四、内存管理方法1)linux内存寻址2)Linux分页机制3)

IDEA运行spring项目时,控制台未出现的解决方案

《IDEA运行spring项目时,控制台未出现的解决方案》文章总结了在使用IDEA运行代码时,控制台未出现的问题和解决方案,问题可能是由于点击图标或重启IDEA后控制台仍未显示,解决方案提供了解决方法... 目录问题分析解决方案总结问题js使用IDEA,点击运行按钮,运行结束,但控制台未出现http://

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

Java中List转Map的几种具体实现方式和特点

《Java中List转Map的几种具体实现方式和特点》:本文主要介绍几种常用的List转Map的方式,包括使用for循环遍历、Java8StreamAPI、ApacheCommonsCollect... 目录前言1、使用for循环遍历:2、Java8 Stream API:3、Apache Commons

C#提取PDF表单数据的实现流程

《C#提取PDF表单数据的实现流程》PDF表单是一种常见的数据收集工具,广泛应用于调查问卷、业务合同等场景,凭借出色的跨平台兼容性和标准化特点,PDF表单在各行各业中得到了广泛应用,本文将探讨如何使用... 目录引言使用工具C# 提取多个PDF表单域的数据C# 提取特定PDF表单域的数据引言PDF表单是一

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫