comparison android/DWindows.kt @ 2788:8a4f162810c2

Android: During dw_file_browse() request read/write access to external storage. Was hoping this would fix the file access problem in DWIB but sadly it did not, however I still think we need this permission so leaving the code changes. It also required updating the androidx libraries and adding the activity library. After updating there were some reported code errors so those are fixed in this commit as well.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 13 Jul 2022 08:09:08 +0000
parents 220d63da2183
children 025b4e3e7e75
comparison
equal deleted inserted replaced
2787:56312f9c1d6c 2788:8a4f162810c2
1 // (C) 2021-2022 Brian Smith <brian@dbsoft.org> 1 // (C) 2021-2022 Brian Smith <brian@dbsoft.org>
2 // (C) 2019 Anton Popov (Color Picker) 2 // (C) 2019 Anton Popov (Color Picker)
3 // (C) 2022 Amr Hesham (Tree View) 3 // (C) 2022 Amr Hesham (Tree View)
4 package org.dbsoft.dwindows 4 package org.dbsoft.dwindows
5 5
6 import android.Manifest
6 import android.R 7 import android.R
7 import android.annotation.SuppressLint 8 import android.annotation.SuppressLint
8 import android.app.Activity 9 import android.app.Activity
9 import android.app.Dialog 10 import android.app.Dialog
10 import android.app.NotificationChannel 11 import android.app.NotificationChannel
39 import android.webkit.WebView 40 import android.webkit.WebView
40 import android.webkit.WebViewClient 41 import android.webkit.WebViewClient
41 import android.widget.* 42 import android.widget.*
42 import android.widget.AdapterView.OnItemClickListener 43 import android.widget.AdapterView.OnItemClickListener
43 import android.widget.SeekBar.OnSeekBarChangeListener 44 import android.widget.SeekBar.OnSeekBarChangeListener
45 import androidx.activity.result.contract.ActivityResultContracts
44 import androidx.appcompat.app.AlertDialog 46 import androidx.appcompat.app.AlertDialog
45 import androidx.appcompat.app.AppCompatActivity 47 import androidx.appcompat.app.AppCompatActivity
46 import androidx.appcompat.widget.AppCompatEditText 48 import androidx.appcompat.widget.AppCompatEditText
47 import androidx.collection.SimpleArrayMap 49 import androidx.collection.SimpleArrayMap
48 import androidx.constraintlayout.widget.ConstraintLayout 50 import androidx.constraintlayout.widget.ConstraintLayout
49 import androidx.constraintlayout.widget.ConstraintSet 51 import androidx.constraintlayout.widget.ConstraintSet
50 import androidx.constraintlayout.widget.Placeholder 52 import androidx.constraintlayout.widget.Placeholder
51 import androidx.core.app.NotificationCompat 53 import androidx.core.app.NotificationCompat
52 import androidx.core.app.NotificationManagerCompat 54 import androidx.core.app.NotificationManagerCompat
55 import androidx.core.content.ContextCompat
53 import androidx.core.content.res.ResourcesCompat 56 import androidx.core.content.res.ResourcesCompat
54 import androidx.core.view.MenuCompat 57 import androidx.core.view.MenuCompat
55 import androidx.recyclerview.widget.LinearLayoutManager 58 import androidx.recyclerview.widget.LinearLayoutManager
56 import androidx.recyclerview.widget.RecyclerView 59 import androidx.recyclerview.widget.RecyclerView
57 import androidx.viewpager2.widget.ViewPager2 60 import androidx.viewpager2.widget.ViewPager2
1502 class DWEventViewHolder(var view: View) : RecyclerView.ViewHolder(view) 1505 class DWEventViewHolder(var view: View) : RecyclerView.ViewHolder(view)
1503 } 1506 }
1504 1507
1505 private class DWWebViewClient : WebViewClient() { 1508 private class DWWebViewClient : WebViewClient() {
1506 //Implement shouldOverrideUrlLoading// 1509 //Implement shouldOverrideUrlLoading//
1510 @Deprecated("Deprecated in Java")
1507 override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { 1511 override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
1508 // We always want to load in our own WebView, 1512 // We always want to load in our own WebView,
1509 // to match the behavior on the other platforms 1513 // to match the behavior on the other platforms
1510 return false 1514 return false
1511 } 1515 }
2014 if(refresh) { 2018 if(refresh) {
2015 menu!!.clear() 2019 menu!!.clear()
2016 } 2020 }
2017 2021
2018 // Enable group dividers for separators 2022 // Enable group dividers for separators
2019 MenuCompat.setGroupDividerEnabled(menu, true) 2023 MenuCompat.setGroupDividerEnabled(menu!!, true)
2020 2024
2021 for (menuitem in children) { 2025 for (menuitem in children) {
2022 // Submenus on Android can't have submenus, so stop at depth 1 2026 // Submenus on Android can't have submenus, so stop at depth 1
2023 if (menuitem.submenu != null && menu !is SubMenu) { 2027 if (menuitem.submenu != null && menu !is SubMenu) {
2024 if(menuitem.submenuitem == null || refresh) { 2028 if(menuitem.submenuitem == null || refresh) {
2587 eventHandlerInt(window, DWEvent.CONFIGURE, width, height, 0, 0) 2591 eventHandlerInt(window, DWEvent.CONFIGURE, width, height, 0, 0)
2588 } 2592 }
2589 } 2593 }
2590 } 2594 }
2591 2595
2592 override fun onCreateOptionsMenu(menu: Menu?): Boolean { 2596 override fun onCreateOptionsMenu(menu: Menu): Boolean {
2593 if(windowLayout != null) { 2597 if(windowLayout != null) {
2594 val index = windowLayout!!.currentItem 2598 val index = windowLayout!!.currentItem
2595 val count = windowMenuBars.count() 2599 val count = windowMenuBars.count()
2596 2600
2597 if (count > 0 && index < count) { 2601 if (count > 0 && index < count) {
2606 } 2610 }
2607 } 2611 }
2608 return false 2612 return false
2609 } 2613 }
2610 2614
2611 override fun onPrepareOptionsMenu(menu: Menu?): Boolean { 2615 override fun onPrepareOptionsMenu(menu: Menu): Boolean {
2612 if(windowLayout != null) { 2616 if(windowLayout != null) {
2613 val index = windowLayout!!.currentItem 2617 val index = windowLayout!!.currentItem
2614 val count = windowMenuBars.count() 2618 val count = windowMenuBars.count()
2615 2619
2616 if (count > 0 && index < count) { 2620 if (count > 0 && index < count) {
6060 fun debugMessage(text: String) 6064 fun debugMessage(text: String)
6061 { 6065 {
6062 Log.d(appID, text) 6066 Log.d(appID, text)
6063 } 6067 }
6064 6068
6069 @Deprecated("Deprecated in Java")
6065 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { 6070 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
6066 super.onActivityResult(requestCode, resultCode, data) 6071 super.onActivityResult(requestCode, resultCode, data)
6067 if(requestCode == 100) { 6072 if(requestCode == 100) {
6068 fileLock.lock() 6073 fileLock.lock()
6069 if(resultCode == Activity.RESULT_OK) { 6074 if(resultCode == Activity.RESULT_OK) {
6098 6103
6099 // Defpath does not seem to be supported on Android using the ACTION_GET_CONTENT Intent 6104 // Defpath does not seem to be supported on Android using the ACTION_GET_CONTENT Intent
6100 fun fileBrowseNew(title: String, defpath: String?, ext: String?, flags: Int): String? 6105 fun fileBrowseNew(title: String, defpath: String?, ext: String?, flags: Int): String?
6101 { 6106 {
6102 var retval: String? = null 6107 var retval: String? = null
6108 var permission = Manifest.permission.WRITE_EXTERNAL_STORAGE
6109 var permissions: Int = -1
6110
6111 // Handle requesting permissions if necessary
6112 permissions = ContextCompat.checkSelfPermission(this, permission)
6113 if(permissions == -1) //PERMISSION_DENIED
6114 {
6115 // You can directly ask for the permission.
6116 requestPermissions(arrayOf(permission), 100)
6117 }
6103 6118
6104 // This can't be called from the main thread 6119 // This can't be called from the main thread
6105 if(Looper.getMainLooper() != Looper.myLooper()) { 6120 if(Looper.getMainLooper() != Looper.myLooper()) {
6106 var success = true 6121 var success = true
6107 6122