JavascriptProva

mercoledì 20 luglio 2016

Inizio del progetto Kouros. Binding e inizio del codice AlarmManager.

Diamo inizio al progetto Kouros.
Per prima cosa, devo costruirmi sempre una struttura "ciclica" del tipo che ho ideato io: Un'attività iniziale chiama un Service che inizia il conto del tempo, quindi questo chiama un'altra attività il cui feedback reinnesca il controllo del tempo.
Il Service va bindato ad ambedue le attività.
Iniziamo con la ricostruzione di questa struttura.
public class TimerService extends Service{
 Intent intent;
 PendingIntent pendingIntent;
 AlarmManager alarmManager;
 @Override
 public IBinder onBind(Intent intent) {
  // TODO Auto-generated method stub
  return null;
 }
 

}
}
Non ricordo dove istanziavo AlarmManager e tutto il resto.
Credo ci fosse un metodo dedicato.
Vado a confrontarmi...

Sì, c'era un metodo dedicato StartTime().
Vado... Prima però devo definire l' "obiettivo" del Service, ossia l'attività che va chiamata dal timer.
Vado...

E adesso facciamo il binding della prima attività con il Service:

Codice di TimerService:
public class TimerService extends Service{

 Intent intent;
 PendingIntent pendingIntent;
 AlarmManager alarmManager;
 
 IBinder mBinder=new LocalBinder();
 
 @Override
 public IBinder onBind(Intent intent) {
  // TODO Auto-generated method stub
  return mBinder;
 }
 
 public class LocalBinder extends Binder{
  TimerService getService(){
   return TimerService.this;
  }
 }

}


Codice di MainActivity:
public class MainActivity extends Activity {

 TimerService mService;
 boolean mBound;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.main, menu);
  return true;
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  // Handle action bar item clicks here. The action bar will
  // automatically handle clicks on the Home/Up button, so long
  // as you specify a parent activity in AndroidManifest.xml.
  int id = item.getItemId();
  if (id == R.id.action_settings) {
   return true;
  }
  return super.onOptionsItemSelected(item);
 }
 
 @Override
 public void onStart(){
  super.onStart();
  Intent intent=new Intent(this,TimerService.class);
  bindService(intent,mConnection,Context.BIND_AUTO_CREATE);
 }
 
 @Override
 public void onStop(){
  super.onStop();
  unbindService(mConnection);
  mBound=false;
 }
 private ServiceConnection mConnection=new ServiceConnection(){

  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
   LocalBinder bnd=(LocalBinder)service;
   mService=bnd.getService();
   mBound=true;
   
  }

  @Override
  public void onServiceDisconnected(ComponentName name) {
   mBound=false;
   
  }
  
 };
}
Spero di non aver dimenticato niente.
Posso provare a mettere delle "spie" e verificare che il Service si avvii all'avvio dell'attività e si distrugga alla distruzione dell'attività...

 @Override
 public void onCreate(){
  super.onCreate();
  Log.d("SERVIZIO", "CREATO");
 }

......

 @Override
 public void onDestroy(){
  super.onDestroy();
  Log.d("SERVIZIO", "DISTRUTTO");
  
 }
07-20 11:43:31.606: D/SERVIZIO(25035): CREATO
07-20 11:43:31.876: I/Timeline(25035): Timeline: Activity_idle id: android.os.BinderProxy@42404380 time:140729091
07-20 11:43:52.436: E/OpenGLRenderer(25035): SFEffectCache:clear(), mSize = 0
07-20 11:43:52.436: D/SERVIZIO(25035): DISTRUTTO
Ok!
Ora procedo al bindaggio dell'altra attività chiamata Form.
public class Form extends Activity {

 TimerService mService;
 boolean mBound=false;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_form);
 }
 @Override
 public void onStart(){
  super.onStart();
  Intent intent=new Intent(this,TimerService.class);
  bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
 }
 
 @Override
 public void onStop(){
  super.onStop();
  unbindService(mConnection);
  mBound=false;
 }
 
 private ServiceConnection mConnection=new ServiceConnection(){

  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
   LocalBinder bnd=(LocalBinder)service;
   mService=bnd.getService();
   mBound=true;
   
  }

  @Override
  public void onServiceDisconnected(ComponentName name) {
   mBound=false;
   
  }
  
 };
}
Andiamo sulla fiducia, che verificare anche questa poi diventa troppo indaginoso...

Ora devo inserire un AlarmManager nel TimerService.
 public void StartTime(){
  intent=new Intent(getApplicationContext(),Form.class);
  pendingIntent=PendingIntent.getActivity(getApplicationContext(), 
            0, intent, 0);
  alarmManager=(AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
  alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+10*1000, pendingIntent);
 }
