为什么当意图被抛出来识别次要活动中的NFC标签时,这个当前活动会自动关闭并返回任意主要活动吗?
我正在开发一个主要活动(Yes
)启动新活动(MainActivity
)的应用程序,其中我需要将记录发送到云后端({{1然后在标签上写下nfc代码这条新记录。当我将NFC标签接近设备时,要在其中编写代码,当前活动(RegisterActivity
)立即关闭,主活动(parse.com
)打开,因此无法写入NFC标签。
任何人都知道如何解决这个问题?这是两个活动的代码,以及清单。
MainActivity
RegisterActivity
RegisterActivity
MainActivity
清单
package com.example.prototiponfc.activities;
import com.example.prototiponfc.R;
import com.example.prototiponfc.R.id;
import com.example.prototiponfc.R.layout;
import com.example.prototiponfc.R.menu;
import android.support.v7.app.ActionBarActivity;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity implements OnClickListener{
//ImageView
ImageView imgHeader;
//Botones
Button btnBuscar, btnRegistrar, btnTerminar;
//Intent
Intent intentBuscar, intentRegistrar;
//Adaptador de nfc
//NfcAdapter mNfcAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imgHeader = (ImageView)findViewById(R.id.imageViewTitle);
btnBuscar = (Button) findViewById(R.id.btnBusqueda);
btnRegistrar = (Button) findViewById(R.id.btnNuevoRegistro);
btnTerminar = (Button) findViewById(R.id.btnTerminar);
btnBuscar.setOnClickListener(this);
btnRegistrar.setOnClickListener(this);
btnTerminar.setOnClickListener(this);
//iniciar adaptador de nfc, con un contexto (la actividad)
// mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
// verificarEstadoDeNFC(mNfcAdapter);
}
private void verificarEstadoDeNFC(NfcAdapter mNfcAdapter2) {
// TODO Auto-generated method stub
if (mNfcAdapter2 != null && mNfcAdapter2.isEnabled())
{
Toast.makeText(this, "NFC disponible", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(this, "NFC no disponible, Active el servicio" +
" e intente nuevamente", Toast.LENGTH_SHORT).show();
//Terminar actividad
finish();
}
}
@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 onClick(View v) {
// solo lanzar la actividad correspondiente o terminar
if (v.getId() == btnBuscar.getId())
{
intentBuscar = new Intent(getApplicationContext(), SearchActivity.class);
startActivity(intentBuscar);
}
else if (v.getId() == btnRegistrar.getId())
{
intentRegistrar = new Intent(getApplicationContext(), RegisterActivity.class);
startActivity(intentRegistrar);
}
else if (v.getId() == btnTerminar.getId())
{
Toast.makeText(this, "¡Hasta luego!", Toast.LENGTH_SHORT).show();
//Terminar
finish();
}
}
}
在关闭当前活动之前,在识别nfc标记时记录
package com.example.prototiponfc.activities;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Locale;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
import com.example.prototiponfc.R;
import com.example.prototiponfc.model.Persona;
import com.parse.GetCallback;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseFile;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.SaveCallback;
public class RegisterActivity extends ActionBarActivity implements OnClickListener{
/* codigo necesario para distinguir cuando se obtenga la fotografia */
private static final int LOAD_IMAGE=1;
Button btnSelecFoto, btnRegresarAInicio, btnRegistrarUsuario;
ImageView imageElement;
EditText editNombre, editApellido, editCargo;
private boolean hayImagen = false;
private Intent intentNFC;
private Parcelable nfcTag;
private Bitmap myBitmap;
private RequestQueue requestQueue;
private NfcAdapter mNfcAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
btnSelecFoto = (Button)findViewById(R.id.btnSelecFoto);
btnRegresarAInicio = (Button)findViewById(R.id.btnRegresarAInicio);
btnRegistrarUsuario = (Button)findViewById(R.id.btnRegistrarUsuario);
editNombre = (EditText)findViewById(R.id.editNombre);
editApellido = (EditText)findViewById(R.id.editApellido);
editCargo = (EditText)findViewById(R.id.editCargo);
btnSelecFoto.setOnClickListener(this);
btnRegresarAInicio.setOnClickListener(this);
btnRegistrarUsuario.setOnClickListener(this);
//Conectar con backend de parse llave de app y de cliente
Parse.initialize(getApplicationContext(),
"0nCpqh1JNL4zpVDePY9bqW60qwsc5ro5vADHuzzD",
"phifCGjvsbxWHSzgbdCDiuIRtJeGk6fbQHD7kupD");
//iniciar requestQueue
requestQueue = Volley.newRequestQueue(this);
//mNfcAdapter = MainActivity.
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
//verificarEstadoDeNFC(mNfcAdapter);
}
@SuppressLint("NewApi") @Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//Reconocer la etiqueta
nfcTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
//Toast.makeText(this, ta.getTechList()[0], Toast.LENGTH_LONG).show();
intentNFC = intent;
disableForegroundDispatchSystem();
// if (intentNFC.hasExtra(NfcAdapter.EXTRA_TAG))
// {
// Toast.makeText(this, "Etiqueta NFC detectada", Toast.LENGTH_LONG).show();
//
// Parcelable[] parcelables =intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
// if (parcelables != null && parcelables.length > 0)
// {
// String mensajeNDEF = readTextFromNdefMessage((NdefMessage)parcelables[0]);
//
// Toast.makeText(this, mensajeNDEF, Toast.LENGTH_LONG).show();
// }
// else
// {
// Toast.makeText(this, "No se encontraron mensajes ndef", Toast.LENGTH_LONG).show();
// }
//
// }
}
//Leer desde la etiqueta nfc
private String readTextFromNdefMessage(NdefMessage ndefMessage) {
NdefRecord[] ndefRecords= ndefMessage.getRecords();
if (ndefRecords != null && ndefRecords.length > 0)
{
NdefRecord ndefRecord = ndefRecords[0];
String tagContent = getTextFromNdefRecord(ndefRecord);
//Asignar el contenido de la etiqueta en el textview destinado para eso
//txtNfcContenido.setText(tagContent);
return tagContent;
}
else
{
Toast.makeText(this, "No se encontraron records ndef", Toast.LENGTH_LONG).show();
return null;
}
}
public String getTextFromNdefRecord (NdefRecord ndefRecord)
{
String tagContent = null;
try {
byte[] payload = ndefRecord.getPayload();
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16" ;
int languageSize = payload [0] & 0063 ;
tagContent = new String(payload, languageSize + 1,
payload.length - languageSize - 1, textEncoding);
} catch (UnsupportedEncodingException e) {
Log.e("getTextFromNdefRecord", e.getMessage());
}
return tagContent;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.register, 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);
}
/* (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onPause()
*/
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
disableForegroundDispatchSystem();
}
private void disableForegroundDispatchSystem()
{
mNfcAdapter.disableForegroundDispatch(this);
}
/* de NFC ACTIVAR y desactivar lectura de tajertas */
private void enableForegroundDispatchSystem()
{
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
PendingIntent mpPendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
IntentFilter[] intentFilters = new IntentFilter[]{};
mNfcAdapter.enableForegroundDispatch(this, mpPendingIntent, intentFilters, null);
}
/* (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onResume()
*/
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
enableForegroundDispatchSystem();
}
@Override
public void onClick(View v) {
// las opciones son cargarFoto, registrar usuario o volver al inicio
Toast.makeText(this, "Recuerde acercar la etiqueta NFC al\n" +
" dispositivo para evitar errores", Toast.LENGTH_LONG);
if (v.getId() == btnSelecFoto.getId())
{
cargarFotoDeGaleria();
}
else if (v.getId() == btnRegistrarUsuario.getId())
{
if (hayImagen == true) //si cargó imagen
{
if (editApellido.getText().length() > 0 &&
editNombre.getText().length() > 0 &&
editCargo.getText().length() > 0) //Si completó la informacionm
{
String nombre = editNombre.getText()+"";
String apellido = editApellido.getText()+"";
String cargo = editCargo.getText()+"";
// if (nfcTag !=null) //Hay una etiqueta nfc disponible para escribir el código de registro en parse.com
// {
// registrarUsuario(nombre, apellido, cargo, myBitmap);
// Toast.makeText(getApplicationContext(), "Acerque la etiqueta NFC para guardar" +
// " el código asignado", Toast.LENGTH_LONG);
if (nfcTag !=null && intentNFC != null) //si la acercó, se puede escribir
{
Toast.makeText(getApplicationContext(), "Acerque la etiqueta NFC para guardar" +
" el código asignado", Toast.LENGTH_LONG);
registrarUsuario(nombre, apellido, cargo, myBitmap);
Persona ultimoElementoInsertado = obtenerUltimoRegistroDeParse();
if(ultimoElementoInsertado!=null)
{
//Reconocer la etiqueta
final Tag tag = intentNFC.getParcelableExtra(NfcAdapter.EXTRA_TAG);
//Crear el mensaje para escribir en la etiqueta
Log.e("idInsertado", ultimoElementoInsertado.getId());
NdefMessage mnNdefMessage = createNdefMessage(ultimoElementoInsertado.getId());
//EScribir el mensaje en la etiqueta
writeNdefMessage(tag, mnNdefMessage);
}
else
{
Toast.makeText(getApplicationContext(), "PROBLEMAS", Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(this, "Debe acercar una etiqueta NFC para guardar" +
" información del usuario", Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(this, "Debe llenar todos los campos", Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(this, "No puede registrar un usuario si no selecciona una imagen", Toast.LENGTH_SHORT).show();
}
}
else if (v.getId() == btnRegresarAInicio.getId())
{
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
//Terminar ESTA actividad
this.finish();
}
}
private NdefRecord createTextRecord(String contenido)
{
try
{
byte[] language;
language = Locale.getDefault().getLanguage().getBytes("UTF-8");
final byte[] text = contenido.getBytes("UTF-8");
final int languageSize =language.length;
final int textLength = text.length;
final ByteArrayOutputStream payload = new ByteArrayOutputStream(1 + languageSize + textLength);
payload.write((byte) ( languageSize & 0x1F));
//El cero es el desplazamiento
payload.write(language, 0, languageSize);
payload.write(text, 0, textLength);
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload.toByteArray());
}
catch(UnsupportedEncodingException ue)
{
Log.e("ERROR en createTextRecord", ue.getMessage());
}
return null;
}
private NdefMessage createNdefMessage(String content)
{
NdefRecord ndefRecord = createTextRecord(content);
NdefMessage ndefMessage = new NdefMessage(new NdefRecord[]{ndefRecord});
return ndefMessage;
}
private void writeNdefMessage(Tag tag, NdefMessage ndefMessage)
{
Log.e("mensaje ndef", ndefMessage.toString());
try
{
if (tag == null)
{
Toast.makeText(this, "Problemas al escribir en etiqueta \n" +
"(etiqueta no disponible o no reconocida)", Toast.LENGTH_LONG).show();
}
Ndef ndef = Ndef.get(tag);
if (ndef == null) //si la tarjeta no tiene mensaje escrito(ndef)
{
//formatear la etiqueta con el formato ndef y escribir el mensaje
formatNfcTag(tag, ndefMessage);
}
else
{
ndef.connect();
if (!ndef.isWritable())
{
Toast.makeText(this, "No es posible escribir en la etiqueta", Toast.LENGTH_LONG).show();
//si no se puede escribir, se cierra y se detiene
ndef.close();
return;
}
Toast.makeText(this, "Se pudo escribir en la etiqueta", Toast.LENGTH_LONG).show();
ndef.writeNdefMessage(ndefMessage);
ndef.close();
}
}
catch(IOException io)
{
Log.e("ERROR en write", io.getMessage() +"error");
}
catch(FormatException fe)
{
Log.e("ERROR en write", fe.getMessage());
}
}
private void formatNfcTag(Tag tag, NdefMessage ndefMessage)
{
try
{
NdefFormatable ndefFormatable = NdefFormatable.get(tag);
if (ndefFormatable == null) //la etiqueta no está enumerada en Tag.getTechList
{
Toast.makeText(this, "La etiqueta no está disponible" +
" para formatear ()NdefFormteable", Toast.LENGTH_LONG).show();
return; //para parar la aplicacion
}
ndefFormatable.connect();
ndefFormatable.format(ndefMessage);
ndefFormatable.close();
Toast.makeText(this, "Se pudo escribir en la etiqueta", Toast.LENGTH_LONG).show();
}
catch(IOException e)
{
Log.e("ERROR", "eRROr de entrada salida (en formatNfcTag)");
}
catch(FormatException fe)
{
Log.e("ERROR", "eRROr al formatear etiqueta (en formatNfcTag)");
}
}
private void escribirEnEtiqueta(String id) {
//Toast.makeText(getApplicationContext(), "Nombre persona :" + id, Toast.LENGTH_LONG).show();
}
private Persona obtenerUltimoRegistroDeParse() {
//obtener la tabla
ParseQuery<ParseObject> query = ParseQuery.getQuery("Persona"); //Todos
final Persona persona = new Persona();
//ParseObject obj = query.get("MaIMQ7Y0V4");
query.orderByDescending("createdAt"); //de mayor a menor
query.getFirstInBackground(new GetCallback<ParseObject>() { //El primero de los mayores, o sea, el último
@Override
public void done(ParseObject obj, ParseException arg1) {
// TODO Auto-generated method stub
String nombre = obj.getString("Nombre_persona");
String apellido = obj.getString("Apellido_Persona");
String id = obj.getObjectId();
Log.e("PUTO ID", id.toString());
String cargo = obj.getString("Cargo");
ParseFile foto = obj.getParseFile("Foto_persona");
Log.e("DE IMAGEN", foto.getUrl().toString());
persona.setNombre(nombre);
// Toast.makeText(getApplicationContext(), cargo, Toast.LENGTH_SHORT).show();
persona.setApellido(apellido);
persona.setFotoUrl(foto.getUrl());
persona.setCargo(cargo);
persona.setId(id);
Toast.makeText(getApplicationContext(), persona.getId(), Toast.LENGTH_LONG).show();
}
});
Toast.makeText(getApplicationContext(), persona.getId(), Toast.LENGTH_LONG).show();
return persona;
}
private void registrarUsuario(String nombre, String apellido, String cargo, Bitmap myBitmap2) {
//ParseObject imagenParseObject = new pa
ParseObject nuevoRegistro = new ParseObject("Persona");/*new ParseObject("PRUEBA");*/
nuevoRegistro.put("Nombre_persona", nombre);
nuevoRegistro.put("Apellido_Persona", apellido);
nuevoRegistro.put("Cargo", cargo);
// nuevoRegistro.put("Foto_persona", myBitmap2);
//Intentar guardar imagen
// Save image file
// Drawable drawable = ...;
// Bitmap bitmap = (Bitmap)((BitmapDrawable) drawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
myBitmap2.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] data = stream.toByteArray();
//Ponerle nombre de la persona a la imagen
String nombreImagen = nombre + "--image.jpg" ;
ParseFile imageFile = new ParseFile(nombreImagen, data);
// imageFile.saveInBackground();
nuevoRegistro.put("Foto_persona", imageFile);
//ojo este si es el de guardar een parse
nuevoRegistro.saveInBackground(new SaveCallback() {
@Override
public void done(ParseException arg0) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "Registro exitoso", Toast.LENGTH_SHORT).show();
Log.e("exito", "escritura en parse");
limpiarPantalla();
}
}) ;
// //Tratar de recuperar de una vez el objectId
// ParseQuery<ParseObject> query = ParseQuery.getQuery("Persona");
// ParseObject otro = query.get
}
private void limpiarPantalla() {
editApellido.setText("");
editNombre.setText("");
editCargo.setText("");
imageElement.setImageResource(android.R.color.transparent);
}
private void cargarFotoDeGaleria() {
// TODO Auto-generated method stub
// Este es el intent que manejará la seleccion de imagen de la galeria
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
int code = LOAD_IMAGE;
startActivityForResult(intent, code); // ---> Llama a onActivityResult
}
/*Recibe un código de petición (arg0), un código de respuesta (arg1)y datos(arg2)
este maldito método sobreescrito de Activity, no de la puta ActionBarActivity es
el que implementará que se cargue la puta imagen seleccionada, dentro del ImagwVIew*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//Para demoCamara verificar el codigo de peticion de la foto para saber como actuar qca en on activityResult
switch (requestCode)
{
case LOAD_IMAGE:
if (resultCode == RESULT_OK)
{
fromGallery(data);
}
break;
//
// case CAMERA:
// if (resultCode == RESULT_OK)
// {
// fromCamera(/*data*/);
// }
// break;
}
}
public void fromGallery(Intent data)
{
if ( data != null) //cambiado para demoCamara,
//basada en la constante de esta clase y el codigo de respuesta fué una selección exitosa y hay datos
{
/* Declaro la uri de la imagen */
Uri selectedImage = data.getData(); //datos tomados del intent quye se recibió
/* Definir un cursor que será el que ejecute una consulta
* que finlmente mostrará la imagen, para crearlo se envia
* un arreglo de Strings que es el que lleva la columna seleccionada */
String[] filePathColumn = {MediaStore.Images.Media.DATA};
/*Ahora si el cursor: Uri corresponde a la imagen seleccionada, que
* en este caso corresponde al Uri que se definió previamente, se envia el
* filePathColumn como elemento de la proyección, como se quiere todo o recibido,
* entonces la seleccion será null y los argumentos de selección y ordenamiento
* también serán null. NOTA::: Este tipo de seleccion de imagenes tambien es aplicable
* para obtener otro tipo de archivos como canciones, videos, etc
*/
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
//Asumon que si se seleccionó una imagen, por lo tanto:
if (cursor.moveToFirst())
{
//si hay al menos un primer resultado, entonces se obtiene la primera columna
//obtengo el indice de la columna, correspondiente a la primera posicion del arreglo
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
//ahora obtener la ruta como un String
String picturePath=cursor.getString(columnIndex);
//ahora se debe cerrar el cursor para liberar memoria
cursor.close();
//obtener el imageview para asignarle luego la imagen seleccionada
// ImageView img = (ImageView)findViewById(R.id.image);
imageElement = (ImageView)findViewById(R.id.imageElement);
//Se asigna la imagendecodificando el archivo en base a la ruta de la imagen, declarada unosd pasos antes
myBitmap = BitmapFactory.decodeFile(picturePath);
// imageElement.setImageBitmap(BitmapFactory.decodeFile(picturePath));
imageElement.setImageBitmap(myBitmap);
hayImagen = true;
}
}
}
}
答案 0 :(得分:-1)
当logcat显示
时NFC收到了ntf gid:1
NFC的P2P运行良好。当logcat显示
时NFC收到了ntf gid:0
这意味着硬件可能有问题。我也遇到了这个问题,我换了另一部手机进行测试,它运行良好,从log ntp gid是1。