JavascriptProva

giovedì 13 ottobre 2016

Aggiustamento delle seekBars che regolano gli intervalli di rilevamento in J-Time

Ho una SeekBar. Setto il massimo a 10 e vediamo come "scatta".

public class SetIntervals extends AppCompatActivity {

    SeekBar seekBar1, seekBar2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_set_intervals);

        seekBar1=(SeekBar)findViewById(R.id.seekBar1);
        seekBar2=(SeekBar)findViewById(R.id.seekBar2);

        seekBar1.setMax(10);

        seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                System.out.println(i);
            }


            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }
}
Lo scatto si ha a ognuno dei 10.
Ora lo graduo a 5.
        seekBar1.setMax(5);

        seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                System.out.println(i);
            }


            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
E vediamo...

Adesso scatta a ognuno dei 5.

Ora, io voglio un massimo di 4 ore, che sarebbe 240 minuti, regolabile a valori di 10 minuti.
Se per ogni valore voglio lo scatto, devo far sì che corrisponda nella scala della SeekBar a 1.
Come fare?

In 240 minuti ci sono 24 intervalli di 10 minuti, quindi dovrei graduare a 24.
Proviamo per vedere la "manualità":
        seekBar1.setMax(24);

        seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                System.out.println(i);
            }


            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
Non è molto "acchiappabile" come prima, ovviamente. Ma ha senso che io imposti un intervallo di 4 ore? Posso impostarlo di 3?
Vediamo:
seekBar1.setMax(18);
Va bene, dai, lasciamolo così: a intervalli di 3 ore l'app mi chiede conto di quello che sto facendo.
Il valore sarà il numero dello scatto moltiplicato per 10.
Cosa dovrò riportare nella relativa textView?
Ecco: istanzio le textView e vado:
        seekBar1.setMax(18);

        seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                textViewMin.setText(""+i*10);
            }


            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
Ecco: ottengo il numero di minuti desiderato.

Dal momento che sarebbe ridicolo impostare un intervallo zero, sarebbe il caso di iniziare con un intervallo di 10 minuti.
Dunque bisogna sommare al valore 10, e impostare il Max a 170 (dieci minuti in meno), in modo che nella textView venga un valore da 10 a 180 minuti.
        seekBar1.setMax(17);

        seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                textViewMin.setText(""+i*10+10);
            }


            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
Proviamo... Perfetto! Abbiamo il valore dei minuti da 10 a 180.
Ora devo occuparmi della conversione di questo valore in ore.
Per la conversione in ore:
        seekBar1.setMax(17);

        seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                int ore=(i*10+10)/60.
                textViewMin.setText(""+ore);
            }
Proviamo...

Sì: ho creato il tutto:
        seekBar1.setMax(17);

        seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                int ore=(i*10+10)/60;
                int minuti=(i*10+10)%60;
                textViewMin.setText(ore+" ore e "+minuti+" minuti");
            }


            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
Posso raffinare il risultato omettendo ore e minuti qualora siano zero... ma per il momento facciamo altro: sistemo l'altra SeekBar e poi le devo coordinare.
        seekBar1.setMax(17);
        seekBar2.setMax(17);

        seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                int ore=(i*10+10)/60;
                int minuti=(i*10+10)%60;
                textViewMin.setText(ore+" ore e "+minuti+" minuti");
            }


            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        
        seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                int ore2=(i*10+10)/60;
                int minuti2=(i*10+10)%60;
                textViewMax.setText(ore+" ore e "+minuti+" minuti");
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
Proviamolo...

Funziona!
Ora viene il coordinamento, perché la barra che stabilisce l'intervallo massimo non può avere un valore inferiore a quella dell'intervallo minimo, e viceversa.
Ogni volta che si muove una barra, bisognerà, se è il caso, aggiustare l'altra.
Vediamo come si può fare...

Ecco il codice che riporta la seekBar2 a valori di progress uguali a quelli della seekBar1 qualora fossero minori:
if(seekBar2.getProgress()<i) seekBar2.setProgress(i);


