Servicios en Android
Uso de servicios
Servicios en Android (Servicios)
Descripción general de los servicios
Servicios en Android:
Un servicio en segundo plano:
La diferencia entre IntentService y Service
Service versus IntentService
Introducción a los servicios (ejemplo: Un servicio en segundo plano)
Ejemplo: Crear un servicio para reproducir música
Código del Servicio Reproductor de Música
Ejemplo: Crear un servicio para descargar un fichero en segundo plano
build.gradle:
dependencies { implementation("com.squareup.okhttp3:okhttp:4.12.0") }
permisos en el manifiesto:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Descarga de fichero" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.498" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.044" /> <Switch android:id="@+id/switch1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="IntentService" app:layout_constraintBottom_toTopOf="@+id/botonIniciar" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.919" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textView" app:layout_constraintVertical_bias="1.0" /> <Button android:id="@+id/botonIniciar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="36dp" android:text="Iniciar" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.528" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textView" /> <Button android:id="@+id/botonParar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="32dp" android:text="Parar" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.534" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/botonIniciar" app:layout_constraintVertical_bias="0.0" /> <TextView android:id="@+id/salida" android:layout_width="260dp" android:layout_height="126dp" android:layout_marginTop="44dp" android:text="resultado de la descarga" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.582" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/botonParar" app:layout_constraintVertical_bias="0.0" /> </androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener { public ActivityMainBinding binding; private static final int REQUEST_CONNECT = 1; public static final String WEB = "https://dam.org.es/ficheros/frases.html"; public static final String ACTION_RESP = "RESPUESTA_DESCARGA"; IntentFilter intentFilter; BroadcastReceiver broadcastReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); binding = ActivityMainBinding.inflate(getLayoutInflater()); View view = binding.getRoot(); setContentView(view); binding.botonIniciar.setOnClickListener(this); binding.botonParar.setOnClickListener(this); intentFilter = new IntentFilter(ACTION_RESP); intentFilter.addCategory(Intent.CATEGORY_DEFAULT); broadcastReceiver = new ReceptorOperacion(); // registerReceiver(broadcastReceiver, intentFilter); } @Override public void onResume(){ super.onResume(); //---registrar el receptor --- registerReceiver(broadcastReceiver, intentFilter); } @Override public void onPause(){ super.onPause(); //--- anular el registro del recpetor --- unregisterReceiver(broadcastReceiver); } public class ReceptorOperacion extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String respuesta = intent.getStringExtra("resultado"); binding.salida.setText(respuesta); // mostrarMensaje(respuesta); } } @Override public void onClick(View v) { binding.salida.setText(""); if (v == binding.botonIniciar) { if (comprobarPermiso()) { if (!binding.switch1.isChecked()) { // uso con Service startService(new Intent(MainActivity.this, DownloadService.class)); } else { // uso con IntentService Intent i = new Intent(this, DownloadIntentService.class); i.putExtra("web", WEB); startService(i); } } } if (v == binding.botonParar) { if (!binding.switch1.isChecked()) { stopService(new Intent(MainActivity.this, DownloadService.class)); } else { stopService(new Intent(MainActivity.this, DownloadIntentService.class)); } } } private boolean comprobarPermiso() { //https://developer.android.com/training/permissions/requesting?hl=es-419 String permiso = Manifest.permission.WRITE_EXTERNAL_STORAGE; boolean concedido = false; // comprobar los permisos if (ActivityCompat.checkSelfPermission(this, permiso) != PackageManager.PERMISSION_GRANTED) { // pedir los permisos necesarios, porque no están concedidos if (ActivityCompat.shouldShowRequestPermissionRationale(this, permiso)) { concedido = false; } else { ActivityCompat.requestPermissions(this, new String[]{permiso}, REQUEST_CONNECT); // Cuando se cierre el cuadro de diálogo se ejecutará onRequestPermissionsResult } } else { concedido = true; } return concedido; } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { String permiso = Manifest.permission.WRITE_EXTERNAL_STORAGE; //Manifest.permission.INTERNET; // chequeo los permisos de nuevo if (requestCode == REQUEST_CONNECT) if (ActivityCompat.checkSelfPermission(this, permiso) == PackageManager.PERMISSION_GRANTED) // permiso concedido startService(new Intent(MainActivity.this, DownloadService.class)); else // no hay permiso mostrarError("No se ha concedido permiso para escribir en memoria externa"); } private void mostrarError(String mensaje) { Toast.makeText(this, mensaje, Toast.LENGTH_SHORT).show(); } }
Comprobar permiso para escribir en memoria
Descarga del archivo
Escribir en memoria externa el fichero descargado
DownloadService.java
public class DownloadService extends Service { public static final String WEB = "https://dam.org.es/fichero/frases.html"; public DownloadService() { } @Override public void onCreate() { super.onCreate(); mostrarMensaje("Creando el servicio . . ."); } @Override public int onStartCommand(Intent intent, int flags, int startId) { URL url = null; try { url = new URL(WEB); descargaOkHTTP(url); } catch (MalformedURLException e) { e.printStackTrace(); mostrarMensaje("Error en la URL: " + WEB); } return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); mostrarMensaje("Servicio destruido"); } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } private void descargaOkHTTP(URL web) { final OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url(web) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { Log.e("Error: ", e.getMessage()); } @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException{ try (ResponseBody responseBody = response.body()) { if (!response.isSuccessful()) { //throw new IOException("Unexpected code " + response); Log.e("Error: ", "Unexpected code " + response); } else { // Read data on the worker thread final String responseData = response.body().string(); // guardar el fichero descargado en memoria externa if (escribirExterna(responseData)) { Log.i("Descarga: ", "fichero descargado"); } else Log.e("Error ", "no se ha podido descargar"); } } } }); } private void mostrarMensaje(String mensaje) { Toast.makeText(this,mensaje, Toast.LENGTH_SHORT).show(); } private boolean escribirExterna(String cadena) { File miFichero, tarjeta; BufferedWriter bw = null; boolean correcto = false; try { tarjeta = Environment.getExternalStorageDirectory(); miFichero = new File(tarjeta.getAbsolutePath(), "frases.html"); bw = new BufferedWriter(new FileWriter(miFichero)); bw.write(cadena); Log.i("Información: ", miFichero.getAbsolutePath()); } catch (IOException e) { if (cadena != null) Log.e("Error: ", cadena); Log.e("Error de E/S", e.getMessage()); } finally { try { if (bw != null) { bw.close(); correcto = true; } } catch (IOException e) { Log.e("Error al cerrar", e.getMessage()); } } return correcto; } }
Deja una respuesta
Lo siento, debes estar conectado para publicar un comentario.