Update App - Autostart?

thewavemaster

Member
Licensed User
Hello!

I made an alarm clock, using Service Start Foreground. My problem:
Everytime the user updates the app / (or even worse) the app gets updated automatically from the google play market, the running alarm gets killed and of course doesnt restart again.

So lot of users dont remark when the app got updated and are not awaked in the morning by the app...(thats the worst case - the users don't trust the alarm clock anymore....)


Is there any possibility to restart the app after it got updated?

(I think this question is only for the b4a god master Erel :D )
 

mc73

Well-Known Member
Licensed User
Until Erel arrives, could you please tell us where are you storing the alarm info to be used by your service? :)
 

Erel

Administrator
Staff member
Licensed User
Here is the solution :)

You should make an intent filter and listen to the android.intent.action.PACKAGE_REPLACED intent.

Use this code:
B4X:
AddReceiverText(<service name>, 
<intent-filter>
    <action android:name="android.intent.action.PACKAGE_REPLACED" />
    <data android:scheme="package" />
  </intent-filter>)
The service will start after the program is updated. Check Intent.GetData and make sure that it is your program that was updated. You can then call StartServiceAt.
 

mc73

Well-Known Member
Licensed User
:sign0098:

We are always learning new things, great job, Erel!
 

thewavemaster

Member
Licensed User
One question left....the thing with the intent...:
Like that?


B4X:
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.

End Sub
Sub Service_Create

End Sub

Sub Service_Start (StartingIntent As Intent)

Dim intent1 As Intent
Dim packn as string
packn = intent1.Initialize("android.intent.action.PACKAGE_REPLACED","")

If packn = "package.name" then
ServiceStartat(...)
End if



End Sub

Sub Service_Destroy

End Sub
 

thewavemaster

Member
Licensed User
I solved it with this lines of code (hope they are right? sice I ve never worked with StartingIntent, and not know what it exactly does...?)



B4X:
'Service module
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.

End Sub
Sub Service_Create

End Sub

Sub Service_Start (StartingIntent As Intent)
If StartingIntent.GetData = "package:schichtler.schicht" Then
StartServiceAt(wecker,DateTime.Now + 1000,True)
End If
End Sub

Sub Service_Destroy

End Sub
 

mc73

Well-Known Member
Licensed User
Your code looks correct. However why do you start the service again in one second? Why not schedule it for the next alarm time?
This is the real reason of my initial question.
 

thewavemaster

Member
Licensed User
I think for most alarm cases yours might be the best one!

In my case its different....:

Its an alarm clock for shift workers. The service "wecker" calculates the next alarm time and then calls itself with startserviceat for the next alarmtime...in the foreground.

everytime the module "wecker" gets loaded/created, it calculates the next alarmtime and then checks if this alarmtime is now. if yes...: alarm sound is playing and the next alarm time is calculated (and started with startservice at) if no...just restarts for the next alarm time with startserviceat....


advantage in this case is:
I just have to calculate in 1 module the alarm time.

So when the phone gets rebooted...I just call "wecker"
When the user activates the alarm....I just call "wecker"

or when the app gehts updated... ;) ... I just call "wecker"
 

Yvon Steinthal

Active Member
Licensed User
I have tried to follow the forum on this issue and here's what i have:

This is what i have in my Manifest:

B4X:
AddReceiverText("Reboot",
<intent-filter>
  <action android:name="android.intent.action.PACKAGE_REPLACED" />
  <data android:scheme="package" />
  </intent-filter>)
and here's what i have in my Reboot Service:

B4X:
#Region  Service Attributes
   #StartAtBoot: False
   
#End Region

Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.

End Sub

Sub Service_Create

End Sub

Sub Service_Start (StartingIntent As Intent)
If StartingIntent.GetData = "package:b4a.example" Then
StartServiceAt(Main,DateTime.Now + 1000,True)
End If
End Sub

Sub Service_Destroy

End Sub
My problem is that it goes in the service start on the first time i launch the app, and once i install and update my apk, the service is not there to reboot...
Any ideas?
 

Erel

Administrator
Staff member
Licensed User
My problem is that it goes in the service start on the first time i launch the app
Try to uninstall the app before you run it.

and once i install and update my apk, the service is not there to reboot...
Service_Start will run whenever the service receives an intent. It doesn't matter whether the service has already started in the past.

Are you running your project in release mode?
 

Yvon Steinthal

Active Member
Licensed User
I am using AppUpdate library, Downloading, and then Installing new apk from local server, and everything is working well, the only problem is the auto restart once the installation is done.

I have tested on Debug, installing a new apk that is a Release apk.
I also tested as Release installing a new apk that is a release apk...

The same problem occurs...

EDIT: I am actually having a bug in which in release mode this happens, the service Reboot starts BEFORE the user had a chance to install so im having this error:

java.lang.nullpointerexception: attempt to invoke virtual method 'boolean
java.lang.string.equals(java.lang.object)' on a null object reference


Would changing my package name everytime i install an update help in my service start condition? such as changing b4a.example to b4a.example.v101 ?
 
Last edited:

Erel

Administrator
Staff member
Licensed User
Would changing my package name everytime i install an update help in my service start condition?
You shouldn't change the package name.

EDIT: I am actually having a bug in which in release mode this happens, the service Reboot starts BEFORE the user had a chance to install so im having this error:

java.lang.nullpointerexception: attempt to invoke virtual method 'boolean
java.lang.string.equals(java.lang.object)' on a null object reference
Please post the full error message and the relevant code.
 

Yvon Steinthal

Active Member
Licensed User
Installing file.
PackageAdded: package:b4a.example
Copying updated assets files (300)
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (kioskservice) Create **
** Service (kioskservice) Start **
---- AppUpdating.ReadWebVN
---- AppUpdating.ReadCurVN
Current Version: 1.00
** Service (httputils2service) Create **
** Service (httputils2service) Start **
---- AppUpdating.JobDone --
JobName = JobWebVNonly, Success = true
Read while in JobWebVNonly: ver=1.01
Web version number: 1.01
---- AppUpdating.DownloadApk
---- AppUpdating.JobDone --
JobName = JobApkDownload, Success = true
-- JobApkDownload
newer apk version downloaded and ready to install
---- AppUpdating.InstallApk
user asked to install newer apk
Unexpected event (missing RaiseSynchronousEvents): update_updatecomplete
Check the unfiltered logs for the full stack trace.
** Service (kioskservice) Destroy **
** Activity (main) Pause, UserClosed = false **
** Service (reboot) Create **
** Service (reboot) Start **
Reboot Service Start
Error occurred on line: 20 (Reboot)
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at b4a.example.reboot._service_start(reboot.java:159)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:703)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:337)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:247)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
at b4a.example.reboot.handleStart(reboot.java:95)
at b4a.example.reboot.onStartCommand(reboot.java:69)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3431)
at android.app.ActivityThread.access$2200(ActivityThread.java:181)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1573)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6126)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)


Here's my service_start code:

Line 20 refers to my If Statement, StartingIntent.getData being null i believe...
B4X:
Sub Service_Start (StartingIntent As Intent)
Log("Reboot Service Start")

     If (StartingIntent.GetData = "package:b4a.example") Then
    
       Log("Inside Starting Intent")
       StartServiceAt(Main,DateTime.Now + 1000,True)
    
     Else
  
       Log("Manifest Package:"&StartingIntent.GetData)
  
     End If
  


End Sub
Here's my manifest code:

B4X:
AddReceiverText(Reboot,
<intent-filter>
  <action android:name="android.intent.action.PACKAGE_REPLACED" />
  <data android:scheme="package" />
  </intent-filter>)
 
Top