Ora facciamo il reciproco con seekBar2 qualora il valore di seekBar1 fosse superiore:
if(seekBar1.getProgress()>i) seekBar1.setProgress(i);
Proviamo...

Okay! Funziona!

lunedì 10 ottobre 2016

Pulsanti concentrici: aggiustamento.

Cerchiamo di ragionare...

Intanto salvo il codice, anche se imperfetto, specialmente per non scordare quello relativo all'attribuzione del click, che recupererò in seguito:
public class MainActivity extends AppCompatActivity {
    RelativeLayout mainLayout;
    private Button uno, due, tre, quattro;
    MediaPlayer mp;
    Context context = this;
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mainLayout = (RelativeLayout)findViewById(R.id.mainLayout);
        mp=MediaPlayer.create(context, R.raw.click);
        uno=(Button) findViewById(R.id.uno);
        due=(Button) findViewById(R.id.due);
        tre=(Button) findViewById(R.id.tre);
        quattro=(Button) findViewById(R.id.quattro);



        View.OnTouchListener onTouchListener=new View.OnTouchListener(){
            int colore=0;

            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                GradientDrawable gd = (GradientDrawable) view.getBackground();
                if (inCircle(motionEvent, view.getWidth() / 2.0f, view.getHeight() / 2.0f, view.getWidth() / 2)) {

                    if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {

                        try {
                            if (mp.isPlaying()) {
                                mp.stop();
                                mp.release();
                                mp = MediaPlayer.create(context, R.raw.click);
                            }
                            mp.start();
                        } catch (Exception e) {
                        }

                        gd.setColor(Color.YELLOW);
                    }



                    if (motionEvent.getAction() == MotionEvent.ACTION_UP ) {


                        ((GradientDrawable) uno.getBackground()).setColor(0xffffffff);
                        ((GradientDrawable) due.getBackground()).setColor(0xfffddfe0);
                        ((GradientDrawable) tre.getBackground()).setColor(0xffffe4d2);
                        ((GradientDrawable) quattro.getBackground()).setColor(0xfff0e1d9);

                    }


                }
                return true;

            }

        };
        uno.setOnTouchListener(onTouchListener);
        due.setOnTouchListener(onTouchListener);
        tre.setOnTouchListener(onTouchListener);
        quattro.setOnTouchListener(onTouchListener);




    }



    boolean inCircle(MotionEvent event, float centerX, float centerY, float radius){
        float deltaX=event.getX()-centerX;
        float deltaY=event.getY()-centerY;
        double ipotenusa=Math.sqrt((deltaX*deltaX)+(deltaY*deltaY));
        if(ipotenusa<=radius) return true;
        return false;
    }
}


Bene.
Fatto questo, mi limito a voler ottenere soltanto il cambiamento di colore di ogni pulsante circolare.

Ecco:
public class MainActivity extends AppCompatActivity {
    RelativeLayout mainLayout;
    private Button uno, due, tre, quattro;
    MediaPlayer mp;
    Context context = this;
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mainLayout = (RelativeLayout)findViewById(R.id.mainLayout);
        mp=MediaPlayer.create(context, R.raw.click);
        uno=(Button) findViewById(R.id.uno);
        due=(Button) findViewById(R.id.due);
        tre=(Button) findViewById(R.id.tre);
        quattro=(Button) findViewById(R.id.quattro);
        
