2010-10-21 3 views
4

Nous devons porter notre logiciel à android. L'une des principales caractéristiques de notre logiciel devrait être que le logiciel peut télécharger une nouvelle version de lui-même à partir du net (notre propre serveur) et installer sa nouvelle version aussi. Tout cela devrait être fait par programme.auto mise à niveau propre apk via net par programmation sur android

Je suis nouveau sur Android, donc je n'ai aucune idée de comment cela devrait être fait.

  • Comment créer une alerte apk? - résolu
  • Comment faire pour signer apk? - résolu
  • Comment télécharger apk? - résolu
  • Comment copier le fichier téléchargé en l'écrasant /data/apk/my.software.name.apk? - non résolu
  • Comment faire pour redémarrer le logiciel par la version en cours d'exécution? - non résolu
+0

Iphone et Windows aussi :) Nous ne voulons pas forcer l'utilisateur à mettre à jour, mais ce logiciel ne peut pas aller au marché android par le client.Nous devons donc résoudre la mise à jour automatique d'une manière que j'ai décrite initated par l'utilisateur. – Barna

Répondre

11

Fichier fichier = nouveau Fichier (dir, "App.apk");

Intention intention = nouvelle intention (Intent.ACTION_VIEW); Intention.setDataAndType (Uri.fromFile (fichier), "application/vnd.android.package-archive");

startActivity (intention);

J'ai eu le même problème et après plusieurs tentatives, cela a fonctionné pour moi de cette façon. Auparavant, j'ai obtenu ma nouvelle apk à partir d'un webservice.

+1

J'utilise la méthode ci-dessus pour installer apk .. dose il s'applique également à la mise à niveau? – ayachama

0

Vous n'êtes pas obligé de le faire. Vous venez de télécharger la nouvelle version de votre programme sur l'Android Market, et les gens le voient tout de suite. Les utilisateurs qui ont coché l'option "mettre à jour automatiquement" pour la mise à jour de votre programme automatiquement sans avoir à donner un consentement explicite; D'autres voient "mise à niveau disponible" et peuvent simplement cliquer sur "mise à niveau" pour mettre à niveau vers la nouvelle version de votre programme.

Si pour une raison quelconque vous pensez que vous voulez forcer la mise à jour sur l'utilisateur avec ou sans leur consentement, vous ne pouvez pas le faire. Vous pouvez télécharger l'apk et pouvoir le remettre au gestionnaire de paquets, qui à son tour demandera à l'utilisateur de confirmer s'il veut réellement l'installer - et encore une fois, pour que vous ayez besoin que l'utilisateur ait vérifié le "permettez options inconnues "option dans les options de développement, sinon le gestionnaire de paquets va carrément refuser de le faire. Mais Android ne vous laissera pas installer un nouveau paquet sans que l'utilisateur ne le demande explicitement, ou autorisant explicitement les mises à jour automatiques sur le marché. Si vous avez un problème de compatibilité ascendante et que vous souhaitez interdire l'exécution de versions obsolètes de votre application, vous pouvez intégrer dans votre application une logique qui vérifiera les informations de version sur votre serveur et se terminera si elle est obsolète, avec un message "cette version est obsolète, vous devez mettre à niveau pour continuer à utiliser cette application" ou quelque chose. Mais pas de mise à niveau dans le dos de l'utilisateur.

+1

Le logiciel est produit pour un client directement pas pour le marché android. J'ai lu sur le gestionnaire de paquets et la chose "autoriser les sources inconnues" aussi. Pour nous informer l'utilisateur et leur demander de mettre à jour en appuyant sur un bouton "mise à niveau" est acceptée, mais la question est: Comment je peux écraser mon ancienne apk avec la version téléchargée pendant son exécution et n'a pas le droit de l'écraser? – Barna

+0

Ah, dans ce cas, vous pouvez simplement remettre le nouveau fichier APK au gestionnaire de paquets. Ceci est fait en lançant une intention de type VIEW avec l'URL du fichier téléchargé (local, fichier: //sdcard/.../myfile.apk), qui appellera le gestionnaire pour les fichiers apk, qui est le gestionnaire de paquets. Vous aurez un message "cette application remplacera une application installée, toutes les données utilisateur précédentes seront sauvegardées" et l'application sera terminée, puis mise à jour. Il devra être relancé à la main (la relancer automatiquement est possible en créant une application auxiliaire, mais assez compliquée). – Jean

+0

De toute façon, doit-il être téléchargé sur une carte de stockage ou pourrait-il être téléchargé sur le stockage de l'appareil lui-même? – Barna

