Mostrando entradas con la etiqueta android. Mostrar todas las entradas
Mostrando entradas con la etiqueta android. Mostrar todas las entradas

viernes, 2 de diciembre de 2016

Más de 1 millón de cuentas de Google han sido vulneradas por Gooligan; Aquí te decimos como comprobar si su dispositivo está infectado


El sistema operativo Android de Google siempre ha enfrentado mucha disconformidad por sus vulnerabilidades de seguridad y parece que está destinado a continuar algún tiempo más. Los investigadores de seguridad de Check Point Software Technologies han encontrado que esta nueva familia de malware, que está llamando Gooligan, ha vulnerado alrededor de 1 millón de cuentas de Google.

Se encuentra en al menos 86 aplicaciones que están disponibles en el Google Play a travez de terceros. Una vez instalado, utiliza un proceso de enraizamiento para obtener acceso privilegiado a su sistema. Se dice que afecta a los dispositivos que ejecutan versiones de Android 4+. Cabe señalar que las versiones vulnerables representan el 74 por ciento de los usuarios.

Así, los dispositivos rooteados descargarán e instalarán el software que roba los tokens de autenticación y le da acceso a las cuentas relacionadas con Google del propietario del dispositivo sin necesidad de introducir la contraseña. Estos tokens funcionarán en varios servicios de Google, como Gmail, Google Fotos, Google Docs, Google Play, Google Drive y G Suite.


Básicamente, un token de autorización de Google es una forma de acceder a la cuenta de Google y los servicios relacionados de un usuario que es emitido por Google. Una vez robados por un hacker, pueden usar este token para acceder a todos sus servicios de Google.



¿Está afectado mi dispositivo?
 
Si has estado descargando aplicaciones de distintas fuentes de la tienda oficial de Play Store y quieres comprobar si tu cuenta está comprometida, puedes hacerlo en gooligan.checkpoint.com


 También puede comprobar esta lista de aplicaciones, si ha descargado uno de estos, entonces su dispositivo está infectado.

Oh No, mi dispositivo está afectado. ¿Qué hago ahora?

Check Point le informa dos cosas que usted tendría que hacer. En primer lugar, una instalación limpia del sistema operativo en su dispositivo móvil, es decir, "parpadeando" un sistema operativo más limpio.

Este es un proceso complejo, y se recomienda que los usuarios se acerquen a un técnico / proveedor de servicio móvil certificado si no tienen conocimiento. En segundo lugar. Cambie las contraseñas de su cuenta de Google lo antes posible.

Personalmente me gustaría aconsejar a todos los lectores que no descarguen las aplicaciones de Android de tiendas de terceros.

viernes, 25 de noviembre de 2016

Compartir Imagen desde una App en Android




Compartir Imagen desde una App en Android

Hola a todos, hoy les traigo un tutorial de como compartir imágenes desde un aplicativo nativo en android a pedido de un comentario en este blog.

El codigo fuente inicial viene de un post anterior llamado: Compartir en redes sociales en Android Studio

Se agrego codigo fuente extra.

1. Agregue 2 widgets en activity_main.xml

  android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:text="Foto"    android:id="@+id/foto"    android:layout_alignParentTop="true"    android:layout_centerHorizontal="true" />
    android:layout_width="match_parent"    android:layout_height="match_parent"    android:id="@+id/imgfoto"    android:scaleType="centerCrop"    android:layout_below="@+id/foto"    android:layout_centerHorizontal="true"    android:layout_above="@+id/buttonShare" />


2. Agregue las constantes a usar en MainActivity.java

//Constantes para subir foto
private static String APP_DIRECTORY = "MyPictureApp/";private static String MEDIA_DIRECTORY = APP_DIRECTORY + "PictureApp";
private final int MY_PERMISSIONS = 100;private final int PHOTO_CODE = 200;private final int SELECT_PICTURE = 300;
private ImageView mSetImage;private Button mOptionButton;
private String mPath;


3. en el metodo onCreate agregue:
mOptionButton = (Button) findViewById(R.id.foto);mSetImage = (ImageView) findViewById(R.id.imgfoto);
//ahora le asignamos la accion a relizar a los botonesmOptionButton.setOnClickListener(new View.OnClickListener() {
    @Override    public void onClick(View v) {
        showOptions();    }
});



4. ahora agregamos estas funciones  en el Activity

@Overridepublic void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);    outState.putString("file_path", mPath);}

@Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    mPath = savedInstanceState.getString("file_path");}

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(resultCode == RESULT_OK){
        switch (requestCode){
            case PHOTO_CODE:
                MediaScannerConnection.scanFile(this,                        new String[]{mPath}, null,                        new MediaScannerConnection.OnScanCompletedListener() {
                            @Override                            public void onScanCompleted(String path, Uri uri) {
                                Log.i("ExternalStorage", "Scanned " + path + ":");                                Log.i("ExternalStorage", "-> Uri = " + uri);                            }
                        });

                Bitmap bitmap = BitmapFactory.decodeFile(mPath);                mSetImage.setImageBitmap(bitmap);                break;            case SELECT_PICTURE:
                Uri path = data.getData();                mSetImage.setImageURI(path);                break;
        }
    }
}

