How to install an APK remotely? (how Googleplay updates apps)

Asked

Viewed 1,366 times

4

I made a service to download an updated version of my application when it exists. I would like to display a message on the screen warning that there is an update and install/update behind my application. Is that possible? Thank you in advance.

  • Dude, it’s been a while since I focused on Android, but googlePlay sends a push to the user when there’s a new version.

3 answers

2

Install the application automatically in the background I believe it is not possible, because the device would need to be rooted. But you can show a screen asking if the person wants to download the update and let them decide whether to install or not, follow the commented code:

I am considering that you are already bringing a service information saying that you have an update, so if you have just use the following code. In my case I used a DialogFragment to show the screen saying there is an update, but this is at your discretion:

private static String file_url = "";
private String appName = "";
private File file;
private Button button;

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  button = (Button) ...;

  file_url = "url do seu arquivo .apk";
  appName = "nome do seu aplicativo (não esqueça de colocar .apk no final)";

  file = new File(String.valueOf(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + appName));

  if (file.exists()) { // Se o arquivo já existe (estou verifcando na pasta download)
     abreArquivo();
  }

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) }
           new DownloadAtualizacao().execute(file_url);
        }
    });

}

// Essa classe irá fazer o download do apk em background
class DownloadAtualizacao extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // Faça algo como mostrar uma ProgressBar antes de começar a baixar
    }

    @Override
    protected String doInBackground(String... f_url) {
        int count;
        String erro = "N";
        try {
            URL url = new URL(f_url[0]);
            URLConnection conection = url.openConnection();
            conection.connect();

            int tamFile = conection.getContentLength();
            InputStream input = new BufferedInputStream(url.openStream(), 10 * 1024);
            OutputStream output = new FileOutputStream(String.valueOf(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + appName));
            byte data[] = new byte[1024];
            long total = 0;
            while ((count = input.read(data)) != -1) {
                total += count;
                publishProgress("" + (int) ((total * 100) / tamFile));
                output.write(data, 0, count);
            }
            output.flush();
            output.close();
            input.close();
        } catch (Exception e) { erro = "S"; }
        return erro;
    }

    protected void onProgressUpdate(String... progress) {
        // utilize para incrementar o progresso da ProgressBar
        // use assim progressBar.setProgress(Integer.parseInt(progress[0])); 
    }

    @Override
    protected void onPostExecute(String erro) {
        if (erro.equals("S")) { 
           // Faça algo aqui se ocorreu algum erro
        }
        else {
           abreArquivo();
        }
    }
}

private void abreArquivo() {
    File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + appName);
    String type = getType(file);
    Intent it = new Intent();
    it.setAction(Intent.ACTION_VIEW);
    it.setDataAndType(Uri.fromFile(file), type);
    try { startActivity(it); } catch (Exception e) { e.printStackTrace(); }
}

// Pega o mymeType do arquivo(pode ser usado para qualquer tipo de arquivo)
private String getType(File file) {
    String type = null;
    try {
        URL u = file.toURL();
        URLConnection uc = null;
        uc = u.openConnection();
        type = uc.getContentType();
    } catch (Exception e) { e.printStackTrace(); }
    return type;
}

1

You can do it this way:

Service:

Your Service can inform the app that there are new updates! Through a JSON (for example) you can specify the most current version.

It is also possible to prevent a user from using a very old version: Example of JSON:

{“LAST_VERSION”: “3.7", 
“ALLOWED_WITH_UPDATE” :” 3.6", 
“NOT_ALLOWED”: “2.8”}

Being:

LAST_VERSION: the latest version;

ALLOWED_WITH_UPDATE: There are updates, but the user does not need to update;

NOT_ALLOWED: The User necessarily needs to update;

Android:

Every time the app starts, it performs this query and informs the User if there are any updates (through Dialog, for example).

If the version is less than or equal to NOT_ALLOWED, to Dialog allows only the update (locking the functionality of the app).

To find out which version of the app use the following Constant: BuildConfig.VERSION_NAME

  • 1

    I use this logic, every time I log in to my application, it already brings the version of the database application, and if it is larger than the current version shows a Dialogfragment with the code I showed above.

0

You don’t need to do anything specific to this, the update notification is Google Play’s responsibility.

You need to just climb your new apk and change the versionCode of it in the manifest.

Edit

There are other possibilities like using a hockeyApp or Fabric that they have a system that once the user opens the app he opens a dialog stating that there is an update available.

  • i will not put my app in google play.

  • You can use hockeyApp anyway. @daniel12345smith

  • @daniel12345smith Take my criticism as constructive and in no way boring, but I don’t agree with your approach. Not putting on Google Play have to control this, besides "open your phone" to unknown sources is not a good approach. I have apps published in my clients' accounts, perfectly safe and I’m not afraid to leave in play. Some including the description is: XPTO company’s private application. Automated installation without being distributed by Play I think will never be possible. This would leave Android extremely VERY vulnerable.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.