要实现一个打电话却不能显示号码的功能。本来想写一个拨号器,可以完全替代系统phone的软件。不过研究了系统的phone代码之后就放弃了这个想法。不是一件容易的事。所以只好另想他法。使用系统拨号软件,但是在其上覆盖一层自己的界面。开始查资料。 首先要实现①拨号功能。使用反射和aidl。调用IPhoneInterface接口,获取对象并调用call方法来拨打电话。同时②在系统层添加一层覆盖。管段电话后③删除此次通话记录。
1、利用反射原理打电话和挂断电话:
a. 在src下新建一个包:com.android.internal.telephony(和ITelephony.aidl 中 package 声明的包名一样);
b. 然后从系统源码中把ITelephony.aidl文件拷贝到 com.android.internal.telephony包下。(也可以先新建一个ITelephony.aidl, 然后再把内容拷贝进去(ITelephony.aidl文件内容可以 在http://www.netmite.com/android/mydroid/1.5/frameworks/base/telephony/java/com/android/internal/telephony/ITelephony.aidl找到,这个方法适合没有SDK源码文件的开发者));
c. 在src下新建一个包:android.telephony, 然后新建一个NeighboringCellInfo.aidl,其内容为:
package android.telephony;
parcelable NeighboringCellInfo;
下面是调用的代码:
private static TelephonyManager manager;
manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
ITelephony phone = PhoneUtils.getITelephony(manager);
//下面是拨打电话和挂断电话的操作
phone.call(number); phone.endCall();
PhoneUtils中代码:
package com.linwoain.dial;
import java.lang.reflect.Method;
import com.android.internal.telephony.ITelephony;
import android.content.Context;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
public class PhoneUtils {
/**
* return the ITelephony instance
*
* @param telMgr Provides access to information about the telephony services on the device
* @return ITelephony instance
* @throws Exception
*/
static ITelephony getITelephony(TelephonyManager manager) throws Exception {
Method getITelephonyMethod = manager.getClass().getDeclaredMethod("getITelephony");
getITelephonyMethod.setAccessible(true);
return (ITelephony) getITelephonyMethod.invoke(manager);
}
public static void Call(Context context, String number) {
try {
TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
getITelephony(mTelephonyManager).call(number);
} catch (RemoteException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* end the ringing call
*
* @param context
* Interface to global information about an application
* environment
*/
public static void endRingingCall(Context context) {
try {
TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
getITelephony(mTelephonyManager).endCall();
} catch (RemoteException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* answer the ringing call
*
* @param context
* Interface to global information about an application
* environment
*/
public static void answerRingingCall(Context context) {
try {
TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
getITelephony(mTelephonyManager).answerRingingCall();
} catch (RemoteException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.linwoain.dial;
import android.app.Activity;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
public class Layer
{
private Activity mActivty;
private WindowManager mWindowManager;
private View mLockView;
private LayoutParams mLockViewLayoutParams;
private static Layer mLockLayer;
private boolean isLocked;
public static synchronized Layer getInstance(Activity act)
{
if (mLockLayer == null)
{
mLockLayer = new Layer(act);
}
return mLockLayer;
}
private Layer(Activity act)
{
mActivty = act;
init();
}
private void init()
{
isLocked = false;
mWindowManager = (WindowManager) mActivty.getApplication().getSystemService("window");
mLockViewLayoutParams = new LayoutParams();
mLockViewLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
mLockViewLayoutParams.x = 0;
mLockViewLayoutParams.y = 0;
mLockViewLayoutParams.width = 480;
mLockViewLayoutParams.height = 800;
mLockViewLayoutParams.type = LayoutParams.TYPE_SYSTEM_ALERT;
}
public synchronized void lock()
{
if (mLockView != null && !isLocked)
{
mWindowManager.addView(mLockView, mLockViewLayoutParams);
}
isLocked = true;
}
public synchronized void unlock()
{
if (mWindowManager != null && isLocked)
{
mWindowManager.removeView(mLockView);
}
isLocked = false;
}
public synchronized void setView(View v)
{
mLockView = v;
}
public synchronized void setLayer(int type)
{
mLockViewLayoutParams.type = type;
}
}
需要调用时,获取实例。
layer = Layer.getInstance(getActivity());
layer.setView(view);
layer.lock();当挂断电话时执行
layer.unlock();
3 、删除通话记录
getContentResolver().delete(CallLog.Calls.CONTENT_URI, "number=?", new String[]{number});
因为使用了对通话记录的修改,需要添加权限。
小结:找了一天的资料,终于搞清楚了如何从覆盖一个图层上显示出来。有很多的代码参考了其他作者。将其列出:
关于对打电话部分的DIY-Android源码下载-eoe 移动开发者论坛 - Powered by Discuz! http://www.eoeandroid.com/thread-203681-1-1.html
android 悬浮窗口 - winson_jason的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/winson_jason/article/details/8160718
android 通话记录的查询与删除 - flying_vip_521的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/flying_vip_521/article/details/7258805
来自为知笔记(Wiz)