Page 7 Stage 1

This commit is contained in:
icewithcola 2024-07-20 23:30:49 +08:00
parent ed4a63ff0b
commit da8d47f2b2
38 changed files with 631 additions and 475 deletions

View file

@ -74,6 +74,7 @@ dependencies {
implementation(libs.androidx.lifecycle.viewmodel.ktx) implementation(libs.androidx.lifecycle.viewmodel.ktx)
implementation(libs.androidx.datastore.rxjava3) implementation(libs.androidx.datastore.rxjava3)
implementation(libs.androidx.datastore.preferences) implementation(libs.androidx.datastore.preferences)
implementation(libs.androidx.work)
testImplementation(libs.junit) testImplementation(libs.junit)
@ -85,4 +86,7 @@ dependencies {
debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest) debugImplementation(libs.androidx.ui.test.manifest)
implementation(libs.moshi)
implementation(libs.okhttp3)
} }

View file

@ -4,6 +4,7 @@
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.INTERNET" />
<application <application
android:allowBackup="true" android:allowBackup="true"
@ -12,8 +13,10 @@
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="false"
android:theme="@style/Theme.Android101"> android:theme="@style/Theme.Android101"
android:usesCleartextTraffic="true"
>
<activity <activity
android:name=".Page7" android:name=".Page7"
android:exported="false" android:exported="false"

View file

@ -61,6 +61,7 @@ public class AnimalDatabaseHelper extends SQLiteOpenHelper {
return false; // Name already exists return false; // Name already exists
} }
} }
// Method to clear the table // Method to clear the table
public void clearTable() { public void clearTable() {
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();

View file

@ -1,6 +1,10 @@
package uk.kagurach.android101 package uk.kagurach.android101
import android.os.Bundle import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
@ -11,4 +15,20 @@ open class KaBaseActivity : AppCompatActivity() {
val storage = SettingStorage(this) val storage = SettingStorage(this)
this.setTheme(runBlocking { storage.getDefaultTheme() }) this.setTheme(runBlocking { storage.getDefaultTheme() })
} }
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
if (currentFocus != null) {
// If the Setting float window shows, do nothing
val fl = findViewById<FrameLayout>(R.id.P2SettingPage)
if (fl != null) {
if (fl.visibility == View.VISIBLE) {
return super.dispatchTouchEvent(ev)
}
}
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(currentFocus!!.windowToken, 0)
}
return super.dispatchTouchEvent(ev)
}
} }

View file

@ -16,7 +16,6 @@ import android.widget.TextView;
import androidx.activity.EdgeToEdge; import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets; import androidx.core.graphics.Insets;
@ -129,7 +128,7 @@ public class MainActivity extends KaBaseActivity {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
Intent intent = new Intent(v.getContext(),SettingPage.class); Intent intent = new Intent(v.getContext(), SettingPage.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent); startActivity(intent);
finish(); finish();

View file

@ -5,7 +5,6 @@ import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
@ -16,7 +15,6 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.activity.EdgeToEdge; import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets; import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat;
@ -30,7 +28,7 @@ public class MainActivity2 extends KaBaseActivity {
PageHelper pageHelper; PageHelper pageHelper;
int _text_size = 70; int _text_size = 70;
int _text_color = Color.rgb(0,0,0); int _text_color = Color.rgb(0, 0, 0);
String _text_unit = "sp"; String _text_unit = "sp";
@Override @Override
@ -158,10 +156,10 @@ public class MainActivity2 extends KaBaseActivity {
} }
private void updateCurrentSettingShower(){ private void updateCurrentSettingShower() {
TextView tv = findViewById(R.id.P2SettingResult); TextView tv = findViewById(R.id.P2SettingResult);
String sb = "Color = " + String sb = "Color = " +
new ColorHelper().toString(_text_color,"#",false) + new ColorHelper().toString(_text_color, "#", false) +
"; TextSize = " + "; TextSize = " +
_text_size + _text_size +
"." + "." +
@ -169,7 +167,7 @@ public class MainActivity2 extends KaBaseActivity {
tv.setText(sb); tv.setText(sb);
} }
class SettingButtonHandler implements View.OnClickListener{ class SettingButtonHandler implements View.OnClickListener {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
FrameLayout fl = findViewById(R.id.P2SettingPage); FrameLayout fl = findViewById(R.id.P2SettingPage);
@ -182,7 +180,7 @@ public class MainActivity2 extends KaBaseActivity {
} }
} }
class CloseSettingButtonHandler implements View.OnClickListener{ class CloseSettingButtonHandler implements View.OnClickListener {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
FrameLayout fl = findViewById(R.id.P2SettingPage); FrameLayout fl = findViewById(R.id.P2SettingPage);
@ -197,7 +195,7 @@ public class MainActivity2 extends KaBaseActivity {
} }
} }
class TestColorButtonHandler implements View.OnClickListener{ class TestColorButtonHandler implements View.OnClickListener {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
ImageView imageView = findViewById(R.id.P2ColorShower); ImageView imageView = findViewById(R.id.P2ColorShower);
@ -213,8 +211,8 @@ public class MainActivity2 extends KaBaseActivity {
g_edit.getText().toString().isEmpty() || g_edit.getText().toString().isEmpty() ||
b_edit.getText().toString().isEmpty()) { b_edit.getText().toString().isEmpty()) {
ToastHelper.SmartToast.ShowToast(""" ToastHelper.SmartToast.ShowToast("""
Please input R,G,B within 0-255 Please input R,G,B within 0-255
请在大小选择下方输入0-255的RGB""", 请在大小选择下方输入0-255的RGB""",
v.getContext()); v.getContext());
} }
@ -235,23 +233,5 @@ public class MainActivity2 extends KaBaseActivity {
} }
} }
} }
// Fix: hide keyboard
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (getCurrentFocus() != null) {
// If the Setting float window shows, do nothing
FrameLayout fl = findViewById(R.id.P2SettingPage);
if (fl!=null){
if (fl.getVisibility() == View.VISIBLE){
return super.dispatchTouchEvent(ev);
}
}
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
return super.dispatchTouchEvent(ev);
}
} }

View file

@ -9,7 +9,6 @@ import android.widget.TextView;
import androidx.activity.EdgeToEdge; import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets; import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat;

