📜 ⬆️ ⬇️

When you need a corporate app store


The theme of corporate applications is not the first year actively discussed at conferences and in articles. Everyone draws a "barrel of honey": quickly, always at hand, from home and office ... In general, a promising, convenient tool for the rapid solution of business problems.


But let's stop on one "tar spoon". An idyllic picture can spoil the issue of distributing and updating applications among employees. As experience shows, it is not enough to write a corporate application. We also need to find a convenient way to deliver it to the target audience, and then make updates.


We at Eastanc Technologies have written a number of corporate mobile applications, and always the issue of installation and updating is acute. Among all the options, one seems to us quite technological and interesting - its own application store. In the post we will share the details of how we implemented the Android store for users of corporate applications.



And what is the problem?


Let's think about whether there is a problem. After all, there are several ways to install a corporate application on Android:



Secondly, common sense suggests that for users who are not employees of the company, it may seem to be a problem that the public application is focused only on a closed group of users.


Apple is exactly on hand. With Google things are simpler, there is no strict control. But there is an elementary ethic. Leaving a store with such applications is not a good developer behavior.


There is also a third reason. Sometimes companies have more than one corporate mobile application. And it’s convenient when you don’t need to search for them in the official app store, and everything is in one place.



Yes, we can embed a self-update mechanism in the application. When starting, the application will go to the server and check if the new assembly has been put. And if so, it initiates the process of self-replacement. This scheme works, but it requires a lot of effort to maintain performance.



Using the example of the well-known MDM solution AirWatch, one can see what the company is pouring into - 4-6 dollars per month per device.


It is embarrassing that you need to pay a large amount annually per employee. And if there are a lot of employees? Frankly speaking, it turns out not cheap pleasure.



As you can see, each of the approaches was not good enough. This made us collect our thoughts, design and implement our own app store.
We will describe further implementation details.


Everything in order


For the store to be useful, it is not enough just to show the list of available applications. You need to teach the program a number of familiar to the user actions, such as: checking for new versions, downloading and installing application distributions. Fortunately, the Android API provides many useful tools for implementing similar features.


Getting a list of available applications


Perhaps the easiest part :) You need to negotiate with the server about the format and content of the data, and teach it to give a list with information about available applications. Everyone loves HTTPS / REST / JSON, they suit us.


As for the content, for each application we inform:



Example response from the server:


[ { "id": "etr.appstore", "name": "App Store", "info": "      ", "versionName": "1.3", "versionCode": 6, "url": "https://myappstore.ru/appstore/etr.appstore.apk", "icon": "https://myappstore.ru/appstore/appstore/etr.appstore.android.png" }, { "id": "ru.eastbanctech.mobileregistrator", "name": " ", "info": "     ,           ", "versionName": "v1.1.5", "versionCode": 115, "url": "https://myappstore.ru/appstore/appstore/ru.eastbanctech.mobileregistrator.release.apk", "icon": "https://myappstore.ru/appstore/appstore/ru.eastbanctech.mobileregistrator.release.android.png" } ] 

Please note that the mobile store client itself is also located in the app store, which allows it to update itself :)


To solve this problem, the use of Retrofit2 / OkHttp has become a standard. RxJava - at will. To display icons from the Internet, we use Fresco from Facebook, because it is already successfully used by us on other projects. Although Picasso can compete with Fresco and in terms of functionality and usability. By the way, we already use Kotlin, so all the examples in the article will be on it.


Information about installed applications


Each application from the store may already be installed by the user or not. In addition, each installed application may be the current version or already outdated. All this, of course, would be useful to know the end user of the store. Fortunately, the Android API allows you to get information about all installed applications; you don't even need any special permissions to do this.


 val installedApps = context.packageManager.getInstalledPackages(PackageManager.GET_META_DATA) 

This command will return information about installed applications in the PackageInfo format . There you can find a lot of useful data, but only packageName and versionCode will be useful to versionCode .