@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if(requestCode == MY_PERMISSIONS){
        if(grantResults.length == 2 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED){
            Toast.makeText(MainActivity.this, "Permisos aceptados", Toast.LENGTH_SHORT).show();            mOptionButton.setEnabled(true);        }
    }else{
        showExplanation();    }
}

private void showExplanation() {
    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);    builder.setTitle("Permisos denegados");    builder.setMessage("Para usar las funciones de la app necesitas aceptar los permisos");    builder.setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
        @Override        public void onClick(DialogInterface dialog, int which) {
            Intent intent = new Intent();            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);            Uri uri = Uri.fromParts("package", getPackageName(), null);            intent.setData(uri);            startActivity(intent);        }
    });    builder.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
        @Override        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();            finish();        }
    });
    builder.show();}
5. Agregamos este codigo en el boton de compartir y especifican si desean una red social especifica
mSetImage.buildDrawingCache();Bitmap bitmap = mSetImage.getDrawingCache();
/***** COMPARTIR IMAGEN *****/try {
    File file = new File(getCacheDir(), bitmap + ".png");    FileOutputStream fOut = null;    fOut = new FileOutputStream(file);    bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);    fOut.flush();    fOut.close();    file.setReadable(true, false);    final Intent intent = new Intent(android.content.Intent.ACTION_SEND);    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);    intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));    intent.setType("image/png");    startActivity(intent);} catch (Exception e) {
    e.printStackTrace();}
6. Agregamos los permisos en el Manifest.
android:name="android.permission.CAMERA"/>android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>android:name="android.permission.READ_EXTERNAL_STORAGE"/>android:name="android.intent.action.MEDIA_MOUNTED"/>
Codigo fuente aqui.
https://bitbucket.org/mchiuyari/compartiendoredessociales
Video.
 

jueves, 17 de noviembre de 2016

Las videollamadas de WhatsApp ya están disponibles para todos (IOs, Android y Windows Phone)




Luego de una larga espera y varios meses en periodo de prueba, las videollamadas de WhatsApp ya están disponibles para los más de mil millones de usuarios de la aplicación en 180 países.

Recordemos que esta función había sido introducida semanas antes en versiones beta de Android y Windows Phone en algunos países, pero ahora todos los usuarios de las tres principales plataformas móviles (iOS, Android y Windows) pueden comenzar a disfrutar de esta característica.

Esta nueva función de WhatsApp le permite a los usuarios realizar llamadas de video sin importar el sistema operativo que el otro utilice. Por ahora solo se permiten llamadas 1 a 1 pero es de suponer que en un futuro se podrán realizar videollamadas grupales.

“Queremos poner esta característica a disposición de todos, no sólo para los que pueden pagar los más caros nuevos teléfonos o viven en países con las mejores redes de telefonía móvil”, dijo la compañía en su anuncio.

Con la llegada de las videollamadas, WhatsApp, propiedad de Facebook, ofrecerá una combinación entre mensajería instantánea, llamadas de voz, y llamadas de video, convirtiéndose en rival directo de servicios como Skype, Viber, y el propio Facebook Messenger. La aplicación también entra en un campo que actualmente cuenta con otras opciones para realizar llamadas en video como Snapchat, Google Duo, y FaceTime en iOS, y muchos otros servicios similares.

Para poder disfrutar de las videollamadas en WhatsApp solo hay que actualizar la aplicación a la más reciente versión lanzada hoy. Además, se requiere de dispositivos iOS 8 o superior, Android 4.1 o superior, y Windows 10 Mobile 0 Windows Phone 8 en el caso de los teléfonos de Microsoft. Cabe resaltar que la actualización irá llegando de manera gradual a todos los usuarios.

lunes, 7 de marzo de 2016

Enviar un mensaje de Gmail por Android


Puede utilizar este código cuando se desea que los usuarios tienen la capacidad de enviar correo electrónico desde su aplicación , por ejemplo, es la característica de aplicación donde los usuarios pueden enviar sugerencias, comentarios o sugerencias directamente a cualquier dirección de correo electrónico indicada .

Con este código se abrirá la aplicación de Gmail con la ayuda de filtro intent android.

Ahora se puede añadir este código a su proyecto o clase de utilidad .

public void openGmailApp(String[] emailAddresses, String subject, String text){
Intent i = new Intent(Intent.ACTION_VIEW);
i.setType("plain/text");
i.setClassName("com.google.android.gm", "com.google.android.gm.ComposeActivityGmail");
i.putExtra(Intent.EXTRA_EMAIL, emailAddresses);
i.putExtra(Intent.EXTRA_SUBJECT, subject);
i.putExtra(Intent.EXTRA_TEXT, text);
checkIfAppExists(i, "Gmail"); 
}

Y puede utilizar la funcion anterior de esta manera:
// you can try to add more email in this array: new String[] { "541ntmik@gmail.com", "mchiuyari@yahoo.com" }
// if you're going to send the message to multiple people
openGmailApp(
new String[] { "541ntmik@gmail.com" },
"Feedback for The Code of a Javaheros Programming Blog",
"Sent using The Code of Javaheros Android App"
);

sábado, 5 de marzo de 2016

Ejemplos de AlertDialog.Builder en Android.


