java 如何访问 com.android.internal.telephony.CallManager?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4745899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 07:50:21  来源:igfitidea点击:

how to access com.android.internal.telephony.CallManager?

javaandroidtelephony

提问by Harsha

I am trying to access CallManagerclass object from com.android.internal.telephonypackage.

我正在尝试CallManagercom.android.internal.telephony包访问类对象。

Here is my code:

这是我的代码:

ClassLoader classLoader = TestActivity.class.getClassLoader();
final ClassLoader classLoader = this.getClass().getClassLoader();
try {
    final Class<?> classCallManager =
        classLoader.loadClass("com.android.internal.telephony.CallManager");
    Log.i("TestActivity", classCallManager);
} catch (final ClassNotFoundException e) {
    Log.e("TestActivity", e);
}

Unfortunately, this is throwing a ClassNotFoundException. The same approach allows me to access PhoneFactory, but apparently I'm not allowed to access CallManager.

不幸的是,这是抛出一个ClassNotFoundException. 同样的方法允许我访问PhoneFactory,但显然我不允许访问CallManager.

If I could reach the class, then I'd want to proceed using the class as follows:

如果我可以参加该课程,那么我想继续使用该课程,如下所示:

Method method_getInstance;
method_getInstance = classCallManager.getDeclaredMethod("getInstance");
method_getInstance.setAccessible(true);
Object callManagerInstance = method_getInstance.invoke(null);

Can anyone help me on this?

谁可以帮我这个事?

Thanks in advance,
Harsha C

提前致谢,
Harsha C

回答by tuan

I could successfully load CallManager and its methods. However, when I invoke getState(), getActiveFgCallState(), it always return IDLE even when the app receives different call states from TelephonyManager, i.e. TelephonyManager.CALL_STATE_IDLE, TelephonyManager.CALL_STATE_OFFHOOK, TelephonyManager.CALL_STATE_RINGING.

我可以成功加载 CallManager 及其方法。但是,当我调用 getState()、getActiveFgCallState() 时,即使应用程序从 TelephonyManager 接收到不同的呼叫状态,它也总是返回 IDLE,即 TelephonyManager.CALL_STATE_IDLE、TelephonyManager.CALL_STATE_OFFHOOK、TelephonyManager.CALL_STATE_RINGING。

I used the following code to load the class and its methods:

我使用以下代码加载类及其方法:

final Class<?> classCallManager = classLoader.loadClass("com.android.internal.telephony.CallManager");
Log.i(TAG, "Class loaded " + classCallManager.toString());

Method methodGetInstance = classCallManager.getDeclaredMethod("getInstance");
Log.i(TAG, "Method loaded " + methodGetInstance.getName());

Object objectCallManager = methodGetInstance.invoke(null);
Log.i(TAG, "Object loaded " + objectCallManager.getClass().getName());


Method methodGetState = classCallManager.getDeclaredMethod("getState");
Log.i(TAG, "Method loaded " + methodGetState.getName());

Log.i(TAG, "Phone state = " + methodGetState.invoke(objectCallManager));

Btw, what I am trying to do is detecting when the phone starts ringing. I saw in the source code that ALERTING is the internal event that I should listen to. Therefore, I tried to use CallManager to get Call.State, rather than Phone.State. I also tried to use registerForPreciseCallStateChanges() of CallManager class but none of approached worked so far.

顺便说一句,我想做的是检测电话何时开始响铃。我在源代码中看到 ALERTING 是我应该监听的内部事件。因此,我尝试使用CallManager 来获取Call.State,而不是Phone.State。我还尝试使用 CallManager 类的 registerForPreciseCallStateChanges() 但到目前为止没有任何方法起作用。

回答by Cyrus

I had to solve the exact same problem - getting the disconnection cause during call hangup. My solution was to grep the radio logs for the relevant lines. Seems to work - hope it helps.

