Supported pdf viewing is there.

This commit is contained in:
AlbYoda 2025-03-24 01:00:36 +01:00
parent 925a0b841c
commit a92f970aaf
Signed by untrusted user who does not match committer: AlbYoda
GPG key ID: A539D876452F16FF
9 changed files with 177 additions and 38 deletions

View file

@ -26,6 +26,16 @@
android:supportsRtl="true"
android:theme="@style/Theme.DeNaDrive"
tools:targetApi="31">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<activity
android:name=".oauth.LoadingActivity"
android:exported="false"

View file

@ -26,7 +26,6 @@ object DriveRequester {
context: Context,
tree: FolderTree
) {
Log.e("MEOW", "populateTree: got here", )
val myUrl = "https://www.googleapis.com/drive/v3/files?trashed=false&orderBy=folder"
makeNewRequest(
context = context,
@ -38,25 +37,24 @@ object DriveRequester {
)
}
) { response, exception ->
Log.e("MOO", "populateTree: and here", )
if (exception != null) {
Log.e("RESPONSE EXCEPTION", "populateTree: ${exception.message}", )
Log.e("RESPONSE EXCEPTION", "populateTree: ${exception.message}")
} else {
val responseBody = ResponsesHandler.newResponseArrived<DriveResponseBody>(response)
if (responseBody != null) {
tree.addChildren(
responseBody.files.map { file -> FolderTree(
responseBody.files.map { file ->
FolderTree(
value = file,
ownPath = "${tree.ownPath}/${file.id}",
parent = tree
) }
)
Log.e("CURRENT", "populateTree: ${tree.value}", )
Log.e("CHILDREN", "populateTree: ${responseBody.files}", )
}
)
tree.loaded = true
for (child in tree.getChildren()) {
if (!child.isLeaf()) populateTree(context, child)
}
Log.e("MOO", "populateTree: also here?", )
}
}
}

View file

@ -23,7 +23,8 @@ class FolderTree(
val value: MyFile,
val ownPath: String = value.id,
private val children: MutableList<FolderTree> = mutableListOf(),
val parent: FolderTree? = null
val parent: FolderTree? = null,
var loaded: Boolean = false
) {
fun isLeaf(): Boolean {

View file

@ -77,16 +77,25 @@ class HomeNotAuthActivity : ComponentActivity() {
"com.bbc.denadrive:/oauth2redirect".toUri()
)
val authRequest = authRequestBuilder
.setScope("https://www.googleapis.com/auth/drive")
.setScopes(
listOf(
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/drive.apps"
)
)
.build()
val authService = AuthorizationService(this)
authService.performAuthorizationRequest(
authRequest,
PendingIntent.getActivity(this, 0, Intent(this, LoadingActivity::class.java),
PendingIntent.FLAG_MUTABLE),
PendingIntent.getActivity(this, 0, Intent(this, HomeNotAuthActivity::class.java),
PendingIntent.FLAG_MUTABLE)
PendingIntent.getActivity(
this, 0, Intent(this, LoadingActivity::class.java),
PendingIntent.FLAG_MUTABLE
),
PendingIntent.getActivity(
this, 0, Intent(this, HomeNotAuthActivity::class.java),
PendingIntent.FLAG_MUTABLE
)
)
}
}

View file