0

Désolé pour le désagrément ceci est le code et plus tard j'ai des autorisations XML post Exiger pour cela.

package com.SelfInstall01; 

import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.List; 
import com.SelfInstall01.SelfInstall01Activity; 
import android.app.Activity; 
import android.app.AlertDialog; 
import android.app.Dialog; 
import android.app.AlertDialog.Builder; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.content.pm.PackageInfo; 
import android.net.Uri; 
import android.os.Bundle; 
import android.os.Environment; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.TextView; 
import android.widget.Toast; 

public class SelfInstall01Activity extends Activity 
{ 
    class PInfo { 
     private String appname = ""; 
     private String pname = ""; 
     private String versionName = ""; 
     private int versionCode = 0; 
     //private Drawable icon; 
     /*private void prettyPrint() { 
      //Log.v(appname + "\t" + pname + "\t" + versionName + "\t" + versionCode); 
     }*/ 
    } 
    public int VersionCode; 
    public String VersionName=""; 
    public String ApkName ; 
    public String AppName ; 
    public String BuildVersionPath=""; 
    public String urlpath ; 
    public String PackageName; 
    public String InstallAppPackageName; 
    public String Text=""; 

    TextView tvApkStatus; 
    Button btnCheckUpdates; 
    TextView tvInstallVersion; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     //Text= "Old".toString(); 
     Text= "New".toString(); 


     ApkName = "SelfInstall01.apk";//"Test1.apk";// //"DownLoadOnSDcard_01.apk"; //  
     AppName = "SelfInstall01";//"Test1"; // 

     BuildVersionPath = "http://10.0.2.2:82/Version.txt".toString(); 
     PackageName = "package:com.SelfInstall01".toString(); //"package:com.Test1".toString(); 
     urlpath = "http://10.0.2.2:82/"+ Text.toString()+"_Apk/" + ApkName.toString(); 

     tvApkStatus =(TextView)findViewById(R.id.tvApkStatus); 
     tvApkStatus.setText(Text+" Apk Download.".toString()); 


     tvInstallVersion = (TextView)findViewById(R.id.tvInstallVersion); 
     String temp = getInstallPackageVersionInfo(AppName.toString()); 
     tvInstallVersion.setText("" +temp.toString()); 

