Problem with camera on resume

Kim Rowden

Member
Licensed User
Longtime User
I have an app that uses the camera to take a picture based on a timer event, it then uploads the image to a website.

I am getting an error when I do the following:
1. I pause the app (ie I click on the 'home' button) while the HTTP request is running
2. I then resume the app - and get the error.

Here is the HTTP success SUB:
B4X:
Sub hc1_ResponseSuccess (Response As HttpResponse, TaskId As Int)
Log("hc1 Success: " & Response )
Log("hc1 Success: Timer1.Interval = " & timer1.Interval )   
   
   lblStatus.Text = "Image uploaded. Waiting on timer..."
   Response.Release

   're-enable the timer
   Timer1.Enabled = True
   
   're-activate the camera (because we might have come here from an activity_resume event - and it doesn't get re-init'ed)
   camera1.Initialize(panel1, "Camera1")

Log("hc1 Success(END)")
End Sub

I'm thinking this may have something to do with the HTTPClient being defined at the Process_Globals level and so the HTTP request continues to run (and may even complete) behind the scenes when the app is paused. See the log below for my "hc1 success" log entries between the ACTIVITY PAUSE and the ACTIVITY RESUME.

But then my question is: how do I place the results from that HTTP request into my layout when the app resumes? - given that I also need to place those results into the layout should the app NOT be paused during a normal run of the web request.

...and why does the statement:
lblStatus.Text = "Image uploaded. Waiting on timer..."
work ? Shouldn't this also fail if the HTTP ResponseSuccess code executes BEFORE the resume has had a chance to (re)set the layout.

Here is a screen shot of the error in my IDE environement:


This is the log from the IDE:
B4X:
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
Activity_Resume(): Timer1.Interval = 0
Battery: 100%
hc0 Success: OK
hc0 Success(END)
Camera1_PictureTaken()
Camera1_PictureTaken(END)
hc1 Success: anywheresoftware.b4a.http.HttpClientWrapper$HttpResponeWrapper@45884c48
hc1 Success: Timer1.Interval = 20000
hc1 Success(END)
Camera1_PictureTaken()
Camera1_PictureTaken(END)
** Activity (main) Pause, UserClosed = false **
sending message to waiting queue.
running waiting messages (1)
hc1 Success: anywheresoftware.b4a.http.HttpClientWrapper$HttpResponeWrapper@45889210
hc1 Success: Timer1.Interval = 20000
hc1 Success(END)
** Activity (main) Resume **
Activity_Resume(): Timer1.Interval = 20000
main_camera1_ready (B4A line: 87)
Camera1.StartPreview

java.lang.NullPointerException
   at anywheresoftware.b4a.objects.CameraW.StartPreview(CameraW.java:101)
   at com.britican.autocam.main._camera1_ready(main.java:490)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:521)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:105)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
   at anywheresoftware.b4a.BA.raiseEvent(BA.java:89)
   at anywheresoftware.b4a.objects.CameraW$1.surfaceCreated(CameraW.java:67)
   at android.view.SurfaceView.updateWindow(SurfaceView.java:532)
   at android.view.SurfaceView.dispatchDraw(SurfaceView.java:339)
   at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
   at android.view.View.draw(View.java:6745)
   at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
   at android.view.View.draw(View.java:6745)
   at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
   at android.view.View.draw(View.java:6745)
   at android.widget.FrameLayout.draw(FrameLayout.java:352)
   at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
   at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
   at android.view.View.draw(View.java:6745)
   at android.widget.FrameLayout.draw(FrameLayout.java:352)
   at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1891)
   at android.view.ViewRoot.draw(ViewRoot.java:1416)
   at android.view.ViewRoot.performTraversals(ViewRoot.java:1172)
   at android.view.ViewRoot.handleMessage(ViewRoot.java:1736)
   at android.os.Handler.dispatchMessage(Handler.java:99)
   at android.os.Looper.loop(Looper.java:143)
   at android.app.ActivityThread.main(ActivityThread.java:4701)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:521)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
   at dalvik.system.NativeStart.main(Native Method)
java.lang.NullPointerException

Many thanks!
-Kim
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Make sure not to initialize the camera object multiple times.
Can you post your complete code?

Shouldn't this also fail if the HTTP ResponseSuccess code executes BEFORE the resume has had a chance to (re)set the layout.
The layout is usually build in Activity_Create. If you press on Home button and then resume your application, the layout is not destroyed.
 
Upvote 0

Kim Rowden

Member
Licensed User
Longtime User
I think I have things where they should be - I used the Camera sample code as the basis for this app. After the photo is saved locally to the SDcard I HTTP it up to my server. The Success Sub is here (I have added the Try/Catch statement to prevent the error from hanging the app) :

B4X:
Sub hc1_ResponseSuccess (Response As HttpResponse, TaskId As Int)
Log("hc1 Success: " & Response )
Log("hc1 Success: Timer1.Interval = " & timer1.Interval )   
   
   Response.Release
   
   lblStatus.Text = "Image uploaded. Waiting on timer..."

   're-enable the timer
   Timer1.Enabled = True
   btnTakePicture.Enabled = True
   
   'show camera preview (was frozen whie we uploaded the previous image)
   Try 
      Camera1.StartPreview
   Catch
'Msgbox("Error in HTTP Success!", "Ooops")
   End Try
   
Log("hc1 Success(END)")
End Sub

The app takes a photo every X seconds and uploads it to the server. Hence the timer stuff.

The error I get happens if I press the phone's Home button AFTER an upload has started. If you'll check the Designer logs below you will see that I pause the app, then the HTTP upload finishes (the log displays "sending message to waiting queue.") Then I re-run the app (from the icon on the phone) and I get the error.
The logs seem to show that the HTTP Success sub gets run before the Resume sub - and so the Camera1.StartPreview statement fails.

With the Try/Catch block that I just added all is now ok.

I'm not sure of the ordering as to when the Resume code should run - maybe all is as it should be. I guess I was expecting the Resume sub to kick in immediately I resumed the app, followed by the HTTP Success sub.

The second log below shows how it all works ok with the Try/Catch - but the HTTP message is still being processed before the Resume sub.

Any clarification on this would be much appreciated.
Thanks,
-Kim
(Observation: I display the contents of the HTTPResponse in the log entry. There seems to be a spelling mistake in the phrase "HTTPResponeWrapper":
anywheresoftware.b4a.http.HttpClientWrapper$HttpResponeWrapper@4586c9
- not sure if it is of any cause for concern or not)

Log with the error:

Log from the same process but with the Try/Catch:
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…