我必须解决完全相同的问题 - 在呼叫挂断期间获取断开连接的原因。我的解决方案是 grep 相关线路的无线电日志。似乎有效 - 希望它有所帮助。

private void startRadioLogListener() {
    new Thread(new Runnable() {
        public void run() {
            Process process = null;
            try {
                // Clear the log first
                String myCommandClear = "logcat -b radio -c";  
                Runtime.getRuntime().exec(myCommandClear);

                String myCommand = "logcat -b radio";  
                process = Runtime.getRuntime().exec(myCommand);
                Log.e(LogHelper.CAL_MON, "RadioLogProc: " + process);

                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                while (true) {
                    final String line = bufferedReader.readLine();
                    if (line != null) {
                        if (line.contains("disconnectCauseFromCode") || line.contains("LAST_CALL_FAIL_CAUSE")) {
                            Log.d(LogHelper.CAL_MON, "RadioLog: " + line);
                            radioLogHandler.post(new Runnable() {
                                public void run() {
                                    consolePrint("Radio: " + line + "\n");
                                }
                            });
                        }
                    }
                }
            } catch (IOException e) {
                Log.e(LogHelper.CAL_MON, "Can't get radio log", e);
            } finally {
                if (process != null) {
                    process.destroy();
                }
            }
        }
    }).start();
}

回答by sm13294

I have written a program that recognize the phone calls and list all recent calls in a list. Maybe you can have a look on this code and it can help I think. All you need is this:

我编写了一个程序,可以识别电话并在列表中列出所有最近的电话。也许你可以看看这段代码,它可以帮助我思考。你只需要这个:

String state = bundle.getString(TelephonyManager.EXTRA_STATE);
if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING))

but check this example also:

但也要检查这个例子:

package org.java.sm222bt;

import org.java.sm222bt.R;

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;

public class MainActivity extends ListActivity {
private CountryDbAdapter db;
private Cursor entrycursor;
private ListAdapter adapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //setContentView(R.layout.main);
    registerForContextMenu(getListView());
    db = new CountryDbAdapter(this);
   updateEntry();

}
public void updateEntry(){
    db.open();

    entrycursor = db.fetchAllEntries();

    adapter = new SimpleCursorAdapter(this, R.layout.row, entrycursor, new String[] {"phonenumber"}, new int[] {R.id.number});
    setListAdapter(adapter);
    db.close();
}
@Override
protected void onResume() {

    super.onResume();
    updateEntry();
}

public static final int Call = 0;
public static final int SendSMS = 1;
public static final int Share = 2;
public static final int Delete = 3;
public static final int ClearList = 4;



public void onCreateContextMenu(ContextMenu menu, View v, 
ContextMenu.ContextMenuInfo menuInfo) { 
menu.setHeaderTitle("Select:"); 
menu.add(0, Call, 0, "Call");
menu.add(0, SendSMS, 0, "Send SMS");
menu.add(0, Share, 0, "Share");
menu.add(0, Delete, 0, "Delete");
menu.add(0, ClearList, 0, "Clear all contacts");


}

@Override
public boolean onContextItemSelected(MenuItem item) { 
switch (item.getItemId()) {
case Call:
//System.out.println(entrycursor.getString(1));
//EditText number=(EditText)findViewById(R.id.number);
String toDial="tel:"+entrycursor.getString(1);
//start activity for ACTION_DIAL or ACTION_CALL intent
startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse(toDial)));
    //update(entryCursor.getLong(0));
return true;
case SendSMS:


    //EditText number=(EditText)findViewById(R.id.number);
    //EditText msg=(EditText)findViewById(R.id.msg);
    String sendUri="smsto:"+entrycursor.getString(1);
    Intent sms=new Intent(Intent.ACTION_SENDTO,
                            Uri.parse(sendUri));
    //sms.putExtra("sms_body", msg.getText().toString());
    startActivity(sms);

