Перерахування всіх додатків наміру


251

З причини налагодження я хочу перерахувати всі додаткові елементи (та їх значення) наміру. Тепер отримати ключі не проблема

Set<String> keys = intent.getExtras().keySet();

але отримання значень ключів для мене одне, тому що деякі значення - це рядки, деякі булеві ... Як я можу отримати значення в циклі (перебираючи ключі) і записати значення в логфайл? Дякуємо за будь-яку підказку!

Відповіді:


467

Ось що я використовував для отримання інформації про незадокументований (сторонній) намір:

Bundle bundle = intent.getExtras();
if (bundle != null) {
    for (String key : bundle.keySet()) {
        Log.e(TAG, key + " : " + (bundle.get(key) != null ? bundle.get(key) : "NULL"));
    }
}

Переконайтесь, що bundleперед циклом перевірте, чи немає його.


2
Я щойно дізнався про додаток Intent Intercept Android . Це теж працює.
Виняк

1
if (bundle == null) { return; }FTW
Matyas

23
Bundle bundle = data.getExtras();Де dataнаміри. Для андроїд-початківців.
ЗавойовникиХакі

2
Перед входом у систему потрібно перевірити, чи є значення нульовим, якщо так value = "null".
Себастьян Крефт

Дякую за це! Шукав спосіб перевірити всі клавіші, які були надані в цьому бездокументованому додатку iTracing, щоб керувати моїм телефоном за допомогою дешевої кнопки Bluetooth. Працював як шарм!
Шейн Сміскол

111

Ось як я визначаю корисний метод, щоб скинути всі додатки наміру.

import java.util.Iterator;
import java.util.Set;
import android.os.Bundle;


public static void dumpIntent(Intent i){

    Bundle bundle = i.getExtras();
    if (bundle != null) {
        Set<String> keys = bundle.keySet();
        Iterator<String> it = keys.iterator();
        Log.e(LOG_TAG,"Dumping Intent start");
        while (it.hasNext()) {
            String key = it.next();
            Log.e(LOG_TAG,"[" + key + "=" + bundle.get(key)+"]");
        }
        Log.e(LOG_TAG,"Dumping Intent end");
    }
}

8
Дякую! Тепер, якщо тільки команда Android почала б реалізовувати такі корисні .toString зміни, як це.
Джим Вітек

37

Ви можете зробити це в одному рядку коду:

Log.d("intent URI", intent.toUri(0));

Він видає щось на кшталт:

"#Intent; action = android.intent.action.MAIN; категорія = android.intent.category.LAUNCHER; launchFlags = 0x10a00000; компонент = com.mydomain.myapp / .StartActivity; sourceBounds = 12% 20870% 20276% 201167; l .profile = 0; кінець "

В кінці цього рядка (тієї частини, яку я виділив жирним шрифтом) ви можете знайти список додаткових даних (лише один додатковий у цьому прикладі).

Це відповідно до документації toUri : "URI містить дані намірів як базовий URI з додатковим фрагментом, що описує дію, категорії, тип, прапори, пакет, компонент та додаткові елементи".


3
Якщо ви просто хочете налагоджувати і бачити, який вміст наміру, це найкращий варіант. Дуже дякую
Shyri

Це має бути прийнятою відповіддю. Ідеально підходить для налагодження журналу!
Етан Арнольд

12
private TextView tv;

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

    tv = new TextView(this);
    tv.setText("Extras: \n\r");

    setContentView(tv);

    StringBuilder str = new StringBuilder();
    Bundle bundle = getIntent().getExtras();
    if (bundle != null) {
        Set<String> keys = bundle.keySet();
        Iterator<String> it = keys.iterator();
        while (it.hasNext()) {
            String key = it.next();
            str.append(key);
            str.append(":");
            str.append(bundle.get(key));
            str.append("\n\r");
        }
        tv.setText(str.toString());
    }
}

8

Метод get (String key) в комплекті повертає об'єкт. Ваша найкраща ставка - перевернути набір ключів get (String) на кожній клавіші та використовувати toString () на Object для їх виведення. Це найкраще підійде для примітивів, але ви можете зіткнутися з проблемами з Об'єктами, які не реалізують toString ().


4
Bundle extras = getIntent().getExtras();
Set<String> ks = extras.keySet();
Iterator<String> iterator = ks.iterator();
while (iterator.hasNext()) {
    Log.d("KEY", iterator.next());
}

1
для (String key: extras.keySet ()) {Log.d (LOG_TAG, key + ":" + extras.get (key)); }
Дефуера

4

Я хотів спосіб вивести вміст наміру до журналу та легко прочитати його, ось ось що я придумав. Я створив LogUtilклас, а потім взяв створений dumpIntent()метод @Pratik і трохи його змінив. Ось як це все виглядає:

public class LogUtil {

    private static final String TAG = "IntentDump";

    public static void dumpIntent(Intent i){
        Bundle bundle = i.getExtras();
        if (bundle != null) {
            Set<String> keys = bundle.keySet();

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("IntentDump \n\r");
            stringBuilder.append("-------------------------------------------------------------\n\r");

            for (String key : keys) {
                stringBuilder.append(key).append("=").append(bundle.get(key)).append("\n\r");
            }

            stringBuilder.append("-------------------------------------------------------------\n\r");
            Log.i(TAG, stringBuilder.toString());
        }
    }
}

Сподіваюся, це комусь допоможе!


2