Questo codice non lo ricordo, insieme all'altro per disattivare un alarmManager esistente.
Bisogna che lo ripassi bene.

martedì 19 luglio 2016

MediaRecorder

MediaRecorder.
public class MainActivity extends Activity {

 MediaRecorder mRecorder;
 Button bttRec, bttStop;
 String path;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  bttRec=(Button)findViewById(R.id.button1);
  bttStop=(Button)findViewById(R.id.button2);
  
  path=Environment.getExternalStorageDirectory()+"/provadelmiofile.3gp";
  bttRec.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    mRecorder=new MediaRecorder();
    mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mRecorder.setOutputFile(path);
    try {
     mRecorder.prepare();
     mRecorder.start();
    } catch (IllegalStateException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  });
  
  bttStop.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    mRecorder.stop();
    mRecorder.release();
    mRecorder=null;
    
   }
  });
  
  
 }

}


Manifest:
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />

Creazione e scrittura di un file di testo.

Per prima cosa, vediamo di creare un file.
public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  File file=new File(Environment.getExternalStorageDirectory()+File.separator+"MioFile.txt");
  try {
   file.createNewFile();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
 }

}
Non ottengo niente. Credo che siano necessari dei permessi...

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

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-sdk
        android:minSdkVersion="18"
        android:targetSdkVersion="21" />

    <application

.......
Come si fa per scrivere su questo file di testo?
  OutputStream fo;
  try {
   fo = new FileOutputStream(file);
   byte[] b = {64,65,66};
   fo.write(b);
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

domenica 17 luglio 2016

Memorizzazione di date nel database come stringhe.

Campi del database:
  1. _ID
  2. Data
  3. Ora
  4. Tipo di attività
  5. (appropriatezza)

Facciamo solo con i primi quattro.
  public void save(String attivita){
   SQLiteDatabase db=this.getWritableDatabase();
   Date date=new Date();
   long dateMillis=date.getTime();
   ContentValues values=new ContentValues();
   values.put("data", dateMillis);
   values.put("ore", dateMillis);
   values.put("attivita",attivita);
   db.insert("TABELLA", null,values);
  }

  
  public Cursor query(int numero){
   SQLiteDatabase db=this.getWritableDatabase();
   Cursor crs=db.rawQuery("select * from TABELLA where _id="+numero, null);
   crs.moveToFirst();
   return crs;
  }
Fin qui nessun grosso problema...

Il problema sta nel momento in cui io voglia selezionare i records del database in relazione a una certa data, sia essa compresa fra due date o anteriore o posteriore a un'altra data.
Come fare, dal momento che le date sono salvate sotto forma di millisecondi?

Mi si pone la possibilità di salvare le date come stringhe e poter fare il confronto fra date memorizzate in questo formato...

Sfascio tutto...

E riprovo. Come si converte una data in stringa? Presumo con il ToString.


Ecco il codice:
public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  Helper helper=new Helper(this);
  helper.save("Un tubo");
  

 }
 
 class Helper extends SQLiteOpenHelper{

  public Helper(Context context) {
   super(context, "database.db", null, 1);
   
  }

  @Override
  public void onCreate(SQLiteDatabase db) {
   db.execSQL("create table TABELLA(_id integer primary key,data text ,ora text,attivita text)");
   
   
  }
  

  public void save(String attivita){
   SQLiteDatabase db=this.getWritableDatabase();
   Date date=new Date();
   DateFormat df=new SimpleDateFormat("dd/MM/yyyy");
   DateFormat hf=new SimpleDateFormat("hh:mm");
   String dateFormat=df.format(date).toString();
   String hourFormat =hf.format(date).toString();
   ContentValues values=new ContentValues();
   values.put("data", dateFormat);
   values.put("ora", hourFormat);
   values.put("attivita",attivita);
   db.insert("TABELLA", null, values);
  }
  
  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
   // TODO Auto-generated method stub
   
  }
  
 }
}
Ho immesso alcuni records.
Ora voglio discriminarli.