Estos códigos de AlertDialog.Builder Android  son algunos de los elementos de los widgets o interfaces de usuario más comunes que usamos con cualquier aplicación de Android. En general, un AlertDialog es una pequeña ventana que aparece en la cabecera de la solicitud. Se pone el foco pantalla y capaz de aceptar la interacción del usuario.

Los cuadros de diálogo se utilizan normalmente para las notificaciones al usuario y para realizar tareas cortas.

En este post, vamos a echar un vistazo a algunos tipos comunes de AlertDialog que uso durante el desarrollo de Android. Vamos a cubrir cómo mostrar un AlertDialog Android - desde la básica hasta un poco de tipo complejo.

1. Dialog Simple con un boton

package com.example.alertdialogoneexample;

import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;

public class MainActivity extends Activity {

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

        alertOneButton();

    }

    /*
     * AlertDialog with one action button.
     */
    public void alertOneButton() {

        new AlertDialog.Builder(MainActivity.this)
                .setTitle("Dialog Simple")
                .setMessage("Gracias por visitar javaheros.blogspot.com")
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {

                        dialog.cancel();
                    }
                }).show();
    }

}

2. Dialog con 2 botones OK y CANCELAR

/*
 * AlertDialog with two button choices.
 * 
 * We also set the ninja icon here.
 */
public void alertTwoButtons() {
    new AlertDialog.Builder(MainActivity.this)
            .setTitle("2 botones")
            .setMessage("¿Usted cree que este exeplo es impresionante?")
            .setIcon(R.drawable.ninja)
            .setPositiveButton("YES",
                    new DialogInterface.OnClickListener() {
                        @TargetApi(11)
                        public void onClick(DialogInterface dialog, int id) {
                            showToast("¡Gracias! Usted es impresionante también!");
                            dialog.cancel();
                        }
                    })
            .setNegativeButton("NO", new DialogInterface.OnClickListener() {
                @TargetApi(11)
                public void onClick(DialogInterface dialog, int id) {
                    showToast("Este ejemplo no fue impresionante para usted. :(");
                    dialog.cancel();
                }
            }).show();
}
3. AlertDialog con 3 botones

/*
 * AlertDialog with three button choices.
 * 
 * We also set the ninja icon here.
 */
public void alertThreeButtons() {
    new AlertDialog.Builder(MainActivity.this)
            .setTitle("3 botones")
            .setMessage("¿A donde quieres ir?")
            .setIcon(R.drawable.ninja)
            .setPositiveButton("RIGHT",
                    new DialogInterface.OnClickListener() {
                        @TargetApi(11)
                        public void onClick(DialogInterface dialog, int id) {
                            showToast("Quieres ir a la DERECHA.");

                            dialog.cancel();
                        }
                    })
            .setNeutralButton("CENTER",
                    new DialogInterface.OnClickListener() {
                        @TargetApi(11)
                        public void onClick(DialogInterface dialog, int id) {
                            showToast("Quieres ir al CENTRO.");
                            dialog.cancel();
                        }
                    })
            .setNegativeButton("LEFT",
                    new DialogInterface.OnClickListener() {
                        @TargetApi(11)
                        public void onClick(DialogInterface dialog, int id) {
                            showToast("Quieres ir a la IZQUIERDA.");
                            dialog.cancel();
                        }
                    }).show();
}
4. AlertDialog con TimePicker

El TimePicker en nuestro ejemplo se llama desde un recurso de layout. También puede hacerlo mediante programación pero recomiendo el uso de un recurso del formato XML para que su TimePicker se puede reutilizar fácilmente.

/*
 * Show AlertDialog with time picker.
 */
public void alertTimePicker() {

    /*
     * Inflate the XML view. activity_main is in res/layout/time_picker.xml
     */
    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.time_picker, null, false);

    // the time picker on the alert dialog, this is how to get the value
    final TimePicker myTimePicker = (TimePicker) view
            .findViewById(R.id.myTimePicker);

    /*
     * To remove option for AM/PM, add the following line:
     * 
     * operatingHoursTimePicker.setIs24HourView(true);
     */

    // the alert dialog
    new AlertDialog.Builder(MainActivity.this).setView(view)
            .setTitle("Set Time")
            .setPositiveButton("Go", new DialogInterface.OnClickListener() {
                @TargetApi(11)
                public void onClick(DialogInterface dialog, int id) {

                    String currentHourText = myTimePicker.getCurrentHour()
                            .toString();

                    String currentMinuteText = myTimePicker
                            .getCurrentMinute().toString();

                    // We cannot get AM/PM value since the returning value
                    // will always be in 24-hour format.

                    showToast(currentHourText + ":" + currentMinuteText);

                    dialog.cancel();

                }

            }).show();
}
res/layout/time_picker.xml



5. AlertDialog con DataPicker

Tenga en cuenta que estamos usando un recurso layout de DatePicker en XML aquí, lo llamamos date_picker.xml, el código también se proporciona a continuación.

/*
 * Show AlertDialog with date picker.
 */
