如何在Android中以编程方式拨打电话?

时间:2014-04-30 14:17:41

标签: java android android-intent phone-call

enter image description here

我在useful_numbers_item_fragment.xml中定义了以下布局:

<LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:id="@+id/call_linear_layout">

        <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:orientation="vertical">
            <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/useful_nums_item_name"/>

            <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/useful_nums_item_value"/>
        </LinearLayout>

       <ImageButton
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:src="@drawable/call"
                android:id="@+id/call_btn"
                android:onClick="callNumber"/>

    </LinearLayout>

我在名为UNItemListFragment.java的类中动态填充两个文本视图 在onCreate方法中:

public void onCreate(Bundle savedInstance) {
        super.onCreate(savedInstance);

        if (getArguments().containsKey(Constants.UNItem.GROUP_ID)) {

            simpleCursorAdapter = new SimpleCursorAdapter(getActivity(), R.layout.useful_numbers_item_fragment, null,
                    new String[]{Constants.UNItem.NAME, Constants.UNItem.VALUE},
                    new int[]{R.id.useful_nums_item_name, R.id.useful_nums_item_value}, 0);
            setListAdapter(simpleCursorAdapter);
            getLoaderManager().initLoader(0, getArguments(), this);

        }
    }

对于每个号码,如果我点击按钮,我想拨打电话 用户单击按钮时调用callNumber方法:

public void callNumber(View view) {
        Intent callIntent = new Intent(Intent.ACTION_CALL);
        TextView unItemVal = (TextView) findViewById(R.id.useful_nums_item_value);

            String phoneNumber = unItemVal.getText().toString();
            callIntent.setData(Uri.parse("tel:" + phoneNumber));
            startActivity(callIntent);
    }

单击列表中的第一个按钮即可,但是当我单击其他按钮时 它继续调用第一行中定义的数字......

知道如何解决这个问题吗?

2 个答案:

答案 0 :(得分:9)

问题是这一行:

TextView unItemVal = (TextView) findViewById(R.id.useful_nums_item_value);

在活动上执行,因此findViewById将始终返回带有该ID的第一个项目,这可能是列表中的第一个项目。

解决此问题的最佳方法是覆盖适配器并将包含电话号码的标记添加到视图中。 快速修复此问题的方法是在视图层次结构中进行标记,如下所示:

public void callNumber(View view) {
    if( view != null ) { // view is the button tapped
        View parent = view.getParent(); // this should be the LinearLayout
        if( parent instanceof LinearLayout ) {
            TextView unItemVal = (TextView) ((LinearLayout)parent).findViewById(R.id.useful_nums_item_value);
            if( unItemVal != null ) {
                Intent callIntent = new Intent(Intent.ACTION_CALL);
                String phoneNumber = unItemVal.getText().toString();
                callIntent.setData(Uri.parse("tel:" + phoneNumber));
                startActivity(callIntent);
            }
        }
    }
}

这将找到被点击的按钮的父级,然后找到包含该ViewGroup内的数字的文本视图。

答案 1 :(得分:0)

使用findViewById()将返回具有指定ID的活动或片段中的第一个视图。如果这是一个ListView,它将对应第一行。

有很多方法可以解决这个问题。最快的(但肯定不是最漂亮的,因为它取决于布局)将是相对于包含列表项的LinearLayout使用findViewById()。假设view是ImageButton,它将类​​似于:

((View)view.getParent()).findViewById(R.id.useful_nums_item_value)

更优雅的解决方案是在适配器getView()中设置一个标签,其中包含您需要的数据(在这种情况下,是要拨打的电话号码)。