lunes, 17 de septiembre de 2012

Comprobar si aplicación esta Running y en pantalla

Por algun motivo,  cuando creamos una aplicación nos puede interesar saber si la aplicación esta activa en el sistema y en pantalla.  Para ello, podemos usar la siguiente función:


private boolean isOpenApp() {

      ActivityManager am = (ActivityManager) getSystemService(Activity.ACTIVITY_SERVICE);
      String packageName = am.getRunningTasks(1).get(0).topActivity.getPackageName();

      if (!packageName.equals(TARGET_APP)) {
            return false;
      } 
      return true;
}

Si se da el caso que queremos activar la aplicación (lanzarla de nuevo en pantalla podemos sustituir el código anterior por el siguiente:

private void openApp() {

      ActivityManager am = (ActivityManager) getSystemService(Activity.ACTIVITY_SERVICE);
      String packageName = am.getRunningTasks(1).get(0).topActivity.getPackageName();

      if (!packageName.equals(TARGET_APP)) {
          Intent launchIntent = getPackageManager().getLaunchIntentForPackage(TARGET_APP);
            startActivity(launchIntent);
      } 
}


Espero que les haya servido.

It works!
Roger Sala

Abrir diálogo con los Tonos del teléfono

Si estamos creando una aplicación, por ejemplo, que utiliza sonidos a lo mejor, nos viene bien, usar los que el sistema Android tiene por defecto. Para ello, podemos abrir un cuadro de diálogo mostrando los diferentes tonos que el usuario puede escoger.

A continuación los pasos y el código:

1.- Primero de todo creamos el Intent y luego realizamos la acción de iniciar una Activity esperando el resultado.


private final int TONE_SELECTED = 1;
*********************


Intent intent = new Intent(
RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,
RingtoneManager.TYPE_NOTIFICATION);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE,
"Selecciona el to d'alarma /*Título del cuadro de diálogo*/");
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI,
(Uri) null);
startActivityForResult(intent, TONE_SELECTED);


2.- En el result nos guardamos la URI (dirección) del tono para futuros usos. En este caso lo guardamos usando SharedPreferences.


public static final String PREFERENCE_TONE_URI = "toneUri";
public static final String PREFERENCE_TONE_NAME = "toneName";
public static final String PREFERENCES_NAME = "PREF_NAME";
*********************


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
         switch (requestCode) {
              case TONE_SELECTED:
                      String toneUri,
                      toneName;
                      try {
                        Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
                        Ringtone ringtone = RingtoneManager.getRingtone(this, uri);

                       if (uri != null) {
                          toneUri = uri.toString();
                          toneName = ringtone.getTitle(this);
                          SharedPreferences preferences = getSharedPreferences(
                          PREFERENCES_NAME, Context.MODE_WORLD_WRITEABLE);
                          SharedPreferences.Editor editor = preferences.edit();
                          editor.putString(PREFERENCE_TONE_URI, toneUri);
                          editor.putString(PREFERENCE_TONE_NAME, toneName);
                         editor.commit();
                        } 
                      } catch (Exception e) {
                         e.printStackTrace();
                         Toast.makeText(this, "No se ha seleccionado ningún tono"Toast.LENGTH_SHORT).show();
                      }
                      break;
                   default:
                      break;
           }
}


Finalmente, una imagen donde se puede apreciar el cuadro de diálogo:




It works!
Roger Sala,





domingo, 2 de septiembre de 2012

ExpandableListView

En Android podemos encontrar listas simples (ListView) o bien listas que permiten expandir su contenido (ExpandableListView).
Una ListView nos permite ver información, normalmente, resumida del contenido de ese elemento el cuál podemos acceder para ver más información. En cambio, las ExpandableListView se usan para agrupar elementos que tienen algo en común. Por ejemplo, podríamos tener una aplicación que tratara sobre vehículos. Entonces podríamos estructurar la vista de manera que cada elemento que se muestre dentro de la lista sean: coches, autobuses, trenes... Al acceder al elemento coche se expandiese una nueva lista dentro de coches con las diferentes marcas a consultar (ídem para autobuses y trenes).

