简体   繁体   English

来自意图服务的呼叫活动方法

[英]Call activity method from intent service

There are many questions on how to invoke an activity method from a service using a broadcast receiver or an interface. 关于如何使用广播接收器或接口从服务调用活动方法存在许多问题。 But the examples often differs from my case. 但是这些例子常常与我的情况有所不同。

I have an activity that sends a registration request to a server. 我有一个将注册请求发送到服务器的活动。 This server sends it's requested answer via google cloud messaging (GCM) . 该服务器通过Google云消息传递(GCM)发送请求的答案。 To receive the answer I use a service . 为了得到答案,我使用了一项服务

My manifest : 我的清单

<!-- receiver to handle GCM messages -->
<receiver
   android:name="com.google.android.gcm.GCMBroadcastReceiver"
   android:permission="com.google.android.c2dm.permission.SEND" >
   <intent-filter>
      <!-- Receives the actual messages. -->
      <action android:name="com.google.android.c2dm.intent.RECEIVE" />
      <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
      <category android:name="com.example.myapp" />
   </intent-filter>
</receiver>
<service android:name=".GCMIntentService" />

In my activity, I have a switch. 在我的活动中,我有一个开关。 If the user checks the switch the registration process starts and I disable the switch, so the user could not change the switch state during the registration process. 如果用户检查了交换机,则注册过程开始,并且我禁用了该交换机,因此用户无法在注册过程中更改交换机状态。 After a certain time (about 5 Min) the server sends the answer. 一定时间(大约5分钟)后,服务器将发送答案。

Depending on the answer, I want to set the state of the switch (checked or unchecked) and enable the switch again. 根据答案,我要设置开关的状态(选中或未选中),然后再次启用开关。

My question is now, how can I achieve this behaviour? 我的问题是,现在我该如何实现这种行为? How can I invoke a method in the activity? 如何在活动中调用方法?

The next problem is that the user probably closes the app because the request needs some time. 下一个问题是用户可能会关闭该应用程序,因为请求需要一些时间。 How can I achieve, that the method will be executed even if the activity was closed? 我如何实现即使活动关闭也可以执行该方法?

Regarding the questions, I have read in the forum I would use a LocalBroadcastReceiver . 关于这些问题,我已经在论坛上阅读过,我将使用LocalBroadcastReceiver Would this receiver work, if the app was closed? 如果该应用已关闭,此接收器是否可以工作? Or if it is closed, would it bring the activity to the front (I don't want this)? 或者,如果它关闭了,它会将活动带到最前面吗(我不想要这个)?

You can do some work-arounds to achieve this by re-create your Activity again but this wouldn't be best practice (And also complicated to code). 您可以做一些变通办法,通过再次重新创建您的Activity来实现此目的,但这不是最佳实践(而且代码编写也很复杂)。
I would use SharedPreferences , which is a simple to use data file that you can read from anywhere inside your app (eg your receiver or your activity ). 我将使用SharedPreferences ,它是一种易于使用的数据文件,您可以从应用程序内的任何位置(例如, receiveractivity )读取数据文件。
Inside the Receiver - 接收器内部-

// PREFS_FILE_NAME - a static String variable like: 
public static final String PREFS_FILE_NAME = "MyPrefsFile";
SharedPreferences.Editor editor = getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE).edit();
 editor.putBoolean("mySwitchOn", true);
 editor.commit();

Inside the Activity - 活动内部-

public static final String PREFS_FILE_NAME = "MyPrefsFile";
SharedPreferences prefs = getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE);    
  Boolean mSwitchOn = prefs.getBoolean("mySwitchOn", true);//"True is the default value if no value was found.
  //Do what you need with mSwitchOn
}

The easiest way i can think for your problem is to use LocalBroadcastManger . 我可以想到的最简单的方法是使用LocalBroadcastManger In my current project, there is beacon impl... Whenever i receive signal from beacon in background service, I broadcast intent to activity. 在我当前的项目中,有一个信标暗示...每当我在后台服务中从信标收到信号时,我都会广播活动意图。

AndroidManifest.xml AndroidManifest.xml

<service
      android:exported="true"
      android:name="com.yourpackage.ServiceName"/>

In your service 为您服务

 Intent i = new Intent();
 i.setAction(BeaconHelper.ACTION_BEACON_TRIGGER);
 i.putExtra("data", "my_data");
 LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i)

In your activity's onCreate() or onResume() 在您活动的onCreate()onResume()

registerReceiver(mReceiver,new IntentFilter(BeaconHelper.ACTION_BEACON_TRIGGER));

MyReceiver.java MyReceiver.java

 public class MyReceiver extends BroadcastReceiver {

    MyReceiver() {

    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive() called with: context = [" + context + "], intent = [" + intent + "]");

        try {
            switch (intent.getAction()){
                case BeaconHelper.ACTION_BEACON_TRIGGER:
                        //here is my beacon impl
                   break;

                default:
                    break;

            }
        } catch (JSONException | NullPointerException e) {
            e.printStackTrace();
        }
    }


}     

LocalBroadcastManager only work if your activity and service in same process. 仅当您的活动和服务在同一过程中时,LocalBroadcastManager才起作用。 If you had put process as <service process=":myprocess"/> inside manifest , it won't probably work. 如果您已将流程作为<service process=":myprocess"/>放在清单中 ,则可能无法正常工作。

Make sure you unregister after activity got destroyed . 确保活动销毁后注销 :-) . :-)。

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

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