public void alertDatePicker() {

    /*
     * Inflate the XML view. activity_main is in res/layout/date_picker.xml
     */
    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.date_picker, null, false);

    // the time picker on the alert dialog, this is how to get the value
    final DatePicker myDatePicker = (DatePicker) view.findViewById(R.id.myDatePicker);
    
    // so that the calendar view won't appear
    myDatePicker.setCalendarViewShown(false);
    
    // the alert dialog
    new AlertDialog.Builder(MainActivity.this).setView(view)
            .setTitle("Set Date")
            .setPositiveButton("Go", new DialogInterface.OnClickListener() {
                @TargetApi(11)
                public void onClick(DialogInterface dialog, int id) {

                    /*
                     * In the docs of the calendar class, January = 0, so we
                     * have to add 1 for getting correct month.
                     * http://goo.gl/9ywsj
                     */
                    int month = myDatePicker.getMonth() + 1;
                    int day = myDatePicker.getDayOfMonth();
                    int year = myDatePicker.getYear();

                    showToast(month + "/" + day + "/" + year);

                    dialog.cancel();

                }

            }).show();
}
res/layout/date_picker.xml codigo

6. AlertDialog con simple ListView

/*
 * Show AlertDialog with a simple list view.
 * 
 * No XML needed.
 */
public void alertSimpleListView() {

    /*
     * WebView is created programatically here.
     * 
     * @Here are the list of items to be shown in the list
     */
    final CharSequence[] items = { "John", "Michael", "Vincent", "Dalisay" };

    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    builder.setTitle("Make your selection");
    builder.setItems(items, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int item) {

            // will toast your selection
            showToast("Name: " + items[item]);
            dialog.dismiss();

        }
    }).show();
}
7. AlertDialog con ScrollView

Se puede lograr utilizando el código de abajo con un recurso diseño XML con un TextView envuelto dentro de un widget ScrollView. Ver scroll_text.xml el código también se proporciona a continuación.

/*
 * Show AlertDialog with ScrollView.
 * 
 * We use a TextView as ScrollView's child/host
 */
public void alertScrollView() {

    /*
     * Inflate the XML view.
     * 
     * @activity_main is in res/layout/scroll_text.xml
     */
    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View myScrollView = inflater.inflate(R.layout.scroll_text, null, false);

    // textViewWithScroll is the name of our TextView on scroll_text.xml
    TextView tv = (TextView) myScrollView
            .findViewById(R.id.textViewWithScroll);

    // Initializing a blank textview so that we can just append a text later
    tv.setText("");

    /*
     * Display the text 10 times so that it will exceed the device screen
     * height and be able to scroll
     */
    for (int x = 1; x < 50; x++) {
        tv.append("You've been HACKED!\n");
        tv.append("By NINJAZHAI.\n");
        tv.append("Just kidding.\n\n");
    }

    new AlertDialog.Builder(MainActivity.this).setView(myScrollView)
            .setTitle("Scroll View")
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @TargetApi(11)
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                }

            }).show();

}
res/layout/scroll_text.xml codigo



    

8. AlertDialog con EditText, etc.

/*
 * Show AlertDialog with some form elements.
 */
public void alertFormElements() {

    /*
     * Inflate the XML view. activity_main is in
     * res/layout/form_elements.xml
     */
    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    final View formElementsView = inflater.inflate(R.layout.form_elements,
            null, false);

    // You have to list down your form elements
    final CheckBox myCheckBox = (CheckBox) formElementsView
            .findViewById(R.id.myCheckBox);

    final RadioGroup genderRadioGroup = (RadioGroup) formElementsView
            .findViewById(R.id.genderRadioGroup);

    final EditText nameEditText = (EditText) formElementsView
            .findViewById(R.id.nameEditText);

    // the alert dialog
    new AlertDialog.Builder(MainActivity.this).setView(formElementsView)
            .setTitle("Form Elements")
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @TargetApi(11)
                public void onClick(DialogInterface dialog, int id) {

                    String toastString = "";

                    /*
                     * Detecting whether the checkbox is checked or not.
                     */
                    if (myCheckBox.isChecked()) {
                        toastString += "Happy is checked!\n";
                    } else {
                        toastString += "Happy IS NOT checked.\n";
                    }

                    /*
                     * Getting the value of selected RadioButton.
                     */
                    // get selected radio button from radioGroup
                    int selectedId = genderRadioGroup
                            .getCheckedRadioButtonId();

                    // find the radiobutton by returned id
                    RadioButton selectedRadioButton = (RadioButton) formElementsView
                            .findViewById(selectedId);

                    toastString += "Selected radio button is: "
                            + selectedRadioButton.getText() + "!\n";

                    /*
                     * Getting the value of an EditText.
                     */
                    toastString += "Name is: " + nameEditText.getText()
                            + "!\n";

                    showToast(toastString);

                    dialog.cancel();
                }

            }).show();
}
res/layout/form_elements.xml



    

    


        


        

    

    

        
    

9 AlertDialog con WebView

/*
 * Show AlertDialog with web view.
 * 
 * Don't forget the Internet permission on your AndroidManifest.xml
 */
public void alertWebView() {

    // WebView is created programatically here.
    WebView myWebView = new WebView(MainActivity.this);
    myWebView.loadUrl("http://google.com/");

    /*
     * This part is needed so it won't ask the user to open another browser.
     */
    myWebView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    });

    new AlertDialog.Builder(MainActivity.this).setView(myWebView)
            .setTitle("My Web View")
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @TargetApi(11)
                public void onClick(DialogInterface dialog, int id) {

                    dialog.cancel();

                }

            }).show();
}
10. AlertDialog con diseño personalizado