Ecco, ho trovato:
public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  Helper helper=new Helper(this);
  Log.d("DATA", helper.query().getString(2));
  

 }
 
 class Helper extends SQLiteOpenHelper{

  public Helper(Context context) {
   super(context, "database.db", null, 1);
   
  }

  @Override
  public void onCreate(SQLiteDatabase db) {
   db.execSQL("create table TABELLA(_id integer primary key,data text,ora text,attivita text)");
   
   
  }
  

  public void save(String attivita){
   SQLiteDatabase db=this.getWritableDatabase();
   Date date=new Date();
   DateFormat df=new SimpleDateFormat("dd/MM/yyyy");
   DateFormat hf=new SimpleDateFormat("hh:mm");
   String dateFormat=df.format(date).toString();
   String hourFormat =hf.format(date).toString();
   ContentValues values=new ContentValues();
   values.put("data", dateFormat);
   values.put("ora", hourFormat);
   values.put("attivita",attivita);
   db.insert("TABELLA", null, values);
  }
  
  public Cursor query(){
   SQLiteDatabase db=this.getWritableDatabase();
   Cursor crs=db.rawQuery("select * from TABELLA where data = '17/07/2016'  ",null);
   crs.moveToFirst();
   return crs;
  }
  
  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
   // TODO Auto-generated method stub
   
  }
  
 }
}
Ecco, adesso mi devo esercitare a selezionare per data i records del database. E devo trovare i controlli adeguati.

sabato 16 luglio 2016

Buttando giù un database per memorizzare date

Creare un database in cui venga memorizzata la data attuale.
Questo è il codice che ho trovato nella Palestra Database:
public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  Helper helper=new Helper(this);
  Date d=new Date();
  helper.save(d);

  Long numero=helper.query(5).getLong(1);
  Log.v("NUMERO",""+numero);
  DateFormat df=new SimpleDateFormat("hh:mm:ss");
  Log.v("DATA",df.format(new Date(numero)).toString());
  
  

  
 }
 
 class Helper extends SQLiteOpenHelper{

  public Helper(Context context) {
   super(context, "Database.db", null, 1);
   
  }

  @Override
  public void onCreate(SQLiteDatabase db) {
   db.execSQL("create table TABELLA(_id integer primary key, data integer)");
   
  }
  
  public void save(Date d){
   SQLiteDatabase db=this.getWritableDatabase();
   ContentValues values=new ContentValues();
   values.put("data", d.getTime());
   db.insert("TABELLA", null, values);
  }
  
  public Cursor query(int numero){
   SQLiteDatabase db=this.getReadableDatabase();
   Cursor crs=db.rawQuery("select * from TABELLA where _id="+numero, null);
   crs.moveToFirst();
   return crs;
   
  }

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
   // TODO Auto-generated method stub
   
  }
  
 }

}
Ecco, non ricordo praticamente niente.
Il campo in cui memorizzare la data è un Integer, e ricordo che in SQL un campo di tipo Integer può memorizzare anche un numero Long.
Perché memorizzare un numero long?
Fosse perché si mette il tempo in millisecondi dal 1 gennaio 1970?

Credo proprio di sì.
Analizziamo il codice...

Ho scritto agevolmente il codice per la creazione di un Database:
 class Helper extends SQLiteOpenHelper{

  public Helper(Context context) {
   super(context, "database.db", null, 1);
   // TODO Auto-generated constructor stub
  }

  @Override
  public void onCreate(SQLiteDatabase db) {
   db.execSQL("create table TABELLA(_id integer primary key, date integer)");
   
  }
  
  public void save(int data){
   SQLiteDatabase db=this.getWritableDatabase();
   ContentValues values=new ContentValues();
   values.put("date", data);
   db.insert("TABELLA", null, values);
   
  }
  
  public Cursor query(){
   SQLiteDatabase db=this.getWritableDatabase();
   Cursor crs=db.rawQuery("select * from tabella",null);
   crs.moveToFirst();
   Cursor c=crs;
   crs.close();
   return c;
   
  }

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
   // TODO Auto-generated method stub
   
  }
  
 }
ma riguardando il codice precedente ho visto che il codice per la conversione a numero Long è presente all'interno dello stesso metodo save del database.
Risolto:
  public void save(Date data){
   SQLiteDatabase db=this.getWritableDatabase();
   
   ContentValues values=new ContentValues();
   values.put("date", data.getTime());
   db.insert("TABELLA", null, values);
   
  }
Vado a salvare e a verificare:
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  Helper helper=new Helper(this);
  Date d=new Date();
  helper.save(d);
Sì, sono scritti dei numeri, che sarebbero i millisecondi dalla data chiamata Epoch.

Come si ricompongono in una data?

Si usa DateFormat.
Proviamo.
Definiamo un oggetto DateFormat.
  DateFormat df=new SimpleDateFormat("dd:MM:yyyy");
  Log.v("DATA", ""+df.format(new Date(numero)));
E vediamo:
07-16 20:50:26.622: V/DATA(15687): 16:07:2016
Perfetto!

