Cantumkan semua ekstra Intent

251

Untuk alasan debugging, saya ingin membuat daftar semua ekstra (dan nilainya) dari Intent. Sekarang, mendapatkan kunci bukanlah masalah

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

tetapi mendapatkan nilai-nilai kunci adalah satu untuk saya, karena beberapa nilai adalah string, beberapa boolean ... Bagaimana saya bisa mendapatkan nilai-nilai dalam satu lingkaran (perulangan melalui kunci) dan menulis nilai-nilai ke logfile? Terima kasih atas petunjuknya!

stefan.at.wpf
sumber

Jawaban:

467

Inilah yang saya gunakan untuk mendapatkan informasi tentang maksud (pihak ketiga) yang tidak berdokumen:

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

Pastikan untuk memeriksa apakah bundleada nol sebelum loop.

kshahar
sumber
2
Saya baru tahu tentang aplikasi Intent Intercept Android . Itu juga berhasil.
Vinayak
1
if (bundle == null) { return; }FTW
Matyas
23
Bundle bundle = data.getExtras();Dimana dataIntent. Untuk pemula android.
ConquerorsHaki
2
Sebelum masuk, Anda perlu memeriksa apakah nilainya nol, jika demikian value = "null".
Sebastian Kreft
Terima kasih untuk ini! Sedang mencari cara untuk memeriksa semua kunci yang disediakan dalam aplikasi iTracing tidak berdokumen ini, untuk mengontrol ponsel saya melalui tombol Bluetooth murah. Bekerja seperti pesona!
Shane Smiskol
111

Ini adalah bagaimana saya mendefinisikan metode utilitas untuk membuang semua ekstra suatu Intent.

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");
    }
}
Pratik
sumber
8
Terima kasih! Sekarang, jika hanya tim android yang akan mulai menerapkan .toString yang bermanfaat seperti ini.
Jim Vitek
37

Anda dapat melakukannya dalam satu baris kode:

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

Ini menghasilkan sesuatu seperti:

"#Intent; action = android.intent.action.MAIN; kategori = android.intent.category.LAUNCHER; launchFlags = 0x10a00000; komponen = com.mydomain.myapp / .StartActivity; sourceBounds = 12% 20870% 20276% 201167; l . profil = 0; end "

Di akhir string ini (bagian yang saya cetak tebal) Anda dapat menemukan daftar ekstra (hanya satu tambahan dalam contoh ini).

Ini sesuai dengan dokumentasi toUri : "URI berisi data Intent sebagai URI dasar, dengan fragmen tambahan yang menjelaskan tindakan, kategori, jenis, bendera, paket, komponen, dan ekstra."

Alex Vang
sumber
3
Jika Anda hanya ingin men-debug dan melihat isi maksudnya, ini adalah opsi terbaik. Terima kasih banyak
Shyri
Ini harus menjadi jawaban yang diterima. Sempurna untuk debugging log!
Ethan Arnold
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());
    }
}
pengguna123321
sumber
8

Metode get (String key) dari Bundle mengembalikan Object. Taruhan terbaik Anda adalah dengan memutar set kunci get get (String) pada setiap kunci dan menggunakan toString () pada Object untuk menampilkannya. Ini akan bekerja paling baik untuk primitif, tetapi Anda mungkin mengalami masalah dengan Objek yang tidak menerapkan toString ().

nicholas.hauschild
sumber
4
Bundle extras = getIntent().getExtras();
Set<String> ks = extras.keySet();
Iterator<String> iterator = ks.iterator();
while (iterator.hasNext()) {
    Log.d("KEY", iterator.next());
}
Luis
sumber
1
untuk (Kunci string: extras.keySet ()) {Log.d (LOG_TAG, kunci + ":" + extras.get (kunci)); }
Defuera
4

Saya ingin cara untuk menampilkan isi maksud ke log, dan untuk dapat membacanya dengan mudah, jadi inilah yang saya buat. Saya telah membuat LogUtilkelas, dan kemudian mengambil dumpIntent()metode yang dibuat @Pratik, dan memodifikasinya sedikit. Begini tampilannya:

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());
        }
    }
}

Semoga ini bisa membantu seseorang!

LukeWaggoner
sumber
2

Anda dapat menggunakan for (String key : keys) { Object o = get(key);untuk mengembalikan Obyek, memanggilnya getClass().getName()untuk mendapatkan jenis, dan kemudian melakukan set if name.equals ("String") ketik hal-hal untuk mengetahui metode mana yang Anda seharusnya panggil, untuk mendapatkan nilai ?

Ben Williams
sumber
1

Saya perhatikan di sumber Android bahwa hampir setiap operasi memaksa Bundle untuk menghapus data. Jadi jika (seperti saya) yang perlu Anda lakukan ini sering untuk keperluan debugging, di bawah ini sangat cepat untuk mengetik:

Bundle extras = getIntent().getExtras();
extras.isEmpty(); // unparcel
System.out.println(extras);
Ian Lovejoy
sumber
0

Maaf jika ini terlalu bertele-tele atau terlambat, tetapi ini adalah satu-satunya cara saya dapat menemukan untuk menyelesaikan pekerjaan. Faktor yang paling menyulitkan adalah fakta bahwa java tidak memiliki fungsi referensi, jadi metode get --- memerlukan default untuk kembali dan tidak dapat mengubah nilai boolean untuk mengetahui apakah nilai default dikembalikan secara kebetulan, atau karena hasilnya tidak menguntungkan. Untuk tujuan ini, akan lebih baik untuk memiliki metode meningkatkan pengecualian daripada mengembalikannya default.

Saya menemukan informasi saya di sini: Dokumentasi Intent 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

Atur Dokumentasi

    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();
    }
Jackson Kulik
sumber
Anda tidak ingin menulis begitu banyak kode untuk melakukan hal sederhana ini kecuali Anda ingin menyulitkan kode Anda begitu banyak sehingga Anda yakin tidak akan pernah bisa menyelesaikan pembaruan aplikasi Anda. Jawaban 2 teratas melakukan ini dengan kode jauh lebih sedikit, dan menggunakan Log, yang lebih baik daripada Toasts untuk penggunaan seperti itu
Louis CAD
0

Versi Kotlin dari metode utilitas Pratik yang membuang semua ekstra dari Intent:

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")

}
Roma
sumber
1
Akan lebih mudah digunakanfor (key in bundle.keySet())
DDoSolitary
-2

Jika untuk debugging semua yang Anda inginkan adalah string (semacam tersirat oleh OP tetapi tidak secara eksplisit dinyatakan), cukup gunakan toStringpada ekstra Bundle:

intent.getExtras().toString()

Ini mengembalikan string seperti:

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

Dokumentasi: Bundle.toString () (sayangnya ini adalah Object.toString()javadoc default dan karenanya tidak berguna di sini.)

ralfoide
sumber
4
Ketika saya mencoba ini mengembalikan: Bundel [mParcelledData.dataSize = 480]
ToddH