View file

@ -1,12 +1,9 @@
package uk.kagurach.android101; package uk.kagurach.android101;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
@ -14,7 +11,6 @@ import android.widget.TextView;
import androidx.activity.EdgeToEdge; import androidx.activity.EdgeToEdge;
import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts; import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets; import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat;
@ -80,15 +76,6 @@ public class Page4 extends KaBaseActivity {
mLauncher.launch(intent); mLauncher.launch(intent);
} }
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (getCurrentFocus() != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
return super.dispatchTouchEvent(ev);
}
private final class ButtonHandler implements View.OnClickListener { private final class ButtonHandler implements View.OnClickListener {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -101,7 +88,7 @@ public class Page4 extends KaBaseActivity {
public void onClick(View v) { public void onClick(View v) {
String receivierPath = "uk.kagurach.android101.vibrationBroadcastReceiver.vibrationBroadcastReceiver"; String receivierPath = "uk.kagurach.android101.vibrationBroadcastReceiver.vibrationBroadcastReceiver";
Intent intent = new Intent(vibrationBroadcastReceiver.VIBRATION_ACTION_NAME); Intent intent = new Intent(vibrationBroadcastReceiver.VIBRATION_ACTION_NAME);
ComponentName componentName = new ComponentName("uk.kagurach.android101",receivierPath); ComponentName componentName = new ComponentName("uk.kagurach.android101", receivierPath);
intent.setComponent(componentName); intent.setComponent(componentName);
sendBroadcast(intent); sendBroadcast(intent);
} }

View file

@ -1,18 +1,14 @@
package uk.kagurach.android101; package uk.kagurach.android101;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AutoCompleteTextView; import android.widget.AutoCompleteTextView;
import android.widget.Button; import android.widget.Button;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.activity.EdgeToEdge; import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets; import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat;
@ -21,15 +17,16 @@ import java.io.IOException;
import java.util.Objects; import java.util.Objects;
import chatgpt.AnimalDatabaseHelper; import chatgpt.AnimalDatabaseHelper;
import uk.kagurach.android101.helper.AutoCompleHelper.AnimalTypeAutoCompleteHelper;
import uk.kagurach.android101.helper.PageHelper; import uk.kagurach.android101.helper.PageHelper;
import uk.kagurach.android101.helper.ToastHelper; import uk.kagurach.android101.helper.ToastHelper;
import uk.kagurach.android101.helper.AutoCompleHelper.AnimalTypeAutoCompleteHelper;
public class Page5 extends KaBaseActivity { public class Page5 extends KaBaseActivity {
AnimalTypeAutoCompleteHelper completeHelper = null;
final AnimalDatabaseHelper dbHelper = new AnimalDatabaseHelper(this); final AnimalDatabaseHelper dbHelper = new AnimalDatabaseHelper(this);
AnimalTypeAutoCompleteHelper completeHelper = null;
PageHelper pageHelper; PageHelper pageHelper;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -41,7 +38,7 @@ public class Page5 extends KaBaseActivity {
return insets; return insets;
}); });
pageHelper = new PageHelper(this, Page4.class,Page6.class); pageHelper = new PageHelper(this, Page4.class, Page6.class);
// Set auto-suggestions for animals // Set auto-suggestions for animals
AutoCompleteTextView autoCompleteTextView = findViewById(R.id.AnimalTypeAutoCompleteInput); AutoCompleteTextView autoCompleteTextView = findViewById(R.id.AnimalTypeAutoCompleteInput);
@ -50,9 +47,9 @@ public class Page5 extends KaBaseActivity {
completeHelper.Load(); completeHelper.Load();
autoCompleteTextView.setAdapter( autoCompleteTextView.setAdapter(
completeHelper.GetArrayAdapter( completeHelper.GetArrayAdapter(
this,android.R.layout.simple_list_item_1 this, android.R.layout.simple_list_item_1
)); ));
} catch (IOException e){ } catch (IOException e) {
Log.e("P5IOException", Objects.requireNonNull(e.getMessage())); Log.e("P5IOException", Objects.requireNonNull(e.getMessage()));
} }
@ -83,18 +80,18 @@ public class Page5 extends KaBaseActivity {
String animal_name = name.getText().toString(); String animal_name = name.getText().toString();
String animal_type = type.getText().toString(); String animal_type = type.getText().toString();
if (animal_name.isEmpty()||animal_type.isEmpty()){ if (animal_name.isEmpty() || animal_type.isEmpty()) {
ToastHelper.SmartToast.ShowToast("Please input all fields",v.getContext()); ToastHelper.SmartToast.ShowToast("Please input all fields", v.getContext());
return; return;
} }
// Add to database // Add to database
if (dbHelper.insertAnimalData(animal_name, animal_type.replace(" ","_"))) { if (dbHelper.insertAnimalData(animal_name, animal_type.replace(" ", "_"))) {
// Insert was successful // Insert was successful
ToastHelper.SmartToast.ShowToast( "Animal added successfully!",v.getContext()); ToastHelper.SmartToast.ShowToast("Animal added successfully!", v.getContext());
} else { } else {
// Name already exists // Name already exists
ToastHelper.SmartToast.ShowToast( "Animal with this name already exists!",v.getContext()); ToastHelper.SmartToast.ShowToast("Animal with this name already exists!", v.getContext());
return; return;
} }
try { try {
@ -109,9 +106,9 @@ public class Page5 extends KaBaseActivity {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
type.setAdapter( type.setAdapter(
completeHelper.GetArrayAdapter( completeHelper.GetArrayAdapter(
v.getContext(),android.R.layout.simple_list_item_1 v.getContext(), android.R.layout.simple_list_item_1
)); ));
} }
} }
@ -126,18 +123,18 @@ public class Page5 extends KaBaseActivity {
} }
_a.setAdapter( _a.setAdapter(
completeHelper.GetArrayAdapter( completeHelper.GetArrayAdapter(
v.getContext(),android.R.layout.simple_list_item_1 v.getContext(), android.R.layout.simple_list_item_1
)); ));
ToastHelper.SmartToast.ShowToast("Cleaned Data",v.getContext()); ToastHelper.SmartToast.ShowToast("Cleaned Data", v.getContext());
// Clean DataBase // Clean DataBase
dbHelper.clearTable(); dbHelper.clearTable();
ToastHelper.SmartToast.ShowToast("Cleaned Database",v.getContext()); ToastHelper.SmartToast.ShowToast("Cleaned Database", v.getContext());
return true; return true;
} }
} }
class P5CloseQueryButtonHandler implements View.OnClickListener{ class P5CloseQueryButtonHandler implements View.OnClickListener {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -146,11 +143,11 @@ public class Page5 extends KaBaseActivity {
} }
} }
class QueryButtonHandler implements View.OnClickListener{ class QueryButtonHandler implements View.OnClickListener {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
String res = dbHelper.getAllDataAsString(); String res = dbHelper.getAllDataAsString();
if (res.isEmpty()){ if (res.isEmpty()) {
res = "No animals qwq"; res = "No animals qwq";
} }
TextView tv = findViewById(R.id.P5QueryResult); TextView tv = findViewById(R.id.P5QueryResult);
@ -159,15 +156,5 @@ public class Page5 extends KaBaseActivity {
fl.setVisibility(View.VISIBLE); fl.setVisibility(View.VISIBLE);
} }
} }
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (getCurrentFocus() != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
return super.dispatchTouchEvent(ev);
}
} }

