Android编程中黑名单的实现方法

本文实例讲述了Android编程中黑名单的实现方法。分享给大家供大家参考,具体如下:

说明:由于挂断电话android   api不是对外开放的,所以需要使用反射的方法得到拨打电话的服务。

1.将android源代码中的"aidl"文件拷贝到项目中

这样项目中会生成两个包:android.telephony;此包中文件为:NeighboringCellInfo.aidl

com.android.internal.telephony;此包中文件为:ITelephony.aidl

2.通过反射挂断电话;代码如下:

/**
* 挂断电话
*/
public void endCall() {
    try {
      Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);
      IBinder binder = (IBinder) method.invoke(null, new Object[]{TELEPHONY_SERVICE});
      ITelephony telephony = ITelephony.Stub.asInterface(binder);
      telephony.endCall();
    } catch (Exception e) {
      e.printStackTrace();
    }
}

3.删除通话记录中的记录

/**
* 删除呼叫记录
*/
public void deleteCallLog(String incomingNumber) {
    ContentResolver resolver = getContentResolver();
    Cursor cursor = resolver.query(CallLog.Calls.CONTENT_URI, null,"number=?", new String[]{incomingNumber}, null);
    if(cursor.moveToNext()){
      String id = cursor.getString(cursor.getColumnIndex("_id"));
      resolver.delete(CallLog.Calls.CONTENT_URI, "_id=?", new String[]{id});
    }
}

4.直接这样调用是不能删除电话记录的,因为生成电话记录的过程是一个异步的过程,在挂断电话之后不能立即删除电话记录,所以这里要使用ContentObserver(内容观察者)

private class MyObserver extends ContentObserver{
    private String incomingNumber;
    public MyObserver(Handler handler,String incomingNumber) {
      super(handler);
      this.incomingNumber = incomingNumber;
    }
    @Override
    public void onChange(boolean selfChange) {
      super.onChange(selfChange);
      deleteCallLog(incomingNumber);
      getContentResolver().unregisterContentObserver(this);
    }
}

6.最后把整个service代码贴到下面