A continuación vamos a ver un ejemplo genérico de como crear nuestra propia ExpandableListView. Para ello vamos a crear:

/*Vista principal que contiene la ExpandableListView que vamos a mostrar*/
activity_expandable.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <ExpandableListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="fill_parent" >
    </ExpandableListView>
</LinearLayout>


/*Vista "customizada" de los elementos que conforman los grupos de la lista*/
group_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center" >
    <TextView
        android:id="@+id/tvGroup"
        android:layout_width="wrap_content"
        android:layout_height="40dip"
        android:paddingLeft="5dip"
        android:text="Groups"
        android:gravity="center"
        android:textColor="#000000"
        android:textSize="17sp"
        android:textStyle="bold" >
    </TextView>
</LinearLayout>


/*Vista "customizada" de los elementos que conforman los hijos de la lista*/
child_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/tvChild"
        android:layout_width="fill_parent"
        android:layout_height="45dip"
        android:gravity="center_vertical"
        android:paddingLeft="5dip"
        android:paddingRight="5dip"
        android:text="Children"
        android:textColor="#ffCCCC22"
        android:textSize="17sp"
        android:textStyle="bold" >
    </TextView>
</LinearLayout>


/*Clase que se encargará de gestionar la información que se mostrará en la lista y como se va a mostrar (añadiendo la información en los respectivos TextView, ImageView...)*/
ExpandableListAdapter.java

package com.example.blogexpandablelistview;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

public class ExpandableListAdapter extends BaseExpandableListAdapter {
@Override
public boolean areAllItemsEnabled() {
return true;
}
private Context context;
private ArrayList<String> groups;
private ArrayList<ArrayList<AbstractGroupItem>> children;

public ExpandableListAdapter(Context context, ArrayList<String> groups,
ArrayList<ArrayList<AbstractGroupItem>> children) {
this.context = context;
this.groups = groups;
this.children = children;
}

//Esta función nos añade la información que queremos mostrar en el adapter
public void addItem(AbstractGroupItem groupItem) {
if (!groups.contains(groupItem.getGroup())) {
groups.add(groupItem.getGroup());
}
int index = groups.indexOf(groupItem.getGroup());
if (children.size() < index + 1) {
children.add(new ArrayList<AbstractGroupItem>());
}
children.get(index).add(groupItem);
}

@Override
public Object getChild(int groupPosition, int childPosition) {
return children.get(groupPosition).get(childPosition);
}

@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}

@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
AbstractGroupItem groupItem = (AbstractGroupItem) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.child_layout, null);
}
TextView tv = (TextView) convertView.findViewById(R.id.tvChild);
tv.setText("   " + groupItem.getName());

tv.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
return convertView;
}

@Override
public int getChildrenCount(int groupPosition) {
return children.get(groupPosition).size();
}

@Override
public Object getGroup(int groupPosition) {
return groups.get(groupPosition);
}

@Override
public int getGroupCount() {
return groups.size();
}

@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}

@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String group = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.group_layout, null);
}
TextView tv = (TextView) convertView.findViewById(R.id.tvGroup);
tv.setText(group);
return convertView;
}

@Override
public boolean hasStableIds() {
return true;
}

@Override
public boolean isChildSelectable(int arg0, int arg1) {
return true;
}
}

/*Clase que se encargará de gestionar la información para rellenar la lista y su adaptador*/
ExpandableListActivity.java
package com.example.blogexpandablelistview;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.Toast;

public class ExpandableListActivity extends Activity {

private ExpandableListAdapter mAdapter;
private final int TOTAL_GROUP_1 = 3;
private final int TOTAL_GROUP_2 = 4;
private final int TOTAL_GROUP_3 = 5;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_expandable_list);

ExpandableListView listView = (ExpandableListView) findViewById(R.id.listView);