View file

@ -13,22 +13,29 @@ import android.widget.Button
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.ui.platform.ComposeView
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.viewpager.widget.PagerAdapter import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import androidx.viewpager.widget.ViewPager.LayoutParams import androidx.viewpager.widget.ViewPager.LayoutParams
import androidx.viewpager.widget.ViewPager.OnPageChangeListener import androidx.viewpager.widget.ViewPager.OnPageChangeListener
import androidx.work.Constraints
import androidx.work.Data
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.Worker
import androidx.work.WorkerParameters
import uk.kagurach.android101.helper.PageHelper import uk.kagurach.android101.helper.PageHelper
import uk.kagurach.android101.helper.ToastHelper import uk.kagurach.android101.helper.ToastHelper
import kotlin.random.Random
class Page6 : KaBaseActivity(), OnPageChangeListener, OnClickListener { class Page6 : KaBaseActivity(), OnPageChangeListener, OnClickListener {
class Item(val name: String,val pic: Bitmap) class Item(val name: String, val pic: Bitmap)
private var mItemList : ArrayList<Item> = arrayListOf() private var mItemList: ArrayList<Item> = arrayListOf()
val pageHelper = PageHelper(this, Page5::class.java, null) val pageHelper = PageHelper(this, Page5::class.java, Page7::class.java)
lateinit var pager : ViewPager lateinit var pager: ViewPager
lateinit var idShower: TextView lateinit var idShower: TextView
@ -43,12 +50,12 @@ class Page6 : KaBaseActivity(), OnPageChangeListener, OnClickListener {
} }
val am = assets val am = assets
for (i in 1..4){ for (i in 1..4) {
val item = Item(i.toString(), BitmapFactory.decodeStream(am.open("CatPics/${i}.jpeg"))) val item = Item(i.toString(), BitmapFactory.decodeStream(am.open("CatPics/${i}.jpeg")))
mItemList.add(item) mItemList.add(item)
} }
val adapter = Page6CatPics(this,mItemList) val adapter = Page6CatPics(this, mItemList)
pager = findViewById<ViewPager>(R.id.P6_vp_content) pager = findViewById<ViewPager>(R.id.P6_vp_content)
pager.adapter = adapter pager.adapter = adapter
pager.currentItem = 0 pager.currentItem = 0
@ -60,13 +67,15 @@ class Page6 : KaBaseActivity(), OnPageChangeListener, OnClickListener {
findViewById<Button>(R.id.P6AutoButton).setOnClickListener(this) findViewById<Button>(R.id.P6AutoButton).setOnClickListener(this)
idShower = findViewById(R.id.P6IdShower) idShower = findViewById(R.id.P6IdShower)
idShower.setText(resources.getString(R.string.neko_no_d,0)) idShower.setText(resources.getString(R.string.neko_no_d, 0))
findViewById<Button>(R.id.P6SetWorkButton).setOnClickListener(Page6WorkerButton())
} }
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
override fun onPageSelected(position: Int) { override fun onPageSelected(position: Int) {
idShower.setText(resources.getString(R.string.neko_no_d,position)) idShower.setText(resources.getString(R.string.neko_no_d, position))
} }
override fun onPageScrollStateChanged(state: Int) {} override fun onPageScrollStateChanged(state: Int) {}
@ -76,18 +85,18 @@ class Page6 : KaBaseActivity(), OnPageChangeListener, OnClickListener {
val mHandler = Handler(Looper.getMainLooper()) val mHandler = Handler(Looper.getMainLooper())
val mTimer: Runnable = Runnable { val mTimer: Runnable = Runnable {
run { run {
pager.setCurrentItem((pager.currentItem+1)%mItemList.size) pager.setCurrentItem((pager.currentItem + 1) % mItemList.size)
mHandler.postDelayed(mTimer,3000) mHandler.postDelayed(mTimer, 3000)
} }
} }
override fun onClick(v: View?) { override fun onClick(v: View?) {
isStarted = !isStarted isStarted = !isStarted
val button = findViewById<Button>(R.id.P6AutoButton) val button = findViewById<Button>(R.id.P6AutoButton)
if (isStarted){ if (isStarted) {
mHandler.post(mTimer) mHandler.post(mTimer)
button.setText("Stop") button.setText("Stop")
}else{ } else {
mHandler.removeCallbacks(mTimer) mHandler.removeCallbacks(mTimer)
button.setText(R.string.auto_show) button.setText(R.string.auto_show)
} }
@ -99,19 +108,22 @@ class Page6 : KaBaseActivity(), OnPageChangeListener, OnClickListener {
} }
} }
class Page6CatPics(ctx: Context,lst: List<Page6.Item>) : PagerAdapter() { class Page6CatPics(ctx: Context, lst: List<Page6.Item>) : PagerAdapter() {
private var mViewList : ArrayList<ImageView> = arrayListOf() private var mViewList: ArrayList<ImageView> = arrayListOf()
init{ init {
for (item in lst) { for (item in lst) {
val view = ImageView(ctx) val view = ImageView(ctx)
view.setImageBitmap(item.pic) view.setImageBitmap(item.pic)
view.setLayoutParams(ViewGroup.LayoutParams( view.setLayoutParams(
LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT ViewGroup.LayoutParams(
)) LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT
)
)
mViewList.add(view) mViewList.add(view)
} }
} }
override fun getCount(): Int { override fun getCount(): Int {
return mViewList.size return mViewList.size
} }
@ -130,3 +142,45 @@ class Page6CatPics(ctx: Context,lst: List<Page6.Item>) : PagerAdapter() {
} }
} }
class Page6Worker(context: Context, val workerParams: WorkerParameters) :
Worker(context, workerParams) {
override fun doWork(): Result {
val mInputData = workerParams.inputData
val randomInt = mInputData.getInt("rndResult", -1)
return Result.success(
Data.Builder()
.putInt("resultCode", 0)
.putString("data", "收到数据:${randomInt}")
.putBoolean("isValid", randomInt == -1)
.build()
)
}
}
class Page6WorkerButton : OnClickListener {
override fun onClick(v: View) {
val workTag = "OnceWork"
val onceRequest = OneTimeWorkRequestBuilder<Page6Worker>()
.addTag(workTag)
.setConstraints(
Constraints.Builder()
.setRequiresBatteryNotLow(true)
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
.setInputData(
Data.Builder()
.putInt("rndResult", Random.nextInt(0, 100))
.build()
)
.build()
val workId = onceRequest.id
val workManager = WorkManager.getInstance(v.context)
workManager.enqueue(onceRequest)
ToastHelper.ShowToast("Work: ${workId}", v.context)
}
}

View file

@ -1,35 +1,196 @@
package uk.kagurach.android101 package uk.kagurach.android101
import android.app.Activity
import android.content.Context
import android.os.Bundle import android.os.Bundle
import com.google.android.material.bottomnavigation.BottomNavigationView import android.util.Log
import androidx.appcompat.app.AppCompatActivity import android.view.View
import androidx.navigation.findNavController import android.view.View.GONE
import androidx.navigation.ui.AppBarConfiguration import android.view.View.OnClickListener
import androidx.navigation.ui.setupActionBarWithNavController import android.view.View.VISIBLE
import androidx.navigation.ui.setupWithNavController import android.widget.Button
import uk.kagurach.android101.databinding.ActivityPage7Binding import android.widget.EditText
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.TextView
import androidx.activity.enableEdgeToEdge
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import uk.kagurach.android101.helper.ToastHelper
import java.io.IOException
class Page7 : AppCompatActivity() { val Context.tgDatastore by preferencesDataStore(name = "tg_settings")
val DefaultAPI = stringPreferencesKey("default_api")
private lateinit var binding: ActivityPage7Binding val DefaultID = stringPreferencesKey("default_id")
class Page7 : KaBaseActivity() {
lateinit var storage: TGStorage
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_page7)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
storage = TGStorage(this)
binding = ActivityPage7Binding.inflate(layoutInflater) findViewById<Button>(R.id.P7SendMessageButton).setOnClickListener(ButtonHandler(this))
setContentView(binding.root) findViewById<Button>(R.id.P7SaveAndSetAPI).setOnClickListener(ButtonHandler(this))
val navView: BottomNavigationView = binding.navView findViewById<EditText>(R.id.Page7BotID).setText(runBlocking { storage.getDefaultAPI() })
findViewById<EditText>(R.id.Page7ChatID).setText(runBlocking { storage.getDefaultID() })
val navController = findNavController(R.id.nav_host_fragment_activity_page7) findViewById<Button>(R.id.P7ShowResult).setOnClickListener(FrameButtonHandler())
// Passing each menu ID as a set of Ids because each findViewById<Button>(R.id.P7SetAPI).setOnClickListener(FrameButtonHandler())
// menu should be considered as top level destinations. findViewById<ImageButton>(R.id.P7CloseResultButton).setOnClickListener(FrameButtonHandler())
val appBarConfiguration = AppBarConfiguration( findViewById<ImageButton>(R.id.P7CloseAPIButton).setOnClickListener(FrameButtonHandler())
setOf( }
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
inner class ButtonHandler(val activity: Activity) : OnClickListener {
override fun onClick(v: View) {
val botAPI = activity.findViewById<EditText>(R.id.Page7BotID).text.toString()
val chatID = activity.findViewById<EditText>(R.id.Page7ChatID).text.toString()
val tgHandler = telegramHandler(botAPI, chatID)
val resultTextField = activity.findViewById<TextView>(R.id.P7Result)
// Validate
if (botAPI.isBlank() || (chatID.isBlank() && v.id != R.id.P7SaveAndSetAPI)) {
ToastHelper.ShowToast(getText(R.string.require_api).toString(), baseContext)
}
when (v.id) {
R.id.P7SaveAndSetAPI -> { // 测试并保存API
tgHandler.testSelf { result ->
if (result.contains("""{"ok":true}""")) {
runBlocking { // 成功
storage.setDefaultAPI(botAPI)
storage.setDefaultID(chatID)
}
ToastHelper.ShowToast("OK", baseContext)
}
runOnUiThread {
resultTextField.text = result
}
}
}
R.id.P7SendMessageButton -> { // 发送文本
tgHandler.postText(
activity.findViewById<EditText>(R.id.P7SendMessageText).text.toString()
) { result ->
runOnUiThread {
resultTextField.text = result
}
}
}
else -> resultTextField.text = "?"
}
}
}
inner class FrameButtonHandler : OnClickListener {
override fun onClick(v: View) {
val frame = findViewById<FrameLayout>(
when (v.id) {
R.id.P7ShowResult, R.id.P7CloseResultButton -> R.id.P7ResultFrame
R.id.P7SetAPI, R.id.P7CloseAPIButton -> R.id.P7SetAPIFrame
else -> throw RuntimeException("Invalid Button")
}
) )
) frame.visibility = when (frame.visibility) {
setupActionBarWithNavController(navController, appBarConfiguration) VISIBLE -> GONE
navView.setupWithNavController(navController) else -> VISIBLE
}
}
}
}
class telegramHandler(val BOT_KEY: String, val CHATID: String) {
val client = OkHttpClient()
val basicUri = "https://api.telegram.org/bot${BOT_KEY}"
fun testSelf(callBack: (String) -> Unit) {
val api = "getMe"
val finalUri = "${basicUri}/${api}"
postData(finalUri, callBack)
}
fun postText(text: String, callBack: (String) -> Unit) {
if (text.isEmpty()) {
callBack("Input Something!!")
}
val api = "sendMessage"
val finalUri = "${basicUri}/${api}?chat_id=${CHATID}&text=${text}"
postData(finalUri, callBack)
}
private fun postData(finalUri: String, callBack: (String) -> Unit) {
val request = Request.Builder().url(finalUri).post("".toRequestBody()).build()
val call = client.newCall(request)
call.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
Log.e("TgHelper", e.printStackTrace().toString())
callBack("${e.printStackTrace()}")
}
override fun onResponse(call: Call, response: Response) {
val responseCode = response.code
val responseBody = response.body?.string()
callBack("${responseCode},${responseBody}")
}
})
}
}
class TGStorage(val context: Context) {
suspend fun getDefaultAPI(): String {
return getDefaultAPIFlow.first()
}
suspend fun setDefaultAPI(newValue: String) {
context.tgDatastore.edit { preferences ->
preferences[DefaultAPI] = newValue
}
}
private val getDefaultAPIFlow: Flow<String> = context.tgDatastore.data.map { preferences ->
preferences[DefaultAPI] ?: ""
}
suspend fun getDefaultID(): String {
return getDefaultIDFlow.first()
}
suspend fun setDefaultID(newValue: String) {
context.tgDatastore.edit { preferences ->
preferences[DefaultID] = newValue
}
}
private val getDefaultIDFlow: Flow<String> = context.tgDatastore.data.map { preferences ->
preferences[DefaultID] ?: ""
} }
} }

