Android 文件共享指南

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:name=".App"
        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.Ball"
        tools:targetApi="31">

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.demo.ball.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
    </application>

</manifest>

App:

package com.demo.ball

import android.app.Application
import android.util.Log
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.util.zip.ZipInputStream

class App : Application() {
    companion object {
        private const val TAG = "App"
    }

    override fun onCreate() {
        super.onCreate()
        GlobalScope.launch {
            unTBTZip()
        }
    }

    private fun unTBTZip() {
        Log.i(TAG, "unTBTZip startTime: ${System.currentTimeMillis()}")
        val tbtDir = File(filesDir, "tbt")
        if (tbtDir.exists()) {
            Log.i(TAG, "unTBTZip: tbt dir exists")
            return
        }
        if (!tbtDir.mkdirs()) {
            Log.i(TAG, "unTBTZip: tbt dir create fail")
            return
        }
        Log.i(TAG, "unTBTZip: tbt dir ${tbtDir.exists()}")

        val tbtZipIn = ZipInputStream(assets.open("tbt.zip"))
        var nextEntry = tbtZipIn.nextEntry
        while (nextEntry != null) {
            if (!nextEntry.isDirectory) {
                val file = File(tbtDir, nextEntry.name)
                Log.i(TAG, "unTBTZip: ${file.exists()}")

                val fos = FileOutputStream(file)
                val buffer = ByteArray(1024)
                var len: Int
                while (tbtZipIn.read(buffer).also { len = it } > 0) {
                    fos.write(buffer, 0, len)
                }
                fos.close()
            }
            tbtZipIn.closeEntry()
            nextEntry = tbtZipIn.nextEntry
        }
        tbtZipIn.close()
        Log.i(TAG, "unTBTZip endTime: ${System.currentTimeMillis()}")
    }
}

MainActivity:

package com.demo.ball

import android.annotation.SuppressLint
import android.content.ComponentName
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.ContactsContract
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import com.demo.ball.databinding.ActivityMainBinding
import java.io.File

class MainActivity : AppCompatActivity() {
    private val TAG = MainActivity::class.simpleName

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // Example of a call to a native method
        // binding.sampleText.text = stringFromJNI()

        // 初始化数据
        initData()
        // 初始化事件
        initEvent()
    }

    override fun onDestroy() {
        super.onDestroy()
    }

    private fun initData() {
    }

    private fun initEvent() {
        binding.mainStraightBtn.setOnClickListener { straight() }
        binding.mainLeftBtn.setOnClickListener { left() }
        binding.mainRightBtn.setOnClickListener { right() }
    }

    private fun straight() {
        // path: /data/user/0/com.demo.ball/files
        // absolutePath: /data/user/0/com.demo.ball/files
        // canonicalPath: /data/data/com.demo.ball/files
        // invariantSeparatorsPath: /data/user/0/com.demo.ball/files
        // toPath: /data/user/0/com.demo.ball/files
        Log.i(TAG, "straight")
        Log.i(TAG, "path: ${filesDir.path}")
        Log.i(TAG, "absolutePath: ${filesDir.absolutePath}")
        Log.i(TAG, "canonicalPath: ${filesDir.canonicalPath}")
        Log.i(TAG, "invariantSeparatorsPath: ${filesDir.invariantSeparatorsPath}")
        Log.i(TAG, "toPath: ${filesDir.toPath()}")

        sendTBT(1)
    }

    private fun left() {
        Log.i(TAG, "left")
        sendTBT(2)
    }

    private fun right() {
        Log.i(TAG, "right")
        sendTBT(3)
    }

    private fun sendTBT(id: Int) {
        val uri = getTBT(id)
        Log.i(TAG, "getTBT: $uri")
        if (uri == null) {
            Log.i(TAG, "deleteData: tbt not exists")
            return
        }

        runOnUiThread {
            binding.mainTbtIv.setImageURI(uri)
        }

        val shareIntent = Intent(Intent.ACTION_VIEW)
        shareIntent.setDataAndType(uri, "image/*")
        shareIntent.component = ComponentName("com.demo.baobab", "com.demo.baobab.MainActivity")
        shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        startActivity(shareIntent)
    }

    private fun getTBT(id: Int): Uri? {
        val file = File(File(filesDir, "tbt"), "tbt_$id.png")
        Log.i(TAG, "getTBT file1: ${file.canonicalPath}")
        val tbtFile = File("$filesDir${File.separator}tbt${File.separator}tbt_$id.png")
        Log.i(TAG, "getTBT file2: ${tbtFile.canonicalPath}")
        if (!tbtFile.exists()) {
            Log.i(TAG, "getTBT: file not exists")
            return null
        }

        return FileProvider.getUriForFile(this, "com.demo.ball.fileprovider", tbtFile)
    }
}

接收端App:

package com.demo.baobab

import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.demo.baobab.data.NotesDbHelper

class MainActivity : AppCompatActivity() {

    companion object {
        private const val TAG = "MainActivity"
    }

    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
        }

        setTBT()
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        setTBT()
    }

    private fun setTBT() {
        val tbtUri = intent.data
        Log.i(TAG, "initData: $tbtUri")
        if (tbtUri == null) {
            Log.i(TAG, "setTBT: tbt not exists")
            return
        }

        uiState.tbtIv!!.setImageURI(tbtUri)
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容