亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

一、前言

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

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

二、適用環(huán)境

語言:kotlin

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

三、模板內(nèi)容

1.權(quán)限申請

首先在AndroidManifest.xml中必須注冊這三項權(quán)限:

<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ā)者同志在復(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í)行結(jié)束")
                    } 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 及以下,嘗試轉(zhuǎn)換為文件路徑
                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)容,更多關(guān)于Android kotlin刪除文件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解adb工具的基本使用

    詳解adb工具的基本使用

    adb全稱Android Debug Bridge,是Android SDK中的一個工具, 使用adb可以直接操作管理Android模擬器或者真實的Andriod設(shè)備,就是起到調(diào)試橋的作用,這篇文章主要介紹了adb工具的基本使用,需要的朋友可以參考下
    2022-08-08
  • Android Broadcast 和 BroadcastReceiver的權(quán)限限制方式

    Android Broadcast 和 BroadcastReceiver的權(quán)限限制方式

    這篇文章主要介紹了Android Broadcast 和 BroadcastReceiver的權(quán)限限制方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Android用StaticLayout實現(xiàn)文字轉(zhuǎn)化為圖片效果(類似長微博發(fā)送)

    Android用StaticLayout實現(xiàn)文字轉(zhuǎn)化為圖片效果(類似長微博發(fā)送)

    這篇文章主要給大家介紹了關(guān)于Android利用StaticLayout實現(xiàn)文字轉(zhuǎn)化為圖片效果,實現(xiàn)的效果類似我們常見的長微博效果,文中給出了詳細的示例代碼供大家參考學(xué)習(xí),需要的朋友們下面來一起看看吧。
    2017-08-08
  • Android動態(tài)布局小結(jié)

    Android動態(tài)布局小結(jié)

    android動態(tài)布局相比靜態(tài)布局,動態(tài)布局不用再將xml轉(zhuǎn)變了布局代碼,提高了一定的效率,本篇文章給大家介紹android動態(tài)布局小結(jié),對android動態(tài)布局相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2016-01-01
  • Android開發(fā)Retrofit源碼分析

    Android開發(fā)Retrofit源碼分析

    這篇文章主要為大家介紹了Android開發(fā)Retrofit源碼分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Android手機聯(lián)系人帶字母索引的快速查找

    Android手機聯(lián)系人帶字母索引的快速查找

    這篇文章主要為大家詳細介紹了Android手機聯(lián)系人帶字母索引的快速查找實現(xiàn)方法,感興趣的小伙伴們可以參考一下
    2016-03-03
  • Android 5.0 實現(xiàn)水波擴散效果

    Android 5.0 實現(xiàn)水波擴散效果

    這篇文章主要為大家詳細介紹了Android 5.0 實現(xiàn)水波擴散效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • 詳解Android 7.0 Settings 加載選項

    詳解Android 7.0 Settings 加載選項

    本篇文章主要介紹了Android 7.0 Settings 加載選項,Android 7.0 Settings頂部多了一個建議選項,多了個側(cè)邊欄,操作更加便捷了,有興趣的可以了解一下。
    2017-02-02
  • Android自定義ViewGroup之實現(xiàn)FlowLayout流式布局

    Android自定義ViewGroup之實現(xiàn)FlowLayout流式布局

    這篇文章主要為大家詳細介紹了Android自定義ViewGroup之實現(xiàn)FlowLayout流式布局的相關(guān)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-06-06
  • 詳解Android中PopupWindow在7.0后適配的解決

    詳解Android中PopupWindow在7.0后適配的解決

    本篇文章主要介紹了詳解Android中PopupWindow在7.0后適配的解決,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05

最新評論