Supported pdf viewing is there.
This commit is contained in:
parent
925a0b841c
commit
a92f970aaf
9 changed files with 177 additions and 38 deletions
|
@ -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"
|
||||
|
|
|
@ -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?", )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -57,7 +57,7 @@ class HomeNotAuthActivity : ComponentActivity() {
|
|||
DeNaDriveTheme {
|
||||
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
||||
val logo = painterResource(id = R.drawable.vecchiaicona_)
|
||||
LogoWithCaptionAndButton (
|
||||
LogoWithCaptionAndButton(
|
||||
logo = logo,
|
||||
caption = "DeNa Drive",
|
||||
buttonText = "Log in",
|
||||
|
@ -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
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -32,8 +32,9 @@ fun makeDriveApiCall(
|
|||
authState: AuthState,
|
||||
url: String,
|
||||
// folderId: String,
|
||||
builderModifier:(HttpUrl.Builder) -> Unit,
|
||||
callback: (String?, Exception?) -> Unit) {
|
||||
builderModifier: (HttpUrl.Builder) -> Unit,
|
||||
callback: (String?, Exception?) -> Unit
|
||||
) {
|
||||
val authService = AuthorizationService(context)
|
||||
// _ = idToken
|
||||
authState.performActionWithFreshTokens(authService) { accessToken, _, ex ->
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
4
app/src/main/res/xml/file_paths.xml
Normal file
4
app/src/main/res/xml/file_paths.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<cache-path name="cache" path="." />
|
||||
</paths>
|
Loading…
Add table
Reference in a new issue