JavascriptProva

venerdì 12 ottobre 2018

Aggiunta di fragments da xml.

Nuovo esercizio sui fragment.
Creare due fragments in xml.

Cliccando direttamente su New -> Fragment ottengo sia il file xml sia quello java.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#AAFFFF"
    tools:context=".primo">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/testo1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />


</FrameLayout> 
(ci ho aggiunto uno sfondo celeste per distinguerlo)
public class primo extends Fragment {


    public primo() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_primo, container, false);
    }

}


Adesso ottengo l'altro frammento:



Ecco, ho creato un frammento lasciando il nome di default, BlankFragment.
Vediamone il file xml e il file java.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFAAAA"
    tools:context=".BlankFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout> 
Ci ho aggiunto uno sfondo rosso.

Ora devo riportare questi fragment sulla MainActivity: ho creato un altro video:



Ed ecco:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:id="@+id/container"
    tools:context=".MainActivity">


    <fragment
        android:id="@+id/fragment"
        android:name="com.example.antonello.studiofragment.primo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <fragment
        android:id="@+id/fragment2"
        android:name="com.example.antonello.studiofragment.BlankFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />
</LinearLayout> 
I due fragment hanno l'altezza impostata a wrap_content, per cui appaiono della stessa altezza delle textview compresevi dentro:






Ora vediamo il file java.
public class primo extends Fragment {


    public primo() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_primo, container, false);
    }

}
Ecco, praticamente viene inflatato il codice xml del fragment all'interno del ViewGroup chiamato container.
Tutto qui.

martedì 2 ottobre 2018

YouTubePlayerView

E' il momento di fare e disfare Mandala su YouTubePlayerView.
public class MainActivity extends YouTubeBaseActivity {
    //DICHIARAZIONI DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
    YouTubePlayerView player;
    YouTubePlayer.OnInitializedListener onInitializedListener;
    Button button;
    String videoId = "4DTXAGGPFrw";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //INIZIALIZZAZIONI IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
        player=(YouTubePlayerView)findViewById(R.id.youtubePlayer);
        button=(Button)findViewById(R.id.button);

        onInitializedListener = new OnInitializedListener() {
            @Override
            public void onInitializationSuccess(Provider provider, YouTubePlayer youTubePlayer, boolean b) {
                youTubePlayer.loadVideo(videoId);
            }

            @Override
            public void onInitializationFailure(Provider provider, YouTubeInitializationResult youTubeInitializationResult) {

            }
        };

        //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII

        button.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View view) {
                player.initialize(PlayerConfig.API_KEY,onInitializedListener);
            }
        });
    }
}
Questo codice l'ho scritto quasi di getto, e ha funzionato egregiamente...

sabato 29 settembre 2018

Esercizio sul fragment: creazione e comunicazione con l'activity principale.

Ora voglio tenermi in esercizio con i Fragment.
Non riesco ancora a usare questo blog nella maniera che mi ero preposto, ossia come un diario per esercizi.
Programmiamo un esercizio al giorno sui Fragments, per 5 giorni. Potrebbe essere sufficiente.
Ecco, adesso rompo il mio esercizio e lo ricostruisco da capo.
Aggiunta di due fragment con messa a video in un Toast da parte della finestra principale del testo di una TextBox contenuta in uno di questi due fragments.

Ho cliccato col destro sul nome del package nella finestra "Progetto", e quindi ho cliccato New.
Nel menu ho cliccato Fragment -> Fragment (Blank), quindi ho eliminato le spunte, nella finestra, su include fragment factory methods e su include interface callback?.
, ho scelto un nuovo nome al posto di BlankFragment e Android Studio mi crea il fragment, ossia un file xml e un file java.

Sono stato messo un po' in crisi dal fatto che mi è stato messo tutto in un FrameLayout.
Nell'esercizio che ho fatto ieri non mi ero accorto di questo fatto, confuso da diversi tutorial.
Bene: all'interno del FrameLayout ci mettiamo un layout a nostro piacimento, Linear, Relative o altro.

Questo è l'XML di un fragment:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    tools:context=".fragment_origine">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:weightSum="10"
        tools:context=".fragment_origine">

        <!-- TODO: Update blank fragment layout -->

        <TextView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:text="@string/hello_blank_fragment" />

        <Button
            android:id="@+id/button4"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:text="Button" />

    </LinearLayout>

