Как получить доступ к любому элементу управления Activity из приемника вещания. Без использования «статики» - PullRequest
0 голосов
/ 03 октября 2019

Я хочу получить доступ к элементам управления действия из приемника вещания без использования «статического» или передачи данных между ними. Я просто хочу получить к нему доступ напрямую, как в статическом, но без определения какого-либо класса как статического.

В этом примере я пытаюсь изменить текстовое значение элемента управления TextView из широковещательного приемника.

namespace App2


[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
    private BluetoothManager bluetoothManager;
    private BluetoothAdapter bluetoothAdapter;
    private BluetoothDeviceReceiver _receiver;
    private TextView currentCharacterName;

    int count = 0;
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.activity_main);
        Button ChangeTextButton = FindViewById<Button>(Resource.Id.button1);
        currentCharacterName = FindViewById<TextView>(Resource.Id.textView1);

        ChangeTextButton.Click += delegate {
            currentCharacterName.Text = string.Format("{0} clicks!", count++);
        };
        var appContext = Application.Context;

        bluetoothManager = (BluetoothManager)appContext.GetSystemService(BluetoothService);
        bluetoothAdapter = bluetoothManager.Adapter;
        if (bluetoothAdapter == null || !bluetoothAdapter.IsEnabled)
        {
            bluetoothManager.Adapter.Enable();
        }
        _receiver = new BluetoothDeviceReceiver();
        RegisterReceiver(_receiver, new IntentFilter(BluetoothDevice.ActionFound));
        bluetoothAdapter.StartDiscovery();
    }

    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
    {
        Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

        base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    private class BluetoothDeviceReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            var action = intent.Action;

            TextView currentCharacterName = MainActivity.FindViewById<TextView>(Resource.Id.textView1);
            if (action != BluetoothDevice.ActionFound)
            {
                return;
            }

            // Get the device
            var device = (BluetoothDevice)intent.GetParcelableExtra(BluetoothDevice.ExtraDevice);

            if (device.BondState != Bond.Bonded)
            {
                Console.WriteLine($"Found device with name: {device.Name} and MAC address: {device.Address}");
            }
        }
    }

}

Проблема возникает здесь

TextView currentCharacterName = MainActivity.FindViewById<TextView>(Resource.Id.textView1);

Ошибка CS0120 Ссылка на объект требуется для нестатического поля, метода или свойства

Какой тип ссылки это делаетнужно ? Разве MainActivity не является ссылкой? Есть ли другие MainActivity вокруг? Я определил этот получатель внутри MainActivity, поэтому всякий раз, когда MainActivity получает экземпляр, этот получатель будет принадлежать этому экземпляру. Я действительно не понимаю ясно, что здесь происходит. Я пытался использовать Контекст, который передается получателю, но я не смог этого сделать.

Ответы [ 2 ]

0 голосов
/ 03 октября 2019

Я мог бы получить результат, как я хотел, используя этот код в BroadcastReceiver;

TextView currentCharacterName = ((Activity)context).FindViewById<TextView>(Resource.Id.textView1);

Я создал Broadcastreceiver в mainacctivity и отменил его регистрацию в mainacctivity в случае onPause или другого состояния, связанного с деактивацией активности. Я не утверждаю, что это самый безопасный и лучший способ, но, по крайней мере, он изменяет текстовое представление в действии без каких-либо исключений или ошибок. С наилучшими пожеланиями.

0 голосов
/ 03 октября 2019

Вы не можете и не должны. Вы не уверены, что активность выполняется при запуске BroadcastReceiver. Если вам нужно сделать это, ваше приложение будет неправильно рассмотрено. Единственный случай, когда все в порядке, если BroadcastReceiver зарегистрирован в Activity, и в этом ограниченном случае вы можете либо сделать BR внутренним классом Activity (в этом случае он может получить доступ к любой переменной Activity), либо его можно передатьконтроль, когда вы создаете его экземпляр с помощью его конструктора. Но любой из этих способов опасен, так как любой из них может вызвать его срабатывание после завершения действия, если вы не будете осторожны с отменой регистрации.

Ни при каких обстоятельствах не делайте представление статической переменной. Это будет не только неправильно (не обязательно должен быть только один экземпляр Activity за один раз), но и приведет к утечке памяти всей Activity и всех связанных с ней переменных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...