@ -32,6 +32,7 @@ import com.bbc.denadrive.apihandlers.MyFile
import com.bbc.denadrive.apihandlers.ResponsesHandler
import com.bbc.denadrive.apihandlers.ResponsesViewer
import com.bbc.denadrive.apihandlers.makeDriveApiCall
import com.bbc.denadrive.filehandling.FileDownloader
import com.bbc.denadrive.home.ScaffoldWithSidebar
import com.bbc.denadrive.oauth.AuthStatePersistence
import com.bbc.denadrive.ui.theme.DeNaDriveTheme
@ -42,7 +43,12 @@ import okhttp3.HttpUrl
class MainActivity : ComponentActivity() {
private lateinit var responsesViewer: ResponsesViewer
private var currentPath: String = "root"
private val exportSupportedFiles: List<String> = listOf(
"document",
"drawing",
"presentation",
"spreadsheet",
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -64,6 +70,7 @@ class MainActivity : ComponentActivity() {
finish()
}
}
val fileDownloader = FileDownloader(this)
// goToFolder(parentFolder = "root", forward = true, isFirstRequest = true)
@ -71,16 +78,28 @@ class MainActivity : ComponentActivity() {
// val navController = rememberNavController()
ScaffoldWithSidebar(
responsesViewer,
{ name ->
{ file ->
Toast.makeText(
this,
"You pressed the file $name",
"You pressed the file ${file.name}",
Toast.LENGTH_SHORT
).show()
if (file.mimeType.substringAfterLast(".") in exportSupportedFiles) {
fileDownloader.downloadFile(
"https://www.googleapis.com/drive/v3/files/${file.id}/export",
"application/pdf"
)
} else {
Toast.makeText(
this,
"This file has no default action. Download support coming soon",
Toast.LENGTH_SHORT
).show()
}
},
{ folder ->
responsesViewer.currentFolderTree.value =
responsesViewer.currentFolderTree.value.stepForward(folder)
responsesViewer.currentFolderTree.value.stepForward(folder.id)
// responsesViewer.currentFolderTree.value =
// responsesViewer.currentFolderTree.value.goToPath("$folder/")
// parent ->
@ -94,10 +113,17 @@ class MainActivity : ComponentActivity() {
}
// private fun getApps() {
// val myUrl = "https://www.googleapis.com/drive/v3/apps"
// makeNewRequest(myUrl) { }
// }
private fun getApps() {
val myUrl = "https://www.googleapis.com/drive/v3/apps"
DriveRequester.makeNewRequest(this, myUrl, { }) {
response, exception ->
if (exception != null) {
Log.e("notGood", "getApps: $exception", )
} else {
Log.e("GOOD", "getApps: $response", )
}
}
}
// private fun askForFolder(folderId: String) {
// val myUrl = "https://www.googleapis.com/drive/v3/files"

View file

@ -33,7 +33,8 @@ fun makeDriveApiCall(
url: String,
// folderId: String,
builderModifier: (HttpUrl.Builder) -> Unit,
callback: (String?, Exception?) -> Unit) {
callback: (String?, Exception?) -> Unit
) {
val authService = AuthorizationService(context)
// _ = idToken
authState.performActionWithFreshTokens(authService) { accessToken, _, ex ->

View file

@ -0,0 +1,88 @@
package com.bbc.denadrive.filehandling
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.util.Log
import androidx.core.content.FileProvider
import com.bbc.denadrive.oauth.AuthStatePersistence
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.HttpUrl.Companion.toHttpUrl
import java.io.File
import java.io.FileOutputStream
import java.net.HttpURLConnection
import java.net.URL
class FileDownloader(private val context: Context) {
fun downloadFile(fileUrl: String, mimeType: String) {
CoroutineScope(Dispatchers.IO).launch {
val tempFile = downloadIt(fileUrl, mimeType)
withContext(Dispatchers.Main) {
tempFile?.let {
openFile(it)
}
}
}
}
private fun downloadIt(fileUrl: String, mimeType: String): File? {
var tempFile: File? = null
val authState = AuthStatePersistence.retrieveAuthState(context)
try {
tempFile = File.createTempFile("tempFile", ".pdf", context.cacheDir)
// val builder = fileUrl.toHttpUrl().newBuilder()
// builder.addQueryParameter("mimeType", mimeType)
// val urlConnection = builder.build().toUrl().openConnection() as HttpURLConnection
val urlConnection = URL("$fileUrl?mimeType=application/pdf").openConnection() as HttpURLConnection
urlConnection.setRequestProperty("Authorization", "Bearer ${authState.accessToken}")
urlConnection.connect()
// val inputStream1 = urlConnection.inputStream
// val buffer1 = ByteArray(4)
// inputStream1.read(buffer1)
// val header = String(buffer1)
// if (!header.startsWith("%PDF")) {
// Log.e("FileDownloader", "Downloaded file is not a valid PDF")
// }
if (urlConnection.responseCode == HttpURLConnection.HTTP_OK) {
Log.e("MA", "downloadIt: andato", )
val inputStream = urlConnection.inputStream
val outputStream = FileOutputStream(tempFile)
val buffer = ByteArray(1024)
var bytesRead: Int
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
outputStream.write(buffer, 0, bytesRead)
}
outputStream.close()
inputStream.close()
urlConnection.disconnect()
} else {
Log.e("FileDownloader", "Error: ${urlConnection.responseCode} - ${urlConnection.responseMessage}")
}
} catch (e: Exception) {
Log.e("FileDownloader", "downloadIt: download failed", e)
}
return tempFile
}
private fun openFile(file: File) {
val uri: Uri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)
val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(uri, "application/pdf")
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
context.startActivity(intent)
}
}

View file

@ -53,8 +53,8 @@ import com.bbc.denadrive.apihandlers.ResponsesViewer
@Composable
fun ScaffoldWithSidebar(
responsesViewer: ResponsesViewer,
onFileClick: (String) -> Unit,
onFolderClick: (String) -> Unit,
onFileClick: (MyFile) -> Unit,
onFolderClick: (MyFile) -> Unit,
doIt: () -> Unit,
) {
// State to control the drawer
@ -245,8 +245,8 @@ fun Loading(
@Composable
fun AnotherVisualizer(
responsesViewer: ResponsesViewer,
onFileClick: (String) -> Unit,
onFolderClick: (String) -> Unit
onFileClick: (MyFile) -> Unit,
onFolderClick: (MyFile) -> Unit
) {
val currentFolderTree = responsesViewer.currentFolderTree.value
val updater1 = responsesViewer.updater1.value
@ -256,6 +256,10 @@ fun AnotherVisualizer(
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(text = "How did you get here? You're inside a file...")
}
} else if (!currentFolderTree.loaded) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Loading()
}
} else if (currentFolderTree.getChildren().isEmpty()) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text("Empty folder")
@ -263,8 +267,8 @@ fun AnotherVisualizer(
}
} else {
val fileList = currentFolderTree.getChildren().map { tree -> tree.value }
Log.e("Visualizer", "AnotherVisualizer: ${currentFolderTree.value}", )
Log.e("Visualizer", "AnotherVisualizer: ${currentFolderTree.getChildren()}", )
// Log.e("Visualizer", "AnotherVisualizer: ${currentFolderTree.value}", )
// Log.e("Visualizer", "AnotherVisualizer: ${currentFolderTree.getChildren()}", )
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.TopCenter) {
LazyColumn {
items(fileList) { file ->
@ -273,9 +277,7 @@ fun AnotherVisualizer(
val onClick = if (isFolder) onFolderClick
else onFileClick
LogoTextBox(logo, file.name) {
onClick(
if (isFolder) file.id else file.name
)
onClick(file)
}
}
}
@ -284,7 +286,7 @@ fun AnotherVisualizer(
}
fun getId(mimeType: String): Int {
val extracted = mimeType.drop("application/vnd.google-apps.".length)
val extracted = mimeType.substringAfterLast(".")
return when (extracted) {
"document" -> R.drawable.docslogo_ok
"presentation" -> R.drawable.slideslogo_ok

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path name="cache" path="." />
</paths>