summaryrefslogtreecommitdiff
path: root/app/src/main/java/com/example/mylauncher
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/com/example/mylauncher')
-rw-r--r--app/src/main/java/com/example/mylauncher/AppInfo.java13
-rw-r--r--app/src/main/java/com/example/mylauncher/AppsMenuItemClickListener.java22
-rw-r--r--app/src/main/java/com/example/mylauncher/CancelButtonClickListener.java10
-rw-r--r--app/src/main/java/com/example/mylauncher/ConnectButtonClickListener.java28
-rw-r--r--app/src/main/java/com/example/mylauncher/CustomAdapter.java54
-rw-r--r--app/src/main/java/com/example/mylauncher/MainActivity.java649
-rw-r--r--app/src/main/java/com/example/mylauncher/MainMenuItemClickListener.java18
-rw-r--r--app/src/main/java/com/example/mylauncher/PowerMenuItemClickListener.java22
-rw-r--r--app/src/main/java/com/example/mylauncher/RootHelper.java128
-rw-r--r--app/src/main/java/com/example/mylauncher/SearchTextWatcher.java49
-rw-r--r--app/src/main/java/com/example/mylauncher/WifiConnectedRunnable.java18
-rw-r--r--app/src/main/java/com/example/mylauncher/WifiConnectionFailedRunnable.java16
-rw-r--r--app/src/main/java/com/example/mylauncher/WifiMenuItemClickListener.java22
-rw-r--r--app/src/main/java/com/example/mylauncher/WifiNetworkCallback.java39
14 files changed, 1088 insertions, 0 deletions
diff --git a/app/src/main/java/com/example/mylauncher/AppInfo.java b/app/src/main/java/com/example/mylauncher/AppInfo.java
new file mode 100644
index 0000000..39d63d7
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/AppInfo.java
@@ -0,0 +1,13 @@
+package com.example.mylauncher;
+
+import android.content.pm.ResolveInfo;
+
+public class AppInfo {
+ public String name;
+ public ResolveInfo resolveInfo;
+
+ public AppInfo(String name, ResolveInfo resolveInfo) {
+ this.name = name;
+ this.resolveInfo = resolveInfo;
+ }
+}
diff --git a/app/src/main/java/com/example/mylauncher/AppsMenuItemClickListener.java b/app/src/main/java/com/example/mylauncher/AppsMenuItemClickListener.java
new file mode 100644
index 0000000..562531f
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/AppsMenuItemClickListener.java
@@ -0,0 +1,22 @@
+package com.example.mylauncher;
+
+import android.view.View;
+import android.widget.AdapterView;
+
+public class AppsMenuItemClickListener implements AdapterView.OnItemClickListener {
+ private MainActivity mainActivity;
+
+ public AppsMenuItemClickListener(MainActivity activity) {
+ this.mainActivity = activity;
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ String selected = (String) parent.getItemAtPosition(position);
+ if ("Back".equals(selected)) {
+ mainActivity.showMainMenu();
+ } else {
+ mainActivity.launchAppByName(selected);
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/mylauncher/CancelButtonClickListener.java b/app/src/main/java/com/example/mylauncher/CancelButtonClickListener.java
new file mode 100644
index 0000000..6490eca
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/CancelButtonClickListener.java
@@ -0,0 +1,10 @@
+package com.example.mylauncher;
+
+import android.content.DialogInterface;
+
+public class CancelButtonClickListener implements DialogInterface.OnClickListener {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+}
diff --git a/app/src/main/java/com/example/mylauncher/ConnectButtonClickListener.java b/app/src/main/java/com/example/mylauncher/ConnectButtonClickListener.java
new file mode 100644
index 0000000..e2c6024
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/ConnectButtonClickListener.java
@@ -0,0 +1,28 @@
+package com.example.mylauncher;
+
+import android.content.DialogInterface;
+import android.widget.EditText;
+import android.os.Build;
+
+public class ConnectButtonClickListener implements DialogInterface.OnClickListener {
+ private MainActivity mainActivity;
+ private String ssid;
+ private EditText input;
+
+ public ConnectButtonClickListener(MainActivity activity, String ssid, EditText input) {
+ this.mainActivity = activity;
+ this.ssid = ssid;
+ this.input = input;
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ final String password = input.getText() != null ? input.getText().toString() : "";
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ mainActivity.connectToWifiAndroidQ(ssid, password);
+ } else {
+ mainActivity.connectToWifiPreAndroidQ(ssid, password);
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/mylauncher/CustomAdapter.java b/app/src/main/java/com/example/mylauncher/CustomAdapter.java
new file mode 100644
index 0000000..c30b604
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/CustomAdapter.java
@@ -0,0 +1,54 @@
+package com.example.mylauncher;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.List;
+
+public class CustomAdapter extends ArrayAdapter<String> {
+ private Typeface customFont;
+
+ public CustomAdapter(Context context, List<String> items) {
+ super(context, R.layout.menu_item, items);
+ try {
+ customFont = Typeface.createFromAsset(context.getAssets(), "fonts/custom_font.ttf");
+ } catch (Exception e) {
+ e.printStackTrace();
+ Toast.makeText(context, "Error loading font", Toast.LENGTH_SHORT).show();
+ customFont = Typeface.DEFAULT;
+ }
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder holder;
+
+ if (convertView == null) {
+ LayoutInflater inflater = LayoutInflater.from(getContext());
+ convertView = inflater.inflate(R.layout.menu_item, parent, false);
+
+ holder = new ViewHolder();
+ holder.textView = convertView.findViewById(R.id.text_view);
+ holder.textView.setTypeface(customFont);
+
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+
+ String item = getItem(position);
+ holder.textView.setText(item != null ? item : "");
+
+ return convertView;
+ }
+
+ private static class ViewHolder {
+ TextView textView;
+ }
+}
diff --git a/app/src/main/java/com/example/mylauncher/MainActivity.java b/app/src/main/java/com/example/mylauncher/MainActivity.java
new file mode 100644
index 0000000..ab740e8
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/MainActivity.java
@@ -0,0 +1,649 @@
+package com.example.mylauncher;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.util.Log;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.provider.MediaStore;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.Toast;
+import android.widget.ListView;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import java.io.DataOutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import android.net.Uri;
+import android.net.wifi.WifiManager;
+import android.net.wifi.ScanResult;
+import android.content.Context;
+import android.Manifest;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.net.NetworkRequest;
+import android.net.NetworkCapabilities;
+import android.net.wifi.WifiNetworkSpecifier;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiConfiguration;
+import android.os.Build;
+import android.text.InputType;
+import android.annotation.TargetApi;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.widget.AdapterView;
+
+import androidx.annotation.RequiresApi;
+
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+
+import java.util.Set;
+import java.util.HashSet;
+
+public class MainActivity extends Activity {
+ private ListView menuList;
+ private LinearLayout menuContainer;
+ private EditText searchBar;
+ private TextView itemCount;
+ private List<String> menuItems;
+ private boolean isInAppsMenu = false;
+ private boolean isInPowerMenu = false;
+ private WifiManager wifiManager;
+ private List<String> wifiNetworks;
+ private boolean isInWifiMenu = false;
+ private static final int WIFI_PERMISSION_REQUEST = 100;
+
+ private List<AppInfo> appInfoList; // All available apps
+ private List<AppInfo> filteredAppInfoList; // Apps after filtering
+
+ private static final String[] DEFAULT_MENU = {
+ "💻 t-mode",
+ "📱 Apps",
+ "📂 Files",
+ "Web Browser",
+ "📞 Dialer",
+ "✉️ Texts",
+ "👤 Contacts",
+ "📷 Camera",
+ "🌐 Networks",
+ "🔊 Audio",
+ "⚙️ Config",
+ "⚡ Power",
+ "❌ Close Menu"
+ };
+
+ @Override
+ public void onBackPressed() {
+ // Do nothing to disable the back button
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ menuContainer = findViewById(R.id.menu_container);
+ menuList = findViewById(R.id.menu_list);
+ searchBar = findViewById(R.id.search_bar);
+ itemCount = findViewById(R.id.item_count);
+
+ if (menuContainer == null || menuList == null ||
+ searchBar == null || itemCount == null) {
+ finish();
+ return;
+ }
+
+ menuItems = new ArrayList<>(Arrays.asList(DEFAULT_MENU));
+ loadApps();
+ showMainMenu();
+
+ searchBar.addTextChangedListener(new SearchTextWatcher(this));
+
+ menuList.requestFocus(); // Ensure the ListView has focus
+
+ // Replace the previous EditText listeners with these new ones
+ searchBar.setOnEditorActionListener((v, actionId, event) -> {
+ // Handle both hardware and software keyboard Enter presses
+ if (event != null || actionId == EditorInfo.IME_ACTION_DONE ||
+ actionId == EditorInfo.IME_ACTION_GO ||
+ actionId == EditorInfo.IME_ACTION_SEARCH) {
+ handleEnterKeyPress();
+ return true;
+ }
+ return false;
+ });
+
+ // Add key listener for hardware keyboard
+ searchBar.setOnKeyListener((v, keyCode, event) -> {
+ if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_ENTER) {
+ handleEnterKeyPress();
+ return true;
+ }
+ return false;
+ });
+
+
+ }
+
+ public void filterList(String query) {
+ List<String> filteredNames = new ArrayList<>();
+
+ if (isInAppsMenu && appInfoList != null) {
+ filteredAppInfoList = new ArrayList<>();
+ for (AppInfo appInfo : appInfoList) {
+ if (appInfo.name.toLowerCase().contains(query)) {
+ filteredAppInfoList.add(appInfo);
+ filteredNames.add(appInfo.name);
+ }
+ }
+ filteredNames.add("Back");
+ } else if (isInPowerMenu) {
+ // For simplicity, we won't filter the power menu options
+ filteredNames = Arrays.asList(
+ "Lock",
+ "Reboot",
+ "Shutdown",
+ "Back"
+ );
+ } else if (isInWifiMenu) {
+ // Filter Wi-Fi networks
+ filteredNames = new ArrayList<>();
+ for (String network : wifiNetworks) {
+ if (network.toLowerCase().contains(query)) {
+ filteredNames.add(network);
+ }
+ }
+ filteredNames.add("Back");
+ } else {
+ filteredAppInfoList = null; // Not applicable
+ for (String item : menuItems) {
+ if (item.toLowerCase().contains(query)) {
+ filteredNames.add(item);
+ }
+ }
+ }
+
+ setMenuItems(filteredNames);
+ }
+
+ private void setMenuItems(List<String> items) {
+ CustomAdapter adapter = new CustomAdapter(this, items);
+ menuList.setAdapter(adapter);
+ updateCount();
+
+ // Update the OnItemClickListener
+ if (isInAppsMenu) {
+ menuList.setOnItemClickListener(new AppsMenuItemClickListener(this));
+ } else if (isInPowerMenu) {
+ menuList.setOnItemClickListener(new PowerMenuItemClickListener(this));
+ } else if (isInWifiMenu) {
+ menuList.setOnItemClickListener(new WifiMenuItemClickListener(this));
+ } else {
+ menuList.setOnItemClickListener(new MainMenuItemClickListener(this));
+ }
+
+ // Set the first item as selected by default
+ menuList.setSelection(0);
+ menuList.setItemChecked(0, true);
+ }
+
+ private void loadApps() {
+ try {
+ PackageManager pm = getPackageManager();
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
+ appInfoList = new ArrayList<>();
+ for (ResolveInfo resolveInfo : resolveInfos) {
+ String name = resolveInfo.loadLabel(pm).toString();
+ appInfoList.add(new AppInfo(name, resolveInfo));
+ }
+ } catch (Exception e) {
+ appInfoList = new ArrayList<>();
+ }
+ }
+
+ public void showMainMenu() {
+ isInAppsMenu = false;
+ isInPowerMenu = false;
+ isInWifiMenu = false;
+ setMenuItems(menuItems);
+ searchBar.setText("");
+ }
+
+ private void showAppMenu() {
+ if (appInfoList == null || appInfoList.isEmpty()) {
+ Toast.makeText(this, "No apps found", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ isInAppsMenu = true;
+ isInPowerMenu = false;
+ isInWifiMenu = false;
+ filteredAppInfoList = new ArrayList<>(appInfoList); // Start with all apps
+
+ List<String> appNames = new ArrayList<>();
+ for (AppInfo appInfo : filteredAppInfoList) {
+ appNames.add(appInfo.name);
+ }
+ appNames.add("Back");
+
+ setMenuItems(appNames);
+ searchBar.setText("");
+ }
+
+ private void showPowerMenu() {
+ isInPowerMenu = true;
+ isInAppsMenu = false;
+ isInWifiMenu = false;
+ List<String> powerOptions = Arrays.asList(
+ "Lock",
+ "Reboot",
+ "Shutdown",
+ "Back"
+ );
+ setMenuItems(powerOptions);
+ searchBar.setText("");
+ }
+
+ private void showWifiMenu() {
+ if (checkWifiPermissions()) {
+ scanWifiNetworks();
+ }
+ }
+
+ private boolean checkWifiPermissions() {
+ if (ContextCompat.checkSelfPermission(this,
+ Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
+ WIFI_PERMISSION_REQUEST);
+ return false;
+ }
+ return true;
+ }
+
+ private void scanWifiNetworks() {
+ wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
+ if (!wifiManager.isWifiEnabled()) {
+ wifiManager.setWifiEnabled(true);
+ }
+
+ Set<String> wifiNetworkSet = new HashSet<>();
+ wifiManager.startScan(); // Start a new scan
+ List<ScanResult> scanResults = wifiManager.getScanResults();
+
+ for (ScanResult scanResult : scanResults) {
+ if (scanResult.SSID != null && !scanResult.SSID.isEmpty()) {
+ wifiNetworkSet.add(scanResult.SSID);
+ }
+ }
+ wifiNetworks = new ArrayList<>(wifiNetworkSet);
+
+ isInWifiMenu = true;
+ isInAppsMenu = false;
+ isInPowerMenu = false;
+
+ setMenuItems(wifiNetworks);
+ searchBar.setText("");
+}
+
+
+ public void connectToWifi(String ssid) {
+ final String finalSsid = ssid; // Declare ssid as final
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle("Connect to " + finalSsid);
+
+ // Set up the input
+ final EditText input = new EditText(this);
+ input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ input.setHint("Password");
+
+ builder.setView(input);
+
+ // Set up the buttons
+ builder.setPositiveButton("Connect", new ConnectButtonClickListener(this, finalSsid, input));
+ builder.setNegativeButton("Cancel", new CancelButtonClickListener());
+
+ builder.show();
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.Q)
+ public void connectToWifiAndroidQ(final String ssid, final String password) {
+ WifiNetworkSpecifier.Builder builder = new WifiNetworkSpecifier.Builder()
+ .setSsid(ssid);
+
+ if (password != null && !password.isEmpty()) {
+ builder.setWpa2Passphrase(password);
+ }
+
+ WifiNetworkSpecifier wifiNetworkSpecifier = builder.build();
+
+ NetworkRequest networkRequest = new NetworkRequest.Builder()
+ .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+ .setNetworkSpecifier(wifiNetworkSpecifier)
+ .build();
+
+ final ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ final WifiNetworkCallback networkCallback = new WifiNetworkCallback(this, ssid, connectivityManager);
+
+ connectivityManager.requestNetwork(networkRequest, networkCallback);
+ }
+
+ public void connectToWifiPreAndroidQ(final String ssid, final String password) {
+ WifiConfiguration wifiConfig = new WifiConfiguration();
+ wifiConfig.SSID = "\"" + ssid + "\"";
+ if (password != null && !password.isEmpty()) {
+ wifiConfig.preSharedKey = "\"" + password + "\"";
+ } else {
+ wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ }
+
+ WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
+
+ int netId = wifiManager.addNetwork(wifiConfig);
+ if (netId != -1) {
+ wifiManager.disconnect();
+ wifiManager.enableNetwork(netId, true);
+ wifiManager.reconnect();
+ runOnUiThread(new WifiConnectedRunnable(this, ssid));
+ } else {
+ runOnUiThread(new WifiConnectionFailedRunnable(this));
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+ if (requestCode == WIFI_PERMISSION_REQUEST) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ scanWifiNetworks();
+ } else {
+ Toast.makeText(this, "WiFi scanning requires location permission", Toast.LENGTH_LONG).show();
+ }
+ }
+ }
+
+ public void launchAppByName(String appName) {
+ if (filteredAppInfoList != null) {
+ for (AppInfo appInfo : filteredAppInfoList) {
+ if (appInfo.name.equals(appName)) {
+ launchApp(appInfo.resolveInfo);
+ break;
+ }
+ }
+ } else {
+ // Fallback to searching in the full list
+ for (AppInfo appInfo : appInfoList) {
+ if (appInfo.name.equals(appName)) {
+ launchApp(appInfo.resolveInfo);
+ break;
+ }
+ }
+ }
+ }
+
+ private void launchApp(ResolveInfo app) {
+ try {
+ Intent intent = getPackageManager().getLaunchIntentForPackage(app.activityInfo.packageName);
+ if (intent != null) {
+ startActivity(intent);
+ } else {
+ Toast.makeText(this, "Unable to launch app", Toast.LENGTH_SHORT).show();
+ }
+ } catch (Exception e) {
+ Toast.makeText(this, "Error launching app", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void updateCount() {
+ if (menuList.getAdapter() != null) {
+ itemCount.setText(String.valueOf(menuList.getAdapter().getCount()));
+ }
+ }
+
+ public void handleMenuSelection(String item) {
+ if (isInWifiMenu) {
+ if (item.equals("Back")) {
+ showMainMenu();
+ } else {
+ connectToWifi(item);
+ }
+ return;
+ }
+
+ switch (item) {
+ case "💻 t-mode":
+ Intent termuxIntent = getPackageManager().getLaunchIntentForPackage("com.termux.x11");
+ if (termuxIntent != null) {
+ startActivity(termuxIntent);
+ } else {
+ Toast.makeText(this, "Termux X11 not installed", Toast.LENGTH_SHORT).show();
+ }
+ break;
+ case "📱 Apps":
+ showAppMenu();
+ break;
+ case "Web Browser":
+ Intent browserIntent = getPackageManager().getLaunchIntentForPackage("app.vanadium.browser");
+ if (browserIntent != null) {
+ startActivity(browserIntent);
+ } else {
+ Toast.makeText(this, "Vanadium browser not found", Toast.LENGTH_SHORT).show();
+ }
+ break;
+ case "📂 Files":
+ Intent filesIntent = new Intent(Intent.ACTION_VIEW);
+ filesIntent.setDataAndType(Uri.parse("file:///"), "*/*");
+ if (filesIntent.resolveActivity(getPackageManager()) != null) {
+ startActivity(filesIntent);
+ } else {
+ Toast.makeText(this, "No file manager found", Toast.LENGTH_SHORT).show();
+ }
+ break;
+ case "📞 Dialer":
+ startActivity(new Intent(Intent.ACTION_DIAL));
+ break;
+ case "✉️ Texts":
+ Intent msgIntent = new Intent(Intent.ACTION_MAIN);
+ msgIntent.addCategory(Intent.CATEGORY_APP_MESSAGING);
+ if (msgIntent.resolveActivity(getPackageManager()) != null) {
+ startActivity(msgIntent);
+ } else {
+ Toast.makeText(this, "No messaging app found", Toast.LENGTH_SHORT).show();
+ }
+ break;
+ case "👤 Contacts":
+ Intent contactsIntent = new Intent(Intent.ACTION_VIEW);
+ contactsIntent.setType("vnd.android.cursor.dir/contact");
+ if (contactsIntent.resolveActivity(getPackageManager()) != null) {
+ startActivity(contactsIntent);
+ } else {
+ Toast.makeText(this, "No contacts app found", Toast.LENGTH_SHORT).show();
+ }
+ break;
+ case "📷 Camera":
+ Intent cameraIntent = getPackageManager().getLaunchIntentForPackage("app.grapheneos.camera");
+ if (cameraIntent != null) {
+ startActivity(cameraIntent);
+ } else {
+ startActivity(new Intent(MediaStore.ACTION_IMAGE_CAPTURE));
+ }
+ break;
+ case "🌐 Networks":
+ showWifiMenu();
+ break;
+ case "🔊 Audio":
+ startActivity(new Intent(Settings.ACTION_SOUND_SETTINGS));
+ break;
+ case "⚙️ Config":
+ startActivity(new Intent(Settings.ACTION_SETTINGS));
+ break;
+ case "⚡ Power":
+ showPowerMenu();
+ break;
+ case "❌ Close Menu":
+ menuContainer.setVisibility(View.GONE);
+ break;
+ default:
+ Toast.makeText(this, "Unknown selection", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ public void handlePowerOption(String option) {
+ switch (option) {
+ case "Lock":
+ executeRootCommand("input keyevent 26");
+ break;
+ case "Reboot":
+ executeRootCommand("reboot");
+ break;
+ case "Shutdown":
+ executeRootCommand("reboot -p");
+ break;
+ default:
+ Toast.makeText(this, "Unknown power option", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void executeRootCommand(String command) {
+ try {
+ Process suProcess = Runtime.getRuntime().exec("su");
+ DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
+ os.writeBytes(command + "\n");
+ os.writeBytes("exit\n");
+ os.flush();
+ suProcess.waitFor();
+ suProcess.destroy();
+ } catch (Exception e) {
+ Toast.makeText(this, "Error executing command: " + e.getMessage(), Toast.LENGTH_LONG).show();
+ }
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ int action = event.getAction();
+ int keyCode = event.getKeyCode();
+ if (action == KeyEvent.ACTION_DOWN) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ return onKeyDown(keyCode, event); // Handle volume keys
+ default:
+ break;
+ }
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (menuList == null || menuList.getAdapter() == null) return super.onKeyDown(keyCode, event);
+
+ // Get current state
+ int currentPosition = menuList.getSelectedItemPosition();
+ int itemCount = menuList.getAdapter().getCount();
+
+ // If nothing is selected, start at first item
+ if (currentPosition == -1) {
+ currentPosition = 0;
+ }
+
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ if (currentPosition < itemCount - 1) {
+ currentPosition++;
+ }
+ menuList.requestFocusFromTouch();
+ menuList.setSelection(currentPosition);
+ menuList.setItemChecked(currentPosition, true);
+ menuList.requestFocus();
+ return true;
+
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ if (currentPosition > 0) {
+ currentPosition--;
+ }
+ menuList.requestFocusFromTouch();
+ menuList.setSelection(currentPosition);
+ menuList.setItemChecked(currentPosition, true);
+ menuList.requestFocus();
+ return true;
+
+ case KeyEvent.KEYCODE_POWER:
+ case KeyEvent.KEYCODE_ENTER:
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ // Handle item selection
+ View selectedView = menuList.getChildAt(currentPosition - menuList.getFirstVisiblePosition());
+ if (selectedView != null) {
+ menuList.performItemClick(
+ selectedView,
+ currentPosition,
+ menuList.getAdapter().getItemId(currentPosition)
+ );
+ }
+ return true;
+
+ default:
+ return super.onKeyDown(keyCode, event);
+ }
+ }
+
+ // Add new method to handle Enter key press
+ private void handleEnterKeyPress() {
+ if (menuList.getAdapter() != null && menuList.getAdapter().getCount() > 0) {
+ String selectedItem = (String) menuList.getAdapter().getItem(0);
+
+ // Execute the action before clearing focus
+ if (isInAppsMenu) {
+ if (!selectedItem.equals("Back")) {
+ // Post the action to ensure it runs after the current operation
+ menuList.post(() -> {
+ launchAppByName(selectedItem);
+ });
+ } else {
+ showMainMenu();
+ }
+ } else if (isInWifiMenu) {
+ if (!selectedItem.equals("Back")) {
+ menuList.post(() -> {
+ connectToWifi(selectedItem);
+ });
+ } else {
+ showMainMenu();
+ }
+ } else if (isInPowerMenu) {
+ if (!selectedItem.equals("Back")) {
+ menuList.post(() -> {
+ handlePowerOption(selectedItem);
+ });
+ } else {
+ showMainMenu();
+ }
+ } else {
+ menuList.post(() -> {
+ handleMenuSelection(selectedItem);
+ });
+ }
+
+ // Clear focus after posting the action
+ searchBar.clearFocus();
+
+ // Hide keyboard explicitly
+ InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(searchBar.getWindowToken(), 0);
+ }
+ }
+
+
+}
diff --git a/app/src/main/java/com/example/mylauncher/MainMenuItemClickListener.java b/app/src/main/java/com/example/mylauncher/MainMenuItemClickListener.java
new file mode 100644
index 0000000..084c8e5
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/MainMenuItemClickListener.java
@@ -0,0 +1,18 @@
+package com.example.mylauncher;
+
+import android.view.View;
+import android.widget.AdapterView;
+
+public class MainMenuItemClickListener implements AdapterView.OnItemClickListener {
+ private MainActivity mainActivity;
+
+ public MainMenuItemClickListener(MainActivity activity) {
+ this.mainActivity = activity;
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ String selected = (String) parent.getItemAtPosition(position);
+ mainActivity.handleMenuSelection(selected);
+ }
+}
diff --git a/app/src/main/java/com/example/mylauncher/PowerMenuItemClickListener.java b/app/src/main/java/com/example/mylauncher/PowerMenuItemClickListener.java
new file mode 100644
index 0000000..9570dff
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/PowerMenuItemClickListener.java
@@ -0,0 +1,22 @@
+package com.example.mylauncher;
+
+import android.view.View;
+import android.widget.AdapterView;
+
+public class PowerMenuItemClickListener implements AdapterView.OnItemClickListener {
+ private MainActivity mainActivity;
+
+ public PowerMenuItemClickListener(MainActivity activity) {
+ this.mainActivity = activity;
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ String selected = (String) parent.getItemAtPosition(position);
+ if ("Back".equals(selected)) {
+ mainActivity.showMainMenu();
+ } else {
+ mainActivity.handlePowerOption(selected);
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/mylauncher/RootHelper.java b/app/src/main/java/com/example/mylauncher/RootHelper.java
new file mode 100644
index 0000000..886e07f
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/RootHelper.java
@@ -0,0 +1,128 @@
+package com.example.mylauncher;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class RootHelper {
+ public static boolean executeRootCommand(String command) {
+ Process process = null;
+ DataOutputStream os = null;
+ try {
+ process = Runtime.getRuntime().exec("su");
+ os = new DataOutputStream(process.getOutputStream());
+ os.writeBytes(command + "\n");
+ os.writeBytes("exit\n");
+ os.flush();
+ return process.waitFor() == 0;
+ } catch (IOException | InterruptedException e) {
+ e.printStackTrace();
+ return false;
+ } finally {
+ try {
+ if (os != null) {
+ os.close();
+ }
+ if (process != null) {
+ process.destroy();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static boolean hasRoot() {
+ return executeRootCommand("echo test");
+ }
+
+ /**
+ * Execute a shell command as root with a return value
+ */
+ public static String executeRootCommandWithOutput(String command) {
+ Process process = null;
+ StringBuilder output = new StringBuilder();
+ try {
+ process = Runtime.getRuntime().exec("su");
+ DataOutputStream os = new DataOutputStream(process.getOutputStream());
+ os.writeBytes(command + "\n");
+ os.writeBytes("exit\n");
+ os.flush();
+
+ java.io.BufferedReader reader = new java.io.BufferedReader(
+ new java.io.InputStreamReader(process.getInputStream()));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ output.append(line).append('\n');
+ }
+
+ process.waitFor();
+ return output.toString().trim();
+ } catch (IOException | InterruptedException e) {
+ e.printStackTrace();
+ return null;
+ } finally {
+ if (process != null) {
+ process.destroy();
+ }
+ }
+ }
+
+ /**
+ * Check if a specific package is installed
+ */
+ public static boolean isPackageInstalled(String packageName) {
+ String command = "pm list packages " + packageName;
+ String result = executeRootCommandWithOutput(command);
+ return result != null && result.contains(packageName);
+ }
+
+ /**
+ * Execute a specific app with root permissions
+ */
+ public static boolean launchApp(String packageName) {
+ String command = "monkey -p " + packageName + " -c android.intent.category.LAUNCHER 1";
+ return executeRootCommand(command);
+ }
+
+ /**
+ * Reboot device
+ */
+ public static void reboot() {
+ executeRootCommand("reboot");
+ }
+
+ /**
+ * Power off device
+ */
+ public static void powerOff() {
+ executeRootCommand("reboot -p");
+ }
+
+ /**
+ * Lock screen
+ */
+ public static void lockScreen() {
+ executeRootCommand("input keyevent 26");
+ }
+
+ /**
+ * Change system settings (requires root)
+ */
+ public static boolean changeSystemSetting(String setting, String value) {
+ return executeRootCommand("settings put system " + setting + " " + value);
+ }
+
+ /**
+ * Kill a specific app
+ */
+ public static boolean killApp(String packageName) {
+ return executeRootCommand("am force-stop " + packageName);
+ }
+
+ /**
+ * Clear app data
+ */
+ public static boolean clearAppData(String packageName) {
+ return executeRootCommand("pm clear " + packageName);
+ }
+}
diff --git a/app/src/main/java/com/example/mylauncher/SearchTextWatcher.java b/app/src/main/java/com/example/mylauncher/SearchTextWatcher.java
new file mode 100644
index 0000000..cf2e750
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/SearchTextWatcher.java
@@ -0,0 +1,49 @@
+/*package com.example.mylauncher;
+
+import android.text.Editable;
+import android.text.TextWatcher;
+
+public class SearchTextWatcher implements TextWatcher {
+ private MainActivity activity;
+
+ public SearchTextWatcher(MainActivity activity) {
+ this.activity = activity;
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ activity.filterList(s.toString().toLowerCase());
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {}
+}*/
+package com.example.mylauncher;
+
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.KeyEvent;
+import android.widget.EditText;
+
+public class SearchTextWatcher implements TextWatcher {
+ private MainActivity activity;
+
+ public SearchTextWatcher(MainActivity activity) {
+ this.activity = activity;
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ // Move filtering here to ensure it happens after the text is fully updated
+ activity.filterList(s.toString().toLowerCase());
+ }
+}
diff --git a/app/src/main/java/com/example/mylauncher/WifiConnectedRunnable.java b/app/src/main/java/com/example/mylauncher/WifiConnectedRunnable.java
new file mode 100644
index 0000000..203fe26
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/WifiConnectedRunnable.java
@@ -0,0 +1,18 @@
+package com.example.mylauncher;
+
+import android.widget.Toast;
+
+public class WifiConnectedRunnable implements Runnable {
+ private MainActivity mainActivity;
+ private String ssid;
+
+ public WifiConnectedRunnable(MainActivity activity, String ssid) {
+ this.mainActivity = activity;
+ this.ssid = ssid;
+ }
+
+ @Override
+ public void run() {
+ Toast.makeText(mainActivity, "Connected to " + ssid, Toast.LENGTH_SHORT).show();
+ }
+}
diff --git a/app/src/main/java/com/example/mylauncher/WifiConnectionFailedRunnable.java b/app/src/main/java/com/example/mylauncher/WifiConnectionFailedRunnable.java
new file mode 100644
index 0000000..e8a56a9
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/WifiConnectionFailedRunnable.java
@@ -0,0 +1,16 @@
+package com.example.mylauncher;
+
+import android.widget.Toast;
+
+public class WifiConnectionFailedRunnable implements Runnable {
+ private MainActivity mainActivity;
+
+ public WifiConnectionFailedRunnable(MainActivity activity) {
+ this.mainActivity = activity;
+ }
+
+ @Override
+ public void run() {
+ Toast.makeText(mainActivity, "Unable to connect to Wi-Fi", Toast.LENGTH_SHORT).show();
+ }
+}
diff --git a/app/src/main/java/com/example/mylauncher/WifiMenuItemClickListener.java b/app/src/main/java/com/example/mylauncher/WifiMenuItemClickListener.java
new file mode 100644
index 0000000..074acf1
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/WifiMenuItemClickListener.java
@@ -0,0 +1,22 @@
+package com.example.mylauncher;
+
+import android.view.View;
+import android.widget.AdapterView;
+
+public class WifiMenuItemClickListener implements AdapterView.OnItemClickListener {
+ private MainActivity mainActivity;
+
+ public WifiMenuItemClickListener(MainActivity activity) {
+ this.mainActivity = activity;
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ String selected = (String) parent.getItemAtPosition(position);
+ if ("Back".equals(selected)) {
+ mainActivity.showMainMenu();
+ } else {
+ mainActivity.connectToWifi(selected);
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/mylauncher/WifiNetworkCallback.java b/app/src/main/java/com/example/mylauncher/WifiNetworkCallback.java
new file mode 100644
index 0000000..f365b17
--- /dev/null
+++ b/app/src/main/java/com/example/mylauncher/WifiNetworkCallback.java
@@ -0,0 +1,39 @@
+package com.example.mylauncher;
+
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.os.Build;
+import android.widget.Toast;
+
+public class WifiNetworkCallback extends NetworkCallback {
+ private final String ssid;
+ private final ConnectivityManager connectivityManager;
+ private final MainActivity mainActivity;
+
+ public WifiNetworkCallback(MainActivity activity, String ssid, ConnectivityManager connectivityManager) {
+ this.ssid = ssid;
+ this.connectivityManager = connectivityManager;
+ this.mainActivity = activity;
+ }
+
+ @Override
+ public void onAvailable(Network network) {
+ // Use this network object to send requests
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ connectivityManager.bindProcessToNetwork(network);
+ } else {
+ ConnectivityManager.setProcessDefaultNetwork(network);
+ }
+ mainActivity.runOnUiThread(() -> {
+ Toast.makeText(mainActivity, "Connected to " + ssid, Toast.LENGTH_SHORT).show();
+ });
+ }
+
+ @Override
+ public void onUnavailable() {
+ mainActivity.runOnUiThread(() -> {
+ Toast.makeText(mainActivity, "Unable to connect to " + ssid, Toast.LENGTH_SHORT).show();
+ });
+ }
+}