public void alertCustomizedLayout(){
    
    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

    // get the layout inflater
    LayoutInflater inflater = MainActivity.this.getLayoutInflater();

    // inflate and set the layout for the dialog
    // pass null as the parent view because its going in the dialog layout
    builder.setView(inflater.inflate(R.layout.login, null))
    
    // action buttons
    .setPositiveButton("Login", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {
            // your sign in code here
        }
    })
    .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            // remove the dialog from the screen
        }
    })
    .show();  
    
}
res/layout/login.xml



    

    

    

11. AlertDialog con radio butons/Single Choice Item

public void alertSingleChoiceItems(){
    
    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    
    // Set the dialog title
    builder.setTitle("Choose One")
    
    // specify the list array, the items to be selected by default (null for none),
    // and the listener through which to receive call backs when items are selected
    // again, R.array.choices were set in the resources res/values/strings.xml
    .setSingleChoiceItems(R.array.choices, 0, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface arg0, int arg1) {
            showToast("Some actions maybe? Selected index: " + arg1);
        }

    })
           
     // Set the action buttons
    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {
            // user clicked OK, so save the mSelectedItems results somewhere
            // or return them to the component that opened the dialog
            
            int selectedPosition = ((AlertDialog)dialog).getListView().getCheckedItemPosition();
            showToast("selectedPosition: " + selectedPosition);
            
        }
    })
    
    .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {
            // removes the dialog from the screen
            
        }
    })
    
    .show();
    
}
res/values/strings.xml



    TestApp
    Hello world!
    Settings
    TestApp
    showTimeDialogFrom

    
        Coke
        Pepsi
        Sprite
        Seven Up
    

12. AlertDialog con CheckButtons/Multiple Choice Item


public void alertMultipleChoiceItems(){
    
    // where we will store or remove selected items
    mSelectedItems = new ArrayList();  
    
    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    
    // set the dialog title
    builder.setTitle("Choose One or More")
    
    // specify the list array, the items to be selected by default (null for none),
    // and the listener through which to receive call backs when items are selected
    // R.array.choices were set in the resources res/values/strings.xml
    .setMultiChoiceItems(R.array.choices, null, new DialogInterface.OnMultiChoiceClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which, boolean isChecked) {
            
            if (isChecked) {
                // if the user checked the item, add it to the selected items
                mSelectedItems.add(which);
            } 
        
            else if (mSelectedItems.contains(which)) {
                // else if the item is already in the array, remove it 
                mSelectedItems.remove(Integer.valueOf(which));
            }
            
            // you can also add other codes here, 
            // for example a tool tip that gives user an idea of what he is selecting
            // showToast("Just an example description.");
        }

    })
           
     // Set the action buttons
    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {
            
            // user clicked OK, so save the mSelectedItems results somewhere
            // here we are trying to retrieve the selected items indices
            String selectedIndex = "";
            for(Integer i : mSelectedItems){
                selectedIndex += i + ", ";
            }
            
            showToast("Selected index: " + selectedIndex);
        
        }
    })
    
    .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {
            // removes the AlertDialog in the screen
        }
    })
    
    .show();
    
}
El strings.xml usado es el mismo de el ejemplo 11.

13. AlertDialog con EditText y Soft-Keyboard muestra automaticamente.

public void alertEditTextKeyboardShown(){
    
    // creating the EditText widget programatically
    EditText editText = new EditText(MainActivity.this);
    
    // create the AlertDialog as final
    final AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
        .setMessage("You are ready to type")
        .setTitle("The Code of a Ninja")
        .setView(editText)
        
         // Set the action buttons
        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                
            }
        })
        
        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {
            // removes the AlertDialog in the screen
            }
        })
        .create();
    
    // set the focus change listener of the EditText
    // this part will make the soft keyboard automaticall visible
    editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {
                dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
            }
        }
    });
    
    dialog.show();

}
14. Previniendo AlertDialog de cerrar cuando un boton se clickeado

public void alertPersistentDialog(){
    
    final AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this)
        .setTitle("The Code of a Ninja")
        .setMessage("This is a persistent AlertDialog")
        .setPositiveButton("Show Toast", null) // null to override the onClick
        .setNegativeButton("Dismiss", null)
        .setCancelable(false)
        .create();

    alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {

        @Override
        public void onShow(DialogInterface dialog) {

            Button btnPositive = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
            btnPositive.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View view) {

                    showToast("Dialog not dismissed!");
                    
                }
            });
            
            
            Button btnNegative = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
            btnNegative.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View view) {

                    // dismiss once everything is ok
                    alertDialog.dismiss();
                }
            });
        }
    });
    
    // don't forget to show it
    alertDialog.show();
        
}

lunes, 4 de enero de 2016

Lista interminable con RecyclerView


