zoukankan      html  css  js  c++  java
  • 让后台服务不被杀———电话录音

    最近做了一个监听电话并录音的小例子,而保证它在后台运行不被杀确实不容易。

    首先在主service中:

    service中重写onStartCommand方法,这个方法有三个返回值, START_STICKYservicekill掉后自动

    public int onStartCommand(Intent intent, int flags, int startId) {
    
            IntentFilter filter=new IntentFilter();
            filter.addAction(Intent.ACTION_TIME_TICK);
            UserPresentReceive userReceive = new UserPresentReceive();
            registerReceiver(userReceive,filter);
            
            int flag = START_STICKY;
            // 判断是否是Broadcast发来的intentif (!("Protect".equals(intent.getAction()))) {
                System.out.println("action" + intent.getAction());
                this.outGoingNum = intent.getStringExtra("outGoingNums");
                // 将耗时操作放到子线程中
                backGroundExecution();
            }
            return super.onStartCommand(intent, flag, startId);
        }

     在onDestroy()方法中,启动当前服务,同时再启动protectService()

    public void onDestroy() {
            System.out.println("ServicePhone_onDestroy");
            Intent ins = new Intent(this, ServicePhone.class);
            ins.setAction("Protect");
            startService(ins);
    Intent
    in = new Intent(this, ProtectService.class); startService(in); super.onDestroy(); }

    新建一个ProtectService服务 ,同时再建一个broadcastReceive 

    public int onStartCommand(Intent intent, int flags, int startId) {
            
            Intent ins = new Intent(this, ServicePhone.class);
            ins.setAction("Protect");
            startService(ins);
            flags = START_STICKY;
            return super.onStartCommand(intent, flags, startId);
        }
    
        public void onDestroy() {
            Intent in = new Intent(this, ServicePhone.class);
            in.setAction("Protect");
            startService(in);
    //相互关联 Intent ins
    = new Intent(this, ProtectService.class); startService(ins); super.onDestroy(); }

     ProtectService中用alarmManager来不断触发UserPresentReceive 

    private void proctectServiceInBack() {
            /**
             * 指定时间间隔 重复唤醒alarm
             */
            AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
            // 在合适的时间醒来
            int alarmType = AlarmManager.RTC_WAKEUP;
            // 设置时间长度
            long timeOrLengthofWait = 150;
            long timeOrLengthofWaits=20000;
            Intent intent = new Intent(getApplicationContext(),
                    UserPresentReceive.class);
            intent.setAction("protect");
            PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0,
                    intent, 0);
            alarmManager.setRepeating(alarmType, timeOrLengthofWait,
                    timeOrLengthofWaits, alarmIntent);
    
        }

    在UserPresentReceive 监听系统广播:

    Intent.ACTION_TIME_TICK,这个广播每分钟发送一次,我们可以每分钟检查一次Service的运行状态,如果已经被结束了,就重新启动Service。
    同时监听    ACTION_BOOT_COMPLETED   

        public void onReceive(Context content, Intent intent) {
            System.out.println("UserPresentReceive");
            if(Intent.ACTION_TIME_TICK.equals(intent.getAction()) ){
                Intent in=new Intent(content, ProtectService.class);
                content.startService(in);
            }else if(Intent.ACTION_BUG_REPORT.equals(intent.getAction())){
                Intent in=new Intent(content, ProtectService.class);
                content.startService(in);
            }else{
                Intent in=new Intent(content, ProtectService.class);
                content.startService(in);
            }
            //开机自启
            if(Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())){
                Intent in=new Intent(content,ServicePhone.class);
                in.setAction("Protect");
                content.startService(in);
            } else{
                Intent in=new Intent(content, ServicePhone.class);
                in.setAction("Protect");
                content.startService(in);
            }
        }
    
    }

    另外建再建一个broadcastReceive来监听电话状态

    if (Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) {
                //取得号码
                String outGoingNum = intent
                        .getStringExtra(Intent.EXTRA_PHONE_NUMBER);
                Intent in=new Intent(content,ServicePhone.class);
                in.setAction(".b2");
                //将号码传给service
                in.putExtra("outGoingNums", outGoingNum);
                content.startService(in);
    
            } else{
                Intent in=new Intent(content, ServicePhone.class);
                in.setAction(".b3");
                content.startService(in);
            }
        }

    manifest.xml    application中可以加  android:persistent="true"  提高不被杀死的几率   

    <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:persistent="true"
            android:theme="@style/AppTheme" >

     将protectService另起一个进程

    <service
                android:process=":protect"
                android:name="com.example.phonelisten.ProtectService"
                android:enabled="true" >
            </service>

    监听系统广播  设置android:priority 提高优先权

    <receiver android:name="com.example.phonelisten.ReceivePhone" >
               <intent-filter android:priority="1000" >
                   <action android:name="android.intent.action.TIME_TICK" />
                    <action android:name="android.intent.action.PHONE_STATE" />
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
                    <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
                </intent-filter>
            </receiver>
            <receiver android:name="com.example.phonelisten.UserPresentReceive" >
                <intent-filter android:priority="999" >
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
                    <action android:name="android.intent.action.TIME_TICK" />
                    <action android:name="android.intent.action.BUG_REPORT" />
                     <action android:name="android.intent.action.USER_PRESENT" />
                     <action android:name="android.media.RINGER_MODE_CHANGED" />
                </intent-filter>
            </receiver>

     

  • 相关阅读:
    HBase 异步查询导致的死锁和zookeeper通信中断问题追踪与总结[非技术]
    [读书笔记]代码整洁之道读书笔记
    HBase行锁与MVCC分析
    进程、线程、轻量级进程、协程和go中的Goroutine 那些事儿
    上周回顾 - 2012年11.26-12.4
    2012年一个屌丝程序员的学习总结:读书、户外、泡妞、习惯、母猪产后护理
    C#_WinForm接收命令行参数
    SQL常识
    集成.Net / Flex3 & FluorineFX — Part II: The Client
    DB2基本概念
  • 原文地址:https://www.cnblogs.com/mydomainlistentome/p/4692795.html
Copyright © 2011-2022 走看看