Android Question I can't show image in ImageView if target SDK is > 13

agraham

Expert
Licensed User
Longtime User
I must missing something obvious here but I can't see it :(

I have the simplest Activity to try to show an image and the image shows if the manifest has this entry

<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="13"/>

If I set targetSdkVersion to 14 or higher the image doesn't show although the size of the bitmap is correctly logged so it looks like it has loaded it.

Also if I comment out ImageView1.Bitmap = Bitmap1 then ImageView1.Color = Colors.Red has no effect no matter what targetSdkVersion is set to.

B4X:
#Region  Activity Attributes
   #FullScreen: False
   #IncludeTitle: True
#End Region

Sub Process_Globals
   Dim Bitmap1 As Bitmap
End Sub

Sub Globals

   Dim ImageView1 As ImageView  
End Sub

Sub Activity_Create(FirstTime As Boolean)
   ImageView1.Initialize("ImageView1")
   Activity.AddView(ImageView1, 0, 0, 100%x, 100%y)
   ImageView1.Color = Colors.Red
   Log("Viewer created")
End Sub

Sub Activity_Resume
   Bitmap1.Initialize(File.DirRootExternal, Starter.ViewerFolder &  Starter.ViewerFilename)
   ImageView1.Gravity = Gravity.FILL
   ImageView1.Bitmap = Bitmap1
   Log("Bitmap = " & Bitmap1.Width & " x " & Bitmap1.Height)
End Sub

Sub Activity_Pause (UserClosed As Boolean)
   ' avoid hangs on rotation caused by large bitmaps
   Log("Viewer Paused")
   Dim Obj1 As Reflector
   Obj1.Target = Bitmap1 ' the unwanted Bitmap
   Obj1.RunMethod("recycle")
   Bitmap1 = Null
End Sub
 

walterf25

Expert
Licensed User
Longtime User
I must missing something obvious here but I can't see it :(

I have the simplest Activity to try to show an image and the image shows if the manifest has this entry

<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="13"/>

If I set targetSdkVersion to 14 or higher the image doesn't show although the size of the bitmap is correctly logged so it looks like it has loaded it.

Also if I comment out ImageView1.Bitmap = Bitmap1 then ImageView1.Color = Colors.Red has no effect no matter what targetSdkVersion is set to.

B4X:
#Region  Activity Attributes
   #FullScreen: False
   #IncludeTitle: True
#End Region

Sub Process_Globals
   Dim Bitmap1 As Bitmap
End Sub

Sub Globals

   Dim ImageView1 As ImageView 
End Sub

Sub Activity_Create(FirstTime As Boolean)
   ImageView1.Initialize("ImageView1")
   Activity.AddView(ImageView1, 0, 0, 100%x, 100%y)
   ImageView1.Color = Colors.Red
   Log("Viewer created")
End Sub

Sub Activity_Resume
   Bitmap1.Initialize(File.DirRootExternal, Starter.ViewerFolder &  Starter.ViewerFilename)
   ImageView1.Gravity = Gravity.FILL
   ImageView1.Bitmap = Bitmap1
   Log("Bitmap = " & Bitmap1.Width & " x " & Bitmap1.Height)
End Sub

Sub Activity_Pause (UserClosed As Boolean)
   ' avoid hangs on rotation caused by large bitmaps
   Log("Viewer Paused")
   Dim Obj1 As Reflector
   Obj1.Target = Bitmap1 ' the unwanted Bitmap
   Obj1.RunMethod("recycle")
   Bitmap1 = Null
End Sub
Not sure if this has anything to do with it, but have you added the Permission to access the File.DirRootExternal directory to your manifest file?

Walter
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Not sure if this has anything to do with it, but have you added the Permission to access the File.DirRootExternal directory to your manifest file?
No, but in the Main activity that starts this activity I have
B4X:
    Dim rp As RuntimePermissions
   rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE) ' Implicit read capability if granted
   Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
   Log($"PERMISSION_WRITE_EXTERNAL_STORAGE = ${Result}"$)
It always shows the permission result as True and as the bitmap is always the correct size it appears to be always loading the bitmap, but only shows it if targetSdkVersion is 13 or less.
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
No, but in the Main activity that starts this activity I have
B4X:
    Dim rp As RuntimePermissions
   rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE) ' Implicit read capability if granted
   Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
   Log($"PERMISSION_WRITE_EXTERNAL_STORAGE = ${Result}"$)