        View.OnTouchListener onTouchListener=new View.OnTouchListener(){
            int colore=0;

            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                GradientDrawable gd = (GradientDrawable) view.getBackground();
                if (inCircle(motionEvent, view.getWidth() / 2.0f, view.getHeight() / 2.0f, view.getWidth() / 2)) {

                    switch(motionEvent.getAction()){
                        case MotionEvent.ACTION_DOWN:
                            gd.setColor(Color.RED);
                            break;
                        case MotionEvent.ACTION_UP:
                            ((GradientDrawable) uno.getBackground()).setColor(0xffffffff);
                            ((GradientDrawable) due.getBackground()).setColor(0xfffddfe0);
                            ((GradientDrawable) tre.getBackground()).setColor(0xffffe4d2);
                            ((GradientDrawable) quattro.getBackground()).setColor(0xfff0e1d9);
                            break;

                    }
                }
                return true;

            }

        };
        uno.setOnTouchListener(onTouchListener);
        due.setOnTouchListener(onTouchListener);
        tre.setOnTouchListener(onTouchListener);
        quattro.setOnTouchListener(onTouchListener);
    }
    
    boolean inCircle(MotionEvent event, float centerX, float centerY, float radius){
        float deltaX=event.getX()-centerX;
        float deltaY=event.getY()-centerY;
        double ipotenusa=Math.sqrt((deltaX*deltaX)+(deltaY*deltaY));
        if(ipotenusa<=radius) return true;
        return false;
    }
}
Questo dovrebbe colorare la view cliccata di rosso, mentre quando si rilascia il dito tutte le views riassumono il loro colore originario.
Proviamola...

E infatti funziona.

C'è un comportamento particolare: se scivolo col dito verso un pulsante più esterno, il colore rosso si congela, mentre ciò non avviene se scivolo verso un pulsante più interno.
Ho posto come condizione che il tocco avvenga entro un limite circolare dato dalle dimensioni del pulsante, sia in battere sia in levare. Se dunque vado all'esterno, viene meno la condizione e quindi il levare non ha effetto, mentre se vado all'interno, dal momento che il listener è impostato anche per gli altri pulsanti, funziona questo restituendo i colori originari.


Ora devo studiare quel fantomatico ACTION_OUTSIDE o qualcosa di simile.
Non riesco a ottenere il funzionamento.
Riesaminiamo le condizioni...

Il ritorno del colore avviene solo se tutte queste azioni vengono svolte entro il limite del pulsante circolare, quindi può darsi che qualunque cosa io faccia non abbia effetto perché esclusa dalla limitazione della circonferenza.

public class MainActivity extends AppCompatActivity {
    RelativeLayout mainLayout;
    private Button uno, due, tre, quattro;
    MediaPlayer mp;
    Context context = this;
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mainLayout = (RelativeLayout)findViewById(R.id.mainLayout);
        mp=MediaPlayer.create(context, R.raw.click);
        uno=(Button) findViewById(R.id.uno);
        due=(Button) findViewById(R.id.due);
        tre=(Button) findViewById(R.id.tre);
        quattro=(Button) findViewById(R.id.quattro);

        View.OnTouchListener onTouchListener=new View.OnTouchListener(){
            int colore=0;

            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                GradientDrawable gd = (GradientDrawable) view.getBackground();

                switch(motionEvent.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        if (inCircle(motionEvent, view.getWidth() / 2.0f, view.getHeight() / 2.0f, view.getWidth() / 2)) {
                            gd.setColor(Color.RED);
                        }
                        break;

                    case MotionEvent.ACTION_UP:
                        ((GradientDrawable) uno.getBackground()).setColor(0xffffffff);
                        ((GradientDrawable) due.getBackground()).setColor(0xfffddfe0);
                        ((GradientDrawable) tre.getBackground()).setColor(0xffffe4d2);
                        ((GradientDrawable) quattro.getBackground()).setColor(0xfff0e1d9);
                        break;

                }

                return true;

            }

        };
        uno.setOnTouchListener(onTouchListener);
        due.setOnTouchListener(onTouchListener);
        tre.setOnTouchListener(onTouchListener);
        quattro.setOnTouchListener(onTouchListener);
    }

    boolean inCircle(MotionEvent event, float centerX, float centerY, float radius){
        float deltaX=event.getX()-centerX;
        float deltaY=event.getY()-centerY;
        double ipotenusa=Math.sqrt((deltaX*deltaX)+(deltaY*deltaY));
        if(ipotenusa<=radius) return true;
        return false;
    }
}
FUNZIONA!.
In fondo era banale!

sabato 8 ottobre 2016

Creazione di una shape su XML e a runtime.