Disegno di cerchio e raggio su display.

Come si fa a disegnare?
Ho bisogno di ripassarlo.

Ecco il codice che ho ritrovato, e che salvo:
public class MainActivity extends Activity {

 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  RelativeLayout mainLayout=(RelativeLayout)findViewById(R.id.mainLayout);
  View v=new CustomView(this);
  mainLayout.addView(v);
  v.getLayoutParams().width=300;
  v.getLayoutParams().height=300;

  

 }
 
 public class CustomView extends View{

  private Paint paint;
  public CustomView(Context context) {
   super(context);
   paint=new Paint();
   paint.setStyle(Style.STROKE);
   paint.setStrokeWidth(50);
   paint.setColor(Color.GREEN);
  }
  

  @Override
  protected void onDraw(Canvas canvas){
   super.onDraw(canvas);
   
   canvas.drawCircle(100, 100, 100, paint);
  }
  
 }
  
  


}
Viene creata una View.
Ne creo il costruttore:
 public class MiaView extends View{
  public MiaView(Context context){
   super(context);
  }
 }
e poi bisogna implementare il metodo onDraw:
  @Override
  protected void onDraw(Canvas canvas){
   super.onDraw(canvas);
   
  }
E in questo si mette la funzione per disegnare qualcosa:
  @Override
  protected void onDraw(Canvas canvas){
   super.onDraw(canvas);
   canvas.drawCircle(100, 100, 50, paint);
  }
ma ottengo un errore per il fatto che non ho mai dichiarato la variabile paint.
Devo farlo all'inizio, come variabile della view.
 public class MiaView extends View{
  
  Paint paint;
  public MiaView(Context context){
   super(context);
  }
  
  @Override
  protected void onDraw(Canvas canvas){
   super.onDraw(canvas);
   canvas.drawCircle(100, 100, 50, paint);
  }
 }
Ma devo stabilire le caratteristiche di questo paint nel costruttore.
Il paint sarebbe un po' il pennello.
Proviamo:
  Paint paint;
  public MiaView(Context context){
   super(context);
   paint=new Paint();
   paint.setColor(Color.RED);
   paint.setStrokeWidth(10);
   paint.setStyle(Style.STROKE);
  }
Vediamo cosa viene fuori.
Riscrivo il tutto...

 public class Immagine extends View{

  Paint paint;
  public Immagine(Context context) {
   super(context);
   paint.setStyle(Style.STROKE);
   paint.setColor(Color.RED);
   paint.setStrokeWidth(10);
   
  }
  
  @Override 
  public void onDraw(Canvas canvas){
   super.onDraw(canvas);
   canvas.drawCircle(100, 100, 50, paint);
   
  }
  
 }
Facciamo gli aggiustamenti e andiamo...
public class MainActivity extends Activity {

 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  RelativeLayout mainLayout=(RelativeLayout)findViewById(R.id.mainLayout);
  Immagine mImmagine=new Immagine(this);
  mainLayout.addView(mImmagine);
  mImmagine.getLayoutParams().width=300;
  mImmagine.getLayoutParams().height=300;
 }
 

 public class Immagine extends View{

  Paint paint;
  public Immagine(Context context) {
   super(context);
   paint=new Paint();
   paint.setStyle(Style.STROKE);
   paint.setColor(Color.RED);
   paint.setStrokeWidth(10);
   
  }
  
  @Override 
  public void onDraw(Canvas canvas){
   super.onDraw(canvas);
   canvas.drawCircle(100, 100, 50, paint);
   
  }
  
 }

}
Dopo una bella schiera di NullPointerException debitamente corrette, siamo arrivati a farlo funzionare, e a tracciare un cerchio rosso.
Teniamo presenti le finalità immediate, e creiamo un cerchio più grande e dal bordo più sottile...
public class MainActivity extends Activity {

 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  RelativeLayout mainLayout=(RelativeLayout)findViewById(R.id.mainLayout);
  Immagine mImmagine=new Immagine(this);
  mainLayout.addView(mImmagine);
  mImmagine.getLayoutParams().width=LayoutParams.MATCH_PARENT;
  mImmagine.getLayoutParams().height=LayoutParams.MATCH_PARENT;
 }
 

 public class Immagine extends View{

  Paint paint;
  public Immagine(Context context) {
   super(context);
   paint=new Paint();
   paint.setStyle(Style.STROKE);
   paint.setColor(Color.RED);
   paint.setStrokeWidth(1);
   
  }
  
  @Override 
  public void onDraw(Canvas canvas){
   super.onDraw(canvas);
   canvas.drawCircle(200, 200, 200, paint);
   
  }
  
 }

}
Tracciamo il raggio orizzontalmente...