It always shows the permission result as True and as the bitmap is always the correct size it appears to be always loading the bitmap, but only shows it if targetSdkVersion is 13 or less.
What Target SDK version are you compiling against?

I believe Runtime permissions are only required if you are using api 26 or above.

Walter
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

walterf25

Expert
Licensed User
Longtime User
No, but in the Main activity that starts this activity I have
B4X:
    Dim rp As RuntimePermissions
   rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE) ' Implicit read capability if granted
   Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
   Log($"PERMISSION_WRITE_EXTERNAL_STORAGE = ${Result}"$)
It always shows the permission result as True and as the bitmap is always the correct size it appears to be always loading the bitmap, but only shows it if targetSdkVersion is 13 or less.
Read here to get access to the File.DirRootExternal directory
https://www.b4x.com/android/forum/threads/runtime-permissions-android-6-0-permissions.67689/
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
What Target SDK version are you compiling against?
As I said in the first post targetSdkVersion="13" works, targetSdkVersion="14" or higher doesn't work

Read here to get access to the File.DirRootExternal directory
I've read and implemented it as I want to use SDK26 as recommended. As I said above I do seem to have permission and the bitmap always seems to load at the correct size so it would seem that it is not a permissions problem.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
This is truly weird. The problem seems to arise from the size of the bitmap which I found by accident when I wrote the simplest possible app to open an existing map image in the downloads folder. The entire program is below. I've tried this on two different devices, up to now I've been using the Huawei as it's larger size makes it more convenient for testing

Samsung A3 - Android 8.0.0
Huawei Y7 (2018) - Android 8.0.0

B4X:
Sub Activity_Create(FirstTime As Boolean)
   Dim Bitmap1 As Bitmap
   Dim rp As RuntimePermissions
   rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE) ' Implicit read capability if granted
   Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
   Log($"PERMISSION_WRITE_EXTERNAL_STORAGE = ${Result}"$)
   Activity.LoadLayout("Layout1")
   Bitmap1.Initialize(File.DirRootExternal, "Download/OS Search Map.jpg")
   ImageView1.Bitmap = Bitmap1
End Sub

android:targetSdkVersion="13"
When the target image is a 4000 x 4000 pixel image both devices display it properly
When the target image is a 8000 x 8000 pixel image both devices display it properly
When the target image is a 10000 x 10000 pixel image both devices display it properly

android:targetSdkVersion="26"
When the target image is a 4000 x 4000 pixel image both device display it properly
When the target image is a 8000 x 8000 pixel image the Huawei fails to display it with no message in the log (which is what I've been seeing before) but the Samsung crashes with a Canvas out of memory error.

This is a massive difference in behaviour from just changing a single value in the manifest. I'm getting Deja Vu as to why I abandoned Android in disgust previously. I'm also getting problems with ExternalStorage failing to remember its permissions and now asking every time - but that's for another time!
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
To clarify, the above is the simplest way of showing that a problem exists with the different target SDKs and is not the way I am actually using the images. The images are maps covering the UK at different scales. Each map covers an area of 10Km square or 20Km square and there are over 4000 of them. I want to display a map zoomed in and pre-positioned at a particular point which has been located from a data set containing the locations over 2.5 million places, roads and postcodes in the UK. LoadBitmapResize is of no use as the maps require to be seen in full resolution.

I have tried the TouchImageView library, which seems to be buggy at opening a map both zoomed and positioned and am currently quite successfully using the JsTouchImageView library which is not without some problems but for which I have found workarounds. This actually does all that I want and I am very satisfied with the app and have it running very well on devices with 2GB of memory or more, and on devices with as little as 1GB of memory with some memory saving tricks and with reduced map resolutions. The 'problem' is that I am forced to use a target SDK of 13 for this all to work.

This is because ImageView, TouchImageView, JsTouchImageView all will not work with large images with a target SDK greater than 13. I think the underlying cause is probably common to all three and is hinted at in the Samsung error in my post above. I suspect that Canvas is the culprit and for some reason cannot take a large image when target SDK is more than 13. If I wrote my own zooming and positioning code I would need to put the full resolution bitmap in a Canvas and draw smaller portions of it on an ImageView, which I guess is what all these views do, but if Canvas cannot handle the full image then the app will not do what I need.

As I have been concentrating on finishing the app I have not had time to check this. When I get a bit more time I will play with canvas and ImageView and various target SDKs and see what I can find.
 
Upvote 0
Top