public class AddressService extends Service{
  private static final String TAG = "AddressService";
  private TelephonyManager manager;
  private MyPhoneListener listener;
  private WindowManager wManager;
  private View view;
  private SharedPreferences sp;
  long startTime = 0;
  long endTime = 0;
  private BlackNumberDao dao;
  @Override
  public IBinder onBind(Intent arg0) {
    return null;
  }
  /**
   * 服务第一次被创建的时候调用的方法
   * 服务被初始化时调用的方法
   */
  @Override
  public void onCreate() {
    super.onCreate();
    listener = new MyPhoneListener();
    manager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    wManager = (WindowManager) this.getSystemService(WINDOW_SERVICE);
    manager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
    sp = getSharedPreferences("config", MODE_PRIVATE);
    dao = new BlackNumberDao(this);
//   if(3000>(endTime - startTime)){
//     String ns = Context.NOTIFICATION_SERVICE;
//     NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
//     //定义通知栏展现的内容信息
//     int icon = R.drawable.icon5;
//     CharSequence tickerText = "我的通知栏标题";
//     long when = System.currentTimeMillis();
//     Notification notification = new Notification(icon, tickerText, when);
//     //定义下拉通知栏时要展现的内容信息
//     Context context = getApplicationContext();
//     CharSequence contentTitle = "我的通知栏标展开标题";
//     CharSequence contentText = "我的通知栏展开详细内容";
//     Intent notificationIntent = new Intent(AddressService.this,BootStartDemo.class);
//     PendingIntent contentIntent = PendingIntent.getActivity(AddressService.this, 0,notificationIntent, 0);
//     notification.setLatestEventInfo(context, contentTitle, contentText,contentIntent);
//     //用mNotificationManager的notify方法通知用户生成标题栏消息通知
//     mNotificationManager.notify(1, notification);
//   }
  }
  /**
   * 服务停止的时候调用
   */
  @Override
  public void onDestroy() {
    super.onDestroy();
    manager.listen(listener, PhoneStateListener.LISTEN_NONE);
    listener = null;
  }
  private class MyPhoneListener extends PhoneStateListener{
    /**
     * 电话状态发生改变的时候调用的方法
     */
    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
      super.onCallStateChanged(state, incomingNumber);
      switch (state) {
      case TelephonyManager.CALL_STATE_IDLE:
        if(null != view){
          wManager.removeView(view);
          view = null;
        }
        endTime = System.currentTimeMillis();
        break;
      case TelephonyManager.CALL_STATE_RINGING: // 零响状态
        //判断number是否在黑名单中
        if(dao.find(incomingNumber)){
          //挂断电话
          endCall();
          //删除呼叫记录
//         deleteCallLog(incomingNumber);
          ContentResolver resolver = getContentResolver();
          resolver.registerContentObserver(CallLog.Calls.CONTENT_URI, true, new MyObserver(new Handler(),incomingNumber));
        }
        Log.i(TAG,"来电号码为"+ incomingNumber);
        String address = NumberAddressService.getAddress(incomingNumber);
        Log.i(TAG,"归属地为"+ address);
        showLocation(address);
        //获取当前系统的时间
        startTime = System.currentTimeMillis();
        break;
      case TelephonyManager.CALL_STATE_OFFHOOK: //接通电话状态
        break;
      }
    }
  }
  /**
   * 在窗体上显示出来位置信息
   * @param address
   */
  public void showLocation(String address) {
    WindowManager.LayoutParams params = new WindowManager.LayoutParams();
    params.height = WindowManager.LayoutParams.WRAP_CONTENT;
    params.width = WindowManager.LayoutParams.WRAP_CONTENT;
    params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
        | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
    params.format = PixelFormat.TRANSLUCENT;
    params.type = WindowManager.LayoutParams.TYPE_TOAST;
    params.setTitle("Toast");
    params.gravity = Gravity.LEFT | Gravity.TOP;
    int x = sp.getInt("lastx", 0);
    int y = sp.getInt("lasty", 0);
    params.x = x;
    params.y = y;
    view = View.inflate(getApplicationContext(), R.layout.show_location, null);
    LinearLayout ll_location = (LinearLayout) view.findViewById(R.id.ll_location);
    TextView tv_location = (TextView) view.findViewById(R.id.tv_location);
    int background = sp.getInt("background", 0);
    if(0 == background){
      ll_location.setBackgroundResource(R.drawable.call_locate_gray);
    }else if(1 == background){
      ll_location.setBackgroundResource(R.drawable.call_locate_orange);
    }else {
      ll_location.setBackgroundResource(R.drawable.call_locate_green);
    }
    tv_location.setText(address);
    tv_location.setTextSize(24);
    wManager.addView(view, params);
  }
  /**
   * 删除呼叫记录
   */
  public void deleteCallLog(String incomingNumber) {
    ContentResolver resolver = getContentResolver();
    Cursor cursor = resolver.query(CallLog.Calls.CONTENT_URI, null,"number=?", new String[]{incomingNumber}, null);
    if(cursor.moveToNext()){
      String id = cursor.getString(cursor.getColumnIndex("_id"));
      resolver.delete(CallLog.Calls.CONTENT_URI, "_id=?", new String[]{id});
    }
  }
  /**
   * 挂断电话
   */
  public void endCall() {
    try {
      Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);
      IBinder binder = (IBinder) method.invoke(null, new Object[]{TELEPHONY_SERVICE});
      ITelephony telephony = ITelephony.Stub.asInterface(binder);
      telephony.endCall();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  private class MyObserver extends ContentObserver{
    private String incomingNumber;
    public MyObserver(Handler handler,String incomingNumber) {
      super(handler);
      this.incomingNumber = incomingNumber;
    }
    @Override
    public void onChange(boolean selfChange) {
      super.onChange(selfChange);
      deleteCallLog(incomingNumber);
      getContentResolver().unregisterContentObserver(this);
    }
  }
}

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android开发入门与进阶教程》、《Android通信方式总结》、《Android基本组件用法总结》、《Android视图View技巧总结》、《Android布局layout技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

(0)

