Android Question StartReceiverAt OkHttpUtils2 during phone sleep

Cainsoft

Member
Licensed User
Longtime User
Hi,
I have a scheduled task that downloads a web page (OkHttpUtils2) every morning. When the phone is "not asleep" it can download it, otherwise it gets an error message: java.net.UnknownHostException: Unable to resolve host.

The scheduler launcher::
StartReceiverAt(Reminder_receiver, nextTime, False)


I tried PhoneWakeState:
Public Sub loadWebPage
    Dim job As HttpJob
    Dim textReader As TextReader
    Dim inputStream As InputStream
    Dim webPage As String
    Dim pws As PhoneWakeState

    If startFromService = True Then
        pws.KeepAlive(False)
        'Sleep(500) not help
    End If

    job.Initialize("Download",Me)
    job.Download(URL)
    
    wait for (job) JobDone (job As HttpJob)
    If job.Success Then   
    
    ......
    
        Else
            logger.LogEvent("HTTP - No Internet: " & job.ErrorMessage)
            StartReceiverAt(Reminder_receiver, DateTime.Now + DateTime.TicksPerHour * 1, False)    'rerun +1 hour

        End If
        
    End If
    
    job.Release
    
    If startFromService = True Then
        pws.ReleaseKeepAlive()
    End If

Does anyone have any idea how to "wake up" the network ?

Thank you!
 

Cainsoft

Member
Licensed User
Longtime User
It seems to work fine.
Unfortunately, it does not work with Android 13, after 4 seconds of waiting it still gives the same error.
I extend the code to run the HTTP re-read more than 5 times.
 
Last edited:
Upvote 0

Cainsoft

Member
Licensed User
Longtime User
Repeated attempts did not help.
I tried four times in 10 seconds, but always the same error message.
Any other ideas ?
 
Last edited:
Upvote 0

Cainsoft

Member
Licensed User
Longtime User
Hi Erel,
My dev phone is always "on" the internet, wifi and/or mobile net is always active.
I can only think of 2 reasons:
1, when I start the scheduled task (when the phone is "asleep") it only gets processor time but the network remains off
or
2, the network won't be active in time and then the last error code will be "stuck" in the http class.

I'll try to rewrite the timing to see if I can, but the family has replaced my laptop charger and I have to wait for it to come back :)
 
Upvote 0

Cainsoft

Member
Licensed User
Longtime User
I rewrote my timer section but the same error.

The process after the receiver is started:
1, pws.KeepAlive(False)
2, 4 seconds wait
3, http request run
4, every 2 seconds check what is the status of the http request
5, if it ran to error then request again, otherwise pws.ReleaseKeepAlive() and end
6, it checks for up to 60 seconds, then pws.ReleaseKeepAlive() and end

I have no other idea, except that Android 13 does not initialize/enable the network when the phone asleep and the receiver class starts the http request (and of course if there is a network because the user is using the phone then it works)

