2

我正在编写一个应用程序:

  1. 拦截拨出电话

  2. 显示一个对话框,询问呼叫是“个人”还是“业务”(意大利语为“Aziendale”)

    • 如果是“个人”,则使用给定号码拨打电话
    • 如果 "business",在数字前面加上一个后缀(例如 4888 - 只是暂时在我的代码中)

关键是:由于我不知道如何让呼叫等待用户的选择,我:

  1. 关闭来电setResultData(null)

  2. 显示警报对话框

  3. 用户按下一个按钮后拨打电话

但是,到了打电话的时候,什么都没有发生。

让我描述一下我的应用程序的类:

  • MainActivity(目前没有任何功能的标准自创活动 - 通话工作时会改进)

  • OutgoingCallReceiver(扩展类BroadcastReceiver- 拦截拨出电话)

  • AlertActivity(主题为警报对话框,显示警报)

  • CallActivity(由AlertActivity- 应拨打电话)

清单文件是:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.simplecall"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />


    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <receiver android:name="OutgoingCallReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
        <activity
            android:name="com.example.simplecall.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity 
            android:name="com.example.simplecall.AlertActivity"
            android:theme="@android:style/Theme.Dialog" >
        </activity>
        <activity 
            android:name="com.example.simplecall.CallActivity" >
        </activity>
    </application>

</manifest>

这是我编写课程的方式:

MainActivity

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

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

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

OutgoingCallReceiver

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class OutgoingCallReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub


        // il numero che si stava per chiamare
        final String numero = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);


        Intent in = new Intent(context,AlertActivity.class);
        in.putExtra("com.example.simplecall.numero", numero);
        in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        setResultData(null);
        context.startActivity(in);

        //Toast toast = Toast.makeText(context, "Chiamata verso: " + numero, 1500);
        //toast.show();
    }

}

AlertActivity

import android.app.Activity; 
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.widget.Toast;

public class AlertActivity extends Activity {
    String numero;
    Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
        numero = getIntent().getStringExtra("com.example.simplecall.numero");
        Toast toast = Toast.makeText(this, "numero : " + numero, 5000);
        toast.show();
        showSettingsAlert();


    }



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

     /**
     * Mostra una finestra di dialogo
     * Cliccando su Impostazioni si accede al menù di configurazione 
     * */
    public void showSettingsAlert(){
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);

        // Titolo della finestra
        alertDialog.setTitle("Tipo di chiamata");

        // Mostra l'avvertimento
        alertDialog.setMessage("Che tipo di chiamata effettuare?");

        // Cliccando su Impostazioni ...
        alertDialog.setPositiveButton("Aziendale", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog,int which) {
                numero = "tel:4888"+numero;
                /*
                 Intent callIntent = new Intent(Intent.ACTION_CALL);
                callIntent.setData(Uri.parse(numero));
                //dialog.dismiss();
                startActivity(callIntent);
               */
                Intent in = new Intent(mContext,CallActivity.class);
                in.putExtra("com.example.simplecall.numero", numero);
                in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                mContext.startActivity(in);
                dialog.dismiss();
                finish();
            }
        });

        // Cliccando su Personale
        alertDialog.setNegativeButton("Personale", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                numero = "tel:" + numero;
                /*
                Intent callIntent = new Intent(Intent.ACTION_CALL);
                callIntent.setData(Uri.parse(numero));
                //dialog.dismiss();

                startActivity(callIntent);
                */
                Intent in = new Intent(mContext,CallActivity.class);
                in.putExtra("com.example.simplecall.numero", numero);
                in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                mContext.startActivity(in);
                dialog.dismiss();
                finish();
            }
        });

        // Mostra la finestra di alert
        alertDialog.show();
    }

    private void makeCall(String number, DialogInterface dial) {
        dial.dismiss();
        try {
            Intent callIntent = new Intent(Intent.ACTION_CALL);
            callIntent.setData(Uri.parse("tel:"+number));
            startActivity(callIntent);
            finish();
        } catch (ActivityNotFoundException activityException) {
             activityException.printStackTrace();
        }
    }

}

CallActivity

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;

public class CallActivity extends Activity
{
String numero; 

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    numero = getIntent().getStringExtra("com.example.simplecall.numero");
    Intent callIntent = new Intent(Intent.ACTION_CALL);
    callIntent.setData(Uri.parse(numero));
    //finish();
    startActivity(callIntent);

}

}

但问题是当我实例化时CallActivity什么都没有发生......任何提示?

我创建了一个新的“应用程序”,只是为了测试我是否以正确的方式做所有事情,清单文件中的权限相同,但它只有一个标准的自我创建的活动,我在其中执行

Intent callIntent = new Intent(Intent.ACTION_CALL);
    callIntent.setData(Uri.parse("tel:xxx")); // xxx is a real number in the code
    finish();
    startActivity(callIntent);

一切正常,不明白我失败的地方。

我还注意到,如果由于任何原因在按下两个按钮之一后应用程序崩溃(例如,如果我在没有调用 super.ondestroy() 的情况下调用 onDestroy()),则调用正确执行

4

2 回答 2

1

一旦你弄清楚问题实际上很简单。你有一个用于传出呼叫的广播接收器,它会拦截它们并显示你的对话。在您选择是私人电话还是商务电话后,您使用修改后的号码拨打电话......并猜猜谁拦截了电话?您的广播接收器,因此循环进行。为了防止这种无限循环,我知道的唯一方法是在进行修改后的呼叫之前禁用广播接收器,并在呼叫结束后再次启用它。

private void makeCall1(String number)  {
    PackageManager pm = mContext.getPackageManager();
    ComponentName componentName = new ComponentName(mContext, OutgoingCallReceiver.class);
    pm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
    Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse(number));
    startActivity(callIntent);
    // Now wait for the call to end somehow and afterwards ->
    // pm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}

我希望我有帮助!

于 2013-07-12T15:52:09.570 回答
0

可以拦截拨出电话,并使用特定的 BroadcastReceiver 进行更改。请参阅Android 开发人员博客中的此条目

现在,问题是 BroadcastReceivers 需要立即处理它。在这里,我们不知道用户响应对话花费了多少时间。

如上面博客条目中的示例所示,在用户响应后取消广播、显示对话框和拨号。但是这一次,在意图中放置一个额外的标志,表明此调用已被处理,因此您的 BroadcastReceivers 下次不会处理它。

于 2013-07-12T16:28:33.970 回答