【问题标题】:Sending data from activity to foreground service将数据从活动发送到前台服务
【发布时间】:2021-06-26 23:38:30
【问题描述】:

我在活动中通过蓝牙从微控制器接收数据。这些数据不断发送到应用程序,我正在使用前台服务在后台实现此线程。

在 MainActivity4 中接收到数据,intent 将与接收到的数据一起发送到前台服务类,然后将数据重定向到 MainActivity5 以绘制图表。

我不确定如何正确实现发送到 MainActivity4 的意图,因为前台服务不断处理数据,但不会将其不断重定向到 MainActivity5。 Intent 第一次使屏幕转到 MainActivity5,这很好,但没有发送和更新数据。

这是 MainActivity4 中的代码:

@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        super.onCharacteristicChanged(gatt, characteristic);

        String value = String.valueOf(characteristic.getValue());
        Intent serviceIntent = new Intent(MainActivity4.this, ForegroundService.class);
        serviceIntent.putExtra("inputExtra", value);
        ContextCompat.startForegroundService(MainActivity4.this, serviceIntent);
}

这是 ForegroundService 中的代码:

public class ForegroundService extends Service {

//private static final int ID_SERVICE = 101;
public static final String CHANNEL_ID = "ForegroundServiceChannel";

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

    createNotificationChannel();
    Intent notificationIntent = new Intent(this, MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Foreground Service")
            .setContentIntent(pendingIntent)
            .build();

    startForeground(1, notification);
}

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

    String input = intent.getStringExtra("inputExtra");
    Log.i("Tag", input);
    sendData(input);

    createNotificationChannel();
    Intent notificationIntent = new Intent(this, MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,
            0, notificationIntent, 0);
    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Foreground Service")
            .setContentText(input)
            .setContentIntent(pendingIntent)
            .build();
    startForeground(1, notification);
    //do heavy work on a background thread
    //stopSelf();
    return START_NOT_STICKY;
    //return START_REDELIVER_INTENT;
}
@Override
public void onDestroy() {
    super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent)
{
        return null;
}

private void sendData(String input){
    Log.i("Tag", "inside sendData");
    Intent intent2 = new Intent(ForegroundService.this, MainActivity5.class);
    intent2.putExtra("inputExtra", input);
    intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    //intent2.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
    //intent2.putExtra("inputExtra", input);
    startActivity(intent2);
}

private void createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel serviceChannel = new NotificationChannel(CHANNEL_ID, "Foreground Service Channel", NotificationManager.IMPORTANCE_DEFAULT);
        NotificationManager manager = getSystemService(NotificationManager.class);
        manager.createNotificationChannel(serviceChannel);
    }
}
}

这是 MainActivity5 中的代码:

Intent intent = getIntent();
    String data = intent.getStringExtra("inputString");
    Log.i(TAG, "data sending");
    dataText = (TextView) findViewById(R.id.data2);
    dataText.setText(data);

如何连续接收 MainActivity5 中的数据?也许 Intent 设置标志是我弄错了。数据在后台接收并发送到前台服务但不发送到其他活动,尽管该活动的屏幕在代码运行时自动打开。任何帮助和建议将不胜感激。谢谢

*** 这是我目前在前台服务类中的功能的更新:

private void sendData(String input){
    Log.i("Tag", "inside sendData");
    Intent intent = new Intent();
    intent.setAction("com.example.Pillwoah.sendbroadcast");
    intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
    intent.putExtra("inputExtra", input);
    sendBroadcast(intent);
}

*** 以下是我目前在 MainActivity5 中拥有的功能的更新:

public class MainActivity5 extends AppCompatActivity {

protected static final String TAG = "TAG";

TextView dataText;

BroadcastReceiver receiver;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main5);

    GraphView move = (GraphView) findViewById(R.id.move);
    GraphView sound = (GraphView) findViewById(R.id.sound);

    LineGraphSeries<DataPoint> series = new LineGraphSeries<>(new DataPoint[] {
            new DataPoint(0, 1),
            new DataPoint(1, 5),
            new DataPoint(2, 3),
            new DataPoint(3, 2),
            new DataPoint(4, 6)
    });
    move.addSeries(series);
    series.setColor(Color.GREEN);
    series.setDrawDataPoints(true);
    series.setAnimated(true);
    series.setDrawBackground(true);

    move.setTitle("Movement");
    move.setTitleTextSize(90);
    move.setTitleColor(Color.WHITE);

    LineGraphSeries<DataPoint> series2 = new LineGraphSeries<>(new DataPoint[] {
            new DataPoint(0, 1),
            new DataPoint(1, 5),
            new DataPoint(2, 4),
            new DataPoint(3, 9),
            new DataPoint(4, 6)
    });
    sound.addSeries(series);
    series2.setColor(Color.YELLOW);
    series2.setDrawDataPoints(true);
    series2.setAnimated(true);
    series2.setDrawBackground(true);

    sound.setTitle("Sound");
    sound.setTitleTextSize(90);
    sound.setTitleColor(Color.WHITE);

    Log.i(TAG, "data sending");
    configureReceiver();
}
class DataBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String message = "Broadcast intent detected " + intent.getAction();
        Log.i(TAG, message);
    }
}

private void configureReceiver(){
    IntentFilter filter = new IntentFilter();
    filter.addAction("com.example.Pillwoah.sendbroadcast");
    receiver = new DataBroadcastReceiver();
    registerReceiver(receiver, filter);
}

}

我没有收到任何错误,但我知道我缺少一些功能。如果有人能看到我缺少的东西,那就太好了。

【问题讨论】:

  • 您可以使用广播接收器将数据从服务发送到 MainActivity4
  • 谢谢@guest 我怎样才能实现这个?我需要一个广播接收器类还是可以是 MainActivity4 中的一个函数?

标签: java android-studio android-intent android-activity android-service


【解决方案1】:

有一个带有广播接收器的示例

class MainActivity : Activity() {
    companion object {
        const val ACTION_DATA = "package.your.app.DATA"
        private val filters = arrayOf(ACTION_DATA)
        private val intentFilter: IntentFilter by lazy {
            IntentFilter().apply {
                filters.forEach { addAction(it) }
            }
        }

    }
    inner class DataBroadcastReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                ACTION_DATA -> showData(intent)
            }
        }
    }

    fun showData(intent: Intent) {
        //TODO extract data from intent
    }

    private lateinit var broadcastReceiver: MainActivity.DataBroadcastReceiver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        broadcastReceiver = DataBroadcastReceiver()
        applicationContext.registerReceiver(broadcastReceiver, intentFilter)
    }

    override fun onDestroy() {
        super.onDestroy()
        applicationContext.unregisterReceiver(broadcastReceiver)
    }
}

class ForegroundService: Service() {
    ...
    private fun sendData(input: String) {
        Intent().run {
            action = MainActivity.ACTION_DATA
            putExtra("inputExtra", input)
            applicationContext.sendBroadcast(this)
        }
    }
    ...
}

【讨论】:

  • 上面的代码是在 Kotlin 中的,对吧?我尝试在 java 中为我的代码实现其中的一些,但我遇到了几个错误
  • 我已经用我放入服务类的内容编辑了帖子
  • 我仍然很难理解如何在 java 中理解代码
  • @RomkoSmuk 对不起。 Kotlin 编程语言现在是 Android 应用程序开发人员的首选语言。应该解释样本的哪一部分?
  • 我相信我能够弄清楚。基本上它是私有的 lateinit 行,内部函数 onReceive 和内部伴随对象
猜你喜欢
  • 1970-01-01
  • 2012-12-30
  • 1970-01-01
  • 2013-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多