diff options
Diffstat (limited to 'app/src/main/java/com/example')
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(); + }); + } +} |