En un post previo les prometí escribir acerca de hacer una lista interminable con RecyclerView y mostrando una barra de progreso en el pie de página , mientras que la descarga de datos desde una base de datos externa . Después de jugar con él durante horas por fin logré hacerlo y lo estoy compartiendo con ustedes.
Haremos el mismo efecto usando la misma técnica de lo que hicimos con listviews . La única diferencia es que RecyclerViews no tienen pies de página así que tenemos que utilizar dos ViewHolders diferentes . Pero eso era mi problema de averiguar , sólo puede copiar y pegar el código :)
Hay dos cosas que tenemos que lograr para la experiencia de usuario perfecta:
  • En cada descarga de desplazamiento sólo una pequeña cantidad de datos para mostrar sin mantener la espera de usuario
  • Mostrar una Cargando ... mensaje con una barra de progreso mientras se descargan los datos
Vamos a definir nuestra RecyclerView y empezar a descargar los primeros 8 artículos .

rv = (RecyclerView)view.findViewById(R.id.rv);
rv.setHasFixedSize(true);
llm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(llm);

arr_userid = new ArrayList();
arr_username = new ArrayList();
arr_photo = new ArrayList();
arr_level = new ArrayList();
arr_date = new ArrayList();

num_loadstart = 0;
num_loadfinish = 8;

OnScrollListener

Este fragmento onScrollListener está listo para copiar y pegar. Se ocupa de la carga de nuevos registros cuando el usuario llega al final de los registros ya descargados en la aplicación. Esto es más simple de lo que necesitábamos para usar con listviews.

rv.addOnScrollListener(new RecyclerView.OnScrollListener() {

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        visibleItemCount = rv.getChildCount();
        totalItemCount = llm.getItemCount();
        firstVisibleItem = llm.findFirstVisibleItemPosition();

        if (loading) {
            if (totalItemCount > previousTotal) {
                loading = false;
                previousTotal = totalItemCount;
            }
        }
        if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
            //End has been reached
            //Below we need the -1 otherwise 1 item will be missed the first time we scroll. I don't know why only the first
            //time but the point is it's working this way
            DownloadUsersClassic(String.valueOf(totalItemCount-1), String.valueOf(num_loadfinish));
            loading = true;
        }
    }
});

Descarga de los datos

Yo uso Volley para descargar los datos de una fuente externa porque es más rápido y más eficiente que AsyncTask . Si usted no utiliza Volley, por favor, eche un vistazo a este video para entender cómo funciona. Olvídese OnPreExecute () , doInBackground () y onPostExecute (). Volley es mucho más fácil de usar.

