Autore Topic: Gestire la progress bar scaricando un file trami script php  (Letto 891 volte)

Offline sgotenks

  • Utente junior
  • **
  • Post: 57
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Geeksphone zero
  • Sistema operativo:
    Windows
Gestire la progress bar scaricando un file trami script php
« il: 12 Ottobre 2011, 13:30:49 CEST »
0
Ciao a tutti o un problemone da cui non vengo a capo dato la mia scarsa conoscenza di php. In pratica nella mia app l'utente può cliccare su un pulsante per avviare il download di un file. Quando clicca lancio una notification che ha una progressbar che man mano che il file viene scaricato mostra la percentuale di download raggiunta. Attualmente faccio tutto in java e funziona bene.

Codice (Java): [Seleziona]
OutputStream fileOutput = null;
                        InputStream inputStream = null;
                        HttpURLConnection conn = null;
                        try
                        {      
                        URL url = new URL(path);
                        String fileName = new File(path).getName();
                        conn = (HttpURLConnection) url.openConnection();
                        conn.setRequestMethod("GET");
                        conn.setDoOutput(true);
                        conn.setDoInput(true);
                        conn.setRequestProperty("content-type", "binary/data");
                        conn.connect();
                        File SDCardRoot = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
                        boolean success = SDCardRoot.mkdirs();
                        File temp = new File(SDCardRoot+File.separator + "MyMarketZip");
                        success = temp.mkdirs();
                            File file = new File(temp,fileName);
                            fileOutput = new BufferedOutputStream(new FileOutputStream(file,false));
                            inputStream = new BufferedInputStream(conn.getInputStream());
                            throwsNotification_download(appId);
                            int totalSize = conn.getContentLength();
                            int downloadedSize = 0;
                        byte[] buffer = new byte[1024];
                        int bufferLength = 0;
                        while ( (bufferLength = inputStream.read(buffer)) > 0 )
                        {
                                fileOutput.write(buffer, 0, bufferLength);
                            downloadedSize += bufferLength;
                            progress = (int)((float)100/((float)totalSize/(float)downloadedSize));
                            if (progress > (tempVariable+5))
                            {
                                tempVariable = progress;
                                notification.contentView.setProgressBar(R.id.status_progress, 100, progress, false);
                                notification.contentView.setTextViewText(R.id.status_text, "Completed: "+progress+"%");
                                notificationManager.notify(appId, notification);
                                tempVariable2 = tempVariable2 +1;
                            }
                            //updateProgress(downloadedSize, totalSize);
                        }
                        fileOutput.flush();
                            notificationManager.cancel(appId);
                            throwNotification(appId, appName, "Downloaded", R.drawable.download_icon, stato);


Il codice non è molto pulito nel calolare il path del file da scaricare e dove salvarlo, ma comunque funziona. All'interno del while ho una variabile Progress che calcola la percentuale di download e aggiorna la progressbar.


Il mio problema è il seguente. Mi è stato chiesto di fare il download  tramite un file.php, ovvero in java chiamerò semplicemente lo script che darà inizio al download del file. Su internet ho trovato che per dire a php di scaricare un file basta scrivere:

Codice: [Seleziona]

header("Cache-Control: "); // Questo lascialo vuoto per evitare errori con Internet Explorer
 header("Pragma: "); // Anche questo.
 header("Content-type: application/octet-stream");
 header("Content-Disposition: attachment; filename=".$filename."");
 header("Content-length: $filesize"); 

oppure

Codice: [Seleziona]
header("Cache-Control: public");
 header("Content-Description: File Transfer");
 header("Content-Disposition: attachment; filename= " . $file);
 header("Content-Transfer-Encoding: binary");
 readfile($file);

non chiedetemi quale sia la differenza e se non è giusto pls indicatemi la via :)
Ad ogni modo il vero problema a questo punto è: io da java chiamo lo script tipo così

Codice (Java): [Seleziona]
URL url = new URL(Costanti.IP_SERVER+"DownloadFile.php"+"?nomeFile="+fileName,+"?destinazioneFile="+dest);
try
{
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        conn2.disconnect();
}