Having received a list of installed and a list of available applications, we must display the resulting list of applications with all the combined information. Sounds like a training example of some article on RxJava, isn't it? ;) RxJava we will use:


  class RemoteAppModel //        class DeviceAppModel //        val storeAppsObs: Observable<List<RemoteAppModel>> = appsService.getApps() val localAppsObs: Observable<List<DeviceAppModel>> = deviceService.installedApps() Observable.combineLatest(storeAppsObs, localAppsObs) { onlineAppList, localAppList -> //     //              onlineAppList.map { onlineApp -> //       ,    val localApp = localAppList.find { it.id == onlineApp.id } AppInfo(onlineApp, localApp) } } 

The resulting list is already showing the user with, for example, RecyclerView. The list of actions available to the user is quite obvious:




Application installation


With the installation of applications is not so simple. This problem can be solved in two ways: ask the user to install the distribution kit or do it yourself programmatically.


The first approach is quite simple:


  //uri -    apk- override fun install(uri: Uri) { val intent = makeInstallerIntent(uri) context.startActivity(intent) } private fun makeInstallerIntent(uri: Uri): Intent { val intent = Intent(Intent.ACTION_VIEW) intent.setDataAndType(uri, "application/vnd.android.package-archive") intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //  Android N             Uri, //        ,        val targets = context.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY) targets.forEach { info -> context.grantUriPermission(info.activityInfo.packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION) } } return intent } 

We run the intent and transfer control to the hands of the distribution system installer.



The second installation method will require much more code, but its main problem is not in the amount of code, but in that the program installation of the apk file requires that the program has the privileges android.permission.INSTALL_PACKAGES that only the “system” application can receive.


Your application can be considered systemic in two cases:



As you understand, not every user can cope with the installation of the store in the second way. However, no one bothers you to combine both options: to implement the software installation with a separate plugin application. The client can check the presence of the installed plug-in and, if available, delegate the installation to him, and otherwise install the distribution in the usual way. If you decide to follow the second path, here are some useful resources:



checking for updates


No one in their right mind will open the store every hour and check for new versions; the phone must do this on its own and imperceptibly to the user. Android provides several ways to perform periodic background work. We analyzed a number of popular methods.


Alarmmanager


Perhaps the most popular way. There are more than enough instructions and guides for using the AlarmManager on the network.


Pros:



Minuses:



After the reboot, you can try to restore the work, if you listen to Broadcast BOOT_COMPLETE.


SyncAdapter and SyncService


Designed to synchronize local data and data on the server, i.e. just what we want to do.


Pros:



Minuses:



JobScheduler


An excellent framework that combines the advantages of AlarmManager and SyncAdapter. It works stably, efficiently and flexibly configured. It has one drawback: API 21+


Firebase jobdispatcher


Can be considered as a backport JobScheduler.


Pros:



Minuses:



Which way to choose is an individual matter. We follow the scheme: SyncAdapter on pre-Lollipop and JobScheduler on API 21+.



Server


At first, we managed to do without our own server, using Firbase Hosting as a backend. On the hosting were all apk files, icons and json-file with all the meta-information. Such a scheme worked for some time, but it had a number of obvious flaws: nobody wants to manually write json-files and there is a big risk to write something wrong into it.


So we decided to automate this process and made our own server based on NodeJS.
Among the great number of npm libraries, we found an extremely useful app-bundle-info module that can extract versionCode , versionName and even application icons from the apk file.


As a result, the human factor when publishing the application is minimized: the server will independently verify the validity of the distribution and will independently obtain all the technical information.


Conclusion


The idea of ​​providing company employees with mobile applications is good and correct, but at the same time it is necessary to resolve the issue with the delivery of applications and support of their relevance.


The article describes a method that allows employees not only to have on hand a list of corporate applications and install them, but also provides a mechanism for updating them.


To get started, you must enable the ability to install applications from unknown sources in the device settings, download the store application and then everything will happen in semi-automatic mode. Even the app store itself can also download its new version and update.


The solution was very well suited for the COPE scheme (When an employee is given a phone number of the company, with the preliminary configuration steps already taken).


For us, this approach turned out to be good due to the fact that it is not tied to a specific customer. The solution can be reused. It is enough to replace the server address where the applications are downloaded from, and the company’s logos in the store application.


Have a good day and corporate applications!


')

Source: https://habr.com/ru/post/328980/


All Articles