private void DownloadUsersClassic(final String start, final String finish) {

    StringRequest postReq = new StringRequest(Request.Method.POST, download_leaderboard, new Response.Listener() {

        @Override
        public void onResponse(String response) {

            if (response.length() > 10) { //if there are any records retrieved, otherwise null
                try {
                    jArray = new JSONArray(response);
                    for(int i=0;i getParams() {
            Map params = new HashMap();
            params.put("start", start);
            params.put("finish", finish);
            return params;
        }

    };

    postReq.setShouldCache(false);
    AppController.getInstance().addToRequestQueue(postReq);
}


Adapter

La clave es usar dos ViewHolders diferentes. Uno de los elementos normales y otro para el pie de página. Utilizamos getItemViewType para determinar cuál queremos mostrar . Una vez hemos descargado todos los datos de nuestra base de datos externa que llamamos mAdapter.hideFooter ( ) para eliminar el FooterView.

public class CustomAdapter extends RecyclerView.Adapter {

    ArrayList arr_userid = new ArrayList();
    ArrayList arr_username = new ArrayList();
    ArrayList arr_photo = new ArrayList();
    ArrayList arr_level = new ArrayList();
    ArrayList arr_date = new ArrayList();
    boolean show_footer;
    public LayoutInflater inflater;

    public static final int TYPE_ITEM = 1;
    public static final int TYPE_FOOTER = 2;
    Context context;

    public CustomAdapter(Context context) {
        this.context = context;
    }

    public CustomAdapter(Context context, ArrayList arr_userid, ArrayList arr_username, ArrayList arr_photo, ArrayList arr_level, ArrayList arr_date, boolean show_footer) {
        super();
        this.arr_userid = arr_userid;
        this.arr_username = arr_username;
        this.arr_photo = arr_photo;
        this.arr_level = arr_level;
        this.arr_date = arr_date;
        this.show_footer = show_footer;
        this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public class GenericViewHolder extends RecyclerView.ViewHolder {
        public TextView txtName, txtPoints, txtDate;
        public ImageView ivUser;
        public LinearLayout llLoadmore;

        public GenericViewHolder(View v) {
            super(v);
            txtName = (TextView) v.findViewById(R.id.txtName);
            txtPoints = (TextView) v.findViewById(R.id.txtPoints);
            txtDate = (TextView) v.findViewById(R.id.txtDate);
            ivUser = (ImageView) v.findViewById(R.id.ivUser);
            llLoadmore = (LinearLayout) v.findViewById(R.id.loadmore);
        }
    }

    class FooterViewHolder extends RecyclerView.ViewHolder {
        TextView tvloadmore;

        public FooterViewHolder (View itemView) {
            super (itemView);
            this.tvloadmore = (TextView) itemView.findViewById (R.id.tvloadmore);
        }
    }


    public void add(int position, String item) {
        arr_userid.add(position, item);
        notifyItemInserted(position);
    }

    public void remove(String item) {
        int position = arr_userid.indexOf(item);
        arr_userid.remove(position);
        notifyItemRemoved(position);
    }

    public CustomAdapter(ArrayList myDataset) {
        arr_userid = myDataset;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder (ViewGroup parent, int viewType) {
        if(viewType == TYPE_FOOTER) {
            View v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.loadmore, parent, false);
            return new FooterViewHolder (v);
        } else if(viewType == TYPE_ITEM) {
            View v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.leaderboard_row, parent, false);
            return new GenericViewHolder (v);
        }
        return null;
    }


    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        if(holder instanceof FooterViewHolder) {
            FooterViewHolder footerHolder = (FooterViewHolder) holder;
            footerHolder.tvloadmore.setText("Loading");
        } else if(holder instanceof GenericViewHolder) {
            GenericViewHolder genericViewHolder = (GenericViewHolder) holder;

            genericViewHolder.txtName.setText(arr_username.get(position));
            genericViewHolder.txtPoints.setText(arr_level.get(position) + " Levels");

            String year = arr_date.get(position).substring(0, 4);
            String month = arr_date.get(position).substring(5, 7);
            String day = arr_date.get(position).substring(8, 10);
            genericViewHolder.txtDate.setText(month + "." + day + "." + year);

            if (!arr_photo.get(position).equals("")) {
                Picasso.with(getActivity())
                        .load(arr_photo.get(position))
                        .into(genericViewHolder.ivUser);
            } else {
                genericViewHolder.ivUser.setImageDrawable(null);
            }
        }
    }

    @Override
    public int getItemCount() {
        if (show_footer) {
            return arr_userid.size() + 1; //+1 is for the footer as it's an extra item
        } else {
            return arr_userid.size();
        }
    }

    @Override
    public int getItemViewType (int position) {
        if (show_footer) {
            if (isPositionFooter(position)) {
                return TYPE_FOOTER;
            }
            return TYPE_ITEM;
        } else {
            return TYPE_ITEM;
        }
    }

    private boolean isPositionFooter (int position) {
        //if position == arr_userid.size then we need to show footerView otherwise we'll get indexOutOfBoundsException
        return position == arr_userid.size ();
    }

    public void hideFooter() {
        show_footer = false;
    }


Mi objetivo con este tutorial es para mostrar que la creación de un desplazamiento sin fin, con poderosa RecyclerView de Android por suerte no es tan difícil como parece a primera vista ser. No he encontrado realmente alguna buena tutoriales sobre esto, así que decidieron disfrutar de sufrir durante horas y compartirlo con ustedes. ¡Espero que ayude!

miércoles, 30 de diciembre de 2015

Reemplazar su ListView con RecyclerView


Con mi nueva aplicación que he estado desarrollando con los nuevos elementos del material design de google. Va a ser un pequeño juego divertido y es perfecta para experimentar. He implementado una tabla de clasificación en la aplicación utilizando un ListView, pero luego pensé que podría sustituirlo por el RecyclerView . El RecyclerView sirve para manejar grandes conjuntos de datos de manera más eficiente que el ListView y ofrece grandes soluciones de personalización y de animación. Se centra en el reciclaje que hace que la adición y eliminación de productos más eficientes. Si la lista no es dinámica o no está poblada desde la nube entonces no hay razón para reemplazar su ListView existente con RecyclerView .

Me voy a centrar en el código e ignorar el hablar mucho porque yo mismo voy directo al punto en lugar de hacer una entrada del blog larga.

Mi ListView actualmente incluye tres TextViews y un ImageView. Así es como se construye:

Layout


List item layout


    

        

            

        

        
            
            
        

        

    

    



Code

Pon este código cuando termine de llenar sus matrices:
myadapter = new MyAdapter(getActivity(), arr_userid, arr_username, arr_photo, arr_level, arr_date);
lv.setAdapter(myadapter);

Esta es tu clase Adapter:


public class MyAdapter extends BaseAdapter
{
    public String title[];
    public String description[];
    public Activity context;
    ArrayList arr_userid = new ArrayList();
    ArrayList arr_username = new ArrayList();
    ArrayList arr_photo = new ArrayList();
    ArrayList arr_level = new ArrayList();
    ArrayList arr_date = new ArrayList();

    public LayoutInflater inflater;

    public MyAdapter(Context context, ArrayList arr_userid, ArrayList arr_username, ArrayList arr_photo, ArrayList arr_level, ArrayList arr_date) {
        super();
        this.arr_userid = arr_userid;
        this.arr_username = arr_username;
        this.arr_photo = arr_photo;
        this.arr_level = arr_level;
        this.arr_date = arr_date;
        this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return arr_userid.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    public class ViewHolder {
        TextView txtName, txtPoints, txtDate;
        ImageView ivUser;
        RelativeLayout row;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        final ViewHolder holder;
        if(convertView==null)
        {
            holder = new ViewHolder();
            convertView = inflater.inflate(R.layout.leaderboard_row, null);

            holder.txtName = (TextView) convertView.findViewById(R.id.txtName);
            holder.txtPoints = (TextView) convertView.findViewById(R.id.txtPoints);
            holder.txtDate = (TextView) convertView.findViewById(R.id.txtDate);
            holder.ivUser = (ImageView) convertView.findViewById(R.id.ivUser);
            holder.row = (RelativeLayout) convertView.findViewById(R.id.lineItem);

            convertView.setTag(holder);
        }
        else
            holder=(ViewHolder)convertView.getTag();

        holder.txtName.setText(arr_username.get(position));
        holder.txtPoints.setText(arr_level.get(position) + " Levels");

        String year = arr_date.get(position).substring(0,4);
        String month = arr_date.get(position).substring(5,7);
        String day = arr_date.get(position).substring(8,10);

        holder.txtDate.setText(month + "." + day + "." + year);

        if (!arr_photo.get(position).equals("")) {
            Picasso.with(getActivity())
                    .load(arr_photo.get(position))
                    .into(holder.ivUser);
        } else {
            holder.ivUser.setImageDrawable(null);
        }

        return convertView;
    }
} 
Su aplicación ListView debería ser muy similar a la mía. Rellenar las matrices de alguna manera (en mi caso puedo descargar los datos desde la nube), y obligar a estos a la adaptador.
Aquí viene la parte divertida. Nuestra implementación RecyclerView es de aprox. 20 % diferente :)

Gradle

Agregue esto a su build.gradle:
compile 'com.android.support:recyclerview-v7:+'

Si usted tiene cualquier problema, reconstruir y limpiar el proyecto. No te olvides de descargar la biblioteca de soporte en el Administrador de SDK.

Layout


Definir el RecyclerView
rv = (RecyclerView)view.findViewById(R.id.rv);
rv.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(llm);

Utilice setHasFixedSize cuando se sabe que la anchura y la altura de la RecyclerView no cambiarán. Siempre que se insertan artículos, moviendo o eliminado el tamaño (anchura y altura) de RecyclerView podría cambiar. Los elementos de la lista también pueden tener anchura variable o la altura por defecto. Si su aplicación carece de estas operaciones, RecyclerView estará mejor optimizado como sabe el tamaño exacto de antemano sobre la base de su adaptador.
A diferencia de ListView , un RecyclerView necesita un LayoutManager para gestionar el posicionamiento de sus artículos y para detertime cuando es el momento de reciclar las vistas. Hay 3 tipos de la LayoutManager como LinearLayoutManager, GridLayoutManager y StaggeredGridLayoutManager. Ahora quedémonos con LinearLayoutManager.

Pon este código en el que termine de llenar sus matrices :
myadapter = new CustomAdapter(getActivity(), arr_userid, arr_username, arr_photo, arr_level, arr_date);
rv.setAdapter(myadapter);
Codigo
public class CustomAdapter extends RecyclerView.Adapter {

    ArrayList arr_userid = new ArrayList();
    ArrayList arr_username = new ArrayList();
    ArrayList arr_photo = new ArrayList();
    ArrayList arr_level = new ArrayList();
    ArrayList arr_date = new ArrayList();

    public LayoutInflater inflater;

    public CustomAdapter(Context context, ArrayList arr_userid, ArrayList arr_username, ArrayList arr_photo, ArrayList arr_level, ArrayList arr_date) {
        super();
        this.arr_userid = arr_userid;
        this.arr_username = arr_username;
        this.arr_photo = arr_photo;
        this.arr_level = arr_level;
        this.arr_date = arr_date;
        this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public TextView txtName, txtPoints, txtDate;
        public ImageView ivUser;

        public ViewHolder(View v) {
            super(v);
            txtName = (TextView) v.findViewById(R.id.txtName);
            txtPoints = (TextView) v.findViewById(R.id.txtPoints);
            txtDate = (TextView) v.findViewById(R.id.txtDate);
            ivUser = (ImageView) v.findViewById(R.id.ivUser);
        }
    }

    public void add(int position, String item) {
        arr_userid.add(position, item);
        notifyItemInserted(position);
    }

    public void remove(String item) {
        int position = arr_userid.indexOf(item);
        arr_userid.remove(position);
        notifyItemRemoved(position);
    }

    public CustomAdapter(ArrayList myDataset) {
        arr_userid = myDataset;
    }

    @Override
    public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.leaderboard_row, parent, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        final String name = arr_username.get(position);
        holder.txtName.setText(arr_username.get(position));
        holder.txtName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                remove(name);
            }
        });

        holder.txtPoints.setText(arr_level.get(position) + " Levels");

        String year = arr_date.get(position).substring(0,4);
        String month = arr_date.get(position).substring(5,7);
        String day = arr_date.get(position).substring(8,10);
        holder.txtDate.setText(month + "." + day + "." + year);

        if (!arr_photo.get(position).equals("")) {
            Picasso.with(getActivity())
                    .load(arr_photo.get(position))
                    .into(holder.ivUser);
        } else {
            holder.ivUser.setImageDrawable(null);
        }
        
    }

    @Override
    public int getItemCount() {
        return arr_userid.size();
    }
}

No es gran cosa, Pero espero que puedan encontrar las similitudes en ambos métodos y reemplazar su ListView existente con RecyclerView.
La desventaja de RecyclerView es que la creación de un OnClickListener es complicado y la adición de una cabecera y el pie (especialmente una vista loadmore ) es aún más compleja . Voy a hacer otro tutorial sobre que tan pronto como encuentre la manera de hacer eso.