先看下效果图
说下思路:
1:监听来电广播
2:根据来电号码,和本地数据库做匹配,有记录的,则提取出头像、名字、职位,生成悬浮窗
3:监听来电广播,如果当前行为是空闲的(没有任何通话行为),则删除掉悬浮窗。
tips:原先使用服务来监听,可惜在后台服务锁屏后一段时间很容易被杀死,试过各种办法无效,所以采用监听广播的方式,但是在魅族手机上测试时,发现需要允许(开机自启动),否则一样监听不到广播
说了思路之后,就贴上代码了,逻辑很简单,就不多赘述了。
1:监听来电类
记得在AndroidManifest.xml加上权限声明
<receiver android:name=".call.IncomingCallBroadCastReceiver"> <intent-filter android:priority="1000"> <action android:name="android.intent.action.PHONE_STATE" /> </intent-filter> </receiver>
package zhexian.app.smartcall.call; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.telephony.TelephonyManager; import android.view.View; import android.view.WindowManager; import zhexian.app.smartcall.base.BaseApplication; public class IncomingCallBroadCastReceiver extends BroadcastReceiver { private static View addedView = null; @Override public void onReceive(Context context, Intent intent) { TelephonyManager tManager = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE); int callState = tManager.getCallState(); switch (callState) { case TelephonyManager.CALL_STATE_RINGING: removeView(context); CallFlatWindowManager windowManager = new CallFlatWindowManager((BaseApplication) context.getApplicationContext()); String incomingNumber = intent.getStringExtra("incoming_number"); addedView = windowManager.OnCall(incomingNumber); break; case TelephonyManager.CALL_STATE_IDLE: removeView(context); break; } } void removeView(Context context) { if (addedView == null) return; try { WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); windowManager.removeViewImmediate(addedView); } catch (Exception e) { e.printStackTrace(); } finally { addedView = null; } } }
悬浮窗实现代码也一并贴出,仅供各位参考
通过WindowManager,生成一个不可触摸的窗体
package zhexian.app.smartcall.call; import android.content.Context; import android.graphics.PixelFormat; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; import android.widget.TextView; import zhexian.app.smartcall.R; import zhexian.app.smartcall.base.BaseApplication; import zhexian.app.smartcall.lib.ZContact; import zhexian.app.smartcall.lib.ZIO; import zhexian.app.smartcall.lib.ZString; import zhexian.app.smartcall.tools.Utils; /** * 来电悬浮窗管理类 */ public class CallFlatWindowManager { private int IMAGE_SIZE = 128; private WindowManager mWindowManager; private WindowManager.LayoutParams layoutParams; private View view; private TextView mUserName; private TextView mJob; private BaseApplication baseApp; private ImageView imageView; public CallFlatWindowManager(BaseApplication baseApp) { this.baseApp = baseApp; initWindow(); ContactSQLHelper.Init(baseApp); } public View OnCall(String incomingNumber) { if (ZContact.isPhoneExists(baseApp, incomingNumber)) return null; CallUserEntity entity = ContactSQLHelper.getInstance().getContact(incomingNumber); if (entity == null) return null; return attachWindow(entity.getName(), entity.getJob(), entity.getAvatarUrl()); } private View attachWindow(String userName, String job, String url) { mUserName.setText(userName); mJob.setText(job); loadImage(url); mWindowManager.addView(view, layoutParams); return view; } private void initWindow() { mWindowManager = (WindowManager) baseApp.getSystemService(Context.WINDOW_SERVICE); layoutParams = new WindowManager.LayoutParams(); layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; layoutParams.format = PixelFormat.RGBA_8888; layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; LayoutInflater inflater = (LayoutInflater) baseApp.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.call_flat_window, null); mUserName = (TextView) view.findViewById(R.id.flat_user_name); imageView = (ImageView) view.findViewById(R.id.flat_user_avatar); mJob = (TextView) view.findViewById(R.id.flat_user_job); } private void loadImage(String url) { if (url.isEmpty()) { imageView.setVisibility(View.GONE); return; } String cachedUrl = ZString.getFileCachedDir(url, baseApp.getFilePath()); if (ZIO.isExist(cachedUrl)) imageView.setImageBitmap(Utils.getScaledBitMap(cachedUrl, IMAGE_SIZE, IMAGE_SIZE)); else imageView.setVisibility(View.GONE); } }