You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用户滑动卸载应用前删除临时录音文件的实现问题

解决Android应用滑动卸载时删除临时录制文件的方案

这个场景确实有点棘手——因为用户从最近任务列表滑掉应用时,进程可能直接被终止,Activity的onDestroy方法不一定能正常执行,常规的退出逻辑会失效。不过我们可以结合WorkManager和全局状态记录来覆盖所有场景,确保未保存的临时文件一定会被清理掉。

核心思路

我们需要处理两种情况:

  1. 用户正常退出ExoPlayerActivity(比如按返回键):直接在生命周期方法里删除文件。
  2. 用户滑掉应用/进程被系统杀死:用WorkManager启动延迟删除任务,同时在应用下次启动时兜底清理。

具体实现步骤

1. 先添加WorkManager依赖

在你的app/build.gradle中加入WorkManager的依赖(版本可以用最新稳定版):

implementation "androidx.work:work-runtime:2.8.1"

2. 创建删除文件的Worker类

这个类负责实际执行文件删除操作,即使应用进程被杀死,WorkManager也会在合适的时机触发它:

class DeleteTempFileWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
    override fun doWork(): Result {
        val filePath = inputData.getString("FILE_PATH") ?: return Result.failure()
        val tempFile = File(filePath)
        
        // 删除文件
        if (tempFile.exists()) tempFile.delete()
        
        // 清除临时文件的记录
        val prefs = applicationContext.getSharedPreferences("TempFilePrefs", Context.MODE_PRIVATE)
        prefs.edit().remove("current_temp_file").apply()
        
        return Result.success()
    }
}

3. 在ExoPlayerActivity中处理逻辑

我们需要跟踪用户是否点击了保存按钮,同时在Activity前后台切换时管理删除任务:

class ExoPlayerActivity : AppCompatActivity() {
    private var isSaved = false // 标记用户是否点击保存
    private var tempFilePath: String? = null
    private var deleteWorkRequestId: UUID? = null // 记录Work任务ID,用于取消
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_exo_player)
        
        // 获取从SingActivity传递过来的文件路径
        tempFilePath = intent.getStringExtra("RECORD_FILE_PATH")
        
        // 把文件路径存到SharedPreferences,防止进程被杀后丢失
        val prefs = getSharedPreferences("TempFilePrefs", MODE_PRIVATE)
        prefs.edit().putString("current_temp_file", tempFilePath).apply()
        
        // 保存按钮点击事件
        findViewById<Button>(R.id.btn_save).setOnClickListener {
            isSaved = true
            // 取消延迟删除任务
            deleteWorkRequestId?.let { WorkManager.getInstance(this).cancelWorkById(it) }
            // 清除临时记录
            prefs.edit().remove("current_temp_file").apply()
            Toast.makeText(this, "文件已保存", Toast.LENGTH_SHORT).show()
            finish()
        }
    }
    
    // 当Activity退到后台时,启动延迟删除任务
    override fun onStop() {
        super.onStop()
        if (!isSaved && tempFilePath != null) {
            val constraints = Constraints.Builder()
                .setRequiredNetworkType(NetworkType.NOT_REQUIRED) // 不需要网络
                .build()
            
            val data = Data.Builder()
                .putString("FILE_PATH", tempFilePath)
                .build()
            
            // 延迟10分钟执行删除,给用户留足够时间回到应用
            val deleteWorkRequest = OneTimeWorkRequestBuilder<DeleteTempFileWorker>()
                .setConstraints(constraints)
                .setInitialDelay(10, TimeUnit.MINUTES)
                .setInputData(data)
                .build()
            
            deleteWorkRequestId = deleteWorkRequest.id
            WorkManager.getInstance(this).enqueue(deleteWorkRequest)
        }
    }
    
    // 当Activity回到前台时,取消删除任务
    override fun onStart() {
        super.onStart()
        deleteWorkRequestId?.let { WorkManager.getInstance(this).cancelWorkById(it) }
    }
    
    // 正常退出时直接删除文件
    override fun onDestroy() {
        super.onDestroy()
        if (!isSaved && tempFilePath != null) {
            val tempFile = File(tempFilePath!!)
            if (tempFile.exists()) tempFile.delete()
            
            val prefs = getSharedPreferences("TempFilePrefs", MODE_PRIVATE)
            prefs.edit().remove("current_temp_file").apply()
        }
    }
}

4. 应用启动时兜底清理

万一WorkManager的任务没触发(比如系统长时间空闲),我们在应用启动时再检查一次,确保临时文件被删除:

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        val prefs = getSharedPreferences("TempFilePrefs", MODE_PRIVATE)
        val tempFilePath = prefs.getString("current_temp_file", null)
        
        tempFilePath?.let {
            val tempFile = File(it)
            if (tempFile.exists()) tempFile.delete()
            prefs.edit().remove("current_temp_file").apply()
        }
    }
}

记得在AndroidManifest.xml中注册这个Application:

<application
    android:name=".MyApplication"
    ...>
    ...
</application>

方案优势

  • 覆盖所有场景:不管用户是正常退出、滑掉应用,还是进程被系统杀死,未保存的临时文件都会被清理。
  • 可靠性高:WorkManager是Android官方推荐的后台任务管理工具,能保证任务在合适的时机执行。
  • 友好性:延迟删除给用户留了反悔时间,只要在延迟时间内回到应用,文件就不会被删除。

内容的提问来源于stack exchange,提问作者BraveEvidence

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:33:41