(I was thinking of logging the phone's network connections (android.net.conn.CONNECTIVITY_CHANGE) to see if it shows anything.)

I welcome all ideas.
 
Last edited:
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
This is an issue with modern versions of android. when the phone sleeps, it drops all network connectivity, only sporadically waking up for push notifications. its weird. For example, the Discord app will drop out and get stuck on Connecting when I wake the phone up and I have to kill the app and restart it.

My phone will kill everything until it notices I pick it up and move it, then it wakes up network services and push notification services even while the screen is off.
 
Upvote 0

Cainsoft

Member
Licensed User
Longtime User
This is an issue with modern versions of android. when the phone sleeps, it drops all network connectivity, only sporadically waking up for push notifications. its weird. For example, the Discord app will drop out and get stuck on Connecting when I wake the phone up and I have to kill the app and restart it.

My phone will kill everything until it notices I pick it up and move it, then it wakes up network services and push notification services even while the screen is off.

It's frustrating. Then it means that there is no simple solution to run an http request in a scheduled task. Because there is no guarantee that there will be network access.
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
It's frustrating. Then it means that there is no simple solution to run an http request in a scheduled task. Because there is no guarantee that there will be network access.

Yeah, its why I am slowly disliking android. if I wasn't trapped into the ecosystem (since there really isnt any alternative for what I do) id have fled already.

Seems with each new version from 8 on forward, its gotten "worse" in unique ways. But its my highly subjective opinion. Android 7 was peak Android.

Now with each version release its all about tightening the noose and taking control away from users little by little in the name of security . Breaking things along the way that should never even be broken in the name of "battery optimization" (such as this). Not to mention the iOSification of the UI.

Anyways, ill stop now.
 
Upvote 0

Cainsoft

Member
Licensed User
Longtime User
Thank you, I'll have to look into that.

+Just for interest:

I changed it to pws.KeepAlive(true).

The scheduled task started nicely, and the screen turned on and showed that the wifi connection was active!
but failed to connect, with the usual error.
In the meantime, while the process was still trying, I clicked on the fingerprint reader, the phone unlocked and immediately got a network connection and was able to run the http download.

So there is a network connection, but if the user is not "interactive", the android 13 will not give internet access.
 
Last edited:
Upvote 0

Cainsoft

Member
Licensed User
Longtime User
Hi Erel,
What would be the process with push notification ? I don't understand how this could solve the scheduled download problem...
(I've been reading the Google Android dev documentation, and workmanager could be a solution, since we can specify there to start only when there is a network connection. But my chances of using this are small :), because I'm not familiar with Java.)
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
What would be the process with push notification ?
It really depends on what your app is doing, something that I only guessed. If your app needs to check for some information from time to time, you might be able to send this information with a notification, instead of polling the server in the background.
 
Upvote 0

Cainsoft

Member
Licensed User
Longtime User
It really depends on what your app is doing, something that I only guessed. If your app needs to check for some information from time to time, you might be able to send this information with a notification, instead of polling the server in the background.
I understand, thank you. At the moment I'm not planning to use a client-server solution, I'm still working on it, to see if there is a workaround.
 
Upvote 0

Cainsoft

Member
Licensed User
Longtime User
As a test I did a standard java downloader (ctrl c + ctrl v), but the same issue. I cannot get around the restrictions of android 13. :)
Anyway, I'm attaching the code in case it's useful for someone


JavaDownload:
#if java
    
 
    import java.io.IOException;
    import java.net.URL;
    import java.net.URLConnection;
    import java.io.InputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.lang.String;    
    import java.nio.charset.StandardCharsets;
    import java.text.SimpleDateFormat;    
    import java.util.Date;    
    import java.lang.Thread;
    import java.util.concurrent.atomic.AtomicReference;
    import java.io.BufferedInputStream;    

    public static String downloadHtml(String url, String filesDir, String filename) throws IOException 
    {

        AtomicReference<String> errorMessage = new AtomicReference<>("");
    
        Thread thread = new Thread(
        new Runnable() 
        {
            @Override
            public void run() 
            {
                try
                {
                    URLConnection connection = new URL(url).openConnection();
                    connection.setRequestProperty("Accept-Encoding", "identity");
                    InputStream inputStream = new BufferedInputStream(connection.getInputStream()); 

                    File file = new File(filesDir, filename);
                    file.getParentFile().mkdirs();
                    file.createNewFile();

                    FileOutputStream outputStream = new FileOutputStream(file);
                    byte[] buffer = new byte[1024];
                    int bytesRead;
                    
                    while ((bytesRead = inputStream.read(buffer)) != -1) 
                    {
                        outputStream.write(buffer, 0, bytesRead);
                    }

                    inputStream.close();
                    outputStream.close();                

                }
                catch (IOException e) 
                { 
                    errorMessage.set("Internal error: " + e.getMessage());
                }
            }                
        }
        
        );
    
        thread.start();
      
         long timeoutMillis = 30000; // 30 sec
        long startTime = System.currentTimeMillis();

        while (thread.isAlive()) 
        {
            if (System.currentTimeMillis() - startTime > timeoutMillis) 
            {
                thread.interrupt();
                errorMessage.set("Thread timeout");
                break;
            }
        }

        try 
        {
            thread.join();
        } 
        catch (InterruptedException e) 
        {
            errorMessage.set("Thread error: " + e.getMessage());
        }

        String error = errorMessage.get();

        return error;  
     }
    
    #End If
 
Upvote 0
Top