Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Publish a Android private app for multiple clients

Tags:

What we are dealing with

We have this app which we distribute to our clients in an offline fashion (i.e. not uploaded to Play store). The app flavour distributed to each client is almost identical with a bit of tweak here and there. All our clients share this app to their employees for usage. Basically this is an Enterprise App.

What's the problem

Recently one of our client started using a MDM (Mobility Device management) tool which blocks apps which are not downloaded from Google play. As obviously we got a request from our client to see if we can upload this app on Google play or not.

Important thing here is that we have over 100 clients and the package name of the app provided to each client is actually the same. So it's the same app with a bit of tweak here and there. If we go down the road of publishing the app to the play store, we might end up in a mayhem (we don't wanna upload 100 different apps to the play store - i.e. one for each client). We are doing some optimisation from our end so that multiple clients can use the same app (but we can't make all 100+ clients use the same app.).

What am I looking at ?

I started looking at Android For Work (AFW), Google private apps , Managed Google play and still digesting the stuffs. But to me it looked like just a secure way for enterprises to deploy/publish apps which can be downloaded only on specific devices and under a certain profile (which keeps things separate from user's personal apps and data in case they use the same phone for personal and work purpose).

What solution i am looking for ?

  1. To privately deploy an app (host it with Google or privately host but listed with Google play in both cases) and let my clients share this app with their employee.

  2. Each private app for each client should be on its own little private island. I want to distribute the app with the same package name to all my clients (From what I have read so far, this might not be possible with Google play. But I am hoping somebody can point out facts if I am missing something).

like image 585
Dibzmania Avatar asked Aug 03 '17 23:08

Dibzmania


People also ask

Can you publish your app to limited users?

In Play Console, you can't publish the app for a specific group of users. You can publish an app intended for a specific country or specific device models. If you want to beta test your app with specific groups, or Play Store users, you can set up alpha/beta testing. The app must be less than the download size limit.

How do I distribute an APK without Google Play?

From your smartphone or tablet running Android 4.0 or higher, go to Settings, scroll down to Security, and select Unknown sources. Selecting this option will allow you to install apps outside of the Google Play store. Depending on your device, you can also choose to be warned before installing harmful apps.

What are the three ways to publish your company private applications in managed Google Play?

There are three options. The first option is to integrate with the EMM API, sometimes called "Managed Play". This is designed for companies to publish private apps to their users. If you use Managed Play you can also publish Self-hosted private apps.


2 Answers

This is my solution:

Creating run-time dynamic app that get data and configs from back-end and render its views and data with its own Client Id.

You can create single app and upload to google play, but you should manage your clients by clientId that makes every app acts separated. This clientId is unique and generated per your clients. This solution have two sides. Android side and server side.

1 - Android side: Our app should have a baseUrl like this in Constants:

baseUrl = "http://yourCorporation.com/{clienId}/api/" 

And then all the services of All clients use the same url. clientId is the key point. The difference of you client app is clientId. For generating url of api-call you should do something like this:

Constant.ClientId = scannedQRCode;
url = baseUrl.replace("{client_id}",Contant.ClientId) + apiUrl ;

You must create QR code per your clients that should scanned in app first run. It is good to send QR code after registration to his/her (client of your Clients) email. This QR code have clientId. Therefor every clients have their own services and really works as separated islands, even if you want to change server address, you can put all baseUrl in QR code but this is not suggested, because you have to create server per clients and this is headache.

You can even handle config and UI elements of you app with calling a config api that returns a customConfigDto as json like this:

public class CustomConfigDto {

String colorPrimary ;
String colroPrimaryDark ;
String colorAccent ;
int tabCounts;

//and more...


public String getColorPrimary() {
    return colorPrimary;
}

public void setColorPrimary(String colorPrimary) {
    this.colorPrimary = colorPrimary;
}

public String getColroPrimaryDark() {
    return colroPrimaryDark;
}

public void setColroPrimaryDark(String colroPrimaryDark) {
    this.colroPrimaryDark = colroPrimaryDark;
}

public String getColorAccent() {
    return colorAccent;
}

public void setColorAccent(String colorAccent) {
    this.colorAccent = colorAccent;
}

public int getTabCounts() {
    return tabCounts;
}

public void setTabCounts(int tabCounts) {
    this.tabCounts = tabCounts;
}
}

And render your views by this configurations. All of this works separated per app by their clientId.

I prefer QR code because it is very handy and classy and fit in your case, however you can enter this clientId with many other ways. This is one of best free and simple QR code generating service, and this is one of best QR-code scanner library for android.

2 - Server Side: You have to handle step1 in server-side and it is very easy. You can have entity calls Client that all other entities have it. Because you should keep all of your data in one place but separated by your clients. You can also map APIs like this in Spring:

@RequestMapping(value = "http://yourCorporation.com/{clienId}/api/customers", method = RequestMethod.GET)
    Customers getCustomers(@PathVariable("clienId") Long clientId) {
        return customerService.findCustomerByClientId(clientId);
    }
like image 121
Mahdi Avatar answered Oct 06 '22 00:10

Mahdi


Based on what you've said, this sounds more like you can solve this with configuration management than sending each client completely separate APKs.

Google has a private channel, but based on the documentation it seems much more oriented towards having a single membership list (i.e. once you're granted access you have access to the entire private channel) rather than highly customized access (i.e. certain people have access to certain items in the channel).

An alternative that I suggest: have all clients download the same APK. Give each of them a client-specific "activation code" for your app. When the app starts for the first time, it calls a web service and passes it its activation code; on the server side, you use the Activation Code to identify the client and then return data on the correct configuration to the client. Then you can distribute the same APK to everyone on your private channel and configure it remotely once it's installed.

A major advantage of this scheme is that you can have multiple configurations for an organization. Just give the client a choice of several activation codes, each of which will give them a certain configuration. For example, if you have an app that's used by both dock workers and janitors (and I'm just throwing out an example here), you could give the dock workers one activation code and janitors a second activation code and you can then easily give them different configurations.

like image 42
EJoshuaS - Stand with Ukraine Avatar answered Oct 05 '22 22:10

EJoshuaS - Stand with Ukraine