android - 始终使用 BroadcastReceiver 运行服务以进行调用窃听

标签 android broadcastreceiver android-broadcast

我的要求

我正在尝试构建一个应用程序,每当用户从手机调用电话时,该应用程序都会显示一个Toast。为此,我使用 BroadcastReceiver 来点击调用操作和服务(始终运行 Receiver)。一旦我开始此 Activity ,当发起拨出调用时,它就会开始显示 toast ...一切正常。

问题

  1. 有时我在拨出电话时也没有收到任何 Toast 操作 EVEN,这是否意味着服务会在一段时间后停止?

  2. 电话重启后,拨出调用的 Toast 操作停止。直到您再次手动启动服务。

  3. 我写的代码可以吗?或者可以改进吗?

下面是完整的代码-

MainActivity.class

public class MainActivity extends Activity 
{
    CallNotifierService m_service;
    boolean isBound = false;

    private ServiceConnection m_serviceConnection = new ServiceConnection() 
    {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) 
        {
            m_service = ((CallNotifierService.MyBinder)service).getService();
            Toast.makeText(MainActivity.this, "Service Connected", Toast.LENGTH_LONG).show();
            isBound = true;
            Intent intent = new Intent(MainActivity.this, CallNotifierService.class);
            startService(intent);
        }

        @Override
        public void onServiceDisconnected(ComponentName className) 
        {
            m_service = null;
            isBound = false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = new Intent(this, CallNotifierService.class);
        bindService(intent, m_serviceConnection, Context.BIND_AUTO_CREATE);
    }
    .
    .
    .
}

CallNotifierService.class

public class CallNotifierService extends Service 
{
    private final IBinder myBinder = new MyBinder();
    private static final String ACTION_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
    private static final String ACTION_ANSWER = "android.intent.action.ANSWER";
    private static final String ACTION_CALL = "android.intent.action.CALL";

    private CallBr br_call;

    @Override
    public IBinder onBind(Intent arg0) 
    {
        return myBinder;
    }

    @Override
    public void onDestroy() 
    {
        Log.d("service", "destroy");
        this.unregisterReceiver(this.br_call);
        Toast.makeText(CallNotifierService.this, "Receiver Un-Registered", Toast.LENGTH_LONG).show();
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        final IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_ANSWER);
        filter.addAction(ACTION_CALL);
        filter.addAction(ACTION_OUTGOING_CALL);
        this.br_call = new CallBr();
        this.registerReceiver(this.br_call, filter);
        Toast.makeText(CallNotifierService.this, "onStartCommand Called", Toast.LENGTH_LONG).show();
        return START_STICKY;
    }

    public class MyBinder extends Binder 
    {
        CallNotifierService getService() 
        {
            return CallNotifierService.this;
        }
    }

    public class CallBr extends BroadcastReceiver 
    {
        public CallBr() {}

        @Override
        public void onReceive(Context context, Intent intent) 
        {
            Toast.makeText(context, "Action:"+intent.getAction(), Toast.LENGTH_LONG).show();
        }
    }
}

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.alwaysrunningprocesswithcallanswertap"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />

    <uses-sdk
        android:minSdkVersion="22"
        android:targetSdkVersion="22" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="com.example.alwaysrunningprocesswithcallanswertap.CallNotifierService" />
    </application>

</manifest>

有人可以帮助解决这个问题或指出更好的东西吗?

最佳答案

@Bharat 一旦设备自动关闭,服务就会停止,因此,当您的设备重新启动时,您需要再次启动服务,那么只有您会得到 Toast 操作,请参阅此示例代码:

BootCompleteReceiver.java

package com.example.newbootservice;

import android.content.BroadcastReceiver;  
import android.content.Context;  
import android.content.Intent;    

public class BootCompleteReceiver extends BroadcastReceiver {   

@Override  
public void onReceive(Context context, Intent intent) {  

   Intent service = new Intent(context, AutostartService.class);  
   context.startService(service);   

        }  

    }

AutostartService.java

package com.example.newbootservice;

import android.app.Service;  
import android.content.Intent;  
import android.os.IBinder;   
import android.widget.Toast;

public class AutostartService extends Service {  


    @Override  
    public void onCreate() {  
        super.onCreate();    
    }  

    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  

        Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
        return Service.START_STICKY;  
    }  

    @Override
    public void onDestroy() {

        super.onDestroy();
        Toast.makeText(this, "Service Destroy", Toast.LENGTH_LONG).show();
    }

    @Override  
    public IBinder onBind(Intent arg0) {  
        return null;  
    }  
} 

MainActivity.java

package com.example.newbootservice;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        startService(new Intent(getBaseContext(), AutostartService.class));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

Manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.newbootservice"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <service android:name=".AutostartService"/>

        <receiver android:name=".BootCompleteReceiver">  
            <intent-filter>     
                <action android:name="android.intent.action.BOOT_COMPLETED"/>  
                <category android:name="android.intent.category.DEFAULT" />  
            </intent-filter>  
        </receiver>

        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

关于android - 始终使用 BroadcastReceiver 运行服务以进行调用窃听,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35594812/

相关文章:

Android SlidingDrawer 使用方法

android - 按下返回键时隐藏软键盘

android widget 提示解锁

即使在应用程序启动后,Android 短信接收器也无法在 ICS 中工作

android - 当有人从任务管理器按下我的应用程序时如何禁用对 onCreate 的调用

java - 如何删除从移动设备清除应用程序数据后触发的通知

android - 删除图像文件后刷新图库?

android - ListView 的 Intent (JSON 数据)

android - 设置值后如何防止复选框动画

java - BroadcastReceiver (TIME_TICK) 每晚都会死掉?