View file

@ -40,34 +40,36 @@ class SettingPage : KaBaseActivity() {
} }
inner class SetColorHandler: View.OnClickListener { inner class SetColorHandler : View.OnClickListener {
override fun onClick(v: View?) { override fun onClick(v: View?) {
if (v == null){ if (v == null) {
return return
} }
val colorTheme = when(v.id){ val colorTheme = when (v.id) {
R.id.ThemeBlue -> R.style.Theme_Blue R.id.ThemeBlue -> R.style.Theme_Blue
R.id.ThemeGreen -> R.style.Theme_Green R.id.ThemeGreen -> R.style.Theme_Green
R.id.ThemeRed -> R.style.Theme_Red R.id.ThemeRed -> R.style.Theme_Red
R.id.ThemeCyan -> R.style.Theme_Cyan R.id.ThemeCyan -> R.style.Theme_Cyan
R.id.ThemePink -> R.style.Theme_Pink R.id.ThemePink -> R.style.Theme_Pink
else -> {throw RuntimeException("Impossible branch met!")} else -> {
throw RuntimeException("Impossible branch met!")
}
} }
runBlocking { runBlocking {
settingStorage.setDefaultTheme(colorTheme) settingStorage.setDefaultTheme(colorTheme)
} }
val intent = Intent(v.context,this@SettingPage::class.java) val intent = Intent(v.context, this@SettingPage::class.java)
startActivity(intent) startActivity(intent)
finish() finish()
} }
} }
inner class FinishButtonHandler: View.OnClickListener{ inner class FinishButtonHandler : View.OnClickListener {
override fun onClick(v: View?) { override fun onClick(v: View?) {
val intent = Intent(v!!.context,MainActivity::class.java) val intent = Intent(v!!.context, MainActivity::class.java)
startActivity(intent) startActivity(intent)
finish() finish()
} }

View file

@ -11,9 +11,9 @@ class SettingStorage(val context: Context) {
suspend fun getDefaultTheme(): Int { suspend fun getDefaultTheme(): Int {
return getDefaultColorFlow.first() return getDefaultColorFlow.first()
} }
suspend fun setDefaultTheme(newValue: Int) { suspend fun setDefaultTheme(newValue: Int) {
context.datastore.edit { context.datastore.edit { preferences ->
preferences ->
preferences[DefaultColor] = newValue preferences[DefaultColor] = newValue
} }
} }
@ -21,8 +21,7 @@ class SettingStorage(val context: Context) {
private val getDefaultColorFlow: Flow<Int> = private val getDefaultColorFlow: Flow<Int> =
context.datastore.data context.datastore.data
.map { .map { preferences ->
preferences ->
preferences[DefaultColor] ?: R.id.ThemeBlue preferences[DefaultColor] ?: R.id.ThemeBlue
} }
} }

View file

@ -15,21 +15,23 @@ import java.util.Scanner;
import java.util.Set; import java.util.Set;
public abstract class AbstractAutoCompleteHelper { public abstract class AbstractAutoCompleteHelper {
List<String> data = null;
public String dataFile = null; public String dataFile = null;
List<String> data = null;
boolean loaded = false; boolean loaded = false;
abstract void AddEntry(String name) throws IOException; abstract void AddEntry(String name) throws IOException;
abstract void DeleteEntry(String name); abstract void DeleteEntry(String name);
public void Load() throws IOException { public void Load() throws IOException {
if (dataFile==null){ if (dataFile == null) {
throw new RuntimeException("dataFile not specified"); throw new RuntimeException("dataFile not specified");
} }
File _data = new File(dataFile); File _data = new File(dataFile);
if (!_data.isFile()){ if (!_data.isFile()) {
_data.createNewFile(); _data.createNewFile();
} }
if (!_data.canRead() || !_data.canWrite()){ if (!_data.canRead() || !_data.canWrite()) {
throw new RuntimeException("File permission denied"); throw new RuntimeException("File permission denied");
} }
loaded = true; loaded = true;
@ -37,8 +39,8 @@ public abstract class AbstractAutoCompleteHelper {
if (data == null) { if (data == null) {
data = new ArrayList<>(); data = new ArrayList<>();
}else { } else {
while (scanner.hasNextLine()){ while (scanner.hasNextLine()) {
data.add(scanner.nextLine()); data.add(scanner.nextLine());
} }
// 去重 // 去重
@ -46,27 +48,27 @@ public abstract class AbstractAutoCompleteHelper {
data = new ArrayList<>(set); data = new ArrayList<>(set);
} }
} }
public void Sync() throws IOException { public void Sync() throws IOException {
if (dataFile==null){ if (dataFile == null) {
throw new RuntimeException("dataFile not specified"); throw new RuntimeException("dataFile not specified");
} }
File _data = new File(dataFile); File _data = new File(dataFile);
if (!_data.isFile()){ if (!_data.isFile()) {
_data.createNewFile(); _data.createNewFile();
} }
if (!_data.canRead() || !_data.canWrite()){ if (!_data.canRead() || !_data.canWrite()) {
throw new RuntimeException("File permission denied"); throw new RuntimeException("File permission denied");
} }
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
for (String name:data) { for (String name : data) {
stringBuilder.append(name); stringBuilder.append(name);
stringBuilder.append('\n'); stringBuilder.append('\n');
} }
try (FileWriter fileWriter = new FileWriter(_data,false)) { try (FileWriter fileWriter = new FileWriter(_data, false)) {
fileWriter.write(stringBuilder.toString()); fileWriter.write(stringBuilder.toString());
} } catch (IOException e) {
catch (IOException e){
throw new IOException(e); throw new IOException(e);
} }
} }
@ -75,17 +77,17 @@ public abstract class AbstractAutoCompleteHelper {
Context ctx, @LayoutRes int resource); Context ctx, @LayoutRes int resource);
public void Clean() throws IOException { public void Clean() throws IOException {
if (dataFile!=null){ if (dataFile != null) {
File _data = new File(dataFile); File _data = new File(dataFile);
if (!_data.isFile()){ if (!_data.isFile()) {
_data.createNewFile(); _data.createNewFile();
} }
if (!_data.canRead() || !_data.canWrite()){ if (!_data.canRead() || !_data.canWrite()) {
throw new RuntimeException("File permission denied"); throw new RuntimeException("File permission denied");
} }
try (FileWriter fileWriter = new FileWriter(_data,false)) { try (FileWriter fileWriter = new FileWriter(_data, false)) {
fileWriter.write(""); fileWriter.write("");
}catch (IOException e){ } catch (IOException e) {
throw new IOException(e); throw new IOException(e);
} }
} }

View file

@ -17,11 +17,11 @@ public class AnimalTypeAutoCompleteHelper extends AbstractAutoCompleteHelper {
@Override @Override
public void AddEntry(String name) throws IOException { public void AddEntry(String name) throws IOException {
if (!loaded){ if (!loaded) {
throw new RuntimeException("Haven't loaded"); throw new RuntimeException("Haven't loaded");
} }
name = name.replace(" ","_"); name = name.replace(" ", "_");
if (data.contains(name)){ if (data.contains(name)) {
return; return;
} }
data.add(name); data.add(name);
@ -38,8 +38,8 @@ public class AnimalTypeAutoCompleteHelper extends AbstractAutoCompleteHelper {
Context ctx, @LayoutRes int resource) { Context ctx, @LayoutRes int resource) {
if (data == null) { if (data == null) {
return new ArrayAdapter<>(ctx, resource, return new ArrayAdapter<>(ctx, resource,
new String[]{ new String[]{
"cat","dog","喵喵" "cat", "dog", "喵喵"
} }
); );
} }

View file

@ -1,7 +1,6 @@
package uk.kagurach.android101.helper package uk.kagurach.android101.helper
import android.graphics.Color import android.graphics.Color
import androidx.compose.ui.util.fastJoinToString
class ColorHelper { class ColorHelper {
fun toColorInt(r: Int, g: Int, b: Int): Int { fun toColorInt(r: Int, g: Int, b: Int): Int {
@ -15,8 +14,11 @@ class ColorHelper {
fun toString(colorInt: Int, start: String = "#", upperCase: Boolean = false): String { fun toString(colorInt: Int, start: String = "#", upperCase: Boolean = false): String {
val colorInt = colorInt.and(0xffffff) // Keep only low six digit val colorInt = colorInt.and(0xffffff) // Keep only low six digit
val colorString = colorInt.toHexString( val colorString = colorInt.toHexString(
if (upperCase) { HexFormat.UpperCase } if (upperCase) {
else{ HexFormat.Default } HexFormat.UpperCase
} else {
HexFormat.Default
}
).drop(2) ).drop(2)
return "$start$colorString" return "$start$colorString"
} }

View file

@ -30,7 +30,7 @@ public class PageHelper {
_activity = activity; _activity = activity;
} }
void goPrev(){// Keep no parameter signature void goPrev() {// Keep no parameter signature
goPrev(true); goPrev(true);
} }
@ -48,6 +48,7 @@ public class PageHelper {
void goNext() { void goNext() {
goNext(true); goNext(true);
} }
void goNext(boolean keepOneInstance) { void goNext(boolean keepOneInstance) {
if (_next == null) { if (_next == null) {
return; return;

View file

@ -42,10 +42,10 @@ fun AIAnswerService(s: String): String {
} }
result = result.replace( result = result.replace(
"","" "", ""
) )
result = result.replace( result = result.replace(
"要要","" "要要", ""
) )
result = result.replace( result = result.replace(
"", "",

View file

@ -16,9 +16,9 @@ fun Kaculate(src: String, ctx: Context): String {
var _curnum = "" var _curnum = ""
// Fix for expression starts with operator // Fix for expression starts with operator
val src = if (src[0] in opList){ val src = if (src[0] in opList) {
"0$src" "0$src"
}else{ } else {
src src
} }
@ -69,8 +69,8 @@ fun Kaculate(src: String, ctx: Context): String {
numStack = dropAtIdx(numStack, intStackCurr + 1) numStack = dropAtIdx(numStack, intStackCurr + 1)
} }
var tmpStack = charArrayOf() var tmpStack = charArrayOf()
for(i in opStack){ for (i in opStack) {
if (i!='^'){ if (i != '^') {
tmpStack += i tmpStack += i
} }
} }

View file

@ -22,9 +22,9 @@ public class vibrationBroadcastReceiver extends BroadcastReceiver {
); );
vibrator.vibrate( vibrator.vibrate(
CombinedVibration.createParallel( CombinedVibration.createParallel(
VibrationEffect.createOneShot(1500,VibrationEffect.DEFAULT_AMPLITUDE) VibrationEffect.createOneShot(1500, VibrationEffect.DEFAULT_AMPLITUDE)
)); ));
Log.d("Debug","Vibrate!"); Log.d("Debug", "Vibrate!");
} }
} }
} }

View file

@ -1,42 +0,0 @@
package uk.kagurach.android101.ui.dashboard
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import uk.kagurach.android101.databinding.FragmentDashboardBinding
class DashboardFragment : Fragment() {
private var _binding: FragmentDashboardBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val dashboardViewModel =
ViewModelProvider(this).get(DashboardViewModel::class.java)
_binding = FragmentDashboardBinding.inflate(inflater, container, false)
val root: View = binding.root
val textView: TextView = binding.textDashboard
dashboardViewModel.text.observe(viewLifecycleOwner) {
textView.text = it
}
return root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View file

@ -1,13 +0,0 @@
package uk.kagurach.android101.ui.dashboard
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class DashboardViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is dashboard Fragment"
}
val text: LiveData<String> = _text
}

View file

@ -1,42 +0,0 @@
package uk.kagurach.android101.ui.home
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import uk.kagurach.android101.databinding.FragmentHomeBinding
class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val homeViewModel =
ViewModelProvider(this).get(HomeViewModel::class.java)
_binding = FragmentHomeBinding.inflate(inflater, container, false)
val root: View = binding.root
val textView: TextView = binding.textHome
homeViewModel.text.observe(viewLifecycleOwner) {
textView.text = it
}
return root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View file

@ -1,13 +0,0 @@
package uk.kagurach.android101.ui.home
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class HomeViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is home Fragment"
}
val text: LiveData<String> = _text
}

View file

@ -1,42 +0,0 @@
package uk.kagurach.android101.ui.notifications
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import uk.kagurach.android101.databinding.FragmentNotificationsBinding
class NotificationsFragment : Fragment() {
private var _binding: FragmentNotificationsBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val notificationsViewModel =
ViewModelProvider(this).get(NotificationsViewModel::class.java)
_binding = FragmentNotificationsBinding.inflate(inflater, container, false)
val root: View = binding.root
val textView: TextView = binding.textNotifications
notificationsViewModel.text.observe(viewLifecycleOwner) {
textView.text = it
}
return root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View file

@ -1,13 +0,0 @@
package uk.kagurach.android101.ui.notifications
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class NotificationsViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is notifications Fragment"
}
val text: LiveData<String> = _text
}

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFDE7" />
<corners android:radius="20dp" />
<padding android:left="20dp"
android:top="20dp"
android:right="20dp"
android:bottom="20dp"/>
<stroke android:color="#FFEB3B" android:width="3dp"/>
</shape>

View file

@ -39,6 +39,13 @@
android:layout_marginEnd="15dp" android:layout_marginEnd="15dp"
android:backgroundTint="?colorSecondary" android:backgroundTint="?colorSecondary"
android:text="@string/auto_show"/> android:text="@string/auto_show"/>
<Button
android:id="@+id/P6SetWorkButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="15dp"
android:backgroundTint="?colorTertiary"
android:text="@string/add_work"/>
<Button <Button
android:id="@+id/P6NextPage" android:id="@+id/P6NextPage"
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -1,33 +1,217 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize"> tools:context=".Page7">
<LinearLayout
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" />
<fragment
android:id="@+id/nav_host_fragment_activity_page7"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:defaultNavHost="true" android:layout_marginVertical="20dp"
app:layout_constraintBottom_toTopOf="@id/nav_view" android:layout_marginHorizontal="5dp"
app:layout_constraintLeft_toLeftOf="parent" android:orientation="vertical">
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" <LinearLayout
app:navGraph="@navigation/mobile_navigation" /> android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="5dp"
>
<EditText
android:id="@+id/P7SendMessageText"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:inputType="text"
android:text="Text Message"
android:hint="Text Message"
/>
<Button
android:id="@+id/P7SendMessageButton"
android:layout_width="80dp"
android:layout_height="match_parent"
android:text="send message"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="5dp"
>
<Button
android:id="@+id/P7SetAPI"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:text="@string/settings"
/>
<Button
android:id="@+id/P7ShowResult"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_marginHorizontal="15dp"
android:layout_height="match_parent"
android:textAllCaps="false"
android:text="@string/show_callback"
/>
<Button
android:id="@+id/P7NextPage"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:text="@string/next_page"
/>
</LinearLayout>
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/P7ResultFrame"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="25dp"
android:visibility="invisible"
android:background="@drawable/p7_result_layout"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="55dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginRight="15dp"
android:textSize="40sp"
android:text="@string/result"/>
<ImageButton
android:id="@+id/P7CloseResultButton"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:background="@drawable/close_24"
android:clickable="true"
android:contentDescription="@string/close" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginHorizontal="5dp">
<TextView
android:id="@+id/P7Result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="22sp"
android:fontFamily="monospace"
android:minHeight="50dp"
android:text=""/>
</ScrollView>
</LinearLayout>
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/P7SetAPIFrame"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="120dp"
android:background="@drawable/p7_result_layout"
android:visibility="invisible"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="55dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginRight="15dp"
android:textSize="40sp"
android:text="@string/settings"/>
<ImageButton
android:id="@+id/P7CloseAPIButton"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:background="@drawable/close_24"
android:clickable="true"
android:contentDescription="@string/close" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:layout_marginLeft="5dp"
android:text="@string/bot_api_key"/>
<EditText
android:id="@+id/Page7BotID"
android:layout_width="match_parent"
android:layout_height="60dp"
android:ems="10"
android:importantForAutofill="no"
android:inputType="textPassword"
android:layout_marginHorizontal="20dp"
android:layout_marginBottom="15dp"
android:hint="@string/test_api_key"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:textSize="30sp"
android:text="@string/chat_id"/>
<EditText
android:id="@+id/Page7ChatID"
android:layout_width="match_parent"
android:layout_height="60dp"
android:ems="10"
android:importantForAutofill="no"
android:inputType="numberSigned"
android:layout_marginHorizontal="20dp"
android:layout_marginBottom="15dp"
android:hint="@string/_123456"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:orientation="horizontal">
<Button
android:id="@+id/P7SaveAndSetAPI"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/save_and_test"
android:textAllCaps="false"
/>
</LinearLayout>
</LinearLayout>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,22 +0,0 @@
<?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=".ui.dashboard.DashboardFragment">
<TextView
android:id="@+id/text_dashboard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,22 +0,0 @@
<?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=".ui.home.HomeFragment">
<TextView
android:id="@+id/text_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,22 +0,0 @@
<?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=".ui.notifications.NotificationsFragment">
<TextView
android:id="@+id/text_notifications"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home" />
<item
android:id="@+id/navigation_dashboard"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_dashboard" />
<item
android:id="@+id/navigation_notifications"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/title_notifications" />
</menu>

View file

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/mobile_navigation"
app:startDestination="@+id/navigation_home">
<fragment
android:id="@+id/navigation_home"
android:name="uk.kagurach.android101.ui.home.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/navigation_dashboard"
android:name="uk.kagurach.android101.ui.dashboard.DashboardFragment"
android:label="@string/title_dashboard"
tools:layout="@layout/fragment_dashboard" />
<fragment
android:id="@+id/navigation_notifications"
android:name="uk.kagurach.android101.ui.notifications.NotificationsFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications" />
</navigation>

View file

@ -46,4 +46,17 @@
<string name="p2_default_setting">Color = #000000; TextSize = 70.sp</string> <string name="p2_default_setting">Color = #000000; TextSize = 70.sp</string>
<string name="set_default_theme">设置默认主题</string> <string name="set_default_theme">设置默认主题</string>
<string name="finish_button">完成</string> <string name="finish_button">完成</string>
<string name="auto_show">自动播放</string>
<string name="neko_no_d">猫猫 %d 号</string>
<string name="title_activity_page7">迷你TG机器人</string>
<string name="title_home">主页</string>
<string name="title_dashboard">面板</string>
<string name="title_notifications">通知</string>
<string name="add_work">添加后台工作</string>
<string name="result">结果</string>
<string name="chat_id">对话 ID</string>
<string name="bot_api_key">机器人 API Key</string>
<string name="show_callback">显示回调</string>
<string name="save_and_test">测试并保存</string>
<string name="require_api">请输入API Key 和 Chat ID</string>
</resources> </resources>

View file

@ -48,8 +48,17 @@
<string name="finish_button">Finish</string> <string name="finish_button">Finish</string>
<string name="auto_show">Auto Show</string> <string name="auto_show">Auto Show</string>
<string name="neko_no_d">Neko No %d</string> <string name="neko_no_d">Neko No %d</string>
<string name="title_activity_page7">Page7</string> <string name="title_activity_page7">Telegram Mini Bot</string>
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_dashboard">Dashboard</string> <string name="title_dashboard">Dashboard</string>
<string name="title_notifications">Notifications</string> <string name="title_notifications">Notifications</string>
<string name="add_work">Add Work</string>
<string name="result">Result</string>
<string name="test_api_key" translatable="false">123456:adfghj-456789</string>
<string name="chat_id">Chat ID</string>
<string name="bot_api_key">Bot API Key</string>
<string name="_123456" translatable="false">123456</string>
<string name="show_callback">Show Callback</string>
<string name="save_and_test">Save And Test</string>
<string name="require_api">Please Fill API Key and Chat ID</string>
</resources> </resources>

View file

@ -1,26 +1,29 @@
[versions] [versions]
agp = "8.4.1" agp = "8.5.0"
datastorePreferences = "1.1.1" datastorePreferences = "1.1.1"
kotlin = "1.9.0" kotlin = "1.9.0"
coreKtx = "1.13.1" coreKtx = "1.13.1"
junit = "4.13.2" junit = "4.13.2"
junitVersion = "1.1.5" junitVersion = "1.2.1"
espressoCore = "3.5.1" espressoCore = "3.6.1"
appcompat = "1.7.0" appcompat = "1.7.0"
material = "1.12.0" material = "1.12.0"
activity = "1.9.0" activity = "1.9.0"
constraintlayout = "2.1.4" constraintlayout = "2.1.4"
lifecycleRuntimeKtx = "2.8.1" lifecycleRuntimeKtx = "2.8.3"
activityCompose = "1.9.0" activityCompose = "1.9.0"
composeBom = "2024.05.00" composeBom = "2024.06.00"
roomCommon = "2.6.1" roomCommon = "2.6.1"
roomKtx = "2.6.1" roomKtx = "2.6.1"
navigationFragmentKtx = "2.7.7" navigationFragmentKtx = "2.7.7"
navigationUiKtx = "2.7.7" navigationUiKtx = "2.7.7"
annotation = "1.8.0" annotation = "1.8.0"
lifecycleLivedataKtx = "2.8.1" lifecycleLivedataKtx = "2.8.3"
lifecycleViewmodelKtx = "2.8.1" lifecycleViewmodelKtx = "2.8.3"
datastoreRxjava3 = "1.1.1" datastoreRxjava3 = "1.1.1"
androidxWork = "2.9.0"
okHttp3 = "4.9.3"
moshiJson = "1.15.1"
[libraries] [libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@ -50,6 +53,10 @@ androidx-annotation = { group = "androidx.annotation", name = "annotation", vers
androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleLivedataKtx" } androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleLivedataKtx" }
androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" } androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
androidx-datastore-rxjava3 = { group = "androidx.datastore", name = "datastore-rxjava3", version.ref = "datastoreRxjava3" } androidx-datastore-rxjava3 = { group = "androidx.datastore", name = "datastore-rxjava3", version.ref = "datastoreRxjava3" }
androidx-work = { group = "androidx.work", name="work-runtime", version.ref = "androidxWork" }
okhttp3 = { group = "com.squareup.okhttp3", name="okhttp",version.ref="okHttp3"}
moshi = {group="com.squareup.moshi",name="moshi-kotlin",version.ref="moshiJson"}
[plugins] [plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" } androidApplication = { id = "com.android.application", version.ref = "agp" }

View file

@ -1,6 +1,6 @@
#Fri Mar 08 22:31:04 CST 2024 #Fri Mar 08 22:31:04 CST 2024
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists