L'interface XmlSerializer dans l'écosystème Android permet de convretir des structures de données en documents XML. Cette approche est particulièrement utile pour l'exportation de données, comme la sauvegarde de messages ou de configurations. Dans cet exemple, nous allons simuler l'exportation d'un historique de messages texte vers un ficheir XML stocké sur le périphérique.
Avant d'implémenter la logique d'écriture, il est nécessaire de déclarer la permission d'écriture sur le stockage externe dans le fichier AndroidManifest.xml :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Modèle de données
Nous commençons par définir une classe POJO pour représenter un enregistrement de message. Les propriétés ont été adaptées pour refléter un modèle de données plus générique.
package com.example.xmlexport;
public class SmsRecord {
private String content;
private long timestamp;
private String phoneNumber;
private boolean isIncoming;
public SmsRecord(String content, long timestamp, String phoneNumber, boolean isIncoming) {
this.content = content;
this.timestamp = timestamp;
this.phoneNumber = phoneNumber;
this.isIncoming = isIncoming;
}
public String getContent() { return content; }
public long getTimestamp() { return timestamp; }
public String getPhoneNumber() { return phoneNumber; }
public boolean isIncoming() { return isIncoming; }
}
Interface utilisaetur
L'interface se limite à un bouton déclenchant le processus de sérialisation. Voici la définition de la mise en page utilisant ConstraintLayout :
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_export_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Exporter les données"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Logique de sérialisation
L'activité principale initialise un jeu de données fictif et utilise XmlSerializer pour écrire le fichier export_data.xml à la racine du stockage externe. L'utilisation de l'instruction try-with-resources garantit la fermeture correcte des flux.
package com.example.xmlexport;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Xml;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import org.xmlpull.v1.XmlSerializer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ExportActivity extends Activity {
private List<SmsRecord> records;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_export);
records = new ArrayList<>();
for (int i = 1; i <= 15; i++) {
records.add(new SmsRecord("Message de test " + i, System.currentTimeMillis(), "+3360000000" + i, i % 2 == 0));
}
Button exportButton = findViewById(R.id.btn_export_data);
exportButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
performExport();
}
});
}
private void performExport() {
File targetFile = new File(Environment.getExternalStorageDirectory(), "export_data.xml");
try (FileOutputStream outputStream = new FileOutputStream(targetFile)) {
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(outputStream, "UTF-8");
serializer.startDocument("UTF-8", true);
serializer.startTag(null, "sms_history");
for (SmsRecord record : records) {
serializer.startTag(null, "entry");
serializer.startTag(null, "text");
serializer.text(record.getContent());
serializer.endTag(null, "text");
serializer.startTag(null, "time");
serializer.text(String.valueOf(record.getTimestamp()));
serializer.endTag(null, "time");
serializer.startTag(null, "contact");
serializer.text(record.getPhoneNumber());
serializer.endTag(null, "contact");
serializer.startTag(null, "direction");
serializer.text(record.isIncoming() ? "received" : "sent");
serializer.endTag(null, "direction");
serializer.endTag(null, "entry");
}
serializer.endTag(null, "sms_history");
serializer.endDocument();
Toast.makeText(this, "Exportation réussie", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "Erreur lors de l'exportation", Toast.LENGTH_SHORT).show();
}
}
}