Creiamo una shape in modo statico con XML e dinamico a runtime.

Creiamo una shape ovale blu, dapprima con XML quindi a runtime.

Commentiamo in abbondanza...
Ho questo, inizialmente:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

</shape> 
Dove specificare il tipo di shape?
Nello stesso tag shape.
Così:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

</shape> 


E' sufficiente tutto questo?
No: bisogna impostare il colore.
Iniziamo con il colore solido, ossia quello del riempimento, che si imposta con un tag a parte, solid.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="#3355ff"/>

</shape> 
Ora che ci sembra sufficiente, possiamo far assumere al nostro Button questa shape come sfondo:
public class MainActivity extends AppCompatActivity {
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button=(Button) findViewById(R.id.button);
        //button.setBackground(getResources().getDrawable(R.drawable.ovale));

    }
}
Ho commentizzato la parte critica per confronto: in questo modo ottengo un button normale.



Ora scommentizzo:
public class MainActivity extends AppCompatActivity {
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button=(Button) findViewById(R.id.button);
        button.setBackground(getResources().getDrawable(R.drawable.ovale));

    }
}


Ora tentiamo di riprodurre questa shape a runtime.

Da quello che leggo sul forum, il codice per riprodurre la mia forma dovrebbe essere questo:
        ShapeDrawable sd=new ShapeDrawable(new OvalShape());
        sd.getPaint().setColor(0x3355ff);
e forse il codice per settare il background a questo drawable sarebbe questo:
button.setBackground(sd);
Ecco il codice completo:
public class MainActivity extends AppCompatActivity {
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button=(Button) findViewById(R.id.button);


        ShapeDrawable sd=new ShapeDrawable(new OvalShape());
        sd.getPaint().setColor(0xFF3355FF);
        button.setBackground(sd);

    }
}
Proviamo...



Perfetto!

Indirizzo del tutorial

venerdì 7 ottobre 2016

Autotutorial per Firebase Seconda parte

Torno a collegare un'App al Progetto Firebase.



Da questa immagine schiaccio CONTINUE e vado qui:

Seguo le istruzioni completando i due files gradle

Project:
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.3'
        classpath 'com.google.gms:google-services:3.0.0'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


app:
apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.2"

    defaultConfig {
        applicationId "com.example.antonello.firebasebase"
        minSdkVersion 18
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.2.0'
}

apply plugin: 'com.google.gms.google-services'
e schiaccio, su Android Studio, Sync Now.

Termino schiacciando FINISH in basso (che qui non si vede ma c'è).
Ecco.
Ho eseguito Sync.

Ora faccio questo:



E appare il codice SHA1 nella finestra di LogCat:



...che va preso e incollato qua:

Autotutorial per la creazione di un progetto su Firebase

Esercizio.

Creare un progetto e linkarlo a Firebase.

Ho creato un progetto ex novo.
Ora vado su Firebase.

Creo un nuovo progetto su Firebase.



Eccolo:



Ora devo aggiungere un'app.

Cliccandoci sopra, si arriva a questa pagina:



Si clicca sul simboletto verde, quello dove è scritto "Add Firebase to Android App".
Ed ecco cosa si apre:



Qui viene richiesto di scrivere il Package e il codice SHA1.
Per ottenere il codice SHA1 c'è tutta una procedura, che può essere rinviata a dopo.
Per intanto copio il nome del package:



e schiaccio ADD APP.


(In alto è scritto "Add Firebase to your Android App", la scritta è stata tagliata)
Qui appaiono le istruzioni, mentre contemporaneamente è stato scaricato un file chiamato google-services.json nella cartella Downloads.
Seguo le istruzioni e apro il progetto sulla finestra a sinistra in modo da visualizzare le giuste cartelle



Ecco:



Prendo il file google-services.json che mi è stato downloadato nella cartella Downloads, e lo copio.



quindi lo incollo nella finestra del mio progetto Android:


Il passo successivo è quello di sistemare i files gradle. Per il momento mi fermo qui.

Dunque, ho visto i primi passaggi:
  • Creazione del Progetto su Firebase
  • Aggiunta di un'App al Progetto: inserimento del nome del Package
  • Seguire le istruzioni a video per copiare e incollare nella cartella App su Android Studio il file google-services.json scaricato automaticamente.

mercoledì 5 ottobre 2016

Codice di J-Time: ricostruzione.

Ora costruiamo un'interfaccia di base che lancia l'activity principale la quale poi si rilancia automaticamente a intervalli di tempo predefiniti.

MainActivity:
public class MainActivity extends AppCompatActivity {

    private AlarmManager alarmManager;
    private Intent intent;
    private PendingIntent pendingIntent;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button=(Button) findViewById(R.id.button);
        intent=new Intent(getApplicationContext(),Seconda.class);
        alarmManager=(AlarmManager)getSystemService(Context.ALARM_SERVICE);
        pendingIntent=PendingIntent.getActivity(getApplicationContext(),0,intent,0);

        button.setOnClickListener(new Button.OnClickListener(){

            @Override
            public void onClick(View view) {
                alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+5*1000,pendingIntent);
                finish();

            }
        });
    }



}


