Генерация случайных символов в Android Studio с помощью трансляции - PullRequest
0 голосов
/ 08 марта 2019

Работа над приложением, которое должно генерировать случайные символы через трансляцию. Мне нужно транслировать случайные символы, сгенерированные моей пользовательской службой, чтобы основной вид деятельности, зарегистрированный для перехвата трансляции, мог получать случайные числа и отображать их в EditText. Макет показан здесь: макет приложения

Кнопка запуска запускает службу генератора случайных символов. EditText будет отображать случайные числа, сгенерированные в режиме реального времени (без нажатия кнопки). Кнопка Стоп остановит сервис. EditText не будет отображать никаких чисел. Я создал сервис (RandomCharacterService) и зарегистрировал его в своем манифесте. После запуска приложения мое приложение падает. Я уверен, что это потому, что я не зарегистрировал свою трансляцию в моем манифесте, но я не понимаю, как это сделать. И возможно, что-то не так с тем, как я веду трансляцию в своей основной деятельности. В моем методе нажатия кнопки «Пуск» я попытался выполнить цикл for, но это также привело к сбою приложения.

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.cs7455rehmarazzaklab8">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".RandomCharacterService"></service>

    </application>

MainActivityjava:

    package com.example.cs7455rehmarazzaklab8;

    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.IBinder;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.content.BroadcastReceiver;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.graphics.Color;
    import android.graphics.drawable.ColorDrawable;
    import android.support.constraint.ConstraintLayout;
    import android.support.v4.content.LocalBroadcastManager;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.Window;
    import android.widget.Button;
    import android.widget.Toast;
    import java.util.Random;

    public class MainActivity extends AppCompatActivity
    {
        private Button btnStart, btnStop;
        private EditText myTV;

        private Intent serviceIntent;
        private RandomCharacterService myService;
        private ServiceConnection myServiceConnection;
        private boolean isServiceOn; //checks if the service is on

        private int myRandomCharacter;
        char MyRandomCharacter = (char)myRandomCharacter;
        private boolean isRandomGeneratorOn;

        private final int MIN = 65;
        char m = (char)MIN;
        private final int MAX = 26;
        char x = (char)MAX;
        private final String TAG = "Random Char Service: ";

        private final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        private Context mContext;
        private Random mRandom = new Random();

        // Initialize a new BroadcastReceiver instance
        private BroadcastReceiver mRandomCharReceiver = new BroadcastReceiver() 
    {
            @Override
            public void onReceive(Context context, Intent intent) {
            // Get the received random number
            myRandomCharacter = intent.getIntExtra("RandomCharacter",-1);

            // Display a notification that the broadcast received
            Toast.makeText(context,"Received : " + myRandomCharacter,Toast.LENGTH_SHORT).show();
        }
    };

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

        // Get the application context
        mContext = getApplicationContext();

        btnStart = (Button) findViewById(R.id.StartButton);
        btnStop = (Button) findViewById(R.id.StopButton);


        myTV = (EditText)findViewById(R.id.RandomCharText);

        // Register the local broadcast
        LocalBroadcastManager.getInstance(mContext).registerReceiver(mRandomCharReceiver, new IntentFilter("BROADCAST_RANDOM_CHARACTER"));

        // Change the action bar color
        getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#FFFF00BF")));

        // Set a click listener for start button
        btnStart.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                isServiceOn = true;

                serviceIntent = new Intent(getApplicationContext(), RandomCharacterService.class);
                startService(serviceIntent);
                setRandomNumber();
                // Generate a random char
                myRandomCharacter = new Random().nextInt(x)+m;

                // Initialize a new intent instance
                Intent intent = new Intent("BROADCAST_RANDOM_CHARACTER");
                // Put the random character to intent to broadcast it
                intent.putExtra("RandomCharacter",myRandomCharacter);

                // Send the broadcast
                LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);

                // Update the TextView with random character
                myTV.setText(" " + myRandomCharacter );
            }
        });

        btnStop.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                isServiceOn = false;

                stopService(serviceIntent);
            }
        });
    }
    private void setRandomNumber()
    {
        myTV.setText("Random Character: " + (char)myService.getRandomCharacter());
        String alphabet = myTV.getText().toString();

    }

}