listView.setOnChildClickListener(new OnChildClickListener() {

@Override
public boolean onChildClick(ExpandableListView arg0, View arg1,
int arg2, int arg3, long arg4) {
Toast.makeText(getBaseContext(), "Child clicked",
Toast.LENGTH_LONG).show();
return false;
}
});

listView.setOnGroupClickListener(new OnGroupClickListener() {

@Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {

Toast.makeText(getBaseContext(), "Group clicked",
Toast.LENGTH_LONG).show();
return false;
}
});

mAdapter = new ExpandableListAdapter(this, new ArrayList<String>(),
new ArrayList<ArrayList<AbstractGroupItem>>());

setupData();

listView.setAdapter(mAdapter);
}

private void setupData() {
AbstractGroupItem groupItem = null;
for (int i = 0; i < TOTAL_GROUP_1; i++) {
groupItem = new GroupItem_1("item child " + i);
mAdapter.addItem(groupItem);
}
for (int i = 0; i < TOTAL_GROUP_2; i++) {
groupItem = new GroupItem_2("item child " + i);
mAdapter.addItem(groupItem);
}
for (int i = 0; i < TOTAL_GROUP_3; i++) {
groupItem = new GroupItem_3("item child " + i);
mAdapter.addItem(groupItem);
}
}
}

A continuación, creamos las distintas clases que conforman el modelo. Como veremos tenemos una clase llamada AbstractGroupItem que nos servirá para tener compartidas las funciones de obtener los grupos y los hijos. Las clases GroupItem_(1,2,3) van a extender de ella para así poder usar esas funciones.

AbstractGroupItem.java
package com.example.blogexpandablelistview;

public class AbstractGroupItem {
private String name;
private String group;

public String getGroup() {
return group;
}

public void setGroup(String group) {
this.group = group;
}

public AbstractGroupItem(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

GroupItem_1.java
package com.example.blogexpandablelistview;
public class GroupItem_1 extends AbstractGroupItem {
    public GroupItem_1(String name) {
        super(name);
        setGroup(GroupItem_1.class.getSimpleName());
    }
}

GroupItem_2.java
package com.example.blogexpandablelistview;
public class GroupItem_2 extends AbstractGroupItem {
    public GroupItem_2(String name) {
        super(name);
        setGroup(GroupItem_2.class.getSimpleName());
    }
}



GroupItem_1.java
package com.example.blogexpandablelistview;
public class GroupItem_3 extends AbstractGroupItem {
    public GroupItem_3(String name) {
        super(name);
        setGroup(GroupItem_3.class.getSimpleName());
    }
}

Finalmente se adjuntan dos imagenes que nos muestran como queda nuestro proyecto:



It works!

Roger Sala,



jueves, 30 de agosto de 2012

Activity Transparent

En algunos de nuestros proyectos podemos tener la necesidad de sobreponer una activity/dialogo/otros transparente. A continuación tenemos un ejemplo de cómo realizar dicha acción:

Como podemos ver tenemos 2 Activities. La primera de ellas (VisibleActivity) es la que estará en la parte de atrás de la Activity Transparente. La otra Activity (TransparentActivity) será la que estará situada sobrepuesta a la VisibleActivity.

La parte importante es añadir en el Manifest la línea de código que podemos ver destacada en rojo. En ella se puede ver com indicamos a la Activity que tendrá el tema transparente.

AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.blogtransaprentactivity"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".VisibleActivity"
            android:label="@string/title_activity_visible" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".TransparentActivity"
            android:label="@string/title_activity_visible"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" />
    </application>
</manifest>

layout_visible.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:padding="@dimen/padding_medium"
        android:text="I'm below"/>
</RelativeLayout>

VisibleActivity.java
package com.example.blogtransaprentactivity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;

public class VisibleActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_visible);

startActivity(new Intent(this, TransparentActivity.class));
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_visible, menu);
return true;
}
}

