nowy bajer
This commit is contained in:
parent
eb138f8e8d
commit
97da39ce9f
6
ToDoApp/.idea/inspectionProfiles/Project_Default.xml
Normal file
6
ToDoApp/.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="ThrowablePrintStackTrace" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
@ -29,21 +29,30 @@ android {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
exclude("META-INF/DEPENDENCIES")
|
||||
exclude("META-INF/LICENSE")
|
||||
exclude("META-INF/LICENSE.txt")
|
||||
exclude("META-INF/license.txt")
|
||||
exclude("META-INF/NOTICE")
|
||||
exclude("META-INF/NOTICE.txt")
|
||||
exclude("META-INF/notice.txt")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
|
||||
|
||||
implementation(libs.appcompat)
|
||||
implementation(libs.material)
|
||||
implementation(libs.activity)
|
||||
implementation(libs.constraintlayout)
|
||||
implementation(libs.work.runtime)
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.ext.junit)
|
||||
androidTestImplementation(libs.espresso.core)
|
||||
|
||||
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.0")
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.0")
|
||||
implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
||||
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
|
||||
implementation("com.squareup.okhttp3:logging-interceptor:4.9.0")
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
|
@ -59,10 +59,4 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||
cursor.close();
|
||||
return tasks;//Zwrócenie listy zadań
|
||||
}
|
||||
|
||||
public void removeExpiredTasks() {
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
String currentDate = new java.text.SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date());
|
||||
db.delete("tasks", "deadline < ?", new String[]{currentDate}); //Usunięcie zadań z przeszłą datą
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.example.todoapp2;
|
||||
|
||||
import android.app.DatePickerDialog;
|
||||
import android.app.TimePickerDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
@ -15,118 +15,145 @@ import android.widget.Toast;
|
||||
import androidx.activity.EdgeToEdge;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.work.Data;
|
||||
import androidx.work.OneTimeWorkRequest;
|
||||
import androidx.work.WorkManager;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private static final String TAG = "MainActivity";
|
||||
private ArrayAdapter<String> itemsAdapter;
|
||||
private EditText deadlineInput;
|
||||
private Spinner priorityInput;
|
||||
private TaskViewModel viewModel;
|
||||
private ArrayAdapter<String> itemsAdapter;//Adapter do zarządzania listą zadań
|
||||
private EditText deadlineInput;//Pole wejściowe dla daty i godziny deadline'u
|
||||
private Spinner priorityInput;//Spinner do wyboru priorytetu zadania
|
||||
private TaskViewModel viewModel;//ViewModel do zarządzania danymi zadań
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
EdgeToEdge.enable(this);
|
||||
setContentView(R.layout.activity_main);
|
||||
EdgeToEdge.enable(this);//Włączenie trybu Edge-to-Edge dla lepszego UX
|
||||
setContentView(R.layout.activity_main);//Ustawienie widoku aktywności
|
||||
|
||||
viewModel = new ViewModelProvider(this).get(TaskViewModel.class);//Inicjalizacja ViewModel
|
||||
|
||||
ListView list = findViewById(R.id.list); //Referencja do ListView
|
||||
Button button = findViewById(R.id.button); //Referencja do przycisku dodawania zadań
|
||||
Button buttonViewHtml = findViewById(R.id.button_view_html); //Referencja do przycisku wyświetlania zadań w HTML
|
||||
deadlineInput = findViewById(R.id.edit_deadline); //Referencja do pola wyboru terminu
|
||||
priorityInput = findViewById(R.id.edit_priority); //Referencja do spinnera wyboru priorytetu
|
||||
ListView list = findViewById(R.id.list);//Inicjalizacja listy zadań
|
||||
Button button = findViewById(R.id.button);//Inicjalizacja przycisku dodawania zadań
|
||||
Button buttonViewHtml = findViewById(R.id.button_view_html);//Inicjalizacja przycisku widoku HTML
|
||||
deadlineInput = findViewById(R.id.edit_deadline);//Inicjalizacja pola wejściowego deadline'u
|
||||
priorityInput = findViewById(R.id.edit_priority);//Inicjalizacja spinnera priorytetu
|
||||
|
||||
itemsAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1); //Inicjalizacja adaptera dla ListView
|
||||
list.setAdapter(itemsAdapter); //Ustawienie adaptera na ListView
|
||||
itemsAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);//Konfiguracja adaptera dla listy zadań
|
||||
list.setAdapter(itemsAdapter);//Ustawienie adaptera dla listy
|
||||
|
||||
//Obserwacja zmian w LiveData
|
||||
viewModel.getTasks().observe(this, tasks -> {
|
||||
Log.d(TAG, "Tasks updated: " + tasks); //Logowanie zmian
|
||||
itemsAdapter.clear(); //Czyszczenie adaptera
|
||||
itemsAdapter.addAll(tasks); //Dodanie nowych danych do adaptera
|
||||
viewModel.getTasks().observe(this, tasks -> {//Obserwacja zmian w liście zadań
|
||||
itemsAdapter.clear();//Wyczyszczenie adaptera
|
||||
itemsAdapter.addAll(tasks);//Dodanie nowych zadań do adaptera
|
||||
itemsAdapter.notifyDataSetChanged();//Powiadomienie adaptera o zmianach
|
||||
});
|
||||
|
||||
//Listener dla pola wyboru terminu
|
||||
deadlineInput.setOnClickListener(v -> {
|
||||
showDatePickerDialog(); //Wyświetlenie DatePickerDialog
|
||||
deadlineInput.setOnClickListener(v -> showDatePickerDialog());//Ustawienie kliknięcia w pole deadline, aby wyświetlić DatePickerDialog
|
||||
|
||||
button.setOnClickListener(view -> addItem());//Ustawienie kliknięcia w przycisk dodawania zadania
|
||||
|
||||
buttonViewHtml.setOnClickListener(v -> viewTasksInHtml());//Ustawienie kliknięcia w przycisk widoku HTML
|
||||
|
||||
list.setOnItemLongClickListener((parent, view, position, id) -> {//Ustawienie długiego kliknięcia na element listy, aby usunąć zadanie
|
||||
remove(position);
|
||||
return true;
|
||||
});
|
||||
|
||||
//Listener dla przycisku dodawania zadań
|
||||
button.setOnClickListener(view -> {
|
||||
Log.d(TAG, "Add button clicked"); //Logowanie kliknięcia przycisku
|
||||
addItem(); //Dodanie nowego zadania
|
||||
});
|
||||
|
||||
//Listener dla przycisku wyświetlania zadań w HTML
|
||||
buttonViewHtml.setOnClickListener(v -> {
|
||||
viewTasksInHtml(); //Wyświetlenie zadań w HTML
|
||||
});
|
||||
|
||||
//Listener dla długiego kliknięcia na element ListView
|
||||
list.setOnItemLongClickListener((parent, view, position, id) -> {
|
||||
return remove(position); //Usunięcie zadania
|
||||
});
|
||||
|
||||
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, //Inicjalizacja adaptera dla spinnera
|
||||
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,//Ustawienie adaptera dla priorytetów
|
||||
R.array.priority_levels, android.R.layout.simple_spinner_item);
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
priorityInput.setAdapter(adapter); //Ustawienie adaptera na spinner
|
||||
priorityInput.setAdapter(adapter);
|
||||
}
|
||||
|
||||
private void showDatePickerDialog() { //Metoda wyświetlająca DatePickerDialog
|
||||
private void showDatePickerDialog() {
|
||||
final Calendar calendar = Calendar.getInstance();
|
||||
int year = calendar.get(Calendar.YEAR);
|
||||
int month = calendar.get(Calendar.MONTH);
|
||||
int day = calendar.get(Calendar.DAY_OF_MONTH);
|
||||
int hour = calendar.get(Calendar.HOUR_OF_DAY);
|
||||
int minute = calendar.get(Calendar.MINUTE);
|
||||
|
||||
//Listener dla wyboru daty
|
||||
DatePickerDialog datePickerDialog = new DatePickerDialog(this, (view, year1, month1, dayOfMonth) -> {
|
||||
String date = year1 + "-" + (month1 + 1) + "-" + dayOfMonth;
|
||||
deadlineInput.setText(date); //Ustawienie wybranej daty w polu tekstowym
|
||||
DatePickerDialog datePickerDialog = new DatePickerDialog(this, (view, year1, month1, dayOfMonth) -> {//Tworzenie DatePickerDialog do wyboru daty
|
||||
TimePickerDialog timePickerDialog = new TimePickerDialog(this, (timeView, hourOfDay, minuteOfHour) -> {//Tworzenie TimePickerDialog do wyboru godziny po wybraniu daty
|
||||
String date = year1 + "-" + (month1 + 1) + "-" + dayOfMonth + " " + hourOfDay + ":" + minuteOfHour + ":00";
|
||||
deadlineInput.setText(date);//Ustawienie wybranej daty i godziny w polu deadline
|
||||
}, hour, minute, true);
|
||||
timePickerDialog.show();
|
||||
}, year, month, day);
|
||||
datePickerDialog.show(); //Wyświetlenie DatePickerDialog
|
||||
datePickerDialog.show();
|
||||
}
|
||||
|
||||
private boolean remove(int position) { //Metoda usuwająca zadanie
|
||||
private void remove(int position) {
|
||||
Context context = getApplicationContext();
|
||||
String item = itemsAdapter.getItem(position); //Pobranie elementu z adaptera
|
||||
String item = itemsAdapter.getItem(position);
|
||||
assert item != null;
|
||||
String task = item.split(" \\(Deadline:")[0];
|
||||
if (viewModel.removeTask(task)) {//Usunięcie zadania z ViewModel
|
||||
Toast.makeText(context, "Item removed", Toast.LENGTH_LONG).show(); //Wyświetlenie Toast z komunikatem
|
||||
return true;
|
||||
Toast.makeText(context, "Item removed", Toast.LENGTH_LONG).show();//Wyświetlenie komunikatu o usunięciu zadania
|
||||
} else {
|
||||
Toast.makeText(context, "Error removing item", Toast.LENGTH_LONG).show(); //Wyświetlenie Toast z błędem
|
||||
return false;
|
||||
Toast.makeText(context, "Error removing item", Toast.LENGTH_LONG).show();//Wyświetlenie komunikatu o błędzie usuwania zadania
|
||||
}
|
||||
}
|
||||
|
||||
private void addItem() { //Metoda dodająca nowe zadanie
|
||||
private void addItem() {
|
||||
EditText taskInput = findViewById(R.id.edit_text);
|
||||
String taskText = taskInput.getText().toString();
|
||||
String deadlineText = deadlineInput.getText().toString();
|
||||
String priorityText = priorityInput.getSelectedItem().toString();
|
||||
|
||||
Log.d(TAG, "Task: " + taskText + ", Deadline: " + deadlineText + ", Priority: " + priorityText);
|
||||
|
||||
if (!(taskText.isEmpty() || deadlineText.isEmpty() || priorityText.isEmpty())) { //Sprawdzenie czy pola nie są puste
|
||||
if (!(taskText.isEmpty() || deadlineText.isEmpty() || priorityText.isEmpty())) {
|
||||
if (viewModel.addTask(taskText, deadlineText, priorityText)) {//Dodanie zadania do ViewModel
|
||||
taskInput.setText(""); //Wyczyszczenie pola tekstowego
|
||||
deadlineInput.setText(""); //Wyczyszczenie pola daty
|
||||
priorityInput.setSelection(0); //Resetowanie spinnera
|
||||
taskInput.setText("");//Wyczyszczenie pola tekstowego zadania
|
||||
deadlineInput.setText("");//Wyczyszczenie pola tekstowego deadline'u
|
||||
priorityInput.setSelection(0);//Resetowanie wyboru priorytetu
|
||||
sendSMSReminder(taskText, deadlineText);//Wysłanie przypomnienia SMS o nowym zadaniu
|
||||
scheduleDeadlineReminder(taskText, deadlineText);//Zaprogramowanie przypomnienia SMS na 5 minut przed deadlinem
|
||||
} else {
|
||||
Toast.makeText(getApplicationContext(), "Error adding task", Toast.LENGTH_LONG).show(); //Wyświetlenie Toast z błędem
|
||||
Toast.makeText(getApplicationContext(), "Error adding task", Toast.LENGTH_LONG).show();//Wyświetlenie komunikatu o błędzie dodawania zadania
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(getApplicationContext(), "Please enter all fields", Toast.LENGTH_LONG).show(); //Wyświetlenie Toast z komunikatem o wypełnieniu wszystkich pól
|
||||
Toast.makeText(getApplicationContext(), "Please enter all fields", Toast.LENGTH_LONG).show();//Wyświetlenie komunikatu o konieczności wypełnienia wszystkich pól
|
||||
}
|
||||
}
|
||||
|
||||
private void viewTasksInHtml() { //Metoda wyświetlająca zadania w HTML
|
||||
private void sendSMSReminder(String task, String deadline) {
|
||||
String phoneNumber = "502836547";//Zamień na numer telefonu, na który ma być wysłany SMS
|
||||
String message = "New task added: " + task + ", Deadline: " + deadline;
|
||||
SmsApiClient.sendSms(phoneNumber, message);//Wysłanie SMS za pomocą SmsApiClient
|
||||
}
|
||||
|
||||
private void scheduleDeadlineReminder(String task, String deadline) {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
try {
|
||||
Date deadlineDate = dateFormat.parse(deadline);
|
||||
if (deadlineDate != null) {
|
||||
long timeDiff = deadlineDate.getTime() - System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(5);//5 minut przed deadline
|
||||
if (timeDiff > 0) {
|
||||
Data data = new Data.Builder()
|
||||
.putString("task", task)
|
||||
.putString("phoneNumber", "502836547")//Zamień na numer telefonu
|
||||
.build();
|
||||
|
||||
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(ReminderWorker.class)
|
||||
.setInitialDelay(timeDiff, TimeUnit.MILLISECONDS)//Ustawienie opóźnienia na 5 minut przed deadline
|
||||
.setInputData(data)//Przekazanie danych do ReminderWorker
|
||||
.build();
|
||||
|
||||
WorkManager.getInstance(this).enqueue(workRequest);//Dodanie zadania do WorkManager
|
||||
}
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void viewTasksInHtml() {
|
||||
StringBuilder htmlBuilder = new StringBuilder();
|
||||
htmlBuilder.append("<html><body><h1>Task List</h1><table border='1'><tr><th>Task</th><th>Deadline</th><th>Priority</th></tr>");
|
||||
for (int i = 0; i < itemsAdapter.getCount(); i++) {
|
||||
@ -140,8 +167,9 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
htmlBuilder.append("</table></body></html>");
|
||||
|
||||
Intent intent = new Intent(MainActivity.this, HtmlActivity.class);
|
||||
intent.putExtra("html_data", htmlBuilder.toString()); //Przekazanie danych HTML do nowej aktywności
|
||||
startActivity(intent); //Rozpoczęcie nowej aktywności
|
||||
//Przekazanie danych HTML do HtmlActivity za pomocą Intent
|
||||
Intent intent = new Intent(this, HtmlActivity.class);
|
||||
intent.putExtra("html_data", htmlBuilder.toString());
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
package com.example.todoapp2;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.work.Worker;
|
||||
import androidx.work.WorkerParameters;
|
||||
|
||||
public class ReminderWorker extends Worker {
|
||||
|
||||
public ReminderWorker(@NonNull Context context, @NonNull WorkerParameters params) {
|
||||
super(context, params);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Result doWork() {
|
||||
//Pobranie danych przekazanych do Workera
|
||||
String task = getInputData().getString("task");
|
||||
String phoneNumber = getInputData().getString("phoneNumber");
|
||||
|
||||
//Wysłanie przypomnienia SMS
|
||||
if (task != null && phoneNumber != null) {
|
||||
SmsApiClient.sendSms(phoneNumber, "Deadline zadania \"" + task + "\" jest dzisiaj!");
|
||||
}
|
||||
|
||||
return Result.success(); //Zwrócenie sukcesu po wykonaniu pracy
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.example.todoapp2;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
import retrofit2.http.Field;
|
||||
import retrofit2.http.FormUrlEncoded;
|
||||
import retrofit2.http.Header;
|
||||
import retrofit2.http.POST;
|
||||
|
||||
public class SmsApiClient {
|
||||
private static final String BASE_URL = "https://api.smsapi.pl/";
|
||||
private static final String TOKEN = "Bearer s1lgvSn5RdZNATyFq1LcPhGlqC13oeTU9fcXd5Ar";
|
||||
|
||||
public interface SmsApiService {
|
||||
@FormUrlEncoded
|
||||
@POST("sms.do")
|
||||
Call<Void> sendSms(
|
||||
@Header("Authorization") String authorization,
|
||||
@Field("to") String to,
|
||||
@Field("message") String message,
|
||||
@Field("format") String format
|
||||
);
|
||||
}
|
||||
|
||||
private static SmsApiService smsApiService;
|
||||
|
||||
//Singleton pattern do uzyskania instancji SmsApiService
|
||||
public static SmsApiService getInstance() {
|
||||
if (smsApiService == null) {
|
||||
Retrofit retrofit = new Retrofit.Builder()
|
||||
.baseUrl(BASE_URL)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build();
|
||||
smsApiService = retrofit.create(SmsApiService.class);
|
||||
}
|
||||
return smsApiService;
|
||||
}
|
||||
|
||||
//Metoda do wysyłania SMS za pomocą SmsApiService
|
||||
public static void sendSms(String to, String message) {
|
||||
SmsApiService service = getInstance();
|
||||
service.sendSms(TOKEN, to, message, "json")
|
||||
.enqueue(new retrofit2.Callback<Void>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
|
||||
//SMS sent successfully
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
|
||||
//Failed to send SMS
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -16,7 +16,6 @@ public class TaskViewModel extends AndroidViewModel {
|
||||
super(application);
|
||||
db = new DatabaseHelper(application); // Inicjalizacja bazy danych
|
||||
tasks = new MutableLiveData<>();
|
||||
removeExpiredTasks(); //Usuwanie przeterminowanych zadań
|
||||
loadTasks(); // Załadowanie zadań z bazy danych
|
||||
}
|
||||
|
||||
@ -31,7 +30,6 @@ public class TaskViewModel extends AndroidViewModel {
|
||||
public boolean addTask(String task, String deadline, String priority) {
|
||||
boolean result = db.addTask(task, deadline, priority); // Dodanie zadania do bazy danych
|
||||
if (result) {
|
||||
removeExpiredTasks(); //Usuwanie przeterminowanych zadań
|
||||
loadTasks(); // Załadowanie zadań po dodaniu nowego
|
||||
}
|
||||
return result;
|
||||
@ -40,13 +38,8 @@ public class TaskViewModel extends AndroidViewModel {
|
||||
public boolean removeTask(String task) {
|
||||
boolean result = db.removeTask(task); // Usunięcie zadania z bazy danych
|
||||
if (result) {
|
||||
removeExpiredTasks(); //Usuwanie przeterminowanych zadań
|
||||
loadTasks(); // Załadowanie zadań po usunięciu
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void removeExpiredTasks() {
|
||||
db.removeExpiredTasks(); //Usunięcie przeterminowanych zadań z bazy danych
|
||||
}
|
||||
}
|
||||
|
@ -67,21 +67,21 @@
|
||||
android:hint="Enter Task"/>
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ADD"
|
||||
android:layout_marginBottom="24dp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button_view_html"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="View Tasks in HTML"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="View Tasks in HTML"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="ADD"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
|
5
ToDoApp/app/src/main/res/values/twilio_config.xml
Normal file
5
ToDoApp/app/src/main/res/values/twilio_config.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<resources>
|
||||
<string name="twilio_account_sid">AC55868eabe6daa1aabfe8805d8e04dc5b</string>
|
||||
<string name="twilio_auth_token">7d117e67f36da055f2f424645ae8bdcd</string>
|
||||
<string name="twilio_phone_number">+17752640737</string>
|
||||
</resources>
|
@ -7,6 +7,7 @@ appcompat = "1.7.0"
|
||||
material = "1.12.0"
|
||||
activity = "1.9.0"
|
||||
constraintlayout = "2.1.4"
|
||||
workRuntime = "2.9.0"
|
||||
|
||||
|
||||
[libraries]
|
||||
@ -17,6 +18,7 @@ appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "a
|
||||
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
||||
activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
|
||||
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
||||
work-runtime = { group = "androidx.work", name = "work-runtime", version.ref = "workRuntime" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
|
Loading…
Reference in New Issue
Block a user