以下學習自https://blog.csdn.net/guolin_blog/article/details/121063078?spm=1001.2014.3001.5501
startActivityForResult()方法如今已經被廢棄了,官方推薦的是使用Activity Result API來實現兩個Activity之間傳遞數據功能。但Activity Result API時能做的事還有很多,下面來學習一下怎么使用。
兩個Activity之間交換數據
傳統的寫法就是使用startActivityForResult()方法傳入intent和請求碼,然后會回調到onActivityResult()中,在這里面進行返回數據的處理。使用Activity Result API的話,SecondActivity的代碼是不用修改的,如下:
class SecondActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_second) val btn = findViewById<Button>(R.id.btn) btn.setOnClickListener { val intent = Intent() intent.putExtra("data", "this is secondactivity") setResult(RESULT_OK, intent) finish() } } }
只需要修改第一個Activity中的代碼:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) binding.toNext.setOnClickListener { val intent = Intent(this, SecondActivity::class.java) requestDataLauncher.launch(intent) } } private val requestDataLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == RESULT_OK) { val data = result.data?.getStringExtra("data") Log.i(TAG, data.toString()) } }
現在只需要調用registerForActivityResult()方法來注冊一個對Activity結果的監聽。
此方法接收兩個參數,第一個是Contract類型,第二個是一個Lambda表達式,當有結果返回時會回調到這里,在這里獲取並處理數據就行。
請求運行時權限
requestPermissions()方法也被廢棄了。同樣推薦使用Activity Result API,不過這挺好,使用起來非常簡單。如下:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) binding.toNext.setOnClickListener { requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) } } private val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted -> if (granted) { Log.i(TAG, "允許: ") } else { Log.i(TAG, "不允許: ") } }
使用同樣的方法,只不過需要將Contract類型改成RequestPermission,同時修改傳入的參數。至於每種Contract需要傳入什么類型的參數,可以前往它的源碼查看,比如上面這個:
public static final class RequestPermission extends ActivityResultContract<String, Boolean> {
第一個String就是請求的權限名,第二個就是布爾類型的參數作為返回結果。
對了,別忘了去AndroidManifest中添加用戶權限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
內置Contract
以下是內置的一些Contract,通過名字就能判斷出是干什么的了:
StartActivityForResult()
StartIntentSenderForResult()
RequestMultiplePermissions()
RequestPermission()
TakePicturePreview()
TakePicture()
TakeVideo()
PickContact()
GetContent()
GetMultipleContents()
OpenDocument()
OpenMultipleDocuments()
OpenDocumentTree()
CreateDocument()
區分數據來源
當一個Activity需要接收其他多個Activity的結果時,由於沒有requestCode,所以就要采用為每個結果注冊一個監聽器,如下:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) binding.toSecond.setOnClickListener { val intent = Intent(Intent.ACTION_VIEW) actionViewLauncher.launch(intent) } binding.toThree.setOnClickListener { val intent = Intent(Intent.ACTION_DIAL) actionDailLauncher.launch(intent) } } private val actionViewLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> } private val actionDailLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> }