return true;
case Share:

    Intent i=new Intent(Intent.ACTION_SEND);
    i.setType("text/plain");
    i.putExtra(Intent.EXTRA_SUBJECT, "Hello");
    i.putExtra(Intent.EXTRA_TEXT, "Sharing this number"+entrycursor.getString(1));
    startActivity(Intent.createChooser(i,
                                  entrycursor.getString(1)));
    return true;

case Delete:

    db.open();
    db.deleteEntry(entrycursor.getLong(0));
    db.close();
    updateEntry();

return true;

case ClearList:

    db.open();
    db.deleteEntry();
    db.close();
    updateEntry();

    return true;

default:
return super.onContextItemSelected(item);
}
}
}

and here is the incomming call receiver:

这是来电接收器:

package org.java.sm222bt;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;

public class IncomingCallReceiver extends BroadcastReceiver {
CountryDbAdapter db;
@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub
    Bundle bundle = intent.getExtras();
    if(null == bundle)
            return;
    String state = bundle.getString(TelephonyManager.EXTRA_STATE);
    if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING))
    {
        String phonenumber = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
        System.out.println(phonenumber);

        db = new CountryDbAdapter(context);
        db.open();
        db.insertEntry(phonenumber);
        db.fetchAllEntries();
        db.close();

}
}} 

回答by t0mm13b

Have you tried this method found here on this blog?

您是否尝试过在此博客上找到的这种方法?

By loading the Phone.apk might be the clue to getting around the ClassNotFound exception error...

通过加载 Phone.apk 可能是绕过 ClassNotFound 异常错误的线索......

回答by Paul Lammertsma

I understand that you want to detect when the call is disconnected. You can instead use the PhoneStateListener.LISTEN_CALL_STATE. For example:

我了解您想检测通话何时断开。您可以改为使用PhoneStateListener.LISTEN_CALL_STATE. 例如:

final TelephonyManager telephony = (TelephonyManager)
        getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(new PhoneStateListener() {
    public void onCallStateChanged(final int state,
            final String incomingNumber) {
        switch (state) {
        case TelephonyManager.CALL_STATE_IDLE:
            break;
        case TelephonyManager.CALL_STATE_OFFHOOK:
            Log.d("TestActivity", "Call disconnected");
            break;
        case TelephonyManager.CALL_STATE_RINGING:
            break;
        default:
            break;
        }
    }
}, PhoneStateListener.LISTEN_CALL_STATE);

回答by Avadhani Y

Use this :

用这个 :

    telephone = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

    private PhoneStateListener psl = new PhoneStateListener() {

    @Override
    public  void onCallStateChanged (int state, String incomingNumber)
    {
        state = telephone.getCallState();

        switch(state) {
        case android.telephony.TelephonyManager.CALL_STATE_IDLE:    
            if (callsucces ) act();

            break;
        case android.telephony.TelephonyManager.CALL_STATE_RINGING:
            callsucces = true; 
            break;
        case android.telephony.TelephonyManager.CALL_STATE_OFFHOOK:
            callsucces = true; 
            break;
        }
    }

};


   private void call(String pnum) {
    try {

        callIntent = new Intent(Intent.ACTION_CALL);

        callsucces = false;
        if (telephone.getNetworkType() != 0) {
        if (telephone.getCallState() == TelephonyManager.CALL_STATE_IDLE) {
        callIntent.setData(Uri.parse("tel:"+pnum)); 
        startActivity(callIntent);
        telephone.listen(psl,PhoneStateListener.LISTEN_CALL_STATE);
        }
        } else act();
        //callIntent.ACTION_NEW_OUTGOING_CALL
    } catch (ActivityNotFoundException activityException) {
         Toast.makeText(getBaseContext(), "Call failed",Toast.LENGTH_SHORT).show();
         act();

    }
}

回答by Tanmay Mandal

Did you add READ_PHONE_STATEin AndroidManifest.xml ?

您是否添加READ_PHONE_STATE了 AndroidManifest.xml ?

I think you miss that one.

我想你很想念那个。