RandomCharacterService.java:

    package com.example.cs7455rehmarazzaklab8;

    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    import android.support.annotation.IntDef;
    import android.support.annotation.Nullable;
    import android.util.Log;

    import java.util.Random;


    public class RandomCharacterService extends Service
    {
        private int myRandomCharacter;
        char MyRandomCharacter = (char)myRandomCharacter;
        private boolean isRandomGeneratorOn;

        private final int MIN = 65;
        char m = (char)MIN;
        private final int MAX = 26;
        char x = (char)MAX;
        private final String TAG = "Random Char Service: ";

        private final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        class RandomCharacterServiceBinder extends Binder{
            public RandomCharacterService getService()
            {
                return RandomCharacterService.this;
            }
        }

    private IBinder myBinder = new RandomCharacterServiceBinder();

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        Log.i(TAG, "In OnStartCommand Thread ID is "+Thread.currentThread().getId());
        isRandomGeneratorOn = true;

        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                startRandomGenerator();
            }
        }
        ).start();

        return START_STICKY;
    }

    private void startRandomGenerator()
    {
        while(isRandomGeneratorOn)
        {
            char alphabet = 'A';
            for (int i = 65; i < 90; i++)
            {
                try
                {
                    Thread.sleep(1000);
                    if(isRandomGeneratorOn)
                    {
                        alphabet++;
                        myRandomCharacter = new Random().nextInt(x)+m;
                        Log.i(TAG, "Thread ID is "+Thread.currentThread().getId() + ", Random character is "+(char)myRandomCharacter);
                    }
                }
                catch(InterruptedException e)
                {
                    Log.i(TAG, "Thread Interrupted.");
                }

            }

        }

    }

    private void stopRandomGenerator()
    {
        isRandomGeneratorOn = false;
    }

    public int getRandomCharacter()
    {
        return myRandomCharacter;
    }

    public boolean isRandomGeneratorOn() {
        return isRandomGeneratorOn;
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        stopRandomGenerator();
        Log.i(TAG, "Service Destroyed.");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent)
    {
        Log.i(TAG, "In onBind ...");
        return myBinder;
    }
}

стек вызовов: стек вызовов от запуска приложения

Вызов стека при попытке нажать кнопку остановки: сбой при попытке нажать кнопку остановки

1 Ответ

0 голосов
/ 09 марта 2019

Так как вы используете связанный сервис (используя Ibinder). Вам придется запустить услугу, позвонив по номеру bindService вместо startService. Но перед этим вам нужно инициализировать переменную ServiceConnection и лучше использовать логическое значение isServiceOn, как в примере ниже.

private ServiceConnection myServiceConnection = new ServiceConnection() {
    @Override
    // IBinder interface is through which we receive the service object for communication.
    public void onServiceConnected(ComponentName name, IBinder binder) {
        RandomCharacterServiceBinder myBinder = (RandomCharacterServiceBinder) binder;
        isServiceOn = true;
        myService = myBinder.getService();
        Toast.makeText(context,"Service connected", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        isServiceOn = false;
        myService = null;
    }
};

После вызова onServiceConnected вы получите свой сервисный объект. Скорее всего, ваш сервис будет инициализирован до того, как вы нажмете кнопку. Но только для того, чтобы убедиться, что вы можете пропустить какое-то сообщение внутри него.

И вам следует запустить службу в методе Activity onCreate, чтобы служба заняла некоторое время при создании. Поэтому переместите приведенный ниже код с прослушивателя, который вы нажали, на метод onCreate.

serviceIntent = new Intent(getApplicationContext(), RandomCharacterService.class);
// startService(serviceIntent); <-- remove this line, call bindService
bindService(intent, myServiceConnection, Context.BIND_AUTO_CREATE);

и дождитесь появления сервисного соединения Toast.

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