I have currently been testing some examples being found on the internet on sending NDEF messages through the NFC on my android phone.
I have three phones that I tested the phone with: Samsung Galaxy Nexus (Android 4.4.4), S3 (Android 4.4.2) and S4 (Android 4.4.4).
The app works perfect the way I wanted it to on the GN (it sends the message), however on the S3 and the S4 it sends the package name of the app instead of the message.
Can anybody help me with this? Does anyone know why or how to fix this? I am pretty new to Android dev and don't fully understand why it is doing this.
Code:
package tapit.cbstech.com.tap_it_3;
import android.app.Activity;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.os.Parcelable;
import android.widget.TextView;
import android.widget.Toast;
public class main extends Activity implements CreateNdefMessageCallback {
NfcAdapter mNfcAdapter;
TextView textView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.textView);
// Check for available NFC Adapter
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
// Register callback
mNfcAdapter.setNdefPushMessageCallback(this, this);
}
#Override
public NdefMessage createNdefMessage(NfcEvent event) {
String text = ("abcdefghi");
NdefMessage msg = new NdefMessage(
new NdefRecord[] { NdefRecord.createMime("text/plain", text.getBytes()),
/**
* The Android Application Record (AAR) is commented out. When a device
* receives a push with an AAR in it, the application specified in the AAR
* is guaranteed to run. The AAR overrides the tag dispatch system.
* You can add it back in to guarantee that this
* activity starts when receiving a beamed message. For now, this code
* uses the tag dispatch system.
*/
//NdefRecord.createApplicationRecord("hello test")
});
return msg;
}
#Override
public void onResume() {
super.onResume();
// Check to see that the Activity started due to an Android Beam
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
processIntent(getIntent());
}
}
#Override
public void onNewIntent(Intent intent) {
// onResume gets called after this to handle the intent
setIntent(intent);
}
/**
* Parses the NDEF Message from the intent and prints to the TextView
*/
void processIntent(Intent intent) {
textView = (TextView) findViewById(R.id.textView);
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage msg = (NdefMessage) rawMsgs[0];
textView.setText(new String(msg.getRecords()[0].getPayload()));
}
}
On the GNexus I get the "abcdefghi" but on the S3 and S4 I get "tapit.cbstech.com.tap_it_3"
Any help is appreciated! Thanks in advance!
Edit: Tested on a friends S3 and does the same (sending the package name) and tested on another friends nexus 5 (running Android L) and it worked sending the "abcdefghi" message.
Related
I'm trying to take control over the Play/Pause html DOM elements (in a browser open in a pc) from an android device.
In the html page (in Google Chrome browser) there's a <video> tag so I can control it like this:
//js code
document.querySelector("video").play();
document.querySelector("video").pause();
But I want that to run from an android device so I'm using GCM.
I read here and got some insight but I still have some questions.
First, since I'm writing in eclipse, and it sees no document variable, it produces an error. So how can eclipse recognize that element in the html page so I can compile and install the apk on the device?
Where do I specify the page url I want to communicate with? (send play/pause commands)
To run js inside java I'm using Rhino. I looked through the examples in the documentation but I'm still not sure if a #JSFunction annotation is enough to declare a js function.
Here's my code:
import com.alaa.chromote.util.SystemUiHider;
import com.google.android.gcm.GCMRegistrar;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
import android.view.View.OnClickListener;
import org.mozilla.javascript.*;
import org.mozilla.javascript.annotations.*;
public class MainApplication extends Activity {
private final static String GCM_SENDER_ID = "484514826047";
private static final String LOG_TAG = "GetAClue::GCMIntentService";
private Button playButton;
private Button pauseButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_application);
playButton = (Button) findViewById(R.id.PlayButton);
pauseButton = (Button) findViewById(R.id.PauseButton);
playButton.setVisibility(View.INVISIBLE);
pauseButton.setVisibility(View.VISIBLE);
//connect to gcm
GCMRegistrar.checkDevice( this );
GCMRegistrar.checkManifest( this );
final String regId = GCMRegistrar.getRegistrationId( this );
if( regId.equals( "" ) ) {
GCMRegistrar.register( this, GCM_SENDER_ID );
}
else {
Log.v( LOG_TAG, "Already registered" );
}
Context.enter(); //start Rhino
setupListeners();
}
#JSFunction
public void play() { document.querySelector("video").play(); }
#JSFunction
public void pause() { document.querySelector("video").pause(); }
private void setupListeners()
{
playButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
play();
}
});
pauseButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
pause();
}
});
}
#Override
protected void onStop() {
Context.exit(); //stop Rhino
super.onStop();
}
}
How do I continue from here?
First, since I'm writing in eclipse, and it sees no document variable, it produces an error. So how can eclipse recognize that element in the html page so I can compile and install the apk on the device?
answ: On your android device you just pass a message to the chrome browser. A.k. an action variable that is set to play or stop. You chrome app will then pick up the message and act accordingly. Also you can send the url as an variable in the message if you want to be able to play different urls.
Where do I specify the page url I want to communicate with? (send play/pause commands)?
answ: Do you already created the chrome app you want and verified it works? It should check with a google cloud server for messages. That server keeps track of the url for you.
To run js inside java I'm using Rhino. I looked through the examples in the documentation but I'm still not sure if a #JSFunction annotation is enough to declare a js function.?
answ: It seems you are misunderstanding the part what the android app does (sending the play action) and what the chrome browser does (actually playing the movie)
I hope my answer has helped a little, feedback is appreciated :)
I am trying to get the gmail inbox using javamail with this code:
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import java.util.Properties;
public class HomeActivity extends Activity {
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button emailRead=(Button)findViewById(R.id.button);
emailRead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Runnable r=new Runnable() {
#Override
public void run() {
Properties props = new Properties();
props.setProperty("mail.store.protocol", "imaps");
Session session = Session.getDefaultInstance(props, null);
IMAPStore imapStore = null;
try {
imapStore = (IMAPStore) session.getStore("imaps");
imapStore.connect("imap.gmail.com", "myemail#gmail.com", "mypassword");
final IMAPFolder folder = (IMAPFolder) imapStore.getFolder("Inbox");
folder.open(IMAPFolder.READ_WRITE);
Message m[]=folder.getMessages();
for(Message n:m){
System.out.println(n.getSubject());
}
} catch (MessagingException e) {
e.printStackTrace();
}
}
};
Thread t=new Thread(r);
t.start();
}
});
}
}
It works in emulator, but when run on a real device(with working internet connection) I constantly fail and get the exception:
com.sun.mail.util.MailConnectException: Couldn't connect to host, port: imap.gmail.com, 993; timeout -1;
nested exception is:
java.net.SocketTimeoutException: failed to connect to imap.gmail.com/2607:f8b0:400e:c02::6c (port 993) after 90000ms
Why am I receiving an MailConnectException, and how can I fix it?
EDIT:
Here are the links I have tried, but with the same result:
1)Reading Gmail mails using android SDK
2)Are there any good short code examples that simply read a new gmail message?
3)Reading all new messages from my gmail using javamail
Its just the subset of what I have tried before posting. I request someone to please share a live working code, which works on a real device here.
EDIT2:
I have tested this on three real devices. One was using wifi internet.Two others were using Gprs for net connectivity. So it appears that gmail setting for javamail have changed with android. The javamail code is working for me on desktop java.But seems something strange with android real devices.
U are not allowed to use networking in main UI thread from android 3.0 and up.
So setup aSyncTask to solve your problem
I want to ask how I can use speech to text code on my emulator. My codes work on real device but not work on emulator. The error said :
No Activity found to handle Intent { act=android.speech.action.RECOGNIZE_SPEECH (has extras) }
What can I do?
package net.viralpatel.android.speechtotextdemo;
import java.util.ArrayList;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.view.Menu;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
protected static final int RESULT_SPEECH = 1;
private ImageButton btnSpeak;
private TextView txtText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtText = (TextView) findViewById(R.id.txtText);
btnSpeak = (ImageButton) findViewById(R.id.btnSpeak);
btnSpeak.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(
RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "en-US");
try {
startActivityForResult(intent, RESULT_SPEECH);
txtText.setText("");
} catch (ActivityNotFoundException a) {
Toast t = Toast.makeText(getApplicationContext(),
"Ops! Your device doesn't support Speech to Text",
Toast.LENGTH_SHORT);
t.show();
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case RESULT_SPEECH: {
if (resultCode == RESULT_OK && null != data) {
ArrayList<String> text = data
.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
txtText.setText(text.get(0));
}
break;
}
}
}
}
You need to install onto your emulator an app that contains an Activity that handles the RECOGNIZE_SPEECH-intent. You might be able to find Google's VoiceSearch.apk on the web.
There are certain things you can't test using an emulator. Speech to text is on of them.
I'm not sure about this, but you can't use this android feature with the emulator.
No matter what, you should handle this exception with a try/ catch an give some feedback to the user.
You can check if there is that Activity in current device running your app doing something like:
PackageManager pm = context.getPackageManager();
List<ResolveInfo> infoList = pm.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
if (infoList.size() == 0) {
/** Show some feedback to user if there is the activity. Something like "Your device is not abl to run this feature..."*/
}else{
/**Your current code goes here.*/
}
Let me know if it helps.
You need to install com.google.android.voicesearch application on target device which has no voice recognition activity like:
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.voicesearch"));
startActivity(browserIntent);
if you try to install Google's Search app - it won't help since it doesn't contain the VR engine inside and thus it will try to do the same - install com.google.android.voicesearch app but it could fail due to a bug in package name (pname:com.google.android.voicesearch instead of just pure package name). However com.google.android.voicesearch installation might be impossible due to "Not available in your country".
You might need a virtual SD Card. You can refer here
I'm trying to record sound using Android Emulator. I know that this question is popular over the internet, I checked many posts, it seems that only one person succeded: Can the Android emulator record and play back audio using pc hardware?. (it think he used
File fTmFile; insteadof String fTmpFile;
which i also tried). And following Philip's advice and the official site tutorial http://developer.android.com/guide/topics/media/audio-capture.html and also other resources, I'm still not able to record. My application throws exception at line:
fMediaRecorder.prepare();
more exactley, this is what I first get:
W/System.err(1042): java.io.FileNotFoundException: /mnt/sdcard/audiorecordtest.3gp (Permission denied)
which makes me think is something wrong with the storage location, because even I added 'SD Card Support' property for the emulator with size 256 MiB, I'm not able to acces it, furthermore I can see in the emulator the message: "Your phone does not have a SD Card inserted" when I go to Music.
I added both audio record and external storage permissions, in AndroidManifest.xml and both audio (record+playback) hardware settings to the emulator 2.3.3 on Win 7. Is anything wrong within my app, the way I storage the file or something else? Please, if anybody has any idea feel free to share, it will be appreciated.
Here is the full source code:
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import android.app.Activity;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class RecordSoundActivity extends Activity {
private MediaRecorder fMediaRecorder = null;
private Button btnrecord;
private Button btnstop;
String fTmpFile;
public RecordSoundActivity() {
fTmpFile = Environment.getExternalStorageDirectory().getPath();
fTmpFile += "/audiorecordtest.3gp";
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnrecord = (Button) findViewById(R.id.button1);
btnstop = (Button) findViewById(R.id.button2);
btnrecord.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(RecordSoundActivity.this, "Recording...", Toast.LENGTH_LONG).show();
Recording();
}
});
btnstop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
fMediaRecorder.stop();
fMediaRecorder.release();
}
});
}
public void Recording() {
fMediaRecorder = new MediaRecorder();
fMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
fMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
fMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
fMediaRecorder.setAudioChannels(1);
fMediaRecorder.setAudioSamplingRate(8000);
fMediaRecorder.setOutputFile(fTmpFile);
try {
fMediaRecorder.prepare();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
try {
fMediaRecorder.start();
} catch (IllegalStateException e) {
// TODO: handle exception
e.printStackTrace();
}
//fMediaRecorder.stop();
//fMediaRecorder.release();
}
}
Try and see if it works for Android 4.0. I know I had some issues with the camera in the emulator, in lower version (Lower than 4.0) it just wouldn't recognize my laptop webcam. But when I tried it on 4.0, when the AVD was loading a popup message came and asked me if I want to connect the webcam to the AVD, and once I agreed it worked.
Another poster in SO asked this question too, about the camera, and changing the AVD version to 4.0 did help him.
Maybe its the same for audio recording too, as both are external hardware for the typical PC.
i tried the following on the emulator but the as the app starts it gives a runtime error . could someone please help me on this . Heres' the code i tried
package com.example.TextSpeaker;
import java.util.Locale;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
public class TextSpeaker extends Activity {
/** Called when the activity is first created. */
int MY_DATA_CHECK_CODE = 0;
private TextToSpeech mtts;
String test1="hello world";
String test2="hi i am working fine";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent myintent = new Intent();
myintent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(myintent, MY_DATA_CHECK_CODE);
}
protected void onActivityResult(int requestcode,int resultcode,Intent data)
{
if(requestcode == MY_DATA_CHECK_CODE)
{
if(resultcode==TextToSpeech.Engine.CHECK_VOICE_DATA_PASS)
{
// success so create the TTS engine
mtts = new TextToSpeech(this,(OnInitListener) this);
mtts.setLanguage(Locale.ENGLISH);
mtts.speak(test1, TextToSpeech.QUEUE_FLUSH, null);
mtts.speak(test2, TextToSpeech.QUEUE_FLUSH, null);
}
else
{
//install the Engine
Intent install = new Intent();
install.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(install);
}
}
}
}
I've stumbled upon this question well over a year after it was posted, but I'm going to go ahead and answer anyway, in the sheer hope it'll help anyone else who ends up here in the future.
I'm writing this against 2.1, so apologies if you were working with <2.1 (no tags on question)
There are a few things I can spot immediately that may give you a little grief.
Firstly, the following :
mtts.speak(test1, TextToSpeech.QUEUE_FLUSH, null);
mtts.speak(test2, TextToSpeech.QUEUE_FLUSH, null);
If I understand the TextToSpeech API correctly, using QUEUE_FLUSH will flush out anything thats currently being spoken, so its possible that the second line is executing before the first has actually spoken, and you'd experience what you've stated above, that only the last one is being spoken.
Ideally, you only want one of those lines there, if the user puts in a different String, then just pass that through and let it flush out.
Next, you should invest in an onDestroy override, in here you can shutdown the mtts object, this prevents your app from hogging usage to the TTS engine, its always nice to free up resources when you're done with them, you wouldn't leave a ResultSet open now would you?!
#Override
public void onDestroy
() {
// Don't forget to shutdown!
if (mTts != null) {
mTts.stop();
mTts.shutdown();
}
super.onDestroy();
}
Also, as you state, it'll only speak English, because of the line you're using :
mtts.setLanguage(Locale.ENGLISH);
That's easy to correct, just set a different locale. Perhaps have some buttons and set the locale accordingly. I believe that the Google TTS engine currently only supports English, French, German, Italian and Spanish, but 3rd party TTS engines may offer more.
If all else fails, I wrote a tutorial here that might be of use.
Good luck!