Descargar un archivo sin extensión desde un servidor
Estoy tratando de descargar un archivo mp3 de la siguiente URL. He encontrado un montón de artículos y ejemplos sobre la descarga de archivos. Estos ejemplos se basan en direcciones URL que terminan con una extensión de archivo, por ejemplo: – yourdomain.com/filename.mp3
pero quiero descargar un archivo de url siguiente que normalmente no termina con extensión de archivo.
youtubeinmp3.com/download/get/?i=1gsE32jF0aVaY0smDVf%2BmwnIZPrMDnGmchHBu0Hovd3Hl4NYqjNdym4RqjDSAis7p1n5O%2BeXmdwFxK9ugErLWQ%3D%3D
- ¿Está el intento de compartir facebook en Android todavía roto?
- Cómo validar un nombre de URL / sitio web en EditText en Android?
- Abrir URL en WebView en lugar del explorador predeterminado
- ¿Qué es un filtro de intenciones que solo mostraría una aplicación en el menú compartido al compartir una URL?
- Android: Cargar imagen desde la URL web
** Tenga en cuenta que utilizo la url tal como está sin usar el método de formato de url de Stackoverflow para entender fácilmente la pregunta.
** He intentado la solución de @Arsal Imam como sigue sigue sin funcionar
btnShowProgress.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // starting new Async Task File cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"Folder Name"); if(!cacheDir.exists()) cacheDir.mkdirs(); File f=new File(cacheDir,"ddedddddd.mp3"); saveDir=f.getPath(); new DownloadFileFromURL().execute(fileURL); } });
Y el código de tarea asíncrona es el siguiente
class DownloadFileFromURL extends AsyncTask<String, String, String> { @Override protected void onPreExecute() { super.onPreExecute(); showDialog(progress_bar_type); } @Override protected String doInBackground(String... f_url) { try{ URL url = new URL(fileURL); HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); int responseCode = httpConn.getResponseCode(); // always check HTTP response code first if (responseCode == HttpURLConnection.HTTP_OK) { String fileName = ""; String disposition = httpConn.getHeaderField("Content-Disposition"); String contentType = httpConn.getContentType(); int contentLength = httpConn.getContentLength(); if (disposition != null) { // extracts file name from header field int index = disposition.indexOf("filename="); if (index > 0) { fileName = disposition.substring(index + 10, disposition.length() - 1); } } else { // extracts file name from URL fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1, fileURL.length()); } System.out.println("Content-Type = " + contentType); System.out.println("Content-Disposition = " + disposition); System.out.println("Content-Length = " + contentLength); System.out.println("fileName = " + fileName); // opens input stream from the HTTP connection InputStream inputStream = httpConn.getInputStream(); String saveFilePath = saveDir + File.separator + fileName; // opens an output stream to save into file FileOutputStream outputStream = new FileOutputStream(saveDir); int bytesRead = -1; byte[] buffer = new byte[BUFFER_SIZE]; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.close(); inputStream.close(); System.out.println("File downloaded"); } else { System.out.println("No file to download. Server replied HTTP code: " + responseCode); } httpConn.disconnect(); }catch(Exception e){ e.printStackTrace(); } return null; } protected void onProgressUpdate(String... progress) { pDialog.setProgress(Integer.parseInt(progress[0])); } @Override protected void onPostExecute(String file_url) { dismissDialog(progress_bar_type); } }
- Android ¿Cuál es la mejor manera de almacenar URL? Miembros de datos estáticos o en String.xml?
- Android cómo crear un esquema de URL personalizado con el formato dado myapp: // http: //
- ¿Cómo hago una solicitud http usando cookies en Android?
- Cómo obtener la URL actual en un navegador de Android
- Descarga de archivos en Android
- Codificación de URL en Android
- ¿Qué tipo de url debería usar en android para enviar solicitud al servidor?
- ¿Hay una manera más rápida de descargar una página de la red a una cadena?
Aunque la biblioteca de Volley no se recomienda para operaciones de descarga o transmisión de gran tamaño, sin embargo, me gustaría compartir mi siguiente código de ejemplo de trabajo.
Supongamos que descargamos sólo archivos MP3 , así que codifico la extensión. Y, por supuesto, deberíamos comprobar más cuidadosamente para evitar excepciones (NullPointer …), como comprobar si los encabezados contienen "Content-Disposition"
clave o no …
¡Espero que esto ayude!
Volley Clase personalizada:
public class BaseVolleyRequest extends Request<NetworkResponse> { private final Response.Listener<NetworkResponse> mListener; private final Response.ErrorListener mErrorListener; public BaseVolleyRequest(String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) { super(0, url, errorListener); this.mListener = listener; this.mErrorListener = errorListener; } @Override protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) { try { return Response.success( response, HttpHeaderParser.parseCacheHeaders(response)); } catch (JsonSyntaxException e) { return Response.error(new ParseError(e)); } catch (Exception e) { return Response.error(new ParseError(e)); } } @Override protected void deliverResponse(NetworkResponse response) { mListener.onResponse(response); } @Override protected VolleyError parseNetworkError(VolleyError volleyError) { return super.parseNetworkError(volleyError); } @Override public void deliverError(VolleyError error) { mErrorListener.onErrorResponse(error); } }
Entonces en su Actividad:
public class BinaryVolleyActivity extends AppCompatActivity { private final Context mContext = this; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_binary_volley); RequestQueue requestQueue = Volley.newRequestQueue(mContext); String url = "http://www.youtubeinmp3.com/download/get/?i=3sI2yV5mJ0kQ8CnddqmANZqK8a%2BgVQJ%2Fmg3xwhHTUsJKuusOCZUzebuWW%2BJSFs0oz8VTs6ES3gjohKQMogixlQ%3D%3D"; BaseVolleyRequest volleyRequest = new BaseVolleyRequest(url, new Response.Listener<NetworkResponse>() { @Override public void onResponse(NetworkResponse response) { Map<String, String> headers = response.headers; String contentDisposition = headers.get("Content-Disposition"); // String contentType = headers.get("Content-Type"); String[] temp = contentDisposition.split("filename="); String fileName = temp[1].replace("\"", "") + ".mp3"; InputStream inputStream = new ByteArrayInputStream(response.data); createLocalFile(inputStream, fileName); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e("Volley", error.toString()); } }); volleyRequest.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 10, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); requestQueue.add(volleyRequest); } private String createLocalFile(InputStream inputStream, String fileName) { try { String folderName = "MP3VOLLEY"; String extStorageDirectory = Environment.getExternalStorageDirectory().toString(); File folder = new File(extStorageDirectory, folderName); folder.mkdir(); File file = new File(folder, fileName); file.createNewFile(); FileOutputStream f = new FileOutputStream(file); byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) > 0) { f.write(buffer, 0, length); } //f.flush(); f.close(); return file.getPath(); } catch (IOException e) { return e.getMessage(); } } }
Aquí el resultado captura de pantalla:
NOTA:
Como comenté a continuación, debido a que la descarga directa de Url cambia regularmente, debería comprobar la nueva url con algunas herramientas como Postman para Chrome , si responde binaria en lugar de una página web (url caducada), entonces la URL es válida y mi código Funciona para esa Url.
Consulte las dos siguientes capturas de pantalla:
URL caducada:
URL no expirada:
ACTUALIZAR LA LÓGICA BÁSICA PARA CONSEGUIR EL DESCARGAR DIRECTO LINK DE LA DOCUMENTACIÓN DE ESTE SITIO:
Según crea tu propio YouTube a MP3 Downloader de forma gratuita
Puedes echar un vistazo a
Ejemplo JSON
También puede recibir los datos en JSON estableciendo el parámetro "format" en "JSON". http://YouTubeInMP3.com/fetch/?format=JSON&video=http://www.youtube.com/watch?v=i62Zjga8JOM
En primer lugar, se crea un JsonObjectRequest
obtener respuesta del vínculo de archivo anterior. Entonces, dentro onResponse
de este JsonObjectRequest
obtendrá el enlace de descarga directa, como este directUrl = response.getString("link");
Y utilizar BaseVolleyRequest volleyRequest
Acabo de decirle a la lógica para obtener url directo, IMO, debe implementar usted mismo. ¡Buena suerte!
Utilice debajo del código que funciona bien para las URL cifradas
public class HttpDownloadUtility { private static final int BUFFER_SIZE = 4096; /** * Downloads a file from a URL * @param fileURL HTTP URL of the file to be downloaded * @param saveDir path of the directory to save the file * @throws IOException */ public static void downloadFile(String fileURL, String saveDir) throws IOException { URL url = new URL(fileURL); HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); int responseCode = httpConn.getResponseCode(); // always check HTTP response code first if (responseCode == HttpURLConnection.HTTP_OK) { String fileName = ""; String disposition = httpConn.getHeaderField("Content-Disposition"); String contentType = httpConn.getContentType(); int contentLength = httpConn.getContentLength(); if (disposition != null) { // extracts file name from header field int index = disposition.indexOf("filename="); if (index > 0) { fileName = disposition.substring(index + 10, disposition.length() - 1); } } else { // extracts file name from URL fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1, fileURL.length()); } System.out.println("Content-Type = " + contentType); System.out.println("Content-Disposition = " + disposition); System.out.println("Content-Length = " + contentLength); System.out.println("fileName = " + fileName); // opens input stream from the HTTP connection InputStream inputStream = httpConn.getInputStream(); String saveFilePath = saveDir + File.separator + fileName; // opens an output stream to save into file FileOutputStream outputStream = new FileOutputStream(saveFilePath); int bytesRead = -1; byte[] buffer = new byte[BUFFER_SIZE]; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.close(); inputStream.close(); System.out.println("File downloaded"); } else { System.out.println("No file to download. Server replied HTTP code: " + responseCode); } httpConn.disconnect(); } }
La url devuelve un redireccionamiento 302 al .mp3 real. El navegador realiza el redireccionamiento en segundo plano para usted, pero en su aplicación necesita hacerlo usted mismo. Aquí está un ejemplo de cómo hacer eso con HttpUrlConnection http://www.mkyong.com/java/java-httpurlconnection-follow-redirect-example/
Si conoce el tipo de archivo con antelación, puede descargar el archivo de url que no tenga extensión.
DownloadService .java
public class DownloadService extends IntentService { public static final int UPDATE_PROGRESS = 8344; private Context context; private PowerManager.WakeLock mWakeLock; ProgressDialog mProgressDialog; String filename; File mypath; String urlToDownload; BroadcastReceiver broadcaster; Intent intent1; static final public String BROADCAST_ACTION = "com.example.app.activity.test.broadcast"; public DownloadService() { super("DownloadService"); } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); intent1 = new Intent(BROADCAST_ACTION); } @Override protected void onHandleIntent(Intent intent) { ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver"); try { intent1 = new Intent(BROADCAST_ACTION); urlToDownload = intent.getStringExtra("url"); filename= intent.getStringExtra("filename"); BufferedWriter out; try { File path=new File("/sdcard/","folder name"); path.mkdir(); mypath=new File(path,filename); Log.e("mypath",""+mypath); if (!mypath.exists()) { out= new BufferedWriter(new FileWriter(mypath)); //ut = new OutputStreamWriter(context.openFileOutput( mypath.getAbsolutePath() ,Context.MODE_PRIVATE)); out.write("test"); out.close(); } }catch(Exception e){ e.printStackTrace(); } URL url = new URL(urlToDownload); URLConnection connection = url.openConnection(); connection.connect(); // this will be useful so that you can show a typical 0-100% progress bar int fileLength = connection.getContentLength(); // download the file InputStream input = new BufferedInputStream(connection.getInputStream()); OutputStream output = new FileOutputStream(mypath); byte data[] = new byte[4096]; long total = 0; int count; while ((count = input.read(data)) != -1) { total += count; // publishing the progress.... Bundle resultData = new Bundle(); resultData.putInt("progress" ,(int) (total * 100 / fileLength)); //Log.e("mypath",""+mypath); resultData.putString("mypath", ""+mypath); receiver.send(UPDATE_PROGRESS, resultData); output.write(data, 0, count); } output.flush(); output.close(); input.close(); } catch (IOException e) { e.printStackTrace(); } Bundle resultData = new Bundle(); resultData.putInt("progress" ,100); resultData.putString("mypath", ""+mypath); receiver.send(UPDATE_PROGRESS, resultData); intent1.putExtra("progressbar", 100); sendBroadcast(intent1); } }
DescargarReceiver.java
public class DownloadReceiver extends ResultReceiver{ private Context context; private PowerManager.WakeLock mWakeLock; ProgressDialog mProgressDialog; String filename; String mypath; public DownloadReceiver(Handler handler ,String filename ,Context context) { super(handler); this.context = context; this.filename = filename; mProgressDialog = new ProgressDialog(context); } @Override protected void onReceiveResult(int resultCode, Bundle resultData) { super.onReceiveResult(resultCode, resultData); if (resultCode == DownloadService.UPDATE_PROGRESS) { int progress = resultData.getInt("progress"); mypath = resultData.getString("mypath"); mProgressDialog.setProgress(progress); //Log.e("progress","progress"); mProgressDialog.setMessage("App name"); mProgressDialog.setIndeterminate(true); mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); mProgressDialog.setCancelable(true); if (progress == 100) { mProgressDialog.dismiss(); Log.e("download","download"); } } } }
Ahora inicie el servicio en su mainactivity por debajo del código:
Intent miIntent = new Intent(mContext, DownloadService.class); miIntent.putExtra("url", url); miIntent.putExtra("filename", id+".mp3"); miIntent.putExtra("receiver", new DownloadReceiver(new Handler() , id,mContext)); startService(miIntent);