Estoy tratando de realizar una clase AsyncTask en mi aplicación para Android que analiza la velocidad de conexión de red para la carga y descarga. Yo estoy trabajando en la parte de descarga del ahora, pero no estoy obteniendo los resultados que esperaba. Yo estoy probando en una red Wifi con la que obtiene 15Mbps de abajo/arriba velocidades constantemente, sin embargo, los resultados que estoy recibiendo de mi aplicación son más alrededor de apenas 1Mpbs. Al ejecutar la prueba de velocidad de la apk en el dispositivo que lo estoy probando en la que se pone alrededor de 3,5 Mbps. La función de las obras, tal parece ser la mitad de la velocidad que debería ser. Si el código siguiente producir resultados precisos?

try {
String DownloadUrl = "http://ipv4.download.thinkbroadband.com:8080/5MB.zip";
String fileName = "testfile.bin";
File dir = new File (context.getFilesDir() + "/temp/");
if(dir.exists()==false) {
dir.mkdirs();
}
URL url = new URL(DownloadUrl); //you can write here any link
File file = new File(context.getFilesDir() + "/temp/" + fileName);
long startTime = System.currentTimeMillis();
Log.d("DownloadManager", "download begining: " + startTime);
Log.d("DownloadManager", "download url:" + url);
Log.d("DownloadManager", "downloaded file name:" + fileName);
/* Open a connection to that URL. */
URLConnection ucon = url.openConnection();
//Define InputStreams to read from the URLConnection.
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
//Read bytes to the Buffer until there is nothing more to read(-1).  
ByteArrayBuffer baf = new ByteArrayBuffer(1024);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
long endTime = System.currentTimeMillis(); //maybe
/* Convert the Bytes read to a String. */
FileOutputStream fos = new FileOutputStream(file);
fos.write(baf.toByteArray());
fos.flush();
fos.close();
File done = new File(context.getFilesDir() + "/temp/" + fileName);
Log.d("DownloadManager", "Location being searched: "+ context.getFilesDir() + "/temp/" + fileName);
double size = done.length();
if(done.exists()) {
done.delete();
}
Log.d("DownloadManager", "download ended: " + ((endTime - startTime) / 1000) + " secs");
double rate = (((size / 1024) / ((endTime - startTime) / 1000)) * 8);
rate = Math.round( rate * 100.0 ) / 100.0;
String ratevalue;
if(rate > 1000)
ratevalue = String.valueOf(rate / 1024).concat(" Mbps");
else
ratevalue = String.valueOf(rate).concat(" Kbps"); 
Log.d("DownloadManager", "download speed: "+ratevalue);       
} catch (IOException e) {
Log.d("DownloadManager", "Error: " + e);
}

Ejemplo de salida

10-08 15:09:52.658: D/DownloadManager(13714): download ended: 70 secs
10-08 15:09:52.662: D/DownloadManager(13714): download speed: 585.14 Kbps

Gracias de antemano por la ayuda. Si hay un método mejor, por favor hágamelo saber.

  • usted está leyendo un byte a la vez, esto puede ser bastante largo. ¿por qué no utilizar un byte[] y leer como varios Kb a la vez ?
  • Normalmente, usted tiene ~600K llamadas a read y append cada segundo.
  • además, su tasa de valor puede no ser muy preciso, porque size, endTime y startTime se entero, como son 1024, 1000 y 8, y por lo tanto su cálculo se realiza en entero antes de ser fundido a largo (esto debería dar imprecisa medida, pero no es responsable de la gran diferencia que se observa)
  • Mi tiempo se establecen los valores para anhela y se mide a la milésima de segundo. @njzk2 voy a mirar en leer más bytes en el tiempo. He probado un par de veces en otras redes y estoy parecen acercarse resultados, así que tal vez este es un problema con el wifi de mi casa.
  • en la media de número entero en el sentido de que la conversión a doble se realiza después de que el cómputo se hace, y por lo tanto no es de precisión perdido. Sin embargo, estoy bastante seguro de que el método de lectura es la causa de la cuestión de la velocidad.
  • Estoy realmente sólo recoger en java y no está seguro de la sintaxis correcta de los cambios que son necesarios para implementar correctamente la lectura / escritura de múltiples bytes. Es este un buen ejemplo? stackoverflow.com/questions/5690954/…
  • Estoy tratando construido una aplicación que realiza la prueba de velocidad, pero estoy de ninguna manera cerca de lograr resultados como Speedtest.net(OOKLA). Tienen que cumplir con lo que has intentado y si es posible por favor me guía.

InformationsquelleAutor Joffroi | 2013-10-08

1 Comentario

  1. 4

    Siguiente en mis comentarios, aquí es un ejemplo de cómo leer varios bytes de la secuencia

    //Define InputStreams to read from the URLConnection.
    InputStream is = ucon.getInputStream();
    BufferedInputStream bis = new BufferedInputStream(is);
    //I usually use a ByteArrayOutputStream, as it is more common.
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int red = 0;
    //This size can be changed
    byte[] buf = new byte[1024];
    while ((red = bis.read(buf)) != -1) {
    baos.write(buf, 0, red);
    }

    Lo que esto hace es que se lee en un byte[] buffer, y el retorno a la cantidad de bytes leídos. Este es a su vez escrito el OutputStream, especificando la cantidad de bytes a escribir.

    ByteArrayOutputStream también tienen un toByteArray que se comporta de manera similar.

    Alternativamente, también se puede escribir directamente el archivo, si se considera que el escribir para la operación de archivos es significativamente más rápido que la función de lectura :

    //Simply start by defining the fileoutputstream
    FileOutputStream fos = new FileOutputStream(file);
    int red = 0;
    //This size can be changed
    byte[] buf = new byte[1024];
    while ((red = bis.read(buf)) != -1) {
    //And directly write to it.
    fos.write(buf, 0, red);
    }
    long endTime = System.currentTimeMillis(); //maybe
    //Flush after, as this may trigger a commit to disk.
    fos.flush();
    fos.close();

    Por otra parte, si realmente se preocupan sólo por la velocidad de descarga, no es obligatorio escribir en el archivo, o en cualquier lugar, esto sería suficiente :

    long size = 0;
    byte[] buf = new byte[1024];
    while ((red = bis.read(buf)) != -1) {
    size += red;
    }
    • Lo siento por no responder antes. Realmente aprecio el detalle de la respuesta. He probado los dos métodos y, finalmente, fue con la sugerencia de no escribir el tamaño de los datos realmente estoy queriendo centrarse sólo en la velocidad de descarga. Desde el cambio a varios bytes, mis resultados han sido debe cerrar para que o de otra prueba de velocidad. De nuevo, gracias de nuevo por el ejemplo, que funcionó a la perfección.

Dejar respuesta

Please enter your comment!
Please enter your name here