Skip to content

Commit

Permalink
Update Flower Android Version (#2429)
Browse files Browse the repository at this point in the history
Co-authored-by: ps-yduck <[email protected]>
Co-authored-by: Taner Topal <[email protected]>
Co-authored-by: Daniel Nata Nugraha <[email protected]>
Co-authored-by: Daniel J. Beutel <[email protected]>
  • Loading branch information
5 people authored Oct 16, 2023
1 parent 07d92a6 commit e8223fd
Show file tree
Hide file tree
Showing 9 changed files with 997 additions and 312 deletions.
4 changes: 3 additions & 1 deletion examples/android/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Flower Android Example (TensorFlowLite)

This example demonstrates a federated learning setup with Android Clients. The training on Android is done on a CIFAR10 dataset using TensorFlow Lite. The setup is as follows:
This example demonstrates a federated learning setup with Android clients in a background thread. The training on Android is done on a CIFAR10 dataset using TensorFlow Lite. The setup is as follows:

- The CIFAR10 dataset is randomly split across 10 clients. Each Android client holds a local dataset of 5000 training examples and 1000 test examples.
- The FL server runs in Python but all the clients run on Android.
- We use a strategy called FedAvgAndroid for this example.
- The strategy is vanilla FedAvg with a custom serialization and deserialization to handle the Bytebuffers sent from Android clients to Python server.

The background thread is established via the `WorkManager` library of Android, thus, it will run comfortably on Android Versions from 8 to 13.

## Project Setup

Start by cloning the example project. We prepared a single-line command that you can copy into your shell which will checkout the example for you:
Expand Down
38 changes: 34 additions & 4 deletions examples/android/client/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.INTERNET" />
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.RETRIEVE_TASKS" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application
android:allowBackup="true"
Expand All @@ -22,6 +30,28 @@
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
</application>

<service android:name=".FlowerWorker"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />

<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
android:foregroundServiceType="dataSync"
tools:node="merge" />

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">

</provider>

<meta-data
android:name="androidx.work.impl.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />

</application>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import androidx.lifecycle.MutableLiveData;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
Expand Down Expand Up @@ -64,6 +66,7 @@ public void setLastLoss(int epoch, float newLoss) {

public void loadData(int device_id) {
try {
Log.d("FLOWERCLIENT_LOAD", "loadData: ");
BufferedReader reader = new BufferedReader(new InputStreamReader(this.context.getAssets().open("data/partition_" + (device_id - 1) + "_train.txt")));
String line;
int i = 0;
Expand Down Expand Up @@ -137,4 +140,38 @@ private static float[] prepareImage(Bitmap bitmap) {

return normalizedRgb;
}
}

// function to write to a file :

public void writeStringToFile( Context context , String fileName, String content) {
try {
// Get the app-specific external storage directory
File directory = context.getExternalFilesDir(null);

if (directory != null) {
File file = new File(directory, fileName);

// Check if the file exists
boolean fileExists = file.exists();

// Open a FileWriter in append mode
FileWriter writer = new FileWriter(file, true);

// If the file exists and is not empty, add a new line
if (fileExists && file.length() > 0) {
writer.append("\n");
}

// Write the string to the file
writer.append(content);

// Close the FileWriter
writer.close();
}
} catch (IOException e) {
e.printStackTrace(); // Handle the exception as needed
}
}


}
Loading

0 comments on commit e8223fd

Please sign in to comment.