Di base, ho la lunghezza del raggio.
Conosco il punto di partenza, che corrisponde al centro della circonferenza.
Conosco l'angolo.

Ora, la differenza fra la coordinata finale X e quella iniziale X è pari al seno dell'angolo per la lunghezza, mentre la differenza fra la coordinata finale Y e quella iniziale Y è pari al coseno dell'angolo per la lunghezza.
Ecco:
public class MainActivity extends Activity {

 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  RelativeLayout mainLayout=(RelativeLayout)findViewById(R.id.mainLayout);
  Immagine mImmagine=new Immagine(this);
  mainLayout.addView(mImmagine);
  mImmagine.getLayoutParams().width=LayoutParams.MATCH_PARENT;
  mImmagine.getLayoutParams().height=LayoutParams.MATCH_PARENT;
 }
 

 public class Immagine extends View{

  Paint paint;
  public Immagine(Context context) {
   super(context);
   paint=new Paint();
   paint.setStyle(Style.STROKE);
   paint.setColor(Color.BLACK);
   paint.setStrokeWidth(3);
   
  }
  
  @Override 
  public void onDraw(Canvas canvas){
   super.onDraw(canvas);
   float centroX=200;
   float centroY=200;
   float radius=200;
   float angle=30;
   canvas.drawCircle(centroX, centroY, radius, paint);
   canvas.drawLine(centroX, centroY, (float)(centroX+radius*Math.cos(Math.toRadians(angle))), (float)(centroY+radius*Math.sin(Math.toRadians(angle))), paint);
   
  }
  
 }

}


venerdì 15 luglio 2016

Esercizi sulla suoneria di default dei tre tipi e sulla scelta di suonerie dei tre tipi.

Esercizi...

Individuare la suoneria di default di tipo ALARM, NOTIFICATION e RINGTONE.

Fatto. Si cambia soltanto il TYPE:

Suoneria RINGTONE:
  Uri ringtoneUri=RingtoneManager.getActualDefaultRingtoneUri
    (this,RingtoneManager.TYPE_RINGTONE);
  Ringtone ringtone=RingtoneManager.getRingtone(this, ringtoneUri);
  ringtone.play();


Suoneria ALARM:
  Uri ringtoneUri=RingtoneManager.getActualDefaultRingtoneUri
    (this,RingtoneManager.TYPE_ALARM);
  Ringtone ringtone=RingtoneManager.getRingtone(this, ringtoneUri);
  ringtone.play();


Suoneria NOTIFICATION:
  Uri ringtoneUri=RingtoneManager.getActualDefaultRingtoneUri
    (this,RingtoneManager.TYPE_NOTIFICATION);
  Ringtone ringtone=RingtoneManager.getRingtone(this, ringtoneUri);
  ringtone.play();
E funzionano tutte.
Ora eseguire la scelta di suonerie dei tre tipi, RINGTONE, ALARM e NOTIFICATION.

Ringtone:
  Intent intent=new Intent();
  intent.setAction(RingtoneManager.ACTION_RINGTONE_PICKER);
  intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE);
  startActivityForResult(intent,0);
  
 }
 
 @Override
 public void onActivityResult(int requestCode, int resultCode, Intent data){
  if(resultCode==RESULT_OK){
   Uri ringtoneUri=data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
   Ringtone ringtone=RingtoneManager.getRingtone(this, ringtoneUri);
   ringtone.play();
  }
 }


Alarm:
  Intent intent=new Intent();
  intent.setAction(RingtoneManager.ACTION_RINGTONE_PICKER);
  intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_ALARM);
  startActivityForResult(intent,0);
 }
 @Override
 public void onActivityResult(int requestCode, int resultCode, Intent data){
  if(resultCode==RESULT_OK){
   Uri ringtoneUri=data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
   Ringtone ringtone=RingtoneManager.getRingtone(this, ringtoneUri);
   ringtone.play();
  }


Notification:
  Intent intent=new Intent();
  intent.setAction(RingtoneManager.ACTION_RINGTONE_PICKER);
  intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION);
  startActivityForResult(intent,0);
 }
 
 @Override
 public void onActivityResult(int requestCode, int resultCode, Intent data){
  if(resultCode==RESULT_OK){
   Uri ringtoneUri=data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
   Ringtone ringtone=RingtoneManager.getRingtone(this, ringtoneUri);
   ringtone.play();
  }
 }
E funziona.