Seconda:
public class Seconda extends AppCompatActivity {

    private AlarmManager alarmManager;
    private Intent intent;
    private PendingIntent pendingIntent;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_seconda);

        intent=new Intent(getApplicationContext(),Seconda.class);
        alarmManager=(AlarmManager)getSystemService(Context.ALARM_SERVICE);
        pendingIntent=PendingIntent.getActivity(getApplicationContext(),0,intent,0);

        button=(Button) findViewById(R.id.button2);

        button.setOnClickListener(new Button.OnClickListener(){

            @Override
            public void onClick(View view) {
                finish();
            }
        });
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+5*1000,pendingIntent);
    }


Manifest (con il codice per non far apparire la finestra fra i Recent Tasks):
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.antonello.j_time">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        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>
        <activity
            android:name=".Seconda"
            android:autoRemoveFromRecents="true"></activity>
    </application>

</manifest> 
La finestra viene egregiamente rimossa dalla finestra dei Recent Tasks.

Ripasso di AlarmManager per far ricomparire un'altra o la stessa Activity dopo un intervallo di tempo predefinito.

Riottenere il codice di una funzione a tempo, di cui ero diventato un esperto.
Creo un'activity che si ripropone ciclicamente a intervalli, per il momento, regolari.

Ecco, ho ripassato e riprodotto. Questa è un'activity che si riproduce da sola dopo un determinato intervallo di tempo:
public class MainActivity extends AppCompatActivity {

    private AlarmManager alarmManager;
    private PendingIntent pendingIntent;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button=(Button) findViewById(R.id.button);
        Intent intent=new Intent(getApplicationContext(),MainActivity.class);
        alarmManager=(AlarmManager)getSystemService(Context.ALARM_SERVICE);
        pendingIntent=PendingIntent.getActivity(getApplicationContext(),0,intent,0);

        button.setOnClickListener(new Button.OnClickListener(){

            @Override
            public void onClick(View view) {



            }
        });
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+5*1000,pendingIntent);

    }

}
Ora devo trovare il modo di far cessare il ciclo.
public class MainActivity extends AppCompatActivity {

    private AlarmManager alarmManager;
    private PendingIntent pendingIntent;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button=(Button) findViewById(R.id.button);
        Intent intent=new Intent(getApplicationContext(),MainActivity.class);
        alarmManager=(AlarmManager)getSystemService(Context.ALARM_SERVICE);
        pendingIntent=PendingIntent.getActivity(getApplicationContext(),0,intent,0);

        button.setOnClickListener(new Button.OnClickListener(){

            @Override
            public void onClick(View view) {
                alarmManager.cancel(pendingIntent);
                if(pendingIntent!=null) pendingIntent.cancel();


            }
        });
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+5*1000,pendingIntent);

    }

}

Ecco.
Il ripasso l'ho fatto da questo mio stesso post