简体   繁体   English

来自Activity的Service中的Android调用方法

[英]Android call method in Service from Activity

I want to call a method in a Service object from an Activity object, however I have found it is not possible to call the method from the MainActivity normally.我想从Activity对象调用Service对象中的方法,但是我发现无法从MainActivity正常调用该方法。

I hope my code explains what I mean better:我希望我的代码能更好地解释我的意思:

Service:服务:

public class Timer extends Service {

public Vibrator v;
public MainActivity ma;
public CountDownTimer mycounter;
public static final String MY_SERVICE = "de.example.timer.MY_SERVICE";

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

public void onCreate() 
{
      super.onCreate();
      ma = new MainActivity();
      v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
      startService();
}

public void startService()
{
    mycounter = null; //delete counter
    mycounter = new CountDownTimer(5000, 100){
        public void onTick(long millisUntilFinished) {
            //ma.timer.setText(ma.formatTime(millisUntilFinished+1000));
            //ma.builder.setContentText("Timer: " + ma.formatTime(millisUntilFinished+1000)); //update Timer
            //ma.notificationManager.notify(MainActivity.MY_NOTIFICATION_ID, ma.builder.build());

//It is not possible to call a methode this way in a service..
        }

        public void onFinish() {
            //ma.timer.setText("00:00:00");
            v.vibrate(1000);
            mycounter.cancel();
            mycounter.start();
        }
    };
    mycounter.start();
}

public void onDestroy() 
{
      super.onDestroy();
      mycounter.cancel();


  }   
}

Activity:活动:

public class MainActivity extends Activity { 

private ImageButton imagebutton;
public Vibrator v;
public TextView timer;
public boolean pressed;
public String output;
public long waitingtime;
public Timer service;

public static final int MY_NOTIFICATION_ID = 1;
public NotificationManager notificationManager;

public Context context;
public Builder builder;

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

    pressed = false;
    waitingtime = 600000; // Standartmäßig auf 10 min

    v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

    imagebutton = (ImageButton) findViewById(R.id.imageButton1);
    imagebutton.setBackgroundResource(R.drawable.start);
    timer = (TextView) findViewById(R.id.timer);
    timer.setText(formatTime(waitingtime));

    Intent intent = new Intent (this, MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
            | Intent.FLAG_ACTIVITY_SINGLE_TOP);

    PendingIntent pend = PendingIntent.getActivity(this, 0, intent, 0);
    notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    context = getApplicationContext();
    builder = new NotificationCompat.Builder(context)
    .setSmallIcon(R.drawable.notlogosmall)
    .setContentTitle("Start!")
    .setContentText("Timer set to " + waitingtime/1000 + " seconds")
    .setContentIntent (pend)
    .setTicker("Go!")
    .setWhen(System.currentTimeMillis())
    .setDefaults(0)
    .setAutoCancel(false)
    .setOngoing(true);
}

public void press(View view){
    if(pressed == false){
        imagebutton.setBackgroundResource(R.drawable.stop);
        pressed = true;
        notificationManager.notify(MY_NOTIFICATION_ID, builder.build()); //Notification
        v.vibrate(100);
        hidebuttons();
        startService(new Intent(Timer.MY_SERVICE));
    }
    else{
        imagebutton.setBackgroundResource(R.drawable.start);
        pressed = false;
        notificationManager.cancel(1);
        timer.setText(formatTime(waitingtime));
        showbuttons();
        stopService(new Intent(Timer.MY_SERVICE));
        v.vibrate(100);
    }
}

How can I call one object's method from an object of another class?如何从另一个类的对象调用一个对象的方法?

The accepted answer isn't wrong but very unnecessarily complex.接受的答案没有错,但非常不必要地复杂。

Add this to the activity:将此添加到活动中:

Intent i = new Intent(this, SERVICE_NAME.class);
i.setAction("YOUR_ACTION");
startService(i);

and this to the Service:这对服务:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent != null && intent.getAction() != null && intent.getAction().equals("YOUR_ACTION")) {
        invokeServiceMethod(); // here you invoke the service method
    }
    return START_STICKY; // or whatever floats your boat
}

A simpke way is to send an intent from Activity and handle it in onStartCommand() method of Service.一个简单的方法是从 Activity 发送一个意图并在服务的 onStartCommand() 方法中处理它。 Don't forget to supply intent with right action/extras & check that in onStartCommand()不要忘记提供具有正确动作/附加功能的意图并在 onStartCommand() 中检查

EDIT:编辑:

Activity:活动:

Add a private class:添加一个私有类:

    private class CustomReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(ACTION_CUSTOM_ACTION)) {
            doCustomAction();
        }
    }
}

Add a private field:添加私有字段:

private CustomReceiver mCustomReceiver;

In onCreate() method:在 onCreate() 方法中:

mCustomReceiver = new CustomReceiver();

In onResume() or other lifecycle method:在 onResume() 或其他生命周期方法中:

IntentFilter filter = new IntentFilter(ACTION_CUSTOM_ACTION);   
registerReceiver(mCustomReceiver , filter);

In onPause() or other paired (to previous step) lifecycle method在 onPause() 或其他配对(到上一步)生命周期方法中

unregisterReceiver(mCustomReceiver );

In activity whenever you wish to call use Service methods:在活动中,只要您想调用 use Service 方法:

startService(new Intent(SOME_ACTION));

In Service:服务中:

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

    if (intent == null) {
        return START_STICKY;
    }

    String action = intent.getAction();

    if (action == null) {
        return START_STICKY;
    } else if (action.equals(SOME_ACTION)) {
                    invokeSomeServiceMethod();// here you invoke service method
            }

    return START_STICKY;
}

Note, that START_STICKY may be not the best choice for you, read about modes in documentation.请注意, START_STICKY可能不是您的最佳选择,请阅读文档中的模式。

Then, when you want to notify activity that you've finished, call:然后,当您想通知活动您已完成时,请调用:

startActivity(ACTION_CUSTOM_ACTION);

This will trigger broadcast reciever where you can handle finish event.这将触发广播接收器,您可以在其中处理完成事件。

Seems that that's a lot of code, but really nothing difficult.看起来这是很多代码,但实际上没有什么困难。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM