最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android kotlin語言實現(xiàn)刪除文件的解決方案

 更新時間:2025年02月03日 11:01:41   作者:ElsaArendelle  
這篇文章主要介紹了Android kotlin語言實現(xiàn)刪除文件的解決方案,在項目開發(fā)過程中,尤其是需要跨平臺協(xié)作的項目,那么刪除用戶指定的文件的這種操作就顯得尤為重要了,需要的朋友可以參考下

一、前言

在項目開發(fā)過程中,尤其是需要跨平臺協(xié)作的項目,那么刪除用戶指定的文件的這種操作就顯得尤為重要了。但是在Android11+的操作系統(tǒng)中,權限聲明變得復雜了起來,而且大多數(shù)的解決方案多為Java語言,kotlin語言的解決方案甚少,而且大多數(shù)的解決方案也沒有用。

本人也是尋求多日無果后嘗試多種解決方案拼合最終發(fā)現(xiàn)的本解決方案,在這里給廣大開發(fā)者同志們提供一個模板,各位同志可以在本模版的基礎上進行改寫,從而減少無謂查詢資料工作。

二、適用環(huán)境

語言:kotlin

操作系統(tǒng)版本:Android7+(本方案已經(jīng)對Android11+和Android7-10進行了區(qū)分,可以放心使用)

三、模板內(nèi)容

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中的模板

本人在模板中按步驟寫了注釋了,廣大開發(fā)者同志在復制走后,按照注釋的流程消化,然后進行簡單的改寫即可。

完整模板(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的時候就注冊,
     * 不可以現(xiàn)用現(xiàn)注冊
     */
    private lateinit var filePickerLauncher: androidx.activity.result.ActivityResultLauncher<Intent>
    private var onFilePicked: ((String) -> Unit)? = null
    /**
     * 定義目標文件路徑的公共變量
     */
    private var sourceFilePath: String? = null
    override fun onCreate(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(uri) // ? 直接用 `Uri` 刪除
                        Log.e("選取文件", "執(zhí)行結束")
                    } 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.調(diào)用
             */
            if (checkAndRequestPermissions()) {
                pickFile()
            }
        }
    }
    /**
     * 2.定義文件選擇器激活函數(shù)
     */
    private fun pickFile() {
        filePickerLauncher.launch(Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "*/*"
        })
    }
    /**
     * 3.定義URI解析函數(shù)
     */
    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.定義文件刪除函數(shù)
     */
    private fun deleteFileByUri(uri: Uri) {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                // ? Android 10+ 需要用 `DocumentsContract.deleteDocument()`
                val deleted = DocumentsContract.deleteDocument(contentResolver, uri)
                if (deleted) {
                    Log.e("刪除文件", "文件刪除成功: $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語言實現(xiàn)刪除文件的解決方案的詳細內(nèi)容,更多關于Android kotlin刪除文件的資料請關注腳本之家其它相關文章!

相關文章

  • Kotlin協(xié)程launch啟動流程原理詳解

    Kotlin協(xié)程launch啟動流程原理詳解

    這篇文章主要為大家介紹了Kotlin協(xié)程launch啟動流程原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • Android編程實現(xiàn)屏幕禁止休眠的方法

    Android編程實現(xiàn)屏幕禁止休眠的方法

    這篇文章主要介紹了Android編程實現(xiàn)屏幕禁止休眠的方法,分析了Android的Manifest.xml設置與代碼實現(xiàn)兩種操作技巧,需要的朋友可以參考下
    2016-10-10
  • Android自定義開關按鈕源碼解析

    Android自定義開關按鈕源碼解析

    這篇文章主要為大家詳細解析了Android自定義開關源碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • android?studio實現(xiàn)簡易的計算器

    android?studio實現(xiàn)簡易的計算器

    這篇文章主要為大家詳細介紹了android?studio實現(xiàn)簡易的計算器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Android開發(fā)RecyclerView性能優(yōu)化之異步預加載

    Android開發(fā)RecyclerView性能優(yōu)化之異步預加載

    這篇文章主要介紹了Android開發(fā)RecyclerView性能優(yōu)化之異步預加載實現(xiàn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • Android中多行文本末尾添加圖片排版問題的解決方法

    Android中多行文本末尾添加圖片排版問題的解決方法

    這篇文章主要給大家介紹了關于Android中多行文本末尾添加圖片排版問題的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-07-07
  • 自定義RadioButton和ViewPager實現(xiàn)TabHost帶滑動的頁卡效果

    自定義RadioButton和ViewPager實現(xiàn)TabHost帶滑動的頁卡效果

    在工作中又很多需求都不是android系統(tǒng)自帶的控件可以達到效果的所以這個時候就要自定義控件來達到效果:使用自定義RadioButton和ViewPager實現(xiàn)TabHost帶滑動的頁卡效果
    2013-01-01
  • 深入Android中BroadcastReceiver的兩種注冊方式(靜態(tài)和動態(tài))詳解

    深入Android中BroadcastReceiver的兩種注冊方式(靜態(tài)和動態(tài))詳解

    這篇文章主要介紹了深入Android中BroadcastReceiver的兩種注冊方式(靜態(tài)和動態(tài))詳解,具有一定的參考價值,有需要的可以了解一下。
    2016-12-12
  • 深入淺析Android Fragment(下篇)

    深入淺析Android Fragment(下篇)

    本篇文章給大家介紹如何管理Fragment回退棧,F(xiàn)ragment如何與Activity交互,F(xiàn)ragment與Activity交互的最佳實踐,沒有視圖的Fragment的用處,使用Fragment創(chuàng)建對話框,如何與ActionBar,MenuItem集成,對Android Fragment感興趣的朋友可以參考下本篇文章
    2015-10-10
  • Android studio 2020中的Android SDK 下載教程

    Android studio 2020中的Android SDK 下載教程

    這篇文章主要介紹了Android studio 2020中的Android SDK 下載教程,本文圖文并茂給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03

最新評論

南部县| 航空| 宁海县| 香港| 察雅县| 句容市| 佛坪县| 安岳县| 土默特右旗| 台湾省| 安岳县| 子洲县| 五台县| 永丰县| 来安县| 天门市| 阿克陶县| 咸阳市| 明水县| 芒康县| 盐池县| 满城县| 嘉善县| 宝坻区| 姚安县| 龙泉市| 游戏| 凯里市| 霍州市| 新龙县| 和平区| 澄迈县| 福贡县| 绩溪县| 弥勒县| 昌宁县| 巴林右旗| 夹江县| 临漳县| 冷水江市| 延川县|