相关推荐

  • Android基于AudioManager、PhoneStateListener实现设置黑名单功能

    本文实例讲述了Android基于AudioManager.PhoneStateListener实现设置黑名单功能.分享给大家供大家参考,具体如下: 手机中一般有设置黑名单的功能.此例通过设置电话黑名单,当黑名单中的电话打来时,手机铃声为变成静音. 程序代码如下: import android.app.Activity; import android.content.Context; import android.media.AudioManager; import android.os.Bund

  • Android项目实现黑名单拦截效果

    本文实例讲述了Android编程中黑名单的实现方法.分享给大家供大家参考,具体如下: 1,黑名单数据库创建 三个字段(_id 自增长字段 phone 黑名单号码 mode 拦截类型) 创建表的sql语句 create table blacknumber (_id integer primary key autoincrement , phone varchar(20), mode varchar(5)); 结合项目,去创建数据库,以及相应的表 2.BlackNumberDao BlackNumb

  • Android编程中黑名单的实现方法

    本文实例讲述了Android编程中黑名单的实现方法.分享给大家供大家参考,具体如下: 说明:由于挂断电话android   api不是对外开放的,所以需要使用反射的方法得到拨打电话的服务. 1.将android源代码中的"aidl"文件拷贝到项目中 这样项目中会生成两个包:android.telephony:此包中文件为:NeighboringCellInfo.aidl com.android.internal.telephony;此包中文件为:ITelephony.aidl 2.通过

  • Android编程中图片特效处理方法小结

    本文实例总结了Android编程中图片特效处理方法.分享给大家供大家参考,具体如下: 这里介绍的Android图片处理方法包括: 转换 -  drawable To  bitmap 缩放 -  Zoom 圆角 -  Round Corner 倒影 -  Reflected bitmapPrcess  code: package com.learn.games; import android.graphics.Bitmap; import android.graphics.Canvas; impo

  • Android编程中光线传感器的调用方法详解

    本文实例讲述了Android编程中光线传感器的调用方法.分享给大家供大家参考,具体如下: 1.activity如果要使用传感器,就必须实现SensorEventListener接口 2.得到传感器管理对象(sensormanager) 3.使用sensormanager.registerlistener 方法注册指定的传感器 4.在sensoreventlistener 接口中的onsensorchanged和onaccuracychanged方法中完成其他具体工作 public class T

  • Android编程中activity启动时出现白屏、黑屏问题的解决方法

    本文实例讲述了Android编程中activity启动时出现白屏.黑屏问题的解决方法.分享给大家供大家参考,具体如下: 默认情况下 activity 启动的时候先把屏幕刷成白色,再绘制界面,绘制界面或多或少有点延迟,这段时间中你看到的就是白屏,显然影响用户体验,怎么消除呢? 在 Activity theme 设置style 即可 <style name="AppTheme" parent="android:Theme.Light.NoTitleBar">

  • Android编程中聊天页面背景图片、标题栏由于键盘引起问题的解决方法

    本文实例讲述了Android编程中聊天页面背景图片.标题栏由于键盘引起问题的解决方法.分享给大家供大家参考,具体如下: 在一个群里面有人问到 聊天页面由于键盘弹出来,导致自定义的标题栏不见和背景图片都变形了,然后自己也折腾了一下,在stackOverFlow上面找到了一个解决方法. 解决方法很简单: 1.在AndroidManifest.xml文件里面的Activity配置: 复制代码 代码如下: android:windowSoftInputMode="adjustResize|stateAl

  • Android编程中出现The connection to adb is down问题的解决方法

    本文分析了Android编程中出现The connection to adb is down问题的解决方法.分享给大家供大家参考,具体如下: 1.报错: BUILD FAILED D:\workspace\ganji\build.xml:144: The following error occurred while executing this line: D:\workspace\ganji\build.xml:271: Unable to delete file D:\workspace\g

  • Android编程中调用Camera时预览画面有旋转问题的解决方法

    本文实例讲述了Android编程中调用Camera时预览画面有旋转问题的解决方法.分享给大家供大家参考,具体如下: 在调用Camera写应用的时候,前后摄像头的情况有时候是不一样的.有时候,明明后摄像头没有问题,而调用到前摄像头时,却倒转了180°,或者其他角度,百思不得其解.在查看了Android源码之后,发现它的解决办法很是好,接下来贴个源码,以备日后查看. public static int getDisplayRotation(Activity activity) { int rotat

  • Android编程中TextView宽度过大导致Drawable无法居中问题解决方法

    本文实例讲述了Android编程中TextView宽度过大导致Drawable无法居中问题解决方法.分享给大家供大家参考,具体如下: 在做项目的时候,很多时候我们都要用到文字和图片一起显示,一般设置TextView的DrawableLeft.DrawableRight.DrawableTop.DrawableBottom就行了.但是有一种情况是当TextView的熟悉是fill_parent或者使用权重的时候并且设置了起Gravity的ceter的时候,Drawable图片是无法一起居中的,为了

  • Android编程中TextView字体属性设置方法(大小、字体、下划线、背景色)

    本文实例讲述了Android编程中TextView字体属性设置方法(大小.字体.下划线.背景色).分享给大家供大家参考,具体如下: import android.content.Context; import android.graphics.Color; import android.text.SpannableString; import android.text.Spanned; import android.text.style.AbsoluteSizeSpan; import andr

  • Android编程中号码匹配位数修改的方法

    本文实例讲述了Android编程中号码匹配位数修改的方法.分享给大家供大家参考,具体如下: Android2.1上默认的号码匹配位数是7位,也就是说从右向左算起,如果两个号码有7位是匹配的,那么就认为是相同的号码,如+86 1234567和01234567是相同的号码:所以判断两个号码是否匹配,简单的用"=="是不行的. 安卓在Sqlite层新增了函数phone_numbers_equal用于号码匹配的判断,这个函数是数据库级的,对应的SQL语句是PHONE_NUMBERS_EQUAL

随机推荐