1 /* <lambda>null2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.healthconnect.controller.exportimport 18 19 import android.app.Activity 20 import android.content.Intent 21 import android.os.Bundle 22 import android.provider.DocumentsContract 23 import android.view.LayoutInflater 24 import android.view.View 25 import android.view.View.GONE 26 import android.view.View.VISIBLE 27 import android.view.ViewGroup 28 import android.widget.Button 29 import android.widget.Toast 30 import androidx.activity.result.ActivityResult 31 import androidx.activity.result.ActivityResultLauncher 32 import androidx.activity.result.contract.ActivityResultContracts 33 import androidx.fragment.app.Fragment 34 import androidx.fragment.app.activityViewModels 35 import androidx.navigation.fragment.findNavController 36 import com.android.healthconnect.controller.R 37 import com.android.healthconnect.controller.exportimport.api.DocumentProviders 38 import com.android.healthconnect.controller.exportimport.api.ExportSettingsViewModel 39 import com.android.healthconnect.controller.exportimport.api.isLocalFile 40 import com.android.healthconnect.controller.utils.DeviceInfoUtils 41 import com.android.settingslib.widget.LinkTextView 42 import dagger.hilt.android.AndroidEntryPoint 43 import javax.inject.Inject 44 45 /** Export destination fragment for Health Connect. */ 46 @AndroidEntryPoint(Fragment::class) 47 class ExportDestinationFragment : Hilt_ExportDestinationFragment() { 48 49 private val contract = ActivityResultContracts.StartActivityForResult() 50 private val saveResultLauncher: ActivityResultLauncher<Intent> = 51 registerForActivityResult(contract, ::onSave) 52 53 private val viewModel: ExportSettingsViewModel by activityViewModels() 54 55 @Inject lateinit var deviceInfoUtils: DeviceInfoUtils 56 57 override fun onCreateView( 58 inflater: LayoutInflater, 59 container: ViewGroup?, 60 savedInstanceState: Bundle? 61 ): View? { 62 val view = inflater.inflate(R.layout.export_destination_screen, container, false) 63 val footerView = view.findViewById<View>(R.id.export_import_footer) 64 val playStoreView = view.findViewById<LinkTextView>(R.id.export_import_go_to_play_store) 65 val backButton = view.findViewById<Button>(R.id.export_import_cancel_button) 66 val nextButton = view.findViewById<Button>(R.id.export_import_next_button) 67 68 backButton?.text = getString(R.string.export_back_button) 69 backButton?.setOnClickListener { 70 findNavController() 71 .navigate(R.id.action_exportDestinationFragment_to_exportFrequencyFragment) 72 } 73 74 nextButton.text = getString(R.string.export_next_button) 75 nextButton.setEnabled(false) 76 77 if (deviceInfoUtils.isPlayStoreAvailable(requireContext())) { 78 playStoreView?.setVisibility(VISIBLE) 79 playStoreView?.setOnClickListener { 80 findNavController().navigate(R.id.action_exportDestinationFragment_to_playStore) 81 } 82 } 83 84 val documentProvidersViewBinder = DocumentProvidersViewBinder() 85 val documentProvidersList = view.findViewById<ViewGroup>(R.id.export_document_providers) 86 viewModel.documentProviders.observe(viewLifecycleOwner) { providers -> 87 documentProvidersList.removeAllViews() 88 nextButton.setOnClickListener {} 89 nextButton.setEnabled(false) 90 91 when (providers) { 92 is DocumentProviders.Loading -> { 93 // Do nothing 94 } 95 is DocumentProviders.LoadingFailed -> { 96 Toast.makeText(activity, R.string.default_error, Toast.LENGTH_LONG).show() 97 } 98 is DocumentProviders.WithData -> { 99 documentProvidersViewBinder.bindDocumentProvidersView( 100 providers.providers, documentProvidersList, inflater) { root -> 101 nextButton.setOnClickListener { 102 saveResultLauncher.launch( 103 Intent(Intent.ACTION_CREATE_DOCUMENT) 104 .addFlags( 105 Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or 106 Intent.FLAG_GRANT_WRITE_URI_PERMISSION) 107 .setType("application/zip") 108 .addCategory(Intent.CATEGORY_OPENABLE) 109 .putExtra(DocumentsContract.EXTRA_INITIAL_URI, root.uri)) 110 } 111 nextButton.setEnabled(true) 112 } 113 114 if (providers.providers.size > 1) { 115 footerView.setVisibility(GONE) 116 } else { 117 footerView.setVisibility(VISIBLE) 118 } 119 } 120 } 121 } 122 123 return view 124 } 125 126 private fun onSave(result: ActivityResult) { 127 if (result.resultCode == Activity.RESULT_OK) { 128 val fileUri = result.data?.data ?: return 129 if (isLocalFile(fileUri)) { 130 Toast.makeText(activity, R.string.export_invalid_storage, Toast.LENGTH_LONG).show() 131 } else { 132 viewModel.updateExportUriWithSelectedFrequency(fileUri) 133 requireActivity().finish() 134 } 135 } 136 } 137 } 138