How to use Pushlink?
- Sign up to receive an API Key.
- Configure your android app (add the jar to the classpath, add internet permission and call PushLink.start method).
- Upload the APK to Pushlink.
- The first APK installation in device is made by yourself. Pushlink helps with a download link by QRCode.
- Upload new versions and manage them in the timeline. Pushlink will keep your app updated from now on.
- Enabling "Install non-market app" is still needed. The installation process is going to ask for it and redirect the user to the Application Settings.
- Make sure you've read the idguide
Android 7 requirement
- Download a eclipse working sample project.
Concerned about security?
- APK traffic always occurs over SSL (download/upload).
- We use a renowned host service.
- APKs are safely stored encrypted.
- Daily backups are performed on extra cloud based servers.
- The APK will never be published or installed by others.
It's very common to run Pushlink behind a firewall in a LAN environment. See the names we use:
Android & Downgrade
Android has changed its behaviour when installing a new apk file. Until ICS (ice cream sandwich), it didn't mater if the new apk had a lower or higher android:versionCode
AndroidManifest.xml. After that, it's mandatory a higher versionCode. In fact, we can't guarantee "when" the new behavior was introduced, but we noticed it was sometime around Jelly Bean
When trying to install a lower version code through adb, you will get the message: INSTALL_FAILED_VERSION_DOWNGRADE. In this case you can force with the undocumented -d flag: adb
install -r -d my.apk
. Pushlink can't force it because it just launches the apk and the control is passed to the OS. So, the installation process will fail with no specific error message.
Keep in mind that Pushlink can't perform downgrades when the OS does not allow.
Android 7 (Nougat) [Build.VERSION.SDK_INT >= 24] requires a FileProvider in the AndroidManifest.xml, otherwise Pushlink will not work.
Don't forget to replace [your.package.name] with your current application package name.
Default Pushlink Strategy
- Title message: "New version of [App Name]".
- Description message: "Click to Update".
- Remains on status bar until the installation happens.
- Clear the message if the admin changes back to an earlier version before the installation.
Usefull for fullscreen apps
- Default message: "New version of [App Name]. Do you want to update it?".
- Default buttons: [Not Now][Update].
- Remains until the user press [Not Now] or [Update] (Back button is blocked).
- Default reminder: 3 hours
- Hide the popup if the admin changes back to an earlier version before the installation.
Don't forget to call
Usefull for fullscreen apps when updates can't wait
- Default message: "For security reasons [App Name] needs to be updated!"
- Default button: [Update].
- Very insistent. Remains until the user press [Update] (Dismiss button is blocked).
- Hide the popup if admin changes back to an earlier version before the installation.
Don't forget to call
There is no notification. Silent update. No user interaction.
Pushlink covers 100% of this need with two strategies:
- For Android <= 4 just use NINJA. (it requires a ROOTED device)
- For Android >= 5 just use CUSTOM. (it requires ADMIN PRIVILEGES on device)
Do you want to perform background updates only when your app is idle?
in the Javadoc
NINJA (Only for rooted devices)
- The application is just re-launched in a new version.
NINJA worked flawlessly until android 4. 🤘
When android 5 was released NINJA began to have issues and we was forced to implement a
<receiver android:name="com.pushlink.android.NinjaReceiver" />
to make it work. Unfortunately it was not fixed completely and it still can fails sometimes, depending the combination of OS version x Vendor. 😕
So if you have Android >= 5, the better choice is CUSTOM with admin privileges on device.
CUSTOM (Take full control of your installation)
- When using CUSTOM strategy, pushlink doesn't display anything and will broadcast two actions
[your.package.name].pushlink.APPLY is sent EVERY 30 seconds (more or less) when there is a downloaded but not applied new apk. The user have to handle those multiples
[your.package.name].pushlink.GIVEUP is sent ONCE when the user gives up the update (in the web admin) before it has been applied.
- Learn how to silently install. (it requires ADMIN PRIVILEGES)
- You also can use CUSTOM without admin privileges if you don't want to perform background updates. Sometimes the developer wants to build a fancier notification or execute extra steps.
You can customize the built in strategies like this:
- Fork our Xamarin Java Binding project.
- Download a monodroid working sample project.
- Download our dll wrapper.
Add some metadata to identify the device/user:
PushLink.hasPendingUpdate() is designed to notify again a skipped update using friendlypopup before the reminder tick. If there is a new version but it wasn't downloaded yet, this method returns
- Pushlink catches all unhandled exceptions in your app by default. It doesn't block the natural exceptions life cycle.
- You can also send handled exceptions calling PushLink.sendAsyncException().
- Pushlink always sends the exceptions asynchronously and garantees its delivery.
- If you also want to get the last 100 LogCat's lines, just add "android.permission.READ_LOGS" in AndroidManifest.xml
- Limits includes handled and unhandled exceptions.
- PushLink was not designed to be a remote log system. Try not sending network issues or something like that.
- Each app has it's own sending limit.
- It's calculated using the last 24H and it isn't cumulative.
- Formula: sendingLimit == planQuantity * 2
- Ex1: free plan (5 installations) can send 10 exceptions in the last 24H for each app.
- Ex2: 200 installations can send 400 exceptions in the last 24H for each app.
- Exception not sent but queued due to: java.lang.Exception: Any reason. Queued
- Exception sent but rejected: Invalid API Key. Probably caused by wrong configuration. Lost
- Excpetion sent but rejected: Invalid Package. You probably never uploaded this app. Lost
- Exception sent but rejected: Invalid APK Hash. Probably you are in a development environment. You did not upload this version yet. Lost
- Exception sent but rejected: The application [app name] has exceeded the 24H sending limit. Lost
- Exception sent. Registered
To get XML output:
To get JSON output:
After uploading you might set the apk as current manually in the web administration
curl -F "apiKey=yourApiKey" -F "apk=@yourApp.apk" https://www.pushlink.com/apps/api_upload
Raw text responses:
- PushLink deploy sucessful.
- PushLink deploy fails. Invalid Api Key.
- PushLink deploy fails. Invalid APK file.
- PushLink deploy fails. This APK hash is the same of another APK you have uploaded.
Download the current APK
curl -o yourApp.apk 'https://www.pushlink.com/download?package=some.package.name&api_key=yourApiKey'
- Now it works on android 7 (Nougat) [Build.VERSION.SDK_INT >= 24]. It requires a
<provider android:name="com.pushlink.android.FileProvider" android:authorities="your.package.name" android:exported="true" /> in AndroidManifest.xml
- Now pushlink cleanup old downloaded apks.
- New custom strategy is available.
- Fixed ninja NPE when using broadcast receiver
- Ninja fallback. (If broadcast receiver is not present, it uses the classic ninja.)
- Commons network exceptions now are debug level in logcat
- Ninja now works in android 5 or higher. Its requires the
<receiver android:name="com.pushlink.android.NinjaReceiver" /> in AndroidManifest.xml
- Ninja.setExtraShellCommand deprecated in favor to setBeforeNinjaTaskShellCommand
- Available from Maven and Gradle by jitack
- Bad release. (Not available anymore)
- Bug fix: Pushlink.hasPendingUpdate does not ignore the idle status anymore (Pushlink.idle method)
- Now Ninja is working in Android 64 bits
- Ninja does not execute the "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/system/lib" command anymore
- New method Ninja.setExtraShellCommand for custom workarounds
- Now Pushlink logs the entire stack trace. (No more clipping)
- Fixed critical bug when using android:process
- New api method setMaxExceptionQueueSize (to avoid huge cache)
- Download resume. (Very welcome!)
- Bug fix that would send old exception assigned with wrong version label.
- Bug fix that in addMetadata/addExceptionMetadata when key == null. Not allowed anymore.
- Now it prevents to send the very same exception twice or more.
- Less data transfer when using the metadata api.
- Now setCurrentActivity and setCurrentStrategy are independent of start method.
- Some timeout adjustments
- NINJA strategy improved. Now working in a large variety of devices.
- Now PushLink uses only the 443 port. Goodbye 6670 port.
- Download method improved to avoid memory overflow.
- Popup strategies no more play notification sound.
- Now popup strategies ask for launching the app even in ICS or later.
- Now it sends the last 200 lines of logcat. (no more 100)
- Now exceptions has a handled/unhandled label
- New method PushLink.addExceptionMetadata. This metadata is going to appear ONLY in the "Exceptions" tab of the web administration
- Important bug fix. PushLink.addMetadata wasn't working fine.
- TCP client improvement. It was aborting connections sometimes.
- Installation checking for duplicated ID's improved.
- Method name changed! PushLink.serCurrentPopUpTarget is now PushLink.setCurrentActivity.
- Now PushLink grabs screenshots for unhandled exceptions.
- Logging improvements
- Bug fix. Calling PushLink.setCurrentStrategy before PushLink.start had no effect.
- Package change. Now all classes are under "com.pushlink.android"
- Critical bug fix. Heartbeat was not working when devices were sleeping.
- Device ID is back. Now the user MUST set the device id. Now the web administration show off-line installations again.
- Api change to support device ID: Now PushLink.start has a brand new fourth parameter. The device ID.
- Method name changed from PushLink.sendAsyncNotification to PushLink.sendAsyncException.
- Pushink now has two lightweight threads. They were named as "PushLink-PushListener" and "PushLink-Heartbeat".
- Huge logging improvements
- Critical bug fix. Low socket/connection timeout was killing some APK downloads.
- Now exceptions are always send lazily with delivery guarantee. PushLink holds the exception (sqlite persistence) until it can be sent to the server. PushLink.sendSyncException was
- New method PushLink.hasPengingUpdate. This method checks if there is a downloaded but not applied update. It also notify the user again.
- Log messages improved
- PushLink.sendExceptionNotification has changed to PushLink.sendAsyncException/PushLink.sendSyncException
- Fixed NPE when setCurrentPopUpTarget called before PushLink.start
- When popup strategies were configured before PushLink.start, the popup title would appear "Application" instead the real application name. Fixed!
- Log messages improved
- Lighter. HttpClient code improvement. Less data transfered between server and client.
- Popups strategies now supports screen rotation
- Popups strategies now can work well even if you do not use PushLink.setCurrentPopUpTarget(this); in all activities
- It is ready to show online installations in the web administration
- Fixed some minor bugs that could happen in push notification
- PushLink.addGlobalInfo has changed to PushLink.addMetadata
- Fixed a NPE that would appear in some cases
- Fixed some confusing log informations
- API method PushLink.idle(boolean) added. Especially useful for NINJA strategy to update your app only when it is idle. See the usage in JAVADOC.
- Now it sends device coordinates if the GPS is enabled. This is sent only once when the app is started.
- Bug fixed. It could happen to receive several notifications to the same version in some specific situations.
- NINJA strategy has been created. Only for rooted devices. BETA!
- Logging improvements.
- Full redesing to support premium features.
- Push.checkForUpdates in no longer available. There is no sense using it the new push architecture.
- Push.start method has changed. Now it has only three parameters
- Notification now play standrd device sound
- Automatic exception catch/send notification is the default.
- Added two method. PushLink.disableExceptionNotification and PushLink.enableExceptionNotification
- Push.addUserInfoForExceptionNotification is now Push.addGlobalInfo. This information is going to appear in all exceptions notifications sent.
- Push.sendExceptionNotification(Throable) was overloaded with Push.sendExceptionNotification(Throwable, Map). Now it's possible to send more information about the exception context in Map.
- Professional JAVADOC added
- Push.requestUpdateRightNow is now Push.checkForUpdates
- Now Push.checkForUpdates does not block the thread anymore.
- Push.checkForUpdates bug fix. It was rushing the download but not the notification.
- Now if exceptionNotification is set to false and you call PushLink.sendExceptionNotification it will not throw an exception anymore. It only will log: "You must start pushlink enabling
exception notification before using PushLink.sendExceptionNotification or PushLink.addUserInfoForExceptionNotification. Check PushLink.start method exceptionNotification parameter."
- Exception notification now sends LogCat (Need READ_LOGS permission)
- Exception notification now sends the whole stack trace
- Fixed some exception notification bugs
- API Redesigned. All PushLink's method are static.
- There is no method "stop" anymore.
- Now we have exception notification! Recieve emails when your app crashes.
- New API method "Pushlink.requestUpdateRightNow()" to rush version check.
- Now popups strategies work nice with PushLink.setCurrentPopUpTarget
- Fixed java.lang.NoClassDefFoundError: com.pushlink.android.SSLHandler when runnig on ADT emulator
- Pop Up strategy support
- i18n support
- SSL Support
- Internal storage bug fix