</FrameLayout> 
Per l'altro fragment faccio la stessa cosa, senza alcuna view particolare, ma solo con uno sfondo azzurrino:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".fragment_altro">

    <LinearLayout
        android:background="#AACCFF"
        android:layout_width="match_parent"
        android:layout_height="match_parent">


    </LinearLayout>



</FrameLayout> 

Ora che ho preparato i fragments, li dispongo all'interno del mainLayout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:id="@+id/container"
    tools:context=".MainActivity">
    
    <fragment
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:id="@+id/fragment1"
        android:name="com.example.antonello.studiofragment.fragment_origine"/>
    
    <fragment
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:id="@+id/fragment2"
        android:name="com.example.antonello.studiofragment.fragment_altro"/>
        



</LinearLayout> 
Funziona!


Ora devo recepire l'azione sul pulsante del primo fragment.
public class fragment_origine extends Fragment {
    TextView testo;
    Button button;
    public fragment_origine() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_origine, container, false);
        testo=view.findViewById(R.id.textview);
        button=view.findViewById(R.id.button4);
        
        return view;
    }
.....
Dichiaro e inizializzo le variabili di tipo TextView e Button.
Avevo dimenticato di specificare l'id per la TextView, e rimedio subito:
        <TextView
            android:id="@+id/textview"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:text="@string/hello_blank_fragment" />
Poi ho creato un'interfaccia:
    public interface OnTextReadListener{
        public void onTextRead(String messaggio);
    }
e ho dichiarato una variabile del tipo dell'interfaccia:
public class fragment_origine extends Fragment {
    OnTextReadListener mListener;
    TextView testo;
    Button button;
    public fragment_origine() {
        // Required empty public constructor
    }
.....
Ora devo fare in modo che all'evento onAttach(Context context) venga eguagliata alla variabile del tipo dell'interfaccia, mListener, la main activity alla quale il fragment si è "attaccato":
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mListener=(OnTextReadListener)context;
    }
Quindi vado a MainActivity e dichiaro che implementa l'interfaccia di cui sopra:
public class MainActivity extends AppCompatActivity implements fragment_origine.OnTextReadListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
Quindi scrivo, sempre in MainActivity, il codice del metodo da implementare:
    @Override
    public void onTextRead(String messaggio) {
        Toast.makeText(this,messaggio,Toast.LENGTH_LONG).show();
    }
Avviando il programma, non ottengo errori.
Ma finora ho solo creato una classe che implementa il metodo dell'interfaccia dichiarata nel fragment, non ho ancora subordinato l'esecuzione di questo metodo da parte del Button.
Provvedo:
        button.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View view) {
                mListener.onTextRead(testo.getText().toString());
            }
        });
E adesso funziona!

domenica 26 agosto 2018

Esercizi sulle suonerie.

Ho bisogno di esercitarmi sulle suonerie.

Prima la sezione sulla scelta della suoneria dalle SharedPreferences o di default:
        bttSuona.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View view) {
                Uri ringtoneUri=null;
                Ringtone ringtone=null;
                String stringSuoneria=sp.getString("suoneria","");
                if(TextUtils.isEmpty(stringSuoneria)){
                    ringtoneUri=RingtoneManager.getActualDefaultRingtoneUri(
                            getApplicationContext(),
                            RingtoneManager.TYPE_NOTIFICATION);
                }else{
                    ringtoneUri=Uri.parse(stringSuoneria);
                }
                ringtone=RingtoneManager.getRingtone(
                        getApplicationContext(),
                        ringtoneUri);
                ringtone.play();


            }
        });
Funziona! Cancellando le SharedPreferences, viene invocata la suoneria di default.

Ora la parte che serve per settare la suoneria.
        button.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View view) {

                Intent intent=new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
                intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,RingtoneManager.TYPE_NOTIFICATION);
                startActivityForResult(intent,0);

            }
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Uri uri=data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
        editor.putString("suoneria",uri.toString());
        editor.apply();
    }
Vediamo se funziona...

Funziona!
Distruggo e riscrivo senza sbirciare:
        bttSuona.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View view) {

                Uri ringtoneUri;
                Ringtone ringtone;
                String strSuoneria=sp.getString("suoneria","");
                if(TextUtils.isEmpty(strSuoneria)){
                    ringtoneUri=RingtoneManager.getActualDefaultRingtoneUri(
                            getApplicationContext(),
                            RingtoneManager.TYPE_NOTIFICATION);

                }else{
                    ringtoneUri=Uri.parse(strSuoneria);
                }
                ringtone=RingtoneManager.getRingtone(getApplicationContext(),
                        ringtoneUri);
                ringtone.play();
            }
        });
