Liệt kê tất cả các tính năng bổ sung của một ý định


251

Vì lý do gỡ lỗi, tôi muốn liệt kê tất cả các tính năng bổ sung (và giá trị của chúng) của một Mục đích. Bây giờ, nhận được các phím không phải là một vấn đề

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

nhưng nhận được các giá trị của các khóa là một đối với tôi, bởi vì một số giá trị là các chuỗi, một số là boolean ... Làm thế nào tôi có thể nhận các giá trị trong một vòng lặp (lặp qua các khóa) và ghi các giá trị vào một logfile? Cảm ơn cho bất kỳ gợi ý!

Câu trả lời:


467

Đây là những gì tôi đã sử dụng để có được thông tin về mục đích không có giấy tờ (bên thứ 3):

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

Hãy chắc chắn kiểm tra nếu bundlenull trước vòng lặp.


2
Tôi vừa tìm hiểu về ứng dụng Intent Intercept Android . Điều đó cũng làm việc.
Vinayak

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

23
Bundle bundle = data.getExtras();Trong trường hợp datalà tiếp cận mục đích. Dành cho người mới bắt đầu sử dụng Android.
Kẻ chinh phụcHaki

2
Trước khi đăng nhập, bạn cần kiểm tra xem giá trị có phải là null hay không, nếu có value = "null".
Sebastian Kreft

Cảm ơn vì điều đó! Đã tìm cách để kiểm tra tất cả các phím được cung cấp trong ứng dụng iTracing không có giấy tờ này, để điều khiển điện thoại của tôi thông qua nút Bluetooth giá rẻ. Làm việc như người ở!
Shane Smiskol

111

Đây là cách tôi xác định phương thức tiện ích để kết xuất tất cả các tính năng bổ sung của Ý định.

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
Cảm ơn! Bây giờ nếu chỉ có nhóm Android sẽ bắt đầu triển khai .toString ghi đè như thế này.
Jim Vitek

37

Bạn có thể làm điều đó trong một dòng mã:

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

Nó xuất ra một cái gì đó như:

"#Intent; action = android.intent.action.MAIN; category = android.intent.category.LAUNCHER; launchFlags = 0x10a00000; thành phần = com.mydomain.myapp / .StartActivity; sourceBounds = 12% 20.870% 20.276% 201.167; l .profile = 0; kết thúc "

Ở cuối chuỗi này (phần mà tôi đã in đậm), bạn có thể tìm thấy danh sách các phần bổ sung (chỉ có một phần bổ sung trong ví dụ này).

Đây là theo tài liệu của toUri : "URI chứa dữ liệu của Intent là URI cơ sở, với một đoạn bổ sung mô tả hành động, danh mục, loại, cờ, gói, thành phần và phần bổ sung."


3
Nếu bạn chỉ muốn gỡ lỗi và xem nội dung của ý định là gì thì đây là lựa chọn tốt nhất. Cảm ơn bạn rất nhiều
Shyri

Đây phải là câu trả lời được chấp nhận. Hoàn hảo để gỡ lỗi đăng nhập!
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());
    }
}

8

Phương thức get (String String) của Bundle trả về một Object. Đặt cược tốt nhất của bạn là quay vòng tập hợp gọi get (String) trên mỗi khóa và sử dụng toString () trên Object để xuất chúng. Điều này sẽ hoạt động tốt nhất cho người nguyên thủy, nhưng bạn có thể gặp phải các vấn đề với các Đối tượng không triển khai 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
for (Khóa chuỗi: extend.keySet ()) {Log.d (LOGiah, key + ":" + extend.get (key)); }
Defuera

4

Tôi muốn có một cách để xuất nội dung của một ý định vào nhật ký và để có thể đọc nó dễ dàng, vì vậy đây là những gì tôi nghĩ ra. Tôi đã tạo một LogUtillớp và sau đó lấy dumpIntent()phương thức @Pratik đã tạo và sửa đổi nó một chút. Đây là những gì tất cả trông giống như:

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

Hy vọng điều này sẽ giúp được ai đó!


2

Bạn có thể sử dụng for (String key : keys) { Object o = get(key);để trả về một Object, gọi getClass().getName()nó để lấy kiểu và sau đó thực hiện một tập hợp các kiểu if name.equals ("String") để tìm ra phương thức nào bạn thực sự nên gọi, để có được giá trị ?


1

Tôi nhận thấy trong nguồn Android rằng hầu hết mọi hoạt động đều buộc Bundle phải hủy dữ liệu của nó. Vì vậy, nếu (như tôi) bạn cần thực hiện việc này thường xuyên cho mục đích gỡ lỗi, thì dưới đây rất nhanh để gõ:

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

0

Xin lỗi nếu điều này quá dài dòng hoặc quá muộn, nhưng đây là cách duy nhất tôi có thể tìm thấy để hoàn thành công việc. Yếu tố phức tạp nhất là java không có các hàm tham chiếu, vì vậy các phương thức get --- cần mặc định để trả về và không thể sửa đổi giá trị boolean để biết liệu giá trị mặc định có được trả về một cách tình cờ hay không, hoặc vì kết quả không thuận lợi. Với mục đích này, sẽ tốt hơn nếu phương thức đưa ra một ngoại lệ hơn là để nó trả về một mặc định.

Tôi tìm thấy thông tin của mình ở đây: Tài liệu Ý định 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

Đặt tài liệu

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

Bạn không muốn viết quá nhiều mã để làm điều đơn giản này trừ khi bạn muốn làm phức tạp mã của mình đến mức bạn chắc chắn sẽ không bao giờ có thể cập nhật ứng dụng của mình. Top-2 câu trả lời thực hiện điều này với ít mã hơn và sử dụng Log, tốt hơn so với Toasts cho các cách sử dụng đó
Louis CAD

0

Phiên bản Kotlin của phương thức tiện ích của Pratik, loại bỏ tất cả các tính năng bổ sung của Ý định:

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
Nó sẽ đơn giản hơn để sử dụngfor (key in bundle.keySet())
DDoSol biệt

-2

Nếu để gỡ lỗi tất cả những gì bạn muốn là một chuỗi (loại được ngụ ý bởi OP nhưng không được nêu rõ ràng), chỉ cần sử dụng toStringtrên các tính năng bổ sung Bundle:

intent.getExtras().toString()

Nó trả về một chuỗi như:

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

Tài liệu: Bundle.toString () (thật không may là Object.toString()javadoc mặc định và như vậy khá vô dụng ở đây.)


4
Khi tôi thử cái này, nó trả về: Bundle [mParcelledData.dataSize = 480]
ToddH
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.