【问题标题】:Always running Service with BroadcastReceiver for Call Tapping始终使用 BroadcastReceiver 运行服务以进行呼叫分接
【发布时间】:2016-02-24 15:12:27
【问题描述】:

我的要求

我正在尝试构建一个应用程序,该应用程序在用户从电话拨出电话时显示 Toast。为此,我使用 BroadcastReceiver 来点击呼叫操作和服务(始终运行 Receiver)。一旦我开始这个活动,它就会在拨出电话开始时开始显示 toast ...一切正常。

问题

  1. 有时我也没有收到任何 Toast Action 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>

谁能帮助解决这个问题或指出更好的东西?

【问题讨论】:

    标签: android broadcastreceiver android-broadcast


    【解决方案1】:

    @Bharat 一旦设备自动关闭,服务就会停止,所以当你的设备重启时,你需要再次启动服务,那么只有你会得到 Toast Action,参考这个示例代码:

    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>
    

    【讨论】:

    • 您对问题 #1 有任何想法吗?
    • 如果您需要一直运行,请查看 Service 并 startForeground。如果您可以让您的服务死掉但重新启动,请查看 onStartCommand 和 START_STICKY。
    • * 如果您可以让您的服务死掉但重新启动,请查看 onStartCommand 和 START_STICKY ==> 我已经在这样做了。但它总是没有开始??..是有条件的吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 2020-02-05
    • 1970-01-01
    相关资源
    最近更新 更多