# App updaten via Button



## TheWalkingFrame (10. Dez 2020)

Ich möchte gerne meine App in Zukunft über einen Button updaten, wenn ich eine neue Version dieser App auf meinen FTP server lade.

Das ganze habe ich mit einem Downloadmanager probiert. Hier habe ich jedoch das Problem, dass er die APK vom FTP-Server zwar runterlädt, jedoch nicht am Smartphone speichert. Anscheinend ist sie nach dem download nur temporär da und das Smartphone erkennt sie auch nicht als eine .apk Datei. Das Smartphone schlägt mir verschiedene Apps vor (Chrome, HTML-Anzeige, Word,...) um diese heruntergeladene Datei zu öffnen, jedoch ist es mir nicht möglich die heruntergeladene APK Datei als solche zu Installieren. Vielleicht kann mir jemand helfen, was da genau der Fehler ist bzw. hat jemand eine bessere Lösung um vielleicht so etwas wie einen Check durchzuführen, ob eine neuere Version der APK auf dem FTP-Server vorhanden ist ?




```
downloadButton = (Button) findViewById(R.id.btn_update);
        downloadButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            downloadManager = (DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
            Uri uri = Uri.parse("http://meinftpserver/update.apk");
            DownloadManager.Request request = new DownloadManager.Request(uri);
                    request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE).setAllowedOverRoaming(true);
                    request.setAllowedOverRoaming(false);

                //show on navigation
                    request.setVisibleInDownloadsUi(true);
                    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);

                //file open when item on navigation is clicked
                    request.allowScanningByMediaScanner();
                    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

                //name to show while downloading
                request.setTitle("Update");

                //description to show while downloading
                request.setDescription("Downloading " + "Update");

            Long reference = downloadManager.enqueue(request);
            }
        });
```


----------



## mihe7 (10. Dez 2020)

Was die Installation betrifft, fehlt wohl der Mime-Type (s. https://stackoverflow.com/questions/28171418/download-apk-with-downloadmanager)

Und auf neue Versionen prüfen kannst Du ja recht einfach, indem Du eine Datei zur Verfügung stellst, die eine (Versions-)Nummer enthält. Dann musst Du nur die Datei abrufen und kannst entscheiden, ob eine neuere Version als die installierte existiert.


----------



## TheWalkingFrame (14. Dez 2020)

Vielen Dank für die Antwort. Ich habe den Mime-Type hinzugefügt, es funktioniert nun die manuelle Installation, jedoch habe ich immer noch ein Problem. Ich habe schon einiges ausprobiert, um die Installation zu starten wenn der Download abgeschlossen, da bekomme ich aber einen Parse Error oder die App crasht mit einem Error receiving broadcast Intent.

```
downloadButton.setOnClickListener(new View.OnClickListener() {


                                              @Override
                                              public void onClick(View v) {



                                                  dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
                                                  String destination = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";

                                                  String fileName = "app_name.apk";
                                                  String url = "http://url/app_name.apk";
                                                  Uri mUri = Uri.parse(url);

                                                  destination += fileName;
                                                  final Uri uri = Uri.parse("file://" + destination);

                                                  File file = new File(destination);
                                                  if (file.exists())
                                                      file.delete();

                                                  DownloadManager.Request request = new DownloadManager.Request(mUri);

                                                  request.setMimeType("application/vnd.android.package-archive");

                                                  request.setAllowedNetworkTypes(android.app.DownloadManager.Request.NETWORK_WIFI | android.app.DownloadManager.Request.NETWORK_MOBILE).setAllowedOverRoaming(true);
                                                  request.setAllowedOverRoaming(false);
                                                  request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, mUri.getLastPathSegment());
                                                  request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);

                                                  dm.enqueue(request);




                                                  final String finalDestination = destination;

                                                  final BroadcastReceiver onComplete = new BroadcastReceiver() {

                                                      public void onReceive(Context ctxt, Intent intent) {
                                                          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                                                              Uri contentUri = FileProvider.getUriForFile(ctxt, BuildConfig.APPLICATION_ID + ".provider", new File(finalDestination));
                                                              Intent openFileIntent = new Intent(Intent.ACTION_VIEW);
                                                              openFileIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                                                              openFileIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                                                              openFileIntent.setData(contentUri);
                                                              startActivity(openFileIntent);
                                                              unregisterReceiver(this);
                                                              finish();
                                                          } else {
                                                              Intent install = new Intent(Intent.ACTION_VIEW);
                                                              install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                                                              install.setDataAndType(uri,
                                                                      "application/vnd.android.package-archive");
                                                              startActivity(install);
                                                              unregisterReceiver(this);
                                                              finish();
                                                          }
                                                      }
                                                  };

                                                  registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
                                              }
                                          });
```


----------



## mihe7 (14. Dez 2020)

TheWalkingFrame hat gesagt.:


> Intent.ACTION_VIEW


Versuch mal Intent.ACTION_INSTALL_PACKAGE (s. https://stackoverflow.com/questions...nt-view-action-not-working-with-file-provider)


----------



## TheWalkingFrame (15. Dez 2020)

Diesen Link habe ich mir bereits zur Brust genommen, leider ändert Intent.ACTION_INSTALL_PACKAGE nichts an dem Fehler.


----------



## mihe7 (15. Dez 2020)

Du hast den Rest inkl. Kommentare bzgl. der Permissions im Link auch gelesen und umgesetzt (s. https://stackoverflow.com/a/40131196)?


----------



## TheWalkingFrame (18. Dez 2020)

Ja, in dem Manifest sind die Permissions für WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE und REQUEST_INSTALL_PACKAGES drinnen.

Im Code habe ich auch wie in deinem Thread die onRequestPermissionsResult, requestPermission und canReadWriteExternal übernommen. 

Den Link von dir hatte ich mir schon vor der erstellung des Threads mehrmals durchgelesen und alle Möglichkeiten ausprobiert, leider ohne Erfolg. Entweder ich mache einen Fehler und komme noch nicht drauf oder es gibt ein anderes Problem.


----------



## TheWalkingFrame (18. Dez 2020)

Das Problem dürfte am Code des Broadcastreceiver liegen, habe ihn testweise rausgelöscht und der Download funktioniert problemlos ohne dass die App crashed. Aber die Installation eben nur manuell. Sobald ich den Broadcastreceiver im Code habe, crashed die App nach dem Download mit dem "Receiving broadcast Intent Error".


----------



## mihe7 (18. Dez 2020)

Was steht denn im Stacktrace (Logcat)?


----------



## TheWalkingFrame (21. Dez 2020)

Ich habe den Code laut Anleitung erneut aufgebaut und habe den "Receiving Broadcast Intent Error" in den Griff bekommen, der taucht nicht mehr auf. 

Das einzige Problem dass ich nun noch habe ist, dass weiterhin ein Parsing Fehler auftritt, sobald er nach Abschluss des Downloads automatisch die .apk Öffnen möchte.  

.setMimeType("application/vnd.android.package-archive"); ist festgelegt

.setDataAndType(apkUri, "application/vnd.android.package-archive"); ist festgelegt

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> ist im Manifest


Logcat zeigt keine Fehler an


----------



## mihe7 (21. Dez 2020)

Im Logcat sollte aber schon irgendwas stehen, wenn ein Parsing Fehler auftritt. Kannst Du Dir das mal ohne Filter ansehen?


----------