Ви можете використовувати for (String key : keys) { Object o = get(key);для повернення Об'єкта, зателефонуйте getClass().getName()на нього, щоб отримати тип, а потім зробіть набір речей if name.equals ("String"), щоб визначити, який метод ви насправді повинні викликати, щоб отримати значення ?


1

Я помітив у джерелі Android, що майже кожна операція змушує групу розпакувати свої дані. Тож якщо (як і мені) вам потрібно це робити часто для налагодження, наведене нижче дуже швидко вводиться:

Bundle extras = getIntent().getExtras();
extras.isEmpty(); // unparcel
System.out.println(extras);

0

Вибачте, якщо це занадто багатослівно або занадто пізно, але це був єдиний спосіб, коли я міг знайти роботу. Найбільш ускладнюючим фактором було те, що java не має прохідних посилальних функцій, тому метод get --- Додаткові методи потребують повернення за замовчуванням і не можуть змінювати булеве значення, щоб повідомити, повертається чи ні за замовчуванням значення випадково, або тому, що результати не були сприятливими. Для цього було б краще, щоб метод підняв виняток, ніж повернути його за замовчуванням.

Тут я знайшов свою інформацію: Документація про наміри Android .

    //substitute your own intent here
    Intent intent = new Intent();
    intent.putExtra("first", "hello");
    intent.putExtra("second", 1);
    intent.putExtra("third", true);
    intent.putExtra("fourth", 1.01);
    // convert the set to a string array

Встановити документацію

    String[] anArray = {};
    Set<String> extras1 = (Set<String>) intent.getExtras().keySet();
    String[] extras = (String[]) extras1.toArray(anArray);
    // an arraylist to hold all of the strings
    // rather than putting strings in here, you could display them
    ArrayList<String> endResult = new ArrayList<String>();
    for (int i=0; i<extras.length; i++) {
        //try using as a String
        String aString = intent.getStringExtra(extras[i]);
        // is a string, because the default return value for a non-string is null
        if (aString != null) {
            endResult.add(extras[i] + " : " + aString);
        }
        // not a string
        else {
            // try the next data type, int
            int anInt = intent.getIntExtra(extras[i], 0);
            // is the default value signifying that either it is not an int or that it happens to be 0 
            if (anInt == 0) {
                // is an int value that happens to be 0, the same as the default value
                if (intent.getIntExtra(extras[i], 1) != 1) {
                    endResult.add(extras[i] + " : " + Integer.toString(anInt));
                }
                // not an int value
                // try double (also works for float)
                else {
                    double aDouble = intent.getDoubleExtra(extras[i], 0.0);
                    // is the same as the default value, but does not necessarily mean that it is not double
                    if (aDouble == 0.0) {
                        // just happens that it was 0.0 and is a double
                        if (intent.getDoubleExtra(extras[i], 1.0) != 1.0) {
                            endResult.add(extras[i] + " : " + Double.toString(aDouble));
                        }
                        // keep looking...
                        else {
                            // lastly check for boolean
                            boolean aBool = intent.getBooleanExtra(extras[i], false);
                            // same as default, but not necessarily not a bool (still could be a bool)
                            if (aBool == false) {
                                // it is a bool!
                                if (intent.getBooleanExtra(extras[i], true) != true) {
                                    endResult.add(extras[i] + " : " + Boolean.toString(aBool));
                                }
                                else {
                                    //well, the road ends here unless you want to add some more data types
                                }
                            }
                            // it is a bool
                            else {
                                endResult.add(extras[i] + " : " + Boolean.toString(aBool));
                            }
                        }
                    }
                    // is a double
                    else {
                        endResult.add(extras[i] + " : " + Double.toString(aDouble));
                    }
                }
            }
            // is an int value
            else {
                endResult.add(extras[i] + " : " + Integer.toString(anInt));
            }
        }
    }
    // to display at the end
    for (int i=0; i<endResult.size(); i++) {
        Toast.makeText(this, endResult.get(i), Toast.LENGTH_SHORT).show();
    }

Ви не хочете писати так багато коду, щоб зробити цю просту річ, якщо ви не хочете так сильно ускладнювати свій код, що ви впевнені, що ніколи не зможете зробити оновлення свого додатка. Топ-2 відповіді роблять це з набагато меншим кодом, і за допомогою журналу, який кращий, ніж Тости для таких звичаїв
Louis CAD

0

Версія Котліна корисного методу Пратіка, яка скидає всі додатки наміру:

fun dumpIntent(intent: Intent) {

    val bundle: Bundle = intent.extras ?: return

    val keys = bundle.keySet()
    val it = keys.iterator()

    Log.d(TAG, "Dumping intent start")

    while (it.hasNext()) {
        val key = it.next()
        Log.d(TAG,"[" + key + "=" + bundle.get(key)+"]");
    }

    Log.d(TAG, "Dumping intent finish")

}

1
Це було б простіше у використанніfor (key in bundle.keySet())
DDoSolitary

-2

Якщо для налагодження все, що ви хочете, це рядок (такий, який мається на увазі в ОП, але прямо не вказано), просто використовуйте toStringдодатки Bundle:

intent.getExtras().toString()

Він повертає рядок, такий як:

Bundle[{key1=value1, key2=value2, key3=value3}]

Документація: Bundle.toString () (на жаль, Object.toString()javadoc за замовчуванням і як такий тут зовсім марний.)


4
Коли я спробував це, він повертається: Bundle [mParcelledData.dataSize = 480]
ToddH
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.