     btnCheckUpdates =(Button)findViewById(R.id.btnCheckUpdates); 
     btnCheckUpdates.setOnClickListener(new OnClickListener() 
     {  
      @Override 
      public void onClick(View arg0) 
      { 
       GetVersionFromServer(BuildVersionPath); 

       if(checkInstalledApp(AppName.toString()) == true) 
       { 
        Toast.makeText(getApplicationContext(), "Application Found " + AppName.toString(), Toast.LENGTH_SHORT).show(); 


       }else{ 
        Toast.makeText(getApplicationContext(), "Application Not Found. "+ AppName.toString(), Toast.LENGTH_SHORT).show();   
       }    
      } 
     }); 

    }// On Create END. 

    private Boolean checkInstalledApp(String appName){ 
     return getPackages(appName);  
    } 

    // Get Information about Only Specific application which is Install on Device. 
    public String getInstallPackageVersionInfo(String appName) 
    { 
     String InstallVersion = "";  
     ArrayList<PInfo> apps = getInstalledApps(false); /* false = no system packages */ 
     final int max = apps.size(); 
     for (int i=0; i<max; i++) 
     { 
      //apps.get(i).prettyPrint();   
      if(apps.get(i).appname.toString().equals(appName.toString())) 
      { 
       InstallVersion = "Install Version Code: "+ apps.get(i).versionCode+ 
        " Version Name: "+ apps.get(i).versionName.toString(); 
       break; 
      } 
     } 

     return InstallVersion.toString(); 
    } 
    private Boolean getPackages(String appName) 
    { 
     Boolean isInstalled = false; 
     ArrayList<PInfo> apps = getInstalledApps(false); /* false = no system packages */ 
     final int max = apps.size(); 
     for (int i=0; i<max; i++) 
     { 
      //apps.get(i).prettyPrint(); 

      if(apps.get(i).appname.toString().equals(appName.toString())) 
      { 
       /*if(apps.get(i).versionName.toString().contains(VersionName.toString()) == true && 
         VersionCode == apps.get(i).versionCode) 
       { 
        isInstalled = true; 
        Toast.makeText(getApplicationContext(), 
          "Code Match", Toast.LENGTH_SHORT).show(); 
        openMyDialog(); 
       }*/ 
       if(VersionCode <= apps.get(i).versionCode) 
       { 
        isInstalled = true; 

        /*Toast.makeText(getApplicationContext(), 
          "Install Code is Less.!", Toast.LENGTH_SHORT).show();*/ 

        DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() 
        { 
         @Override 
         public void onClick(DialogInterface dialog, int which) { 
          switch (which) 
          { 
          case DialogInterface.BUTTON_POSITIVE: 
           //Yes button clicked 
           //SelfInstall01Activity.this.finish(); Close The App. 

           DownloadOnSDcard(); 
           InstallApplication(); 
           UnInstallApplication(PackageName.toString()); 

           break; 

          case DialogInterface.BUTTON_NEGATIVE: 
           //No button clicked 

           break; 
          } 
         } 
        }; 

        AlertDialog.Builder builder = new AlertDialog.Builder(this); 
        builder.setMessage("New Apk Available..").setPositiveButton("Yes Proceed", dialogClickListener) 
         .setNegativeButton("No.", dialogClickListener).show(); 

       }  
       if(VersionCode > apps.get(i).versionCode) 
       { 
        isInstalled = true; 
        /*Toast.makeText(getApplicationContext(), 
          "Install Code is better.!", Toast.LENGTH_SHORT).show();*/ 

        DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() 
        { 
         @Override 
         public void onClick(DialogInterface dialog, int which) { 
          switch (which) 
          { 
          case DialogInterface.BUTTON_POSITIVE: 
           //Yes button clicked 
           //SelfInstall01Activity.this.finish(); Close The App. 

           DownloadOnSDcard(); 
           InstallApplication(); 
           UnInstallApplication(PackageName.toString()); 

           break; 

          case DialogInterface.BUTTON_NEGATIVE: 
           //No button clicked 

           break; 
          } 
         } 
        }; 

        AlertDialog.Builder builder = new AlertDialog.Builder(this); 
        builder.setMessage("NO need to Install.").setPositiveButton("Install Forcely", dialogClickListener) 
         .setNegativeButton("Cancel.", dialogClickListener).show();    
       } 
      } 
     } 

     return isInstalled; 
    } 
    private ArrayList<PInfo> getInstalledApps(boolean getSysPackages) 
    {  
     ArrayList<PInfo> res = new ArrayList<PInfo>();   
     List<PackageInfo> packs = getPackageManager().getInstalledPackages(0); 

     for(int i=0;i<packs.size();i++) 
     { 
      PackageInfo p = packs.get(i); 
      if ((!getSysPackages) && (p.versionName == null)) { 
       continue ; 
      } 
      PInfo newInfo = new PInfo(); 
      newInfo.appname = p.applicationInfo.loadLabel(getPackageManager()).toString(); 
      newInfo.pname = p.packageName; 
      newInfo.versionName = p.versionName; 
      newInfo.versionCode = p.versionCode; 
      //newInfo.icon = p.applicationInfo.loadIcon(getPackageManager()); 
      res.add(newInfo); 
     } 
     return res; 
    } 


    public void UnInstallApplication(String packageName)// Specific package Name Uninstall. 
    { 
     //Uri packageURI = Uri.parse("package:com.CheckInstallApp"); 
     Uri packageURI = Uri.parse(packageName.toString()); 
     Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI); 
     startActivity(uninstallIntent); 
    } 
    public void InstallApplication() 
    { 
     Uri packageURI = Uri.parse(PackageName.toString()); 
     Intent intent = new Intent(android.content.Intent.ACTION_VIEW, packageURI); 

//  Intent intent = new Intent(android.content.Intent.ACTION_VIEW); 

     //intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     //intent.setFlags(Intent.ACTION_PACKAGE_REPLACED); 

     //intent.setAction(Settings. ACTION_APPLICATION_SETTINGS); 

     intent.setDataAndType 
     (Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + ApkName.toString())), 
     "application/vnd.android.package-archive"); 

     // Not open this Below Line Bcuz... 
     ////intent.setClass(this, Project02Activity.class); // This Line Call Activity Recursively its dangerous. 

     startActivity(intent); 
    } 
    public void GetVersionFromServer(String BuildVersionPath) 
    { 
     //this is the file you want to download from the remote server   
     //path ="http://10.0.2.2:82/Version.txt"; 
     //this is the name of the local file you will create 
     // version.txt contain Version Code = 2; \n Version name = 2.1;    
     URL u; 
     try { 
      u = new URL(BuildVersionPath.toString()); 

      HttpURLConnection c = (HttpURLConnection) u.openConnection();   
      c.setRequestMethod("GET"); 
      c.setDoOutput(true); 
      c.connect(); 

      //Toast.makeText(getApplicationContext(), "HttpURLConnection Complete.!", Toast.LENGTH_SHORT).show(); 

      InputStream in = c.getInputStream(); 

      ByteArrayOutputStream baos = new ByteArrayOutputStream(); 

      byte[] buffer = new byte[1024]; //that stops the reading after 1024 chars.. 
      //in.read(buffer); // Read from Buffer. 
      //baos.write(buffer); // Write Into Buffer. 

      int len1 = 0; 
      while ((len1 = in.read(buffer)) != -1) 
      {    
       baos.write(buffer,0, len1); // Write Into ByteArrayOutputStream Buffer. 
      } 

      String temp = "";  
      String s = baos.toString();// baos.toString(); contain Version Code = 2; \n Version name = 2.1; 

      for (int i = 0; i < s.length(); i++) 
      {    
       i = s.indexOf("=") + 1; 
       while (s.charAt(i) == ' ') // Skip Spaces 
       { 
        i++; // Move to Next. 
       } 
       while (s.charAt(i) != ';'&& (s.charAt(i) >= '0' && s.charAt(i) <= '9' || s.charAt(i) == '.')) 
       { 
        temp = temp.toString().concat(Character.toString(s.charAt(i))) ; 
        i++; 
       } 
       // 
       s = s.substring(i); // Move to Next to Process.! 
       temp = temp + " "; // Separate w.r.t Space Version Code and Version Name. 
      } 
      String[] fields = temp.split(" ");// Make Array for Version Code and Version Name. 

      VersionCode = Integer.parseInt(fields[0].toString());// .ToString() Return String Value. 
      VersionName = fields[1].toString(); 

      baos.close(); 
     } 
     catch (MalformedURLException e) { 
      Toast.makeText(getApplicationContext(), "Error." + e.getMessage(), Toast.LENGTH_SHORT).show(); 
      e.printStackTrace(); 
     } catch (IOException e) {   
      e.printStackTrace(); 
      Toast.makeText(getApplicationContext(), "Error." + e.getMessage(), Toast.LENGTH_SHORT).show(); 
     } 
      //return true; 
    }// Method End. 

    // Download On My Mobile SDCard or Emulator. 
    public void DownloadOnSDcard() 
    { 
     try{ 
      URL url = new URL(urlpath.toString()); // Your given URL. 

      HttpURLConnection c = (HttpURLConnection) url.openConnection(); 
      c.setRequestMethod("GET"); 
      c.setDoOutput(true); 
      c.connect(); // Connection Complete here.! 

      //Toast.makeText(getApplicationContext(), "HttpURLConnection complete.", Toast.LENGTH_SHORT).show(); 

      String PATH = Environment.getExternalStorageDirectory() + "/download/"; 
      File file = new File(PATH); // PATH = /mnt/sdcard/download/ 
      if (!file.exists()) { 
       file.mkdirs(); 
      } 
      File outputFile = new File(file, ApkName.toString());   
      FileOutputStream fos = new FileOutputStream(outputFile); 

      //  Toast.makeText(getApplicationContext(), "SD Card Path: " + outputFile.toString(), Toast.LENGTH_SHORT).show(); 

      InputStream is = c.getInputStream(); // Get from Server and Catch In Input Stream Object. 

      byte[] buffer = new byte[1024]; 
      int len1 = 0; 
      while ((len1 = is.read(buffer)) != -1) { 
       fos.write(buffer, 0, len1); // Write In FileOutputStream. 
      } 
      fos.close(); 
      is.close();//till here, it works fine - .apk is download to my sdcard in download file. 
      // So plz Check in DDMS tab and Select your Emualtor. 

      //Toast.makeText(getApplicationContext(), "Download Complete on SD Card.!", Toast.LENGTH_SHORT).show(); 
      //download the APK to sdcard then fire the Intent. 
     } 
     catch (IOException e) 
     { 
      Toast.makeText(getApplicationContext(), "Error! " + 
        e.toString(), Toast.LENGTH_LONG).show(); 
     }   
    } 
} 
+0

Salut ... Je fais comme vous l'avez dit ci-dessus .. mais je vérifie le code de version avec succès .. et le nouveau fichier est créé dans SDcard aussi .. mais la taille de apk est zéro. donc une erreur d'analyse se produit. –

Questions connexes