1

当我的手机有拨出电话时,我正试图让我的服务运行。但是由于某种原因,发生这种情况时我的服务没有运行。我知道“CallReceiver”的代码会执行,因为我使用了 toast 消息来显示它是否运行。我能够通过我的主要活动运行该服务,但这意味着无论是否拨打电话,它都会运行......

下面是我的代码:

收件人:

package com.example.hiworld;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

public class CallReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        context.startService(new Intent(context, CallService.class));

        Toast.makeText(context, "Call Receiver started",
                Toast.LENGTH_LONG).show();

        Log.d("Calling Someone", "onReceived");

    }


}

服务:

package com.example.hiworld;


import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.widget.Toast;

public class CallService extends IntentService  {

    public long StartTime=0;
    public long EndTime =0; 
    public long TotalTime = 0; 
    public long NumFreeMins = 0;


    public CallService() {
          super("CallService");
      }

    @Override
    protected void onHandleIntent(Intent intent) {


        StartTime = (System.currentTimeMillis())/60;

        TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);




            if(tm.getCallState()==0) //getting the time whenever the phone is off 
            {

                EndTime = (System.currentTimeMillis())/60;
                TotalTime = EndTime-StartTime;
                 NumFreeMins = 300-TotalTime; 

                 //notify user
                 this.displaymsg();

            }   



    }

public void displaymsg()
{
    Toast toast = Toast.makeText(getApplicationContext(), ""+NumFreeMins, Toast.LENGTH_SHORT);
    toast.show();
}
}

我看到有些人使用这条线:

context.startService(new Intent(this, CallService.class));

代替:

context.startService(new Intent(context, CallService.class));

但后者对我不起作用......

4

2 回答 2

1

尝试在清单中<intent-filter>为您IntentService的特定“操作”指定一个。例子...

<service
    android:name=".CallService" >
    <intent-filter>
        <action android:name="com.example.hiworld.intent.DO_SOMETHING" />
    </intent-filter>
</service>

然后在onReceive(...)您的方法中BroadcastReceiver执行以下操作...

Intent callReceiverIntent = new Intent("com.example.hiworld.intent.DO_SOMETHING");

// Put the Intent received by the BroadcastReceiver as extras so the
// IntentService can process it...
callReceiverIntent.putExtras(intent);

context.startService(callReceiverIntent);

编辑:

我根据您发布到 pasrebin 的代码构建了一个简单的测试应用程序。我保持清单、接收器和服务的代码相同,只需添加一个默认值Activity即可使其运行。

我可以从eclipse的DDMS角度监控logcat看到CallReceiver成功接收到NEW_OUTGOING_CALL Intent并且确实启动了CallService.

但是,问题在于尝试显示由于“泄漏的处理程序”而导致异常并静默崩溃的Toastfrom an 。IntentService

这背后的原因是,由于应用程序没有运行 UI 组件,因此IntentService使用后台线程执行其工作并尝试Toast从非 UI 线程显示(即 UI 元素)将不起作用。因此,无论您是使用局部context变量还是getApplicationContext(),都根本没有 UI 上下文可与Toast.

CallService从 an启动时它起作用的原因Activity显然是因为它Activity提供了一个可供Toast. 简而言之,除非总是由 UI 组件启动,否则尝试使用 from 通常似乎不是Toast一个IntentService主意,即便如此,让后台线程创建 UI 元素(例如 a )可能会导致问题。IntentServiceToast

可以使其与当前模型一起使用的唯一方法是将 更改IntentServiceService. 默认情况下,a 的代码执行Service是在主(UI)线程上完成的,无论是否有任何应用程序显示,aService显示 a都是完全合法的。事实上,我修改了代码以使用 a并将代码放在in 中,我可以在拨打电话时看到 。ToastActivitiesServiceonHandleIntentonStartCommand()Toasts

于 2012-07-10T22:56:38.490 回答
0

尝试

context.startService(new Intent(context.getApplicationContext(), CallService.class));
于 2012-07-10T22:35:29.517 回答