Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何访问com.android.internal.telephony.CallManager?_Java_Android_Telephony - Fatal编程技术网

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

Java 如何访问com.android.internal.telephony.CallManager?,java,android,telephony,Java,Android,Telephony,我正在尝试从com.android.internal.telephony包访问CallManager类对象 这是我的密码: ClassLoader classLoader = TestActivity.class.getClassLoader(); final ClassLoader classLoader = this.getClass().getClassLoader(); try { final Class<?> classCallManager = c

我正在尝试从
com.android.internal.telephony
包访问
CallManager
类对象

这是我的密码:

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);
}
有人能帮我吗

提前感谢,

Harsha C

您是否在AndroidManifest.xml中添加了
READ\u PHONE\u STATE


我想你错过了这一次。

我知道你想检测电话何时断开。您可以改为使用
PhoneStateListener.LISTEN\u CALL\u 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);

你有没有试过这个方法


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

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

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

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));
final Class classCallManager=classLoader.loadClass(“com.android.internal.telephony.CallManager”);
Log.i(标记,“类加载”+classCallManager.toString());
方法methodGetInstance=classCallManager.getDeclaredMethod(“getInstance”);
i(标记“方法加载”+methodGetInstance.getName());
Object objectCallManager=methodGetInstance.invoke(null);
Log.i(标记“Object loaded”+objectCallManager.getClass().getName());
方法methodGetState=classCallManager.getDeclaredMethod(“getState”);
Log.i(标记,“方法加载”+methodGetState.getName());
Log.i(标记“Phone state=“+methodGetState.invoke(objectCallManager));
顺便说一句,我想做的是检测电话何时开始响。我在源代码中看到,警报是我应该侦听的内部事件。因此,我尝试使用CallManager获取Call.State,而不是Phone.State。我还尝试使用CallManager类的registerForReciseCallStateChanges(),但到目前为止,所有方法都不起作用。

使用以下方法:

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

    }
}

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

String state = bundle.getString(TelephonyManager.EXTRA_STATE);
if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING))
但也请检查此示例:

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);
}
}
}
这是输入呼叫接收器:

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

}
}} 

我必须解决完全相同的问题——在挂断电话时找出断开的原因。我的解决方案是将相关线路的无线电日志进行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();
}

否…:(我想访问CallManager实例,这样我就可以解析整个类并到达GSMConnection以获取调用断开状态。因为所有这些都是内部API,所以我尝试使用Java Refletion。我已经尝试使用
ClassLoader.getSystemClassLoader()
,但这也不起作用。不。我的要求是找出掉话的原因。无论是网络故障还是通话中断等等。对。我实际上在尝试完成类似的事情(发送DTMF音),这也需要访问CallManager。让我们看看是否可以一起解决。您尝试访问CallManager了吗?我在这里尝试做同样的事情….:D也看到了我上面的答案…:D@tommieb75不,恐怕不行。我调查了
Phone.apk
的操作方式,似乎它有特殊权限。我不记得确切的错误,但唯一的解决办法归结为必须根手机。该死的!我正在用API8(android版本2.2)尝试这一点但它似乎不起任何作用?我认为这已经不起作用了,因为Android 4.1,应用程序日志只能由他们自己的应用程序读取…我试图在几天内无任何进展地访问精确的通话状态。我发现,
CallManager
本身在未注册的
Phone
情况下不会提供任何通话信息实例,即它从外部接收有关呼叫状态更改的通知。您正在从应用程序进程访问
CallManager
类,因此您将获得一个在所有字段中都具有默认值的空实例,而
CallManager
的实际实例包含处理cal的
Phone
实例l位于另一个进程中,可能位于某些系统服务中,如电话服务。@VladimirDmi您找到它可能是哪个服务了吗?
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();
}