Ora riscrivo la seconda parte per la scelta della suoneria.
        button.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View view) {
                Intent intent=new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
                intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,RingtoneManager.TYPE_NOTIFICATION);
                startActivityForResult(intent,0);
            }
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Uri uri=data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
        editor.putString("suoneria", uri.toString());
        editor.apply();

    }
}
Credo di aver memorizzato abbastanza...

giovedì 16 agosto 2018

Esercitazione sulle misure dello schermo

Innanzitutto devo definire una variabile di tipo Point in cui mettere i valori di larghezza e altezza del display.
Devo definire anche una variabile di tipo WindowManager.
        wm=(WindowManager)getSystemService(WINDOW_SERVICE);
        szWindow=new Point();
Ora creo un oggetto di tipo Display estraendolo mediante la funzione getDefaultDisplay di WindowManager:
        Display display= wm.getDefaultDisplay();
Quindi di questo display estraggo le dimensioni nella variabile Point:
        display.getSize(szWindow);
Bene.
Cancello tutto e poi vado avanti.
        szWindow=new Point();
        wm=(WindowManager)getSystemService(WINDOW_SERVICE);
        Display display=wm.getDefaultDisplay();
        display.getSize(szWindow);
        System.out.println(szWindow.x + " " + szWindow.y);
Provo a visualizzare in LogCat i valori della larghezza e altezza del display:
08-16 10:46:39.880 5341-5341/com.example.antonello.chatheadstudio I/System.out: 720 1184

Andando a vedere nelle caratteristiche dell'emulatore, ottengo dimensioni di 720 x 1280.
Lo scarto sarà dovuto alle barre, poi lo vedrò meglio.
Ora provo il codice su dispositivo reale.
Bene: ecco le misure:
08-16 13:05:21.371 27953-27953/com.example.antonello.chatheadstudio I/System.out: 720 1280

Da dove venga quella differenza fra emulatore e dispositivo fisico, non saprei.
Comunque funziona!

Esercitazione sui permessi a runtime senza riavviare l'App.

Codice che imposta i permessi a runtime senza necessità di riavviare l'applicazione.
Ho cancellato tutto e ora me lo ricostruisco.
public class MainActivity extends AppCompatActivity {

    Handler handler=new Handler();


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

        Runnable runnable =new Runnable() {
            @Override
            public void run() {
                if(Build.VERSION.SDK_INT >= 23 && Settings.canDrawOverlays(getApplicationContext())){
                    Intent i=new Intent(getApplicationContext(),MainActivity.class);
                    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                    startActivity(i);
                }else{
                    handler.postDelayed(this,1000);
                }
            }
        };
        if(Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(getApplicationContext())){
            Intent intent=new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:"+getPackageName()));
            startActivity(intent);
            handler.postDelayed(runnable,1000);
        }else{
            continua();
        }

    }

    private void continua(){
        System.out.println("STO CONTINUANDO");
    }

}
Funziona! L'ho scritto bene, a quanto pare!

sabato 11 agosto 2018

Headers delle mail in PHP (From, Reply-To)

Vediamo un po' gli header delle mail...

Semplicemente l'header è "From..." eccetera.
E' praticamente una stringa.
Proviamo.

$email="antonello.iaccarino@alice.it";
$titolo="Titolo";
$testo="La vispa teresa avea tra l'erbetta a volo sorpreso gentil farfalletta";
$headers="From: trigonjac@gmail.com";


mail($email,$titolo,$testo,$headers);
Basta scrivere in una sola stringa "From: ... seguito dall'indirizzo o da una variabile che lo rappresenti."

Per l'aggiunta del Reply-To, voglio provare a scrivere questo nella stessa linea, vediamo che succede.
$headers="From: trigonjac@gmail.com Reply-To: cicciofatticcio@minkia.com";
Vediamo che succede...

Non ho ricevuto nessuna mail.br Invece disponendo su linee diverse in questo modo:
$headers="From: trigonjac@gmail.com\r\n";
$headers.="Reply-To: cicciofatticcio@minkia.com";
ottengo una mail avente per mittente trigonjac ma quando vado a rispondere rispondo a cicciofatticcio.

Da quanto ho capito il From: serve solo per notificare chi sia il mittente, mentre il Reply-To sta a indicare il destinatario della risposta.