layout_transparent.xml
<RelativeLayout 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="#80000000" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="60dip"
        android:padding="@dimen/padding_medium"
        android:text="I'm above"
        tools:context=".VisibleActivity" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:text="Finish Activity" />

</RelativeLayout>

TransparentActivity.java
package com.example.blogtransaprentactivity;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
public class TransparentActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transparent);

((Button) findViewById(R.id.button))
.setOnClickListener(new View.OnClickListener() {

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

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_visible, menu);
return true;
}
}

La imagen que podemos ver a continuación nos muestra la Activity transparente encima. Si pulsamos al botón de abajo desaparece y podemos ver la segunda imagen de forma nítida.



 It works!

Roger Sala,

jueves, 9 de agosto de 2012

Subrayar Texto

En ciertas ocasiones nuestra aplicación requiere de un resaltado de texto. En ese caso, podemos optar en subrayar ese texto, ponerlo en negrita, cursiva, etc. Si lo que deseamos es mostrarlo subrayado lo podemos hacer mediante la siguiente opción:

TextView textView = (TextView) findViewById(R.id.textview);
SpannableString myString  = new SpannableString("Este String esta subrayado");
myString.setSpan(new UnderlineSpan(), 0, myString.length(), 0);
textView.setText(myString);

Simple pero...It works!

Roger Sala,

domingo, 5 de agosto de 2012

Base de Datos: SharedPreferences

Android nos ofrece en su sistema de base de datos el denominado como SharedPreferences. Este sistema nos permite almacenar de forma privada e independiente para cada aplicación, datos simples (String, int, boolean, long y float) en formato clave valor. Para ello tenemos 2 tipos de operaciones: lectura o escritura.

Ejemplo de lectura:

//Creamos una instancia SharedPreferences
SharedPreferences preferences = getSharedPreferences("MY_PREF_NAME", Context.MODE_PRIVATE);
/*Recuperamos un valor SharedPreferences 
DEFAULT_VALUE  --> Valor que será asignado a la variable en caso que no haya ningún valor almacenado en el campo NAME_PREFERENCE_STORAGE.*/
String myValue = preferences.getString("NAME_PREFERENCE_STORAGE", "DEFAULT_VALUE");


Ejemplo de escritura:

//Creamos una instancia SharedPreferences
SharedPreferences preferences = getSharedPreferences("MY_PREF_NAME", Context.MODE_PRIVATE);
//Creamos el Editor de preferencias
SharedPreferences.Editor editor = preferences.edit();
//Añadimos/Modificamos un nuevo campo
editor.putString("NAME_PREFERENCE_STORAGE", value_to_save);
//Confirmamos el cambio/creación. Si no hacemos este último paso nada de lo que hemos hecho será guardado
editor.commit();


Notad, que para invocar el método getSharedPreferences, no hemos usado ningún Context, ni nada por estilo. Esto es debido a qué:

  • Si estamos en una Activity, MapActivity...cualquier objeto que tenga un Context no hace falta añadirlo ya que se invoca por defecto.
  • Si estamos fuera del alcance de un Context, por ejemplo, en una clase simple de Java, como podría ser MyUtils.java, hay que pasar el contexto a esa clase/función e invocar las preferencias a partir de la variable Context. Algo así:
          public static String getSharedPreferences (Context context){
                   SharedPreferences preferences = context.getSharedPreferences("MY_PREF_NAME", Context.MODE_PRIVATE);
                   return preferences.getString("NAME_PREFERENCE_STORAGE", "DEFAULT_VALUE");
         }

It works!

Roger Sala,


miércoles, 1 de agosto de 2012

Java: String a Capital letter

En algunas ocasiones podemos necesitar que un String que está en mayúsculas o minúsculas, se muestre con la primera letra en mayúscula. Pues bien aquí les dejo la función que realiza dicha acción:


public static String capitalize(String s){
      if(s.length()==) return s;
      return s.substring(0,1).toUpperCase() + s.substring(1).toLowerCase();
}

It works!


Roger Sala,