AI voice assistant Android App to summarize a webpage.
In this video it shows the steps and code to create your own voice assistant Android App to summarize a webpage. It uses LLM models hosted on Hugging face for summarization.
I hope you like this video. For any questions, suggestions or appreciation please contact us at: https://programmerworld.co/contact/ or email at: programmerworld1990@gmail.com
Details:
Java Code:
package com.programmerworld.summarydoc;
// How to summarize a webpage using the LLM models of Hugging Face in your Android App?
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.speech.tts.TextToSpeech;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import okhttp3.*;
public class MainActivity extends AppCompatActivity {
private EditText urlInput;
private Button summarizeButton;
private TextView resultText;
private final String API_URL = "https://api-inference.huggingface.co/models/facebook/bart-large-cnn";
private final String API_KEY = "hf_DUMMYDUMMYQGOwYduSGeH"; // Replace with your actual API Key
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
private final Handler uiHandler = new Handler(Looper.getMainLooper());
private TextToSpeech textToSpeech;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
urlInput = findViewById(R.id.urlInput);
summarizeButton = findViewById(R.id.summarizeButton);
resultText = findViewById(R.id.resultText);
summarizeButton.setOnClickListener(view -> {
String url = urlInput.getText().toString();
fetchWebContent(url);
});
// Initialize Text-to-Speech
textToSpeech = new TextToSpeech(getApplicationContext(), status -> {
if (status == TextToSpeech.SUCCESS) {
textToSpeech.setLanguage(Locale.ENGLISH);
}
});
}
// Fetch webpage content using Jsoup
private void fetchWebContent(String url) {
executorService.execute(() -> {
try {
Document doc = Jsoup.connect(url).get();
String extractedText = doc.text(); // Extract text from the webpage
// Limit the extracted text to avoid API limits
if (extractedText.length() > 1024) {
extractedText = extractedText.substring(0, 1024);
}
summarizeText(extractedText);
} catch (IOException e) {
String errorMsg = "Error fetching webpage: " + e.getMessage();
uiHandler.post(() -> resultText.setText(errorMsg));
}
});
}
// Send extracted text to Hugging Face API for summarization
private void summarizeText(String inputText) {
executorService.execute(() -> {
try {
OkHttpClient client = new OkHttpClient();
String json = "{"
+ "\"inputs\": \"" + inputText.replace("\"", "\\\"") + "\","
+ "\"parameters\": {"
+ "\"max_length\": 200,"
+ "\"min_length\": 50,"
+ "\"do_sample\": false"
+ "}"
+ "}";
RequestBody body = RequestBody.create(json, MediaType.get("application/json"));
Request request = new Request.Builder()
.url(API_URL)
.addHeader("Authorization", "Bearer " + API_KEY)
.post(body)
.build();
Response response = client.newCall(request).execute();
String responseBody = response.body() != null ? response.body().string() : "Error: Empty response";
// Update UI on main thread
uiHandler.post(() -> resultText.setText(responseBody));
readOutSummary(responseBody);
} catch (IOException e) {
uiHandler.post(() -> resultText.setText("Error calling API: " + e.getMessage()));
}
});
}
// Method to read out the summary using TTS
private void readOutSummary(String textToRead) {
if (!textToRead.isEmpty()) {
textToSpeech.speak(textToRead, TextToSpeech.QUEUE_FLUSH, null, null);
}
}
@Override
protected void onDestroy() {
if (textToSpeech != null) {
textToSpeech.stop();
textToSpeech.shutdown();
}
super.onDestroy();
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.SummaryDoc"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
plugins {
alias(libs.plugins.android.application)
}
android {
namespace = "com.programmerworld.summarydoc"
compileSdk = 35
defaultConfig {
applicationId = "com.programmerworld.summarydoc"
minSdk = 30
targetSdk = 35
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}
dependencies {
implementation(libs.appcompat)
implementation(libs.material)
implementation(libs.activity)
implementation(libs.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
implementation("org.jsoup:jsoup:1.15.3") // For web scraping
implementation("com.squareup.okhttp3:okhttp:4.9.3") // For HTTP requests
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/urlInput"
android:layout_width="383dp"
android:layout_height="82dp"
android:hint="Enter webpage URL"
android:inputType="textUri" />
<Button
android:id="@+id/summarizeButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Summarize" />
<TextView
android:id="@+id/resultText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:textSize="20sp" />
</LinearLayout>
Screenshots:
For API Key in Hugging Face:
https://huggingface.co/settings/tokens