I am trying to have a speech recognition build into my app and I am seeing that onBeginningOfSpeech and onEndOfSpeech are getting fired within the space of 1 second.
Also, when i finish speaking, the speech recognition ends immediately after I give a gap. Normally, the ASR would take about 3-5 seconds wait time before stopping speech recognition.
This code is actually messing up the rest of the speech recognition even on other apps on my phone.
Has there been a case like this?
This is how my code looks like.
Here is my onCreate method for my service. I am using a service to call the Speech recognition
#Override
public void onCreate() {
super.onCreate();
createSR();
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
mSpeechRecognizerIntent.putExtra("android.speech.extra.DICTATION_MODE", true);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
this.getPackageName());
}
Here is the recognition listener code.
protected class SpeechRecognitionListener implements RecognitionListener {
private static final String TAG = "SRecognitionListener";
private boolean isUserSpeaking;
private long userSpokeAt=-1;
private long userStoppedSpeakingAt = -1;
private String completeSegment;
private String recognizingSegment;
private ArrayList<String> recognizedSegments;
#Override
public void onBeginningOfSpeech() {
Log.d(TAG, "onBeginingOfSpeech"); //$NON-NLS-1$
}
#Override
public void onBufferReceived(byte[] buffer) {
}
#Override
public void onEndOfSpeech() {
Log.d(TAG, "onEndOfSpeech"); //$NON-NLS-1$
}
#Override
public void onError(int error) {
Log.d(TAG, "onError: " + error);
if (error == SpeechRecognizer.ERROR_NO_MATCH) {
return;
}
mIsListening = false;
Message message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
try {
mServerMessenger.send(message);
} catch (RemoteException e) {
}
Log.d(TAG, "error = " + error); //$NON-NLS-1$
}
#Override
public void onEvent(int eventType, Bundle params) {
}
/* TODO
* There needs to be a boolean variable that would make sure that the translated message from the partialResults would be a fresh message by refreshing the entire data in the bundle data
* Replace the recognizingSegment to have an empty string before doing anything
* */
#Override
public void onPartialResults(Bundle partialResults) {
ArrayList<String> matches = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
if (matches != null && matches.size() != 0) {
Log.d(TAG, "onPartialResults: " + matches.get(0));
partialBundleData = partialResults;
String nextPartResult=matches.get(0);
if (!recognizingSegment.equals("")){
String[] nextPartWords = nextPartResult.split(" ");
String[] recWords;
String previousSegments="";
recWords = recognizingSegment.split(" "); //The last recognized segment
if (recognizedSegments.size()>0){
previousSegments=mergeSegments(recognizedSegments);
}
if (nextPartWords.length+2>=recWords.length){ //Most definitely the same segment
Log.d(TAG, "onPartialResults: matching "+recognizingSegment+" with "+nextPartResult);
if (doWordsMatch(recWords,nextPartWords)) { //Since the words match this is probably the same segment
recognizingSegment = nextPartResult;
partialResult = previousSegments + " " + recognizingSegment;
Log.d(TAG, "onPartialResults: Same segment - " + partialResult);
partialResults.putString("PartialSentence", partialResult);
}else{ //Since the words don't match this is probably a new segment
recognizedSegments.add(recognizingSegment);
partialResult=previousSegments+" "+recognizingSegment+" "+nextPartResult;
Log.d(TAG, "onPartialResults: New segment - " + partialResult);
partialResults.putString("PartialSentence",partialResult);
recognizingSegment=nextPartResult;
}
}else{ //This must be a new segment
Log.d(TAG, "onPartialResults: matching "+recognizingSegment+" with "+nextPartResult);
if (!doWordsMatch(recWords, nextPartWords)) { //Since the words don't match this is probably a new segment
recognizedSegments.add(recognizingSegment);
partialResult = previousSegments + " " + recognizingSegment + " " + nextPartResult;
Log.d(TAG, "onPartialResults: New segment - " + partialResult);
partialResults.putString("PartialSentence", partialResult);
recognizingSegment = nextPartResult;
}else{ //Since the words match this is probably the same segment
recognizingSegment = nextPartResult;
partialResult = previousSegments + " " + recognizingSegment;
Log.d(TAG, "onPartialResults: Same segment - " + partialResult);
partialResults.putString("PartialSentence", partialResult);
}
}
}else{
partialResult=nextPartResult;
Log.d(TAG, "onPartialResults: First segment - " + partialResult);
recognizingSegment=nextPartResult;
partialResults.putString("PartialSentence",nextPartResult);
}
Message message = new Message();
message.what = ASRService.MSG_RECOGNIZER_PART_RESULT;
message.setData(partialResults);
sendMessageToClients(message);
} else {
Log.d(TAG, "onPartialResults: No Results");
}
}
private boolean doWordsMatch(String[] phraseA, String[] phraseB){
int noOfWordsToMatch=3;
if (phraseA.length<noOfWordsToMatch){
noOfWordsToMatch=phraseA.length;
}
if (phraseB.length<noOfWordsToMatch){
noOfWordsToMatch=phraseB.length;
}
boolean wordsMatch=false;
int noOfMatchingWords=0;
for (int i=0; i<noOfWordsToMatch; i++){
if (phraseA[i].equals(phraseB[i])){
noOfMatchingWords++;
}
}
Log.d(TAG, "onPartialResults: noOfMatchingWords - "+noOfMatchingWords);
if (noOfMatchingWords>=2 || noOfMatchingWords>=noOfWordsToMatch){
wordsMatch=true;
}
return wordsMatch;
}
private String mergeSegments(ArrayList<String> segments){
StringBuilder mergedSegments=new StringBuilder();
for (String segment: segments){
mergedSegments.append(segment+" ");
}
return mergedSegments.toString().trim();
}
#Override
public void onReadyForSpeech(Bundle params) {
Log.d(TAG, "onReadyForSpeech"); //$NON-NLS-1$
Message message = new Message();
message.what = ASRService.MSG_RECOGNIZER_STARTED_LISTENING;
sendMessageToClients(message);
userSpokeAt=-1;
completeSegment ="";
recognizingSegment="";
recognizedSegments=new ArrayList<>();
}
#Override
public void onResults(Bundle results) {
ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
if (matches != null && matches.size() != 0) {
Log.d(TAG, "onResults: " + matches.get(0));
Message message = new Message();
message.what = ASRService.MSG_RECOGNIZER_RESULT;
message.setData(results);
sendMessageToClients(message);
} else {
Log.d(TAG, "onResults: No Results");
}
cancelSR();
}
#Override
public void onRmsChanged(float rmsdB) {
if (rmsdB > 20) {
if (userSpokeAt==-1) { //The user spoke the first time
partialResultsTimer = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(70000); //We wait for a max duration of this time to cancel the speech recognition because the service automatically times out anyway.
partialResultsTimer=null;
cancelSR();
} catch (InterruptedException e) {
}
return null;
}
}.execute();
}
userSpokeAt = System.currentTimeMillis();
if (!isUserSpeaking) {
Log.d(TAG, "User started speaking");
isUserSpeaking = true;
if (userStoppedSpeakingAt != -1) {
long gap = userSpokeAt - userStoppedSpeakingAt;
Log.d(TAG, "User spoke after " + gap + " millis");
}
userStoppedSpeakingAt = -1;
if (timeoutTaskRunner != null) {
Log.d(TAG, "Speech Recognition timer canceling");
timeoutTaskRunner.cancel();
timerRunning = false;
}
Message message = new Message();
message.what = ASRService.MSG_RECOGNIZER_USER_SPEAKING_STATE_CHANGED;
message.arg1 = 1; //1 means true
sendMessageToClients(message);
}
} else if (isUserSpeaking) {
long currentTimeMillis = System.currentTimeMillis();
if (currentTimeMillis - userSpokeAt > 1700) {
isUserSpeaking = false;
Log.d(TAG, "User isn't speaking after: " + (currentTimeMillis - userSpokeAt));
userStoppedSpeakingAt = currentTimeMillis;
startTimer();
Message message = new Message();
message.what = ASRService.MSG_RECOGNIZER_USER_SPEAKING_STATE_CHANGED;
message.arg1 = 0; //0 means false
sendMessageToClients(message);
}
}
}
}
#Override
public IBinder onBind(Intent arg0) {
Log.d("ASRService", "onBind"); //$NON-NLS-1$
return mServerMessenger.getBinder();
} }
Related
I am working on the mobile android application and my phone successfully connects to the ESP32 microcontroller. The ESP32's bluetooth range is high and I want to disconnect my phone's bluetooth if the distance/range between the phone and the hardware is more than 10 meters. I cannot modify ESP32's code to reduce the power range, so is there any way I can reduce the bluetooth's range or make my phone disconnect automatically if it goes above a specific range? Please find my android studio code below that I have so far:
public class ConnectedDevice extends AppCompatActivity {
private BluetoothAdapter myBluetooth = null;
private BluetoothSocket btSocket = null;
private boolean isBtConnected = false;
private BluetoothDisconnect bluetoothDisconnect;
static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connected_device);
new ConnectBT().execute();
btnDis.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DisconnectOnBtnClick();
}
});
bluetoothDisconnect = new BluetoothDisconnect();
IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
registerReceiver(bluetoothDisconnect, intentFilter);
mButtonStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCountDownTimer.cancel();
mTimerRunning = false;
mButtonStop.setVisibility(View.INVISIBLE);
Intent intent = new Intent(ConnectedDevice.this, PairedDevices.class);
startActivity(intent);
}
});
}
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(bluetoothDisconnect);
}
private void DisconnectOnBtnClick() {
if (mReadThread != null) {
mReadThread.stop();
do {
} while (mReadThread.isRunning());
mReadThread = null;
}
try {
btSocket.close();
}
catch(IOException e)
{
Toast.makeText(getApplicationContext(), "Could not disconnect", Toast.LENGTH_SHORT).show();
}
finish();
}
private void sendSMS() {
try {
message = brand + " " + model + " " + licensePlate;
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage("5089715596",null,message,null,null);
Toast.makeText(this,"Message Sent",Toast.LENGTH_SHORT).show();
}
catch (Exception e) {
Toast.makeText(this, "Could not send message",Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
private class BluetoothDisconnect extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
sendSMS();
startTimer();
try {
btSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void startTimer() {
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
mButtonStop.setVisibility(View.VISIBLE);
}
#Override
public void onFinish() {
mTimerRunning = false;
mButtonStop.setVisibility(View.INVISIBLE);
Toast.makeText(ConnectedDevice.this, "Calling", Toast.LENGTH_SHORT).show();
callNumber();
}
}.start();
mTimerRunning = true;
mButtonStop.setText("Stop");
}
#SuppressLint("MissingPermission")
private void callNumber()
{
Intent phoneIntent = new Intent(Intent.ACTION_CALL);
phoneIntent.setData(Uri.parse("tel:5088631994"));
startActivity(phoneIntent);
}
private void updateCountDownText() {
int minutes = (int) (mTimeLeftInMillis / 1000) / 60;
int seconds = (int) (mTimeLeftInMillis / 1000) % 60;
String timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
mTextViewCountDown.setText(timeLeftFormatted);
}
private class ConnectBT extends AsyncTask<Void, Void, Void> {
private boolean ConnectSuccess = true;
#Override
protected void onPreExecute () {
progress = ProgressDialog.show(ConnectedDevice.this, "Connecting...", "Please Wait!!!");
}
#Override
protected Void doInBackground (Void... devices) {
try {
if ( btSocket==null || !isBtConnected ) {
myBluetooth = BluetoothAdapter.getDefaultAdapter();
remoteDevice = myBluetooth.getRemoteDevice(address);
btSocket = remoteDevice.createInsecureRfcommSocketToServiceRecord(myUUID);
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
btSocket.connect();
}
}
catch (IOException e) {
ConnectSuccess = false;
}
return null;
}
#Override
protected void onPostExecute (Void result) {
super.onPostExecute(result);
if (!ConnectSuccess) {
Toast.makeText(getApplicationContext(), "Connection Failed. Make sure your device is in range", Toast.LENGTH_SHORT).show();
finish();
}
else {
isBtConnected = true;
mReadThread = new ReadInput();
getCurrentData();
}
progress.dismiss();
}
}
}
Calculated using rssi intensity and power values
public double getDistance(int measuredPower, double rssi) {
if (rssi >= 0) {
return -1.0;
}
if (measuredPower == 0) {
return -1.0;
}
double ratio = rssi * 1.0 / measuredPower;
if (ratio < 1.0) {
return Math.pow(ratio, 10);
} else {
double distance= (0.42093) * Math.pow(ratio, 6.9476) + 0.54992;
return distance;
}
}
how to get power values?
in ScanResult call getTxPower (if your api > 26)
Note:rssi reliability is not 100%, it may be affected by environmental factors
short rssi = intent.getExtras().getShort(BluetoothDevice.EXTRA_RSSI);
int iRssi = abs(rssi);
// 将蓝牙信号强度换算为距离
double power = (iRssi - 59) / 25.0;
String mm = new Formatter().format("%.2f", pow(10, power)).toString();
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String aa = tvDevices.getText().toString() + "";
if (aa.contains(device.getAddress())) {
return;
} else {
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
short rssi = intent.getExtras().getShort(
BluetoothDevice.EXTRA_RSSI);
int iRssi = abs(rssi);
double power = (iRssi - 59) / 25.0;
String mm = new Formatter().format("%.2f", pow(10, power)).toString();
// tvDevices.append(device.getName() + ":" + device.getAddress() + " :" + mm + "m" + "\n");
}else {
}
}
// search finished
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED
.equals(action)) {
//TODO
}
}
};
Application is working when directly installed using apk, but the same apk which is uploaded to playstore is not working.
All the features are working except for intent service which is running in background. service is getting destroyed after some interval of time.
I tried using foreground service , but dint work.
MyIntentService.java
public class MyIntentService extends IntentService {
private SQLiteDatabase mDB;
private DataBaseOpenHelper mDbHelper;
private Context mContext;
private String mCropNdviValue, mCropName, mCropId, mCropLat="", mCropLong="", mCropCity="", mCropSubCity="", mCropCreatedAt;
private long mRecordId;
private Session mSession;
private boolean isDataUploaded = false;
String threeSecTime="",latestInsertedValue="";
public MyIntentService() {
super("MyIntentService");
}
#Override
public void onCreate() {
super.onCreate();
mContext = MyIntentService.this;
mDbHelper = new DataBaseOpenHelper(mContext);
mDB = mDbHelper.getWritableDatabase();
mSession = new Session(mContext);
Log.e("def", "Service is created");
}
#Override
protected void onHandleIntent(Intent intent) {
while (isDataPresent())
{
Log.d("def", "Service starts since data is yet to be uploaded");
fetchRecordAndUpload();
Notification notification =
new Notification.Builder(this)
.setContentTitle("Service Status")
.setContentText("Service running")
.setSmallIcon(R.mipmap.ic_launcher)
.build();
startForeground(102, notification);
}
Log.d("def", "Service stops since no data is present");
stopSelf();
}
private boolean isDataPresent() {
Log.d("def", "isDataPresent is called");
String[] projection = {
DataBaseContract.FeedEntry._ID,
};
if (mDB != null) {
Cursor cursor = mDB.query(
DataBaseContract.FeedEntry.TABLE_NAME,
projection,
null,
null,
null,
null,
null
);
if (cursor.getCount() > 0) {
return true;
}
cursor.close();
}
return false;
}
private synchronized void fetchRecordAndUpload() {
String[] projection = {
DataBaseContract.FeedEntry._ID,
DataBaseContract.FeedEntry.COLUMN_NAME_CROP_NDVI_VALUE,
DataBaseContract.FeedEntry.COLUMN_NAME_CROP_NAME,
DataBaseContract.FeedEntry.COLUMN_NAME_CROP_ID,
DataBaseContract.FeedEntry.COLUMN_NAME_CROP_LATITUDE,
DataBaseContract.FeedEntry.COLUMN_NAME_CROP_LONGITUDE,
DataBaseContract.FeedEntry.COLUMN_NAME_CROP_CITY,
DataBaseContract.FeedEntry.COLUMN_NAME_CROP_SUB_LOCALITY,
DataBaseContract.FeedEntry.COLUMN_NAME_CROP_CREATED_AT
};
if (mDB != null) {
Cursor cursor = null;
try {
cursor = mDB.query(
DataBaseContract.FeedEntry.TABLE_NAME,
projection,
null,
null,
null,
null,
null
);
Log.d("def", "No of records(4) " + cursor.getCount());
int count = 0;
while (cursor.moveToNext()) {
Log.e("def", "While loop starts for " + count);
mRecordId = cursor.getLong(cursor.getColumnIndexOrThrow(DataBaseContract.FeedEntry._ID));
mCropNdviValue = cursor.getString(cursor.getColumnIndexOrThrow(DataBaseContract.FeedEntry.COLUMN_NAME_CROP_NDVI_VALUE));
mCropName = cursor.getString(cursor.getColumnIndexOrThrow(DataBaseContract.FeedEntry.COLUMN_NAME_CROP_NAME));
mCropId = cursor.getString(cursor.getColumnIndexOrThrow(DataBaseContract.FeedEntry.COLUMN_NAME_CROP_ID));
mCropLat = cursor.getString(cursor.getColumnIndexOrThrow(DataBaseContract.FeedEntry.COLUMN_NAME_CROP_LATITUDE));
mCropLong = cursor.getString(cursor.getColumnIndexOrThrow(DataBaseContract.FeedEntry.COLUMN_NAME_CROP_LONGITUDE));
mCropCity = cursor.getString(cursor.getColumnIndexOrThrow(DataBaseContract.FeedEntry.COLUMN_NAME_CROP_CITY));
mCropSubCity = cursor.getString(cursor.getColumnIndexOrThrow(DataBaseContract.FeedEntry.COLUMN_NAME_CROP_SUB_LOCALITY));
mCropCreatedAt = cursor.getString(cursor.getColumnIndexOrThrow(DataBaseContract.FeedEntry.COLUMN_NAME_CROP_CREATED_AT));
Log.d("def", "Record id fetched from db- " + mRecordId + " Ndvi data- " + mCropNdviValue);
uploadToServer();
isDataUploaded = false;
while (!isDataUploaded) {
}
Log.e("def", "While loop ends for " + count);
count++;
}
} finally {
cursor.close();
}
}
}
private void uploadToServer() {
StringRequest allDealsStringRequest = new StringRequest(Request.Method.POST, Session.baseURl + "ndvi_data_time_insert.php?type=1", new Response.Listener<String>() {
#Override
public void onResponse(String response)
{
if (response != null && !response.isEmpty())
{
try {
JSONObject jsonObject = new JSONObject(response);
Log.i("response",response);
if (jsonObject.getString("Response").equalsIgnoreCase("Success"))
{
Log.d("def", response);
threeSecTime=jsonObject.getString("three_sec_time");
mSession.setthreesectime("");
if(threeSecTime!=null && threeSecTime!="") {
mSession.setthreesectime(threeSecTime);
}
Log.i("three",threeSecTime);
if (deleteRecordFromLocalDB())
{
Log.d("def", "Record is deleted");
isDataUploaded = true;
}
} else {
Log.d("abc", response);
}
} catch (JSONException e) {
Log.d("def", "91 " + e.getMessage());
e.printStackTrace();
}
} else {
Log.d("def", "99");
//uploadToServer();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
isDataUploaded = true;
Log.d("def", "56 " + error.getMessage());
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
Log.d("def", "getParams- " + mSession.getUserId() + " " + mCropNdviValue + " " + mCropCity + " " + mCropLat + " " + mCropLong + " " + mCropSubCity + " " + mCropId + " " + mCropCreatedAt + " " + " " + mSession.getDeviceMacId() + " "+mSession.getthreesectime()+" "+mSession.getpreviousid());
params.put("user_id", mSession.getUserId());
params.put("device_id", mSession.getDeviceMacId());
params.put("ndvi_data", mCropNdviValue.trim());
if(mCropCity!=null)
{
params.put("location", mCropCity.trim());
}
else
{
params.put("crop_latitude", "");
}
if(mCropLat!=null)
{
params.put("crop_latitude", mCropLat.trim());
}else
{
params.put("crop_latitude", "");
}
if(mCropLong!=null)
{
params.put("crop_longitude", mCropLong.trim());
}else
{
params.put("crop_longitude", "");
}
if(mCropSubCity!=null)
{
params.put("crop_sub_locality", mCropSubCity.trim());
}else
{
params.put("crop_sub_locality", "");
}
params.put("crop_id", mCropId.trim());
params.put("crop_name", mCropName.trim());
params.put("created_at", mCropCreatedAt.trim());
params.put("three_update_date",mSession.getthreesectime());
return params;
}
};
allDealsStringRequest.setRetryPolicy(new DefaultRetryPolicy(20 * 1000, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
SingletonVolley.getInstance(mContext).addToRequestQueue(allDealsStringRequest);
}
private boolean deleteRecordFromLocalDB() {
String selection = DataBaseContract.FeedEntry._ID + " LIKE ?";
String[] selectionArgs = {String.valueOf(mRecordId)};
return (mDB.delete(DataBaseContract.FeedEntry.TABLE_NAME, selection, selectionArgs) > 0);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("def", "Service is destroyed");
}
}
Hello #Dinesh Hebbar,
You need to learn about DOZE mode in the Android document which implemented in All latest os of android, In this feature, you are not accessing your device or any network related operation They will stop your background service uploading or network related task automatically.
https://developer.android.com/training/monitoring-device-state/doze-standby.html
This feature specially implemented for reduce Battery uses,
Solution: You can use foreground service.
You should use a Intent service when you are sure that after its job is done it will be destroyed but if you want to do long running tasks then go for Background Service or simple service.
Background Service :
Background service is never destroyed even if user closed your app so you have to stop it yourself or use stopself().
simple service:
simple Service is destroyed when user close your app then it restart itself.
Ok i tried everything every single problem in every site and google even i tried every example
why I cant do speech to text in real time with google voice input ?? it works when we click on mic on the keyboard but that don't have keycode to use it in custom button to keyevent it is there any way to do real time speech to text or implement that mic button (keycode)?
private EditText log;
private SpeechRecognizer sr;
private static final String TAG = "spk2txtD2";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button speakButton = (Button) findViewById(R.id.btn);
log = (EditText) findViewById(R.id.txt);
speakButton.setOnClickListener(this);
//get the SpeechRecognizer and set a listener for it.
sr = SpeechRecognizer.createSpeechRecognizer(this);
sr.setRecognitionListener(new listener());
}
#Override
public void finish() {
sr.destroy();
sr = null;
super.finish();
}
/*
* The Recognitionlistener for the SpeechRecognizer.
*/
class listener implements RecognitionListener {
public void onReadyForSpeech(Bundle params) {
Log.d(TAG, "onReadyForSpeech");
}
public void onBeginningOfSpeech(){
Log.d(TAG, "onBeginningOfSpeech");
}
public void onRmsChanged(float rmsdB){
Log.d(TAG, "onRmsChanged" );
}
public void onBufferReceived(byte[] buffer) {
Log.d(TAG, "onBufferReceived");
}
public void onEndOfSpeech() {
Log.d(TAG, "onEndofSpeech");
}
public void onError(int error) {
Log.d(TAG, "error " + error);
logthis("error " + error);
}
public void onResults(Bundle results) {
Log.d(TAG, "onResults " + results);
// Fill the list view with the strings the recognizer thought it could have heard, there should be 5, based on the call
ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
//display results.
log.setText(String.valueOf(matches));
logthis("results: "+String.valueOf(matches.size()));
for (int i = 0; i < matches.size(); i++) {
Log.d(TAG, "result " + matches.get(i));
logthis("result " +i+":"+ matches.get(i));
}
}
public void onPartialResults(Bundle partialResults)
{
Log.d(TAG, "onPartialResults");
}
public void onEvent(int eventType, Bundle params)
{
Log.d(TAG, "onEvent " + eventType);
}
}
public void onClick(View v) {
if (v.getId() == R.id.btn) {
//get the recognize intent
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
//Specify the calling package to identify your application
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,getClass().getPackage().getName());
//Given an hint to the recognizer about what the user is going to say
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
//specify the max number of results
// intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,0);
intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS,true);
// intent.putExtra("android.speech.extra.DICTATION_MODE", true);
//User of SpeechRecognizer to "send" the intent.
sr.startListening(intent);
Log.i(TAG,"Intent sent");
}
}
/*
* simple method to add the log TextView.
*/
public void logthis (String newinfo) {
if (newinfo != "") {
log.setText(log.getText() + "\n" + newinfo);
}
}
}
As I am receiving data from imu razor 9 degree of freedom,(giving me the value of accelerometer,gyro,and magnetometer) we can burn code in it with the help of Arduino IDE.
So, currently I am receiving data on my Android app as shown in image is like that and in my Android code I am updating receiving code here private void: updateReceivedData(byte[] data)
So when I append data to show my values it works fine like that: mDumpTextView.append(message);
But according to requirement, I want that data in array so I can easily display that specific value on screen, not the whole data and at the same time. I need data to store in .csv file . but I am not able to do this . When I use to save in arraym it doesn't work for me: data obtain from imu in an append form in Android app
The whole code is available on GitHub:
https://github.com/mik3y/usb-serial-for-android/tree/master/usbSerialExamples/src/main
But in the code:
public class SerialConsoleActivity extends Activity {
private final String TAG = SerialConsoleActivity.class.getSimpleName();
/**
* Driver instance, passed in statically via
* {#link #show(Context, UsbSerialPort)}.
*
* <p/>
* This is a devious hack; it'd be cleaner to re-create the driver using
* arguments passed in with the {#link #startActivity(Intent)} intent. We
* can get away with it because both activities will run in the same
* process, and this is a simple demo.
*/
private static UsbSerialPort sPort = null;
private TextView mTitleTextView;
private TextView mDumpTextView;
private ScrollView mScrollView;
private CheckBox chkDTR;
private CheckBox chkRTS;
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
private SerialInputOutputManager mSerialIoManager;
private final SerialInputOutputManager.Listener mListener =
new SerialInputOutputManager.Listener() {
#Override
public void onRunError(Exception e) {
Log.d(TAG, "Runner stopped.");
}
#Override
public void onNewData(final byte[] data) {
SerialConsoleActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
SerialConsoleActivity.this.updateReceivedData(data);
}
});
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.serial_console);
// mDumpTextView = (TextView) findViewById(R.id.consoleText);
mTitleTextView = (TextView) findViewById(R.id.demoTitle);
mDumpTextView = (TextView) findViewById(R.id.consoleText);
// mDumpTextView = (TextView) findViewById(R.id.ex);
mScrollView = (ScrollView) findViewById(R.id.demoScroller);
chkDTR = (CheckBox) findViewById(R.id.checkBoxDTR);
chkRTS = (CheckBox) findViewById(R.id.checkBoxRTS);
chkDTR.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
try {
sPort.setDTR(isChecked);
}catch (IOException x){}
}
});
chkRTS.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
try {
sPort.setRTS(isChecked);
}catch (IOException x){}
}
});
}
#Override
protected void onPause() {
super.onPause();
stopIoManager();
if (sPort != null) {
try {
sPort.close();
} catch (IOException e) {
// Ignore.
}
sPort = null;
}
finish();
}
void showStatus(TextView theTextView, String theLabel, boolean theValue){
String msg = theLabel + ": " + (theValue ? "enabled" : "disabled") + "\n";
theTextView.append(msg);
}
#Override
protected void onResume() {
super.onResume();
Log.d(TAG, "Resumed, port=" + sPort);
if (sPort == null) {
mTitleTextView.setText("No serial device.");
} else {
final UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
UsbDeviceConnection connection = usbManager.openDevice(sPort.getDriver().getDevice());
if (connection == null) {
mTitleTextView.setText("Opening device failed");
return;
}
try {
sPort.open(connection);
sPort.setParameters(57600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
showStatus(mDumpTextView, "CD - Carrier Detect", sPort.getCD());
// sPort.getCD();
showStatus(mDumpTextView, "CTS - Clear To Send", sPort.getCTS());
//sPort.getCTS();
showStatus(mDumpTextView, "DSR - Data Set Ready", sPort.getDSR());
//sPort.getDSR();
showStatus(mDumpTextView, "DTR - Data Terminal Ready", sPort.getDTR());
//sPort.getDTR();
showStatus(mDumpTextView, "DSR - Data Set Ready", sPort.getDSR());
//sPort.getDSR();
showStatus(mDumpTextView, "RI - Ring Indicator", sPort.getRI());
//sPort.getRI();
showStatus(mDumpTextView, "RTS - Request To Send", sPort.getRTS());
//sPort.getRTS();
} catch (IOException e) {
Log.e(TAG, "Error setting up device: " + e.getMessage(), e);
mTitleTextView.setText("Error opening device: " + e.getMessage());
try {
sPort.close();
} catch (IOException e2) {
// Ignore.
}
sPort = null;
return;
}
mTitleTextView.setText("Serial device: " + sPort.getClass().getSimpleName());
}
onDeviceStateChange();
}
private void stopIoManager() {
if (mSerialIoManager != null) {
Log.i(TAG, "Stopping io manager ..");
mSerialIoManager.stop();
mSerialIoManager = null;
}
}
public void writeToCsv1(String x,String y,String z) throws IOException {
Calendar c = Calendar.getInstance();
File folder = new File(Environment.getExternalStorageDirectory() + "/project");
boolean success = true;
if (!folder.exists()) {
success = folder.mkdir();
}
if (success) {
// Do something on success
String csv = folder + "/AccelerometerValue1.csv";
FileWriter file_writer = new FileWriter(csv, true);
;
String s = c.get(Calendar.YEAR) + "," + c.get(Calendar.MONTH) + "," + c.get(Calendar.DATE) + "," + c.get(Calendar.HOUR) + "," + c.get(Calendar.MINUTE) + "," + c.get(Calendar.SECOND) + "," + c.get(Calendar.MILLISECOND) + "," + x + "," + y + "," + z + "\n";
file_writer.append(s);
file_writer.close();
}
}
private void startIoManager() {
if (sPort != null) {
Log.i(TAG, "Starting io manager ..");
mSerialIoManager = new SerialInputOutputManager(sPort, mListener);
mExecutor.submit(mSerialIoManager);
}
}
private String convert(byte[] data) {
StringBuilder sb = new StringBuilder(data.length);
for (int i = 0; i < data.length; ++ i) {
if (data[i] < 0) throw new IllegalArgumentException();
sb.append((char) data[i]);
}
return sb.toString();
}
private void onDeviceStateChange() {
stopIoManager();
startIoManager();
}
private void updateReceivedData(byte[] data) {
final String message = convert(data);
if (convert(data) =="A") {
mDumpTextView.append("\n\n");
}
mDumpTextView.append(message);
mScrollView.smoothScrollTo(0, mDumpTextView.getBottom());
}
/**
* Starts the activity, using the supplied driver instance.
*
* #param context
* #param driver
*/
static void show(Context context, UsbSerialPort port) {
sPort = port;
final Intent intent = new Intent(context, SerialConsoleActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
context.startActivity(intent);
}
[enter image description here][1]}
I am creating a game using the API of Google Play Games. I have read the documentation on the leaderboards. I have used the same code to update the user's score, but it always returns the code RESULT_RECONNECT_REQUIRED. I've used the logcat to display the results of the call:
E/GameProgress: Result score CgkIoY-5lt0DEAIQEA: ScoreSubmissionData{PlayerId=128090785697, StatusCode=2, TimesSpan=DAILY, Result=null, TimesSpan=WEEKLY, Result=null, TimesSpan=ALL_TIME, Result=null}
Here is the code:
public class GameActivity extends AppCompatActivity {
private GameHelper mHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
...
mHelper = new GameHelper(this, 1);
mHelper.enableDebugLog(true);
mHelper.setup(new GameHelper.GameHelperListener() {
#Override
public void onSignInFailed() {
Log.e(TAG, "Sign in failed");
}
#Override
public void onSignInSucceeded() {
Log.e(TAG, "Sign in Succeded");
addScores(GameId.LEADERBOARDS.TEN_THOUSAND);
}
});
}
private void addScores(String leaderBoard) {
PendingResult<Leaderboards.SubmitScoreResult> result = Games.Leaderboards.submitScoreImmediate(mGoogleApiClient, leaderBoard, 5);
result.setResultCallback(new ResultCallback<Leaderboards.SubmitScoreResult>() {
#Override
public void onResult(#NonNull Leaderboards.SubmitScoreResult submitScoreResult) {
Log.e(TAG, "Result score " + leaderBoard + ": " + submitScoreResult.getScoreData().toString());
}
});
}
}
GameHelperClass:
public class GameHelper implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
static final String TAG = "GameHelper";
public interface GameHelperListener {
void onSignInFailed();
void onSignInSucceeded();
}
private boolean mSetupDone = false;
private boolean mConnecting = false;
boolean mExpectingResolution = false;
boolean mSignInCancelled = false;
Activity mActivity = null;
Context mAppContext = null;
public final static int RC_RESOLVE = 9001;
final static int RC_UNUSED = 9002;
GoogleApiClient.Builder mGoogleApiClientBuilder = null;
GamesOptions mGamesApiOptions = GamesOptions.builder().build();
PlusOptions mPlusApiOptions = null;
GoogleApiClient mGoogleApiClient = null;
// Client request flags
public final static int CLIENT_NONE = 0x00;
public final static int CLIENT_GAMES = 0x01;
public final static int CLIENT_PLUS = 0x02;
public final static int CLIENT_SNAPSHOT = 0x08;
public final static int CLIENT_ALL = CLIENT_GAMES | CLIENT_PLUS
| CLIENT_SNAPSHOT;
int mRequestedClients = CLIENT_NONE;
boolean mConnectOnStart = true;
boolean mUserInitiatedSignIn = false;
ConnectionResult mConnectionResult = null;
SignInFailureReason mSignInFailureReason = null;
boolean mShowErrorDialogs = true;
boolean mDebugLog = false;
Handler mHandler;
Invitation mInvitation;
TurnBasedMatch mTurnBasedMatch;
ArrayList<GameRequest> mRequests;
// Listener
GameHelperListener mListener = null;
static final int DEFAULT_MAX_SIGN_IN_ATTEMPTS = 3;
int mMaxAutoSignInAttempts = DEFAULT_MAX_SIGN_IN_ATTEMPTS;
private GameErrorHandler mGameErrorHandler;
public GameHelper(Activity activity, int clientsToUse) {
mActivity = activity;
mAppContext = activity.getApplicationContext();
mRequestedClients = clientsToUse;
mHandler = new Handler();
}
public void setMaxAutoSignInAttempts(int max) {
mMaxAutoSignInAttempts = max;
}
public void setGameErrorHandler(GameErrorHandler mGameErrorHandler) {
this.mGameErrorHandler = mGameErrorHandler;
}
void assertConfigured(String operation) {
if (!mSetupDone) {
String error = "GameHelper error: Operation attempted without setup: "
+ operation
+ ". The setup() method must be called before attempting any other operation.";
logError(error);
throw new IllegalStateException(error);
}
}
private void doApiOptionsPreCheck() {
if (mGoogleApiClientBuilder != null) {
String error = "GameHelper: you cannot call set*ApiOptions after the client "
+ "builder has been created. Call it before calling createApiClientBuilder() "
+ "or setup().";
logError(error);
throw new IllegalStateException(error);
}
}
public void setGamesApiOptions(GamesOptions options) {
doApiOptionsPreCheck();
mGamesApiOptions = options;
}
public void setPlusApiOptions(PlusOptions options) {
doApiOptionsPreCheck();
mPlusApiOptions = options;
}
public GoogleApiClient.Builder createApiClientBuilder() {
if (mSetupDone) {
String error = "GameHelper: you called GameHelper.createApiClientBuilder() after "
+ "calling setup. You can only get a client builder BEFORE performing setup.";
logError(error);
throw new IllegalStateException(error);
}
GoogleApiClient.Builder builder = new GoogleApiClient.Builder(
mActivity, this, this);
if (0 != (mRequestedClients & CLIENT_GAMES)) {
builder.addApi(Games.API, mGamesApiOptions);
builder.addScope(Games.SCOPE_GAMES);
}
if (0 != (mRequestedClients & CLIENT_PLUS)) {
builder.addApi(Plus.API);
builder.addScope(Plus.SCOPE_PLUS_LOGIN);
}
if (0 != (mRequestedClients & CLIENT_SNAPSHOT)) {
builder.addScope(Drive.SCOPE_APPFOLDER);
builder.addApi(Drive.API);
}
mGoogleApiClientBuilder = builder;
return builder;
}
public void setup(GameHelperListener listener) {
if (mSetupDone) {
String error = "GameHelper: you cannot call GameHelper.setup() more than once!";
logError(error);
throw new IllegalStateException(error);
}
mListener = listener;
debugLog("Setup: requested clients: " + mRequestedClients);
if (mGoogleApiClientBuilder == null) {
// we don't have a builder yet, so create one
createApiClientBuilder();
}
mGoogleApiClient = mGoogleApiClientBuilder.build();
mGoogleApiClientBuilder = null;
mSetupDone = true;
}
public GoogleApiClient getApiClient() {
if (mGoogleApiClient == null) {
throw new IllegalStateException(
"No GoogleApiClient. Did you call setup()?");
}
return mGoogleApiClient;
}
public boolean isSignedIn() {
return mGoogleApiClient != null && mGoogleApiClient.isConnected();
}
public boolean isConnecting() {
return mConnecting;
}
public boolean hasSignInError() {
return mSignInFailureReason != null;
}
public SignInFailureReason getSignInError() {
return mSignInFailureReason;
}
public void setShowErrorDialogs(boolean show) {
mShowErrorDialogs = show;
}
public void onStart(Activity act) {
mActivity = act;
mAppContext = act.getApplicationContext();
debugLog("onStart");
assertConfigured("onStart");
if (mConnectOnStart) {
if (mGoogleApiClient.isConnected()) {
Log.w(TAG,
"GameHelper: client was already connected on onStart()");
} else {
debugLog("Connecting client.");
mConnecting = true;
mGoogleApiClient.connect();
}
} else {
debugLog("Not attempting to connect becase mConnectOnStart=false");
debugLog("Instead, reporting a sign-in failure.");
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
notifyListener(false);
}
}, 1000);
}
}
public void onStop() {
debugLog("onStop");
assertConfigured("onStop");
if (mGoogleApiClient.isConnected()) {
debugLog("Disconnecting client due to onStop");
mGoogleApiClient.disconnect();
} else {
debugLog("Client already disconnected when we got onStop.");
}
mConnecting = false;
mExpectingResolution = false;
// let go of the Activity reference
mActivity = null;
}
public String getInvitationId() {
if (!mGoogleApiClient.isConnected()) {
Log.w(TAG,
"Warning: getInvitationId() should only be called when signed in, "
+ "that is, after getting onSignInSuceeded()");
}
return mInvitation == null ? null : mInvitation.getInvitationId();
}
public Invitation getInvitation() {
if (!mGoogleApiClient.isConnected()) {
Log.w(TAG,
"Warning: getInvitation() should only be called when signed in, "
+ "that is, after getting onSignInSuceeded()");
}
return mInvitation;
}
public boolean hasInvitation() {
return mInvitation != null;
}
public boolean hasTurnBasedMatch() {
return mTurnBasedMatch != null;
}
public boolean hasRequests() {
return mRequests != null;
}
public void clearInvitation() {
mInvitation = null;
}
public void clearTurnBasedMatch() {
mTurnBasedMatch = null;
}
public void clearRequests() {
mRequests = null;
}
public TurnBasedMatch getTurnBasedMatch() {
if (!mGoogleApiClient.isConnected()) {
Log.w(TAG,
"Warning: getTurnBasedMatch() should only be called when signed in, "
+ "that is, after getting onSignInSuceeded()");
}
return mTurnBasedMatch;
}
public ArrayList<GameRequest> getRequests() {
if (!mGoogleApiClient.isConnected()) {
Log.w(TAG, "Warning: getRequests() should only be called "
+ "when signed in, "
+ "that is, after getting onSignInSuceeded()");
}
return mRequests;
}
public void enableDebugLog(boolean enabled) {
mDebugLog = enabled;
if (enabled) {
debugLog("Debug log enabled.");
}
}
#Deprecated
public void enableDebugLog(boolean enabled, String tag) {
Log.w(TAG, "GameHelper.enableDebugLog(boolean,String) is deprecated. "
+ "Use GameHelper.enableDebugLog(boolean)");
enableDebugLog(enabled);
}
public void signOut() {
if (!mGoogleApiClient.isConnected()) {
// nothing to do
debugLog("signOut: was already disconnected, ignoring.");
return;
}
// for Plus, "signing out" means clearing the default account and
// then disconnecting
if (0 != (mRequestedClients & CLIENT_PLUS)) {
debugLog("Clearing default account on PlusClient.");
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
}
// For the games client, signing out means calling signOut and
// disconnecting
if (0 != (mRequestedClients & CLIENT_GAMES)) {
debugLog("Signing out from the Google API Client.");
Games.signOut(mGoogleApiClient);
}
// Ready to disconnect
debugLog("Disconnecting client.");
mConnectOnStart = false;
mConnecting = false;
mGoogleApiClient.disconnect();
}
public void onActivityResult(int requestCode, int responseCode,
Intent intent) {
debugLog("onActivityResult: req="
+ (requestCode == RC_RESOLVE ? "RC_RESOLVE" : String
.valueOf(requestCode)) + ", resp="
+ GameHelperUtils.activityResponseCodeToString(responseCode));
if (requestCode != RC_RESOLVE) {
debugLog("onActivityResult: request code not meant for us. Ignoring.");
return;
}
// no longer expecting a resolution
mExpectingResolution = false;
/* if (!mConnecting) {
debugLog("onActivityResult: ignoring because we are not connecting.");
return;
}*/
if (responseCode == Activity.RESULT_OK) {
// Ready to try to connect again.
debugLog("onAR: Resolution was RESULT_OK, so connecting current client again.");
connect();
} else if (responseCode == GamesActivityResultCodes.RESULT_RECONNECT_REQUIRED) {
debugLog("onAR: Resolution was RECONNECT_REQUIRED, so reconnecting.");
connect();
fireOnReconectRequired();
} else if (responseCode == Activity.RESULT_CANCELED) {
// User cancelled.
debugLog("onAR: Got a cancellation result, so disconnecting.");
mSignInCancelled = true;
mConnectOnStart = false;
mUserInitiatedSignIn = false;
mSignInFailureReason = null; // cancelling is not a failure!
mConnecting = false;
mGoogleApiClient.disconnect();
// increment # of cancellations
int prevCancellations = getSignInCancellations();
int newCancellations = incrementSignInCancellations();
debugLog("onAR: # of cancellations " + prevCancellations + " --> "
+ newCancellations + ", max " + mMaxAutoSignInAttempts);
notifyListener(false);
} else {
// Whatever the problem we were trying to solve, it was not
// solved. So give up and show an error message.
debugLog("onAR: responseCode="
+ GameHelperUtils
.activityResponseCodeToString(responseCode)
+ ", so giving up.");
giveUp(new SignInFailureReason(mConnectionResult.getErrorCode(),
responseCode));
}
}
void notifyListener(boolean success) {
debugLog("Notifying LISTENER of sign-in "
+ (success ? "SUCCESS"
: mSignInFailureReason != null ? "FAILURE (error)"
: "FAILURE (no error)"));
if (mListener != null) {
if (success) {
mListener.onSignInSucceeded();
} else {
mListener.onSignInFailed();
}
}
}
public void beginUserInitiatedSignIn() {
debugLog("beginUserInitiatedSignIn: resetting attempt count.");
resetSignInCancellations();
mSignInCancelled = false;
mConnectOnStart = true;
if (mGoogleApiClient.isConnected()) {
// nothing to do
logWarn("beginUserInitiatedSignIn() called when already connected. "
+ "Calling listener directly to notify of success.");
notifyListener(true);
return;
} else if (mConnecting) {
logWarn("beginUserInitiatedSignIn() called when already connecting. "
+ "Be patient! You can only call this method after you get an "
+ "onSignInSucceeded() or onSignInFailed() callback. Suggestion: disable "
+ "the sign-in button on startup and also when it's clicked, and re-enable "
+ "when you get the callback.");
// ignore call (listener will get a callback when the connection
// process finishes)
return;
}
debugLog("Starting USER-INITIATED sign-in flow.");
mUserInitiatedSignIn = true;
if (mConnectionResult != null) {
debugLog("beginUserInitiatedSignIn: continuing pending sign-in flow.");
mConnecting = true;
resolveConnectionResult();
} else {
// We don't have a pending connection result, so start anew.
debugLog("beginUserInitiatedSignIn: starting new sign-in flow.");
mConnecting = true;
connect();
}
}
void connect() {
if (mGoogleApiClient.isConnected()) {
debugLog("Already connected.");
return;
}
debugLog("Starting connection.");
mConnecting = true;
mInvitation = null;
mTurnBasedMatch = null;
mGoogleApiClient.connect();
}
public void reconnectClient() {
if (!mGoogleApiClient.isConnected()) {
Log.w(TAG, "reconnectClient() called when client is not connected.");
// interpret it as a request to connect
connect();
} else {
debugLog("Reconnecting client.");
mGoogleApiClient.reconnect();
}
}
#Override
public void onConnected(Bundle connectionHint) {
debugLog("onConnected: connected!");
if (connectionHint != null) {
debugLog("onConnected: connection hint provided. Checking for invite.");
Invitation inv = connectionHint
.getParcelable(Multiplayer.EXTRA_INVITATION);
if (inv != null && inv.getInvitationId() != null) {
// retrieve and cache the invitation ID
debugLog("onConnected: connection hint has a room invite!");
mInvitation = inv;
debugLog("Invitation ID: " + mInvitation.getInvitationId());
}
// Do we have any requests pending?
mRequests = Games.Requests
.getGameRequestsFromBundle(connectionHint);
if (!mRequests.isEmpty()) {
// We have requests in onConnected's connectionHint.
debugLog("onConnected: connection hint has " + mRequests.size()
+ " request(s)");
}
debugLog("onConnected: connection hint provided. Checking for TBMP game.");
mTurnBasedMatch = connectionHint
.getParcelable(Multiplayer.EXTRA_TURN_BASED_MATCH);
}
// we're good to go
succeedSignIn();
}
void succeedSignIn() {
debugLog("succeedSignIn");
mSignInFailureReason = null;
mConnectOnStart = true;
mUserInitiatedSignIn = false;
mConnecting = false;
notifyListener(true);
}
private final String GAMEHELPER_SHARED_PREFS = "GAMEHELPER_SHARED_PREFS";
private final String KEY_SIGN_IN_CANCELLATIONS = "KEY_SIGN_IN_CANCELLATIONS";
// Return the number of times the user has cancelled the sign-in flow in the
// life of the app
int getSignInCancellations() {
SharedPreferences sp = mAppContext.getSharedPreferences(
GAMEHELPER_SHARED_PREFS, Context.MODE_PRIVATE);
return sp.getInt(KEY_SIGN_IN_CANCELLATIONS, 0);
}
int incrementSignInCancellations() {
int cancellations = getSignInCancellations();
SharedPreferences.Editor editor = mAppContext.getSharedPreferences(
GAMEHELPER_SHARED_PREFS, Context.MODE_PRIVATE).edit();
editor.putInt(KEY_SIGN_IN_CANCELLATIONS, cancellations + 1);
editor.commit();
return cancellations + 1;
}
void resetSignInCancellations() {
SharedPreferences.Editor editor = mAppContext.getSharedPreferences(
GAMEHELPER_SHARED_PREFS, Context.MODE_PRIVATE).edit();
editor.putInt(KEY_SIGN_IN_CANCELLATIONS, 0);
editor.commit();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// save connection result for later reference
debugLog("onConnectionFailed");
mConnectionResult = result;
debugLog("Connection failure:");
debugLog(" - code: "
+ GameHelperUtils.errorCodeToString(mConnectionResult
.getErrorCode()));
debugLog(" - resolvable: " + mConnectionResult.hasResolution());
debugLog(" - details: " + mConnectionResult.toString());
int cancellations = getSignInCancellations();
boolean shouldResolve = false;
if (mUserInitiatedSignIn) {
debugLog("onConnectionFailed: WILL resolve because user initiated sign-in.");
shouldResolve = true;
} else if (mSignInCancelled) {
debugLog("onConnectionFailed WILL NOT resolve (user already cancelled once).");
shouldResolve = false;
} else if (cancellations < mMaxAutoSignInAttempts) {
debugLog("onConnectionFailed: WILL resolve because we have below the max# of "
+ "attempts, "
+ cancellations
+ " < "
+ mMaxAutoSignInAttempts);
shouldResolve = true;
} else {
shouldResolve = false;
debugLog("onConnectionFailed: Will NOT resolve; not user-initiated and max attempts "
+ "reached: "
+ cancellations
+ " >= "
+ mMaxAutoSignInAttempts);
}
if (!shouldResolve) {
// Fail and wait for the user to want to sign in.
debugLog("onConnectionFailed: since we won't resolve, failing now.");
mConnectionResult = result;
mConnecting = false;
notifyListener(false);
return;
}
debugLog("onConnectionFailed: resolving problem...");
resolveConnectionResult();
}
void resolveConnectionResult() {
// Try to resolve the problem
if (mExpectingResolution) {
debugLog("We're already expecting the result of a previous resolution.");
return;
}
if (mActivity == null) {
debugLog("No need to resolve issue, activity does not exist anymore");
return;
}
debugLog("resolveConnectionResult: trying to resolve result: "
+ mConnectionResult);
if (mConnectionResult.hasResolution()) {
// This problem can be fixed. So let's try to fix it.
debugLog("Result has resolution. Starting it.");
try {
// launch appropriate UI flow (which might, for example, be the
// sign-in flow)
mExpectingResolution = true;
mConnectionResult.startResolutionForResult(mActivity,
RC_RESOLVE);
} catch (SendIntentException e) {
// Try connecting again
debugLog("SendIntentException, so connecting again.");
connect();
}
} else {
// It's not a problem what we can solve, so give up and show an
// error.
debugLog("resolveConnectionResult: result has no resolution. Giving up.");
giveUp(new SignInFailureReason(mConnectionResult.getErrorCode()));
mConnectionResult = null;
}
}
public void disconnect() {
if (mGoogleApiClient.isConnected()) {
debugLog("Disconnecting client.");
mGoogleApiClient.disconnect();
} else {
Log.w(TAG,
"disconnect() called when client was already disconnected.");
}
}
void giveUp(SignInFailureReason reason) {
mConnectOnStart = false;
disconnect();
mSignInFailureReason = reason;
if (reason.mActivityResultCode == GamesActivityResultCodes.RESULT_APP_MISCONFIGURED) {
// print debug info for the developer
GameHelperUtils.printMisconfiguredDebugInfo(mAppContext);
}
showFailureDialog();
mConnecting = false;
notifyListener(false);
}
#Override
public void onConnectionSuspended(int cause) {
debugLog("onConnectionSuspended, cause=" + cause);
disconnect();
mSignInFailureReason = null;
debugLog("Making extraordinary call to onSignInFailed callback");
mConnecting = false;
notifyListener(false);
}
. . .
void debugLog(String message) {
if (mDebugLog) {
Log.d(TAG, message);
}
}
void logWarn(String message) {
Log.w(TAG, "!!! GameHelper WARNING: " + message);
}
void logError(String message) {
Log.e(TAG, "*** GameHelper ERROR: " + message);
}
// Represents the reason for a sign-in failure
public static class SignInFailureReason {
public static final int NO_ACTIVITY_RESULT_CODE = -100;
int mServiceErrorCode = 0;
int mActivityResultCode = NO_ACTIVITY_RESULT_CODE;
public int getServiceErrorCode() {
return mServiceErrorCode;
}
public int getActivityResultCode() {
return mActivityResultCode;
}
public SignInFailureReason(int serviceErrorCode, int activityResultCode) {
mServiceErrorCode = serviceErrorCode;
mActivityResultCode = activityResultCode;
}
public SignInFailureReason(int serviceErrorCode) {
this(serviceErrorCode, NO_ACTIVITY_RESULT_CODE);
}
public void setConnectOnStart(boolean connectOnStart) {
debugLog("Forcing mConnectOnStart=" + connectOnStart);
mConnectOnStart = connectOnStart;
}
}
I've tried to change the score, but there is nothing, I have also checked that the leaderboard is set up correctly.