Passandogli il nome del file da scaricare, o meglio il percorso, e la directory in cui salvarla, e lui darà il via al download.
1) Ma come faccio a conoscere la percentuale di download eseguita e in che modo vado ad aggiornare la mia progress bar?

2)Alla fine del tutto come faccio ad avere una reference al file. Ad esempio in java alla fine la mia variabile fileOutput puntava al file scaricato, qua invece?

3)Come gli dico quanto è grosso il file?

Grazie

Offline sgotenks

  • Utente junior
  • **
  • Post: 57
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Geeksphone zero
  • Sistema operativo:
    Windows
Re:Gestire la progress bar scaricando un file trami script php
« Risposta #1 il: 12 Ottobre 2011, 22:07:15 CEST »
0
Con una mano da un mio amico ho risolto così, posto la soluzione magari qualcuno ne avesse bisogno in futturo o avesse degli appunti da fare:

Questo è il php, ho dovuto usare curl per creare una mia funzione per recuperare le dimensioni del file perchè filesize() funziona solo con file in locale e nel mio caso stan su un server:
Codice: [Seleziona]
$file = "http://10.47.103.161:8080/applicazioni/myFile3.zip"; //not public folder

    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . getMyFileSize($file));
        ob_clean();
    flush();
    readfile($file);
    exit;

       
        function getMyFileSize ($file) {
    $ch = curl_init($file);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

    $data = curl_exec($ch);
    curl_close($ch);

    if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {

        // Contains file size in bytes
        $contentLength = (int)$matches[1];
        }
        return $contentLength ;
}       



e il java a grandi linee è questo.....purtroppo di programmazione in rete mi intendo poco quindi non so bene spiegare come funziona.......di fatto è simile alla soluzione in java puro solo che fa la connessione in maniera diversa....c'è quel thread.sleep che nn mi convince non ne capisco l'utilità e penso che proverò a toglierlo, quel pezzo l'ho preso da un articolo.
Codice (Java): [Seleziona]
                   InputStream inputStream = null;
                   FileOutputStream fileOutput = null;
                   byte[] buffer = new byte[1024];        
                   String url = "http://10.47.103.161:8080/phpDownload.php";
                    DefaultHttpClient client = new DefaultHttpClient();
                    HttpGet httpGet = new HttpGet(url);
                    try
                    {
                        String fileName = new File(path).getName();
                        File SDCardRoot = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
                        SDCardRoot.mkdirs();
                        File temp = new File(SDCardRoot+File.separator + "MyMarketZip");
                        temp.mkdirs();
                        File file = new File(temp,fileName);
                       
                            HttpResponse execute = client.execute(httpGet);
                            inputStream = execute.getEntity().getContent();
                            lanciaNotification_download(appId);
                            long totalSize = execute.getEntity().getContentLength();
                            fileOutput = new FileOutputStream(file,false);
                            int bufferLength = 0;
                            int downloadedSize = 0;
                            System.out.println("Sono prima del While");
                            while ((bufferLength = inputStream.read(buffer, 0, 1024)) > 0)
                           {
                                        System.out.println("Sono dentro il while");
                                        System.out.println("Total size = "+totalSize);
                                        System.out.println("Downloaded = "+downloadedSize);
                                        System.out.println("bufferLengh = "+bufferLength);
                             fileOutput.write(buffer, 0, bufferLength);
                             Thread.sleep(100);
                             downloadedSize += bufferLength;
                             progress = (int)((float)100/((float)totalSize/(float)downloadedSize));
                             if (progress > (tempVariable+5))
                             {
                                        tempVariable = progress;
                                        notification.contentView.setProgressBar(R.id.status_progress, 100, progress, false);
                                        notification.contentView.setTextViewText(R.id.status_text, "Completed: "+progress+"%");
                                        notificationManager.notify(appId, notification);
                                        tempVariable2 = tempVariable2 +1;
                                 }
                            }
                        //fileOutput.flush();
                        fileOutput.close();
« Ultima modifica: 12 Ottobre 2011, 22:08:49 CEST da sgotenks »