安卓 - 通过put/getExtra启动带有额外信息的服务

12

我真的尝试了解intent.putExtra()和getIntent().getExtras(),并将它们应用于其中一个SimpleService教程。我知道很多人已经问过“为什么bundle extras总是null?”我保证在发布之前我尝试了在这里找到的答案几个小时,但我认为我不够先进,无法真正理解我可能在做错什么与人们发布的小片段。因此,我放置了我的活动和服务的完整代码。

我认为我的问题是我的起始意图(我在我的活动中创建的那个)不存在于我的服务的上下文中。我想知道也许我完全错误地使用了意图?我确实尝试了在我的服务中使用intent.putExtra,以尝试向另一个方向发送字符串,但那些extras也总是null。因此,冒着重复的风险,为什么bundle extras总是null?如何使单个意图同时存在于我的活动和我的服务的上下文中?

我应该指出,下面显示的代码显然会有一个空的extras,因为我已注释掉了一些失败的尝试来获取.getExtras()。我为了清洁起见删除了其余部分。

编辑:由于回复的答案,以下是代码,供那些已经谷歌了几个小时的人参考。将其放入您的服务中(请注意,返回START_REDELIVER_INTENT可能是错误的):

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

      extras = intent.getExtras();

          //just checking
      if( extras != null )
      Toast.makeText(this,extras.getString("extratoservice"), Toast.LENGTH_SHORT).show();

      return START_REDELIVER_INTENT;

}

我的活动(基于Sai Geetha的博客):

package com.example.BroadcastIntent;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class BroadcastIntentActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Button start = (Button)findViewById(R.id.buttonStart);
    start.setOnClickListener(startListener);

    Button stop = (Button)findViewById(R.id.buttonStop);
    stop.setOnClickListener(stopListener);   

    //the intent I'm using to start and stop the service -- the extras don't go anywhere....
    intent = new Intent(BroadcastIntentActivity.this,BroadcastService.class);     
    intent.putExtra("extratoservice", "if you can read this, it made it to the service" );

}

Boolean serviceRunning;
Intent intent;

//Clicks from Geetha's Blog
private OnClickListener startListener = new OnClickListener() {
     public void onClick(View v){

         startService(intent);
         serviceRunning = true;
     }                 
};

private OnClickListener stopListener = new OnClickListener() {
    public void onClick(View v){

         try
         {
             stopService(intent);
             serviceRunning = false;                
         }
         catch( Exception e)
         {
             Toast.makeText(getApplicationContext(), "Service was not running...",Toast.LENGTH_SHORT).show(); 
         }
     }                 
 };

}

这是我的服务:

package com.example.BroadcastIntent;

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

public class BroadcastService extends Service{

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub

    //extras = arg0.getExtras();    <-- this has null extras, too...

    return null;
}

Bundle extras;

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

      // extras = getIntent().getExtras();   <-- this is undefined?

      if( extras == null )
      Toast.makeText(this,"Service created... extras still null", Toast.LENGTH_SHORT).show();
      else
      Toast.makeText(this,extras.getString("extratoservice"), Toast.LENGTH_SHORT).show();

}

@Override
public void onDestroy() {
      super.onDestroy();
      Toast.makeText(this, "Service destroyed ...", Toast.LENGTH_SHORT).show();

}
}

欢迎来到 Stackoverflow!如果你觉得某个回答有帮助,请点赞。如果某个回答成功地回答了你的问题,请点击旁边的绿色勾选标记以接受答案。同时,请参考 http://stackoverflow.com/questions/how-to-ask 获取有关如何提出好问题的建议。 - Kurtis Nusbaum
Kurtis,我喜欢你的存货邀请!很高兴有人花时间告知新来者如何使用该服务 :) - Yevgeny Simkin
@Adam:抱歉,我不明白:你的服务代码最后没有onStartCommand()吗? - Luis A. Florit
2个回答

17

你需要查看 onStartCommand() 函数(我不在桌面电脑上,所以无法方便地链接到javadoc)。这将接收你传递的意图,你的额外信息应该在那里可用。


不错 - 现在要想办法发送一条回复消息。 - Adam
感谢@H9kDroid提供的URL链接。关于响应,您有几个选项:可以使用BroadcastReceiver或使用onBind。 - Femi
我意识到一种可能不好的方法 - 由于我的服务运行在与我的应用程序相同的进程中(我想是这样的?),我实际上可以访问/更改任何我想要的公共变量... 这对于运行真正的服务来说是一个坏主意,但对于我的简单教程目的而言,它是有效的。 - Adam

2

可以了,谢谢。顺便说一下,在onCreate()之后我似乎必须等待onCommand()发生。然后我才能接收到额外的内容。 - Adam
从文档中得知:这是旧版 onStart 方法,将在 2.0 版本之前的平台上调用。在 2.0 版本或更高版本中,我们会重写 onStartCommand() 方法,因此不会调用此方法。 - Daniel F

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接