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