Sometimes when a user is sitting, or the phone is still on a table. the if statement which checks if inVehicle & 100% is triggered and the service in my app is started. I cannot figure out why ?
Activity Recognition in MainActivity
public String getDetectedActivity(int detectedActivityType) {
Resources resources = this.getResources();
switch (detectedActivityType) {
case DetectedActivity.IN_VEHICLE:
return resources.getString(R.string.in_vehicle);
case DetectedActivity.ON_BICYCLE:
return resources.getString(R.string.on_bicycle);
case DetectedActivity.ON_FOOT:
return resources.getString(R.string.on_foot);
case DetectedActivity.RUNNING:
return resources.getString(R.string.running);
case DetectedActivity.WALKING:
return resources.getString(R.string.walking);
case DetectedActivity.STILL:
return resources.getString(R.string.still);
case DetectedActivity.TILTING:
return resources.getString(R.string.tilting);
case DetectedActivity.UNKNOWN:
return resources.getString(R.string.unknown);
default:
return resources.getString(R.string.unidentifiable_activity, detectedActivityType);
}
}
public void requestActivityUpdates() {
if (!mGoogleApiClient.isConnected()) {
Toast.makeText(this, "GoogleApiClient not yet connected", Toast.LENGTH_SHORT).show();
} else {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("acr", true);
editor.commit();
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, 100, getActivityDetectionPendingIntent()).setResultCallback(this);
}
}
public void removeActivityUpdates() {
ActivityRecognition.ActivityRecognitionApi.removeActivityUpdates(mGoogleApiClient, getActivityDetectionPendingIntent()).setResultCallback(this);
}
private PendingIntent getActivityDetectionPendingIntent() {
Intent intent = new Intent(this, ActivitiesIntentService.class);
return PendingIntent.getService(this, 20, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public void onResult(Status status) {
if (status.isSuccess()) {
Log.e(TAG, "Successfully added activity detection.");
} else {
Log.e(TAG, "Error: " + status.getStatusMessage());
}
}
public class ActivityDetectionBroadcastReceiver extends BroadcastReceiver {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onReceive(Context context, Intent intent) {
ArrayList<DetectedActivity> detectedActivities = intent.getParcelableArrayListExtra(Constants.STRING_EXTRA);
String activityString = "";
for (DetectedActivity activity : detectedActivities) {
activityString += "Activity: " + getDetectedActivity(activity.getType()) + ", Confidence: " + activity.getConfidence() + "%\n";
}
//mDetectedActivityTextView.setText(activityString);
//Toast.makeText(context, activityString, Toast.LENGTH_LONG).show();
Log.d(TAG2, activityString);
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
detectEnabled = preferences.getBoolean("mode", false);
buttonToggleDetect.setBackground(ui.uiToggle(getApplicationContext(), detectEnabled));
}
}
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected");
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode());
}
Intent Service
public class ActivitiesIntentService extends IntentService {
// TODO REMOVE EXPORTED & ENABLED IN MANIFEST RELATED TO THIS CLASS
private static final String TAG = "ActivitiesIntentService";
public ActivitiesIntentService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
boolean serviceState;
int inVehicle = 0;
int onFoot = 2;
int walking = 7;
int running = 8;
int tilting = 5;
int still = 3;
Intent serviceIntent = new Intent(this, CallDetectService.class); //creating a new intent to be sent to CallDetectService class
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
Intent i = new Intent(Constants.STRING_ACTION);
ArrayList<DetectedActivity> detectedActivities = (ArrayList) result.getProbableActivities();
// Log each activity.
Log.i(TAG, "activities detected");
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
serviceState = preferences.getBoolean("mode", false);
for (DetectedActivity da : detectedActivities) {
// // TODO: 16/07/16 local invehicle int precentage, if int is <50 return
// todo set up for logs from past day to be sent by user
if (da.getType() == inVehicle && da.getConfidence() >= 100 ) {
if (!serviceState) {
/*
ComponentName service = new ComponentName(getApplicationContext(), CallDetectService.class);
PackageManager pm = getApplicationContext().getPackageManager();
pm.setComponentEnabledSetting(service,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
*/
Log.d("Service", "service enabled by acr");
startService(serviceIntent);
MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.music_marimba_chord);
mp.start();
//TODO ADD MP.FINISH HERE
}
}
//else if (da.getType() == still && da.getConfidence() >= 25)
else if (da.getType() == onFoot && da.getConfidence() >= 25
|| da.getType() == walking && da.getConfidence() >= 25
|| da.getType() == running && da.getConfidence() >= 25
|| da.getType() == still && da.getConfidence() == 100)
{
// stop detect service
if (serviceState) {
stopService(serviceIntent);
/*ComponentName service = new ComponentName(getApplicationContext(), CallDetectService.class);
PackageManager pm = getApplicationContext().getPackageManager();
pm.setComponentEnabledSetting(service,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
*/
Log.d("Service", "service disabled by acr");
}
}
}
i.putExtra(Constants.STRING_EXTRA, detectedActivities);
LocalBroadcastManager.getInstance(this).sendBroadcast(i);
}
}
Am I missing something? I really cant figure it out.
I tried putting in a component enabled/disabled setting in the intent service which is commented. when I had that in the code, the service did not start when the user was not inVehicle but when turn on and off when they actually where.
Any Help would be greatly appreciated.
Related
I have created a timer that starts timing on a handleClick() and continues timing throughout the app. When I return to the firstActivity I would like the timer to stop in the onResume(). however whenever I return to the firstActivity I get the following error below. How do I solve this?
Error
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.example.warrenedy.julyfinal.TimeTracker2.isTracking()' on a null object reference
Code Below
#Override
protected void onResume() {
super.onResume();
prepareActivityTextsAndButtons();
prepareTimingButtons();
mTimeTracker2.stopTracker();
Toast.makeText(this, "Onresume call", Toast.LENGTH_SHORT).show();
}
public void handleClick(View v) {
if (DBG) Log.d(LOG_TAG, "handleClick()..");
if (!mServiceBound) return;
switch (v.getId()) {
case R.id.button_activity_start_stop:
onActivityButtonClick(v);
break;
}
}
private void onActivityButtonClick(View v) {
if (DBG)
Log.d(LOG_TAG, "onMeditateButtonClick().. tracking " + mTimeTracker2.isTracking());
ToggleButton button = (ToggleButton) v;
if (mTimeTracker2.isTracking()) {
if (mCurrentTrackingActivity == null) return;
if (button == mButtonActivityTimers[mCurrentTrackingActivity.ordinal()]) {
mTimeTracker2.stopTracker();
Utils2.playStopAudio(getApplicationContext());
// button.setText(R.string.str_start);
mCurrentTime.setText(Utils2.secToString(0));
button.setChecked(false);
}
}
}
Code Continued
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (DBG) Log.d(LOG_TAG, "onCreate()..");
setContentView(R.layout.activity_meditation_tracker);
getSupportActionBar().hide();
mContext = getApplicationContext();
mSharedpreferences = getSharedPreferences(Utils.MyPREFERENCES, Context.MODE_PRIVATE);
exercise_star = sharedpreferences.getInt("exercise_star", 0);
meditation_star = sharedpreferences.getInt("meditation_star", 0);
study_star = sharedpreferences.getInt("study_star", 0);
isAlarmSet = sharedpreferences.getBoolean("isAlarmSet", false);
/* Retrieve a PendingIntent that will perform a broadcast */
mActivity = MeditationTrackerActivity.this;
mButtonSavePoints = (Button) findViewById(R.id.btn_save_points);
mButtonRestorePoints = (Button) findViewById(R.id.btn_restore_points);
btnHelpBut = (Button) findViewById(R.id.btnHelp);
ACTIVITY_NAMES = getResources().getStringArray(R.array.activity_names);
mCurrentTime = (TextView) findViewById(R.id.tv_current_time);
mCurrentTime.setText(Utils2.secToString(0));
if (!isAlarmSet) {
SharedPreferences.Editor ed = sharedpreferences.edit();
ed.putBoolean("isAlarmSet", true);
ed.commit();
startAlarmService();
}
isAuthenticated = sharedpreferences.getBoolean("isAuth", true);
if (Build.VERSION.SDK_INT < 23) {
if (!isAuthenticated) {
clientAuthenticationFromServer();
} else {
startService();
}
} else {
insertPermissionWrapper();
}
}
### StartAlarmService
public void startAlarmService() {
Intent alarmIntent = new Intent(MeditationTrackerActivity.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MeditationTrackerActivity.this, 0, alarmIntent, 0);
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar firingCal = Calendar.getInstance();
Calendar currentCal = Calendar.getInstance();
firingCal.set(Calendar.HOUR_OF_DAY, 23); // At the hour you wanna fire
firingCal.set(Calendar.MINUTE, 45); // Particular minute
firingCal.set(Calendar.SECOND, 0); // particular second
long intendedTime = firingCal.getTimeInMillis();
long currentTime = currentCal.getTimeInMillis();
if (intendedTime >= currentTime) {
mAlarmManager.setRepeating(AlarmManager.RTC, intendedTime, AlarmManager.INTERVAL_DAY, pendingIntent);
} else {
firingCal.add(Calendar.DAY_OF_MONTH, 1);
intendedTime = firingCal.getTimeInMillis();
mAlarmManager.setRepeating(AlarmManager.RTC, intendedTime, AlarmManager.INTERVAL_DAY, pendingIntent);
}
Toast.makeText(this, "Main Alarm Set", Toast.LENGTH_SHORT).show();
}
### CancelAlarm
public void cancelAlarmService() {
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
manager.cancel(pendingIntent);
Toast.makeText(this, "Alarm Canceled", Toast.LENGTH_SHORT).show();
}
### StartService
private void startService() {
Intent serIntent = new Intent(this, TimeTrackingService2.class);
startService(serIntent);
bindService(serIntent, mServiceConnection, BIND_AUTO_CREATE);
}
### UpdateCurrentTime
private void updateCurrentTime() {
Date date = Calendar.getInstance().getTime();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
mCurrentTime.setText(sdf.format(date));
}
### ClientAuthenticationFromServer
private void clientAuthenticationFromServer() {
if (Utils2.getConnectivityStatus(mContext)) {
new Auth(mContext, mActivity).execute(Utils2.URL_VALIDATE_CLIENT);
} else {
Utils2.alertPopup(mContext, "You are not connected to internet.kindly connect with internet and try again.The internet is needed only first time for the authentication of client.After authentication no need of internet.", mActivity);
}
}
###Task Complete
#Override
public void onTaskComplete(boolean result) {
if (!result) {
Utils2.alertPopup(mContext, "You are not a valid client.Contact with the owner of the App.", mActivity);
return;
} else {
SharedPreferences.Editor ed = sharedpreferences.edit();
ed.putBoolean("isAuth", true);
ed.commit();
startService();
}
}
### OnStart
#Override
protected void onStart() {
super.onStart();
// updateCurrentTime();
// IntentFilter filter = new IntentFilter(Intent.ACTION_TIME_TICK);
// registerReceiver(mTimeTickReceiver, filter);
}
###OnStop
#Override
protected void onStop() {
super.onStop();
// unregisterReceiver(mTimeTickReceiver);
}
### onDestroy
#Override
protected void onDestroy() {
super.onDestroy();
if (mServiceBound) {
unbindService(mServiceConnection);
}
}
### onTimeButtonClick
private void onTimeButtonClick(View v) {
if (DBG) Log.d(LOG_TAG, "onClick() timebutton.. tracking" + mTimeTracker2.isTracking());
ToggleButton button = (ToggleButton) v;
if (DBG) Log.d(LOG_TAG, "onClick() timebutton.. checked ? " + button.isChecked());
if (mTimeTracker2.isTracking()) {
showStopToast();
Utils2.playStopAudio(getApplicationContext());
button.setChecked(false);
return;
} else {
Utils2.playStartAudio(getApplicationContext());
if (button.isChecked()) {
if (mCurrentCheckedButton != null) mCurrentCheckedButton.setChecked(false);
int time = (Integer) v.getTag();
mCountDownSecs = time;
mCurrentCheckedButton = button;
} else {
mCountDownSecs = 0;
mCurrentCheckedButton = null;
}
}
}
###ShowStopToast
private void showStopToast() {
Toast.makeText(this, "Please stop running activity..", Toast.LENGTH_SHORT).show();
}
### onTimerProgress
#Override
public void onTimerProgress(int sec, ACTIVITIES activity) {
if (mCurrentTrackingActivity == null) {
mCurrentTrackingActivity = activity;
}
mCurrentTime.setText(Utils2.secToString(sec));
if (activity == ACTIVITIES.STUDY) {
if (sec == 3600) {
mTimeTracker2.stopTracker();
}
}
}
### onTimerFinish
#Override
public void onTimerFinish(int end, ACTIVITIES activity) {
mCurrentTime.setText(Utils2.secToString(end));
mButtonActivityTimers[activity.ordinal()].setChecked(false);
mCurrentTrackingActivity = null;
Utils2.playStopAudio(getApplicationContext());
}
private void prepareActivityTextsAndButtons() {
for (int i = 0; i < ACTIVITY_COUNT; i++) {
View parent = findViewById(ACTIVITY_LAYOUT_IDS[i]);
mTextActivityNames[i] = (TextView) parent.findViewById(R.id.tv_activity_name);
mTextActivityNames[i].setText(ACTIVITY_NAMES[i]);
//mTextActivityTimers[i] = (TextView) parent.findViewById(R.id.tv_timer_progress);
mRatingBars[i] = (RatingBar) parent.findViewById(R.id.ratingBar);
mButtonActivityTimers[i] = (ToggleButton) parent.findViewById(R.id.button_activity_start_stop);
mButtonActivityTimers[i].setText(null);
mButtonActivityTimers[i].setTextOn(null);
mButtonActivityTimers[i].setTextOff(null);
mButtonActivityTimers[i].setTag(ACTIVITIES.values()[i]);
}
}
private void prepareTimingButtons() {
mTimingButtons = new ToggleButton[7];
mTimingButtons[0] = (ToggleButton) findViewById(R.id.button_timer_0);
addTextToTimingButtons(5, mTimingButtons[0]);
}
private void addTextToTimingButtons(int min, Button button) {
// button.setText(min + " " + getString(R.string.str_min));
button.setTag(min * 60);
}
public void onCustomTimeStarted(int secs) {
if (DBG) Log.d(LOG_TAG, "onCustomTimeStarted : secs " + secs);
if (mTimeTracker2.isTracking()) {
showStopToast();
} else {
int oneday = 24 * 3600;
if (secs > oneday) {
Toast.makeText(this, "Adjusted to 24 hrs", Toast.LENGTH_SHORT).show();
secs = oneday;
} else if (secs < 60) {
Toast.makeText(this, "Should be at least a minute.", Toast.LENGTH_SHORT).show();
return;
}
mTimingButtons[6].setChecked(true);
mTimingButtons[6].setTag(secs);
onTimeButtonClick(mTimingButtons[6]);
//mTimeTracker2.startTracker(secs, this);
//mButtonMeditate.setText(R.string.meditate_stop);
}
}
private boolean addPermission(List<String> permissionsList, String permission) {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
// Check for Rationale Option
if (!shouldShowRequestPermissionRationale(permission))
return false;
}
}
return true;
}
private void insertPermissionWrapper() {
List<String> permissionsNeeded = new ArrayList<String>();
final List<String> permissionsList = new ArrayList<String>();
if (!addPermission(permissionsList, Manifest.permission.READ_PHONE_STATE))
permissionsNeeded.add("READ_PHONE_STATE");
if (permissionsList.size() > 0) {
if (permissionsNeeded.size() > 0) {
// Need Rationale
String message = "You need to grant access to " + permissionsNeeded.get(0);
for (int i = 1; i < permissionsNeeded.size(); i++)
message = message + ", " + permissionsNeeded.get(i);
showMessageOKCancel(message,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= 23) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
}
});
return;
}
if (Build.VERSION.SDK_INT >= 23) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
return;
} else {
if (!isAuthenticated) {
clientAuthenticationFromServer();
} else {
startService();
}
}
// insertDummyContact();
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new android.app.AlertDialog.Builder(MeditationTrackerActivity.this)
.setMessage(message)
.setCancelable(false)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.create()
.show();
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<String, Integer>();
// Initial
perms.put(Manifest.permission.READ_PHONE_STATE, PackageManager.PERMISSION_GRANTED);
// Fill with results
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for ACCESS_FINE_LOCATION
if (perms.get(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED
) {
// All Permissions Granted
if (!isAuthenticated) {
clientAuthenticationFromServer();
} else {
startService();
}
} else {
// Permission Denied
Toast.makeText(MeditationTrackerActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT)
.show();
finish();
}
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private void setBootReceiverEnabled(int componentEnabledState) {
ComponentName componentName = new ComponentName(this, DeviceBootReceiver.class);
PackageManager packageManager = getPackageManager();
packageManager.setComponentEnabledSetting(componentName,
componentEnabledState,
PackageManager.DONT_KILL_APP);
};
TimeTracker2.class
public class TimeTracker2 {
private static final int MSG_TRACKER_STOPPED = 1;
private static final int MSG_TRACKER_PROGRESS_UPDATE = 2;
private Context mContext;
private boolean mIsTrackingInProgress;
private TrackerServiceCallback mServiceCallback;
private TimerProgressCallback2 mProgressCallback;
private Timer mTimer = new Timer();
private TimerHandler mTimerHandler = new TimerHandler();
private TimerTask mIncrementTask, mDecrementTask;
private int mCounter;
private int mMaxCounter;
private MeditationTrackerActivity.ACTIVITIES mCurrentTrackingActivity;
private class IncrementTask extends TimerTask {
IncrementTask() {
mCounter = 0;
}
#Override
public void run() {
mCounter++;
mTimerHandler.sendEmptyMessage(MSG_TRACKER_PROGRESS_UPDATE);
}
}
private class DecrementTask extends TimerTask {
DecrementTask(int sec) {
mCounter = sec;
}
#Override
public void run() {
if (mCounter == 0) {
ToneGenerator toneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);
toneGenerator.startTone(ToneGenerator.TONE_CDMA_PIP, 500);
cancel();
mTimerHandler.sendEmptyMessage(MSG_TRACKER_STOPPED);
return;
}
mCounter --;
mTimerHandler.sendEmptyMessage(MSG_TRACKER_PROGRESS_UPDATE);
}
}
public interface TimerProgressCallback2 {
void onTimerProgress(int sec, MeditationTrackerActivity.ACTIVITIES activity);
void onTimerFinish(int end, MeditationTrackerActivity.ACTIVITIES activity);
}
public TimeTracker2(Context context, TrackerServiceCallback serviceCallback) {
mContext = context;
mServiceCallback = serviceCallback;
}
public void startTracker(int time_secs, TimerProgressCallback2 callback, MeditationTrackerActivity.ACTIVITIES activity) {
if (mIsTrackingInProgress) {
Log.i(LOG_TAG, "startTracker().. inProgress!!");
return;
}
mMaxCounter = time_secs;
mProgressCallback = callback;
mIsTrackingInProgress = true;
mServiceCallback.onTrackerStarted(true);
mDecrementTask = new DecrementTask(time_secs);
mTimer.scheduleAtFixedRate(mDecrementTask, 0, 1000);
mCurrentTrackingActivity = activity;
}
public void startTracker(TimerProgressCallback2 callback, MeditationTrackerActivity.ACTIVITIES activity) {
if (mIsTrackingInProgress) {
Log.i(LOG_TAG, "startTracker().. inProgress!!");
return;
}
mMaxCounter = 0;
mProgressCallback = callback;
mIsTrackingInProgress = true;
mServiceCallback.onTrackerStarted(true);
mIncrementTask = new IncrementTask();
mTimer.scheduleAtFixedRate(mIncrementTask, 0, 1000);
mCurrentTrackingActivity = activity;
}
public void setTimerProgressCallback(TimerProgressCallback2 callback) {
if (!mIsTrackingInProgress) return;
mProgressCallback = callback;
}
public void removeTimerProgressCallback() {
mProgressCallback = null;
}
public void stopTracker() {
if (!mIsTrackingInProgress) {
Log.i(LOG_TAG, "stopTracker().. Tracker NOT started!!");
return;
}
mIsTrackingInProgress = false;
mServiceCallback.onTrackerStarted(false);
if (mProgressCallback != null) mProgressCallback.onTimerFinish(mCounter, mCurrentTrackingActivity);
mProgressCallback = null;
if (mIncrementTask != null) mIncrementTask.cancel();
if (mDecrementTask != null) mDecrementTask.cancel();
updateDb();
mCurrentTrackingActivity = null;
}
public boolean isTracking() {
return mIsTrackingInProgress;
}
public MeditationTrackerActivity.ACTIVITIES getCurrentTrackingActivity() {
return mCurrentTrackingActivity;
}
private class TimerHandler extends Handler {
#Override
public void handleMessage(Message msg) {
if (DBG) Log.d(LOG_TAG, "handleMessage()..");
switch (msg.what) {
case MSG_TRACKER_PROGRESS_UPDATE:
if (mProgressCallback != null) mProgressCallback.onTimerProgress(mCounter, mCurrentTrackingActivity);
break;
case MSG_TRACKER_STOPPED:
default:
stopTracker();
break;
}
}
}
private void updateDb() {
final int secs = mMaxCounter > 0 ? mMaxCounter - mCounter : mCounter;
final MeditationTrackerActivity.ACTIVITIES activity = mCurrentTrackingActivity;
AsyncTask.execute(new Runnable() {
#Override
public void run() {
TrackerDb3.insertOrUpdateMeditation(mContext, secs, activity);
}
});
}
}
I have a boot receiver starting a service and also I can start and stop the service within the app.
But when I boot up the phone the service does start but stops instantly after starting. I have set the return on onStartCommand to START_STICKY.
This is my boot receiver:
public void onReceive(final Context context, final Intent intent) {
if(Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())){
Toast.makeText(context, "Boot received", Toast.LENGTH_LONG).show();
this.sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
this.mTelephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
this.encryption = new Encryption(mTelephonyMgr, sharedPreferences);
//startService(context);
Intent i = new Intent(context, ProfileActivity.class);
i.putExtra("boot_received", false);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
sharedPreferences.edit().putBoolean(Keys.AVAILABILITY, false).apply();
}
}
public void startService(final Context context){
final Intent intent = new Intent(context, PhoneCallService.class);
// If no token, try getting one.
if (Keys.phoneServiceToken == null || Keys.phoneServiceToken.isEmpty()) {
getToken(context, new Callbacks.ReceivePhoneServiceTokenCallback() {
#Override
public void receivePhoneServiceTokenCallback(boolean gotToken) {
if (gotToken) {
intent.putExtra(Keys.PHONE_SERVICE_TOKEN_EXTRA, Keys.phoneServiceToken);
intent.setAction(PhoneCallService.START_SERVICE);
context.startService(intent);
} else {
Log.d(LOG_TAG, String.valueOf(R.string.unexpected_error));
}
}
});
} else {
intent.putExtra(Keys.PHONE_SERVICE_TOKEN_EXTRA, Keys.phoneServiceToken);
intent.setAction(PhoneCallService.START_SERVICE);
context.startService(intent);
}
}
public void getToken(Context context, final Callbacks.ReceivePhoneServiceTokenCallback callback){
final String API = Keys.getpvmURL() + SharedResources.URL_DIRECT_CALL_TOKEN;
JsonObject json = encryption.getID();
json.addProperty("versionCode", BuildConfig.VERSION_CODE);
Ion.with(context)
.load(API)
.setTimeout(Keys.TIMEOUT_DIRECT_CALL_TOKEN)
.setJsonObjectBody(json)
.asJsonObject()
.withResponse()
.setCallback(new FutureCallback<Response<JsonObject>>() {
#Override
public void onCompleted(Exception e, Response<JsonObject> result) {
if(e == null) {
Log.d(LOG_TAG, "No Exceptions");
if(result.getHeaders().code() == 200) {
if(result.getResult().has("result")) {
Keys.phoneServiceToken = result.getResult().get("result").getAsString();
callback.receivePhoneServiceTokenCallback(true);
} else {
Log.w(LOG_TAG, "Does not have result");
callback.receivePhoneServiceTokenCallback(false);
}
} else {
Log.w(LOG_TAG, "Not getting 200 " + result.getHeaders().message());
callback.receivePhoneServiceTokenCallback(false);
}
} else {
Log.e(LOG_TAG, "Exception has occurred " + e.getClass());
callback.receivePhoneServiceTokenCallback(false);
}
}
});
This is my onStart and onCreate methods:
#Override
public void onCreate() {
Log.d(LOG_TAG, "Service started");
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(PhoneCallService.this);
notificationManager = (NotificationManager) PhoneCallService.this.getSystemService(Context.NOTIFICATION_SERVICE);
voiceBroadcastReceiver = new VoiceBroadcastReceiver();
registerReceiver();
audioManager = (AudioManager) PhoneCallService.this.getSystemService(Context.AUDIO_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent == null || intent.getAction() == null) {
Log.d(LOG_TAG, "No Action");
}
else if (intent.getAction().equals(START_SERVICE)) {
Log.d(LOG_TAG, "Starting PhoneCallService");
accessToken = intent.getStringExtra(Keys.PHONE_SERVICE_TOKEN_EXTRA);
Log.d(LOG_TAG, accessToken);
if (accessToken != null && !accessToken.isEmpty()) {
registerForCallInvites();
MyFcmListenerService.availableToCall = true;
} else {
stopSelf();
MyFcmListenerService.availableToCall = false;
}
}
else if (intent.getAction().equals(STOP_SERVICE)) {
stopSelf();
MyFcmListenerService.availableToCall = false;
}
else if (intent.getAction().equals(ACTION_INCOMING_CALL)) {
handleIncomingCallIntent(intent);
}
else {
Log.d(LOG_TAG, intent.getAction());
}
return START_STICKY;
}
For some reason I just can't get it to work on the boot request.
I'm trying to copy my working TTS service code from app code to wear code but not work.
public class VoiceService extends Service implements
TextToSpeech.OnInitListener, TextToSpeech.OnUtteranceCompletedListener {
private final String TAG = "VoiceService";
private final int LONG_DURATION = 5000;
private final int SHORT_DURATION = 1200;
private TextToSpeech mTts;
private String messageTitle;
private String messageContext;
#Override
public void onCreate() {
Log.i(TAG, "onCreate");
try{
mTts = new TextToSpeech(this, this);
mTts.setOnUtteranceCompletedListener(this);
}
catch(Exception e){
e.printStackTrace();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
Log.i(TAG, "onStartCommand");
messageTitle = ...
messageContext = ...
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onInit(int status) {
Log.i(TAG, "onInit & status = " + status);
if (status == TextToSpeech.SUCCESS) {
int result = mTts.setLanguage(Locale.getDefault());
Log.i(TAG, "TextToSpeech.SUCCESS");
if (result != TextToSpeech.LANG_MISSING_DATA
&& result != TextToSpeech.LANG_NOT_SUPPORTED
&& messageTitle.length() > 0
) {
Log.i(TAG, "messageTitle.length() > 0");
...
}
}
}
#Override
public void onUtteranceCompleted(String uttId) {
Log.i(TAG, "onUtteranceCompleted");
messageTitle = "";
messageContext = "";
stopSelf();
}
#Override
public void onDestroy() {
Log.i(TAG, "onDestroy");
// Text to Speech engine was attached
if (mTts != null) {
mTts.stop();
mTts.shutdown();
mTts = null;
}
super.onDestroy();
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
...
}
The log is simply as follows:
I/VoiceService: onCreate
I/VoiceService: onInit & status = -1
I/VoiceService: onStartCommand
I do not understand why onInit comes before onStartCommand, and failed, and the service stuck there forever...
I followed some threads and run the following code in mainactivity:
PackageManager pm = getPackageManager();
Intent installIntent = new Intent();
installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
ResolveInfo resolveInfo = pm.resolveActivity( installIntent, PackageManager.MATCH_DEFAULT_ONLY );
if( resolveInfo == null ) {
// Not able to find he activity which should be started for this intent
Log.i(TAG, "Not able to find the activity which should be started for this intent");
} else {
Log.i(TAG, "try to install...");
startActivity( installIntent );
}
The log was as follow and I do not have idea to fix it:
Not able to find the activity which should be started for this intent
I am using Android Wear Emulator and I could not find TTS Enable button in Setting -> Accessibility menu. But under the menu, I found TalkBack(experimental), no idea what it is.
I had spent few days in this. a bit tired tonight. Please give me some direction of how to make TTS works in emulator.
The motto here is calling the Service 'ActivityTrackerService' when I say requestActivityUpdates() using the GoogleApiClient's ActivityRecognition.ActivityRecognitionApi as shown in the code below when googleApiClient.connect() is called. After the api is connected the onConnected callback executes and activity updates are requested. The code runs perfectly fine as in the result call back i get a success. But some how Service class onHandleIntent is not called. I am not sure if the service has started working or not.
Service Provider Class:
public class ActivityServiceProvider {
private Context context;
private GoogleApiClient googleApiClient;
private PendingIntent mActivityRecognitionPendingIntent;
public ActivityServiceProvider(Context context) {
this.context = context;
createGoogleLocationServiceClient();
}
private void createGoogleLocationServiceClient() {
googleApiClient = new GoogleApiClient.Builder(context).addApi(ActivityRecognition.API)
.addConnectionCallbacks(new ConnectionCallbacks() {
#Override
public void onConnectionSuspended(int arg0) {
Log.d(ActivityUtils.APPTAG, "GoogleApiClient Suspended");
}
#Override
public void onConnected(Bundle arg0) {
Log.d(ActivityUtils.APPTAG, "GoogleApiClient Connected Now");
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(googleApiClient,
ActivityUtils.DETECTION_INTERVAL_MILLISECONDS, getPendingIntent()).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status arg0) {
if (arg0.isSuccess()) {
Log.d(ActivityUtils.APPTAG, "Updates Requested Successfully");
} else {
Log.d(ActivityUtils.APPTAG, "Updates could not be requested");
}
}
});
}
}).addOnConnectionFailedListener(new OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult arg0) {
Log.d(ActivityUtils.APPTAG, "GoogleApiClient Connection Failed");
}
}).build();
}
public PendingIntent getRequestPendingIntent() {
return mActivityRecognitionPendingIntent;
}
public void setRequestPendingIntent(PendingIntent intent) {
mActivityRecognitionPendingIntent = intent;
}
private PendingIntent getPendingIntent() {
Intent intent = new Intent(context, ActivityTrackerService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
setRequestPendingIntent(pendingIntent);
return pendingIntent;
}
private boolean servicesConnected() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context);
if (ConnectionResult.SUCCESS == resultCode) {
Log.d(ActivityUtils.APPTAG, context.getString(R.string.play_services_available));
return true;
} else {
Log.d(ActivityUtils.APPTAG, context.getString(R.string.play_services_unavailable));
return false;
}
}
public void connect() {
if (servicesConnected() && !googleApiClient.isConnected()) {
Log.d(ActivityUtils.APPTAG, "GoogleApiClient Connection Initiated: connect() Called");
googleApiClient.connect();
} else {
Log.d(ActivityUtils.APPTAG, "GoogleApiClient already connected or is unavailable");
}
}
public void disconnect() {
if (servicesConnected() && googleApiClient.isConnected()) {
Log.d(ActivityUtils.APPTAG, "GoogleApiClient disconnection kicked");
if (mActivityRecognitionPendingIntent != null && googleApiClient != null) {
ActivityRecognition.ActivityRecognitionApi.removeActivityUpdates(googleApiClient,
mActivityRecognitionPendingIntent);
}
googleApiClient.disconnect();
} else {
Log.d(ActivityUtils.APPTAG, "GoogleApiClient already disconnected or is unavailable");
}
}
}
Service Class:
public class ActivityTrackerService extends IntentService {
private SharedPreferences mPrefs;
public ActivityTrackerService() {
super("ActivityTrackerService");
}
#Override
protected void onHandleIntent(Intent intent) {
mPrefs = getApplicationContext().getSharedPreferences(ActivityUtils.SHARED_PREFERENCES, Context.MODE_PRIVATE);
if (ActivityRecognitionResult.hasResult(intent)) {
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
DetectedActivity mostProbableActivity = result.getMostProbableActivity();
int confidence = mostProbableActivity.getConfidence();
int activityType = mostProbableActivity.getType();
String activityName = ActivityUtils.getNameFromType(activityType);
Log.d(ActivityUtils.APPTAG, "Activity Detected:" + activityName);
Intent regularActivityUpdateIntent = new Intent(ActivityUtils.REGULAR_ACTIVITY_UPDATE_INTENT);
regularActivityUpdateIntent.putExtra(ActivityUtils.EXTRA_ACTIVITY_NAME, activityName);
regularActivityUpdateIntent.putExtra(ActivityUtils.EXTRA_ACTIVITY_TYPE, activityType);
getApplicationContext().sendBroadcast(regularActivityUpdateIntent);
if (!mPrefs.contains(ActivityUtils.KEY_PREVIOUS_ACTIVITY_TYPE)) {
Editor editor = mPrefs.edit();
editor.putInt(ActivityUtils.KEY_PREVIOUS_ACTIVITY_TYPE, activityType);
editor.putString(ActivityUtils.KEY_PREVIOUS_ACTIVITY_NAME, activityName);
editor.commit();
Intent newActivityUpdateIntent = new Intent(ActivityUtils.NEW_ACTIVITY_UPDATE_INTENT);
regularActivityUpdateIntent.putExtra(ActivityUtils.EXTRA_ACTIVITY_NAME, activityName);
regularActivityUpdateIntent.putExtra(ActivityUtils.EXTRA_ACTIVITY_TYPE, activityType);
getApplicationContext().sendBroadcast(newActivityUpdateIntent);
} else if (isMoving(activityType) && activityChanged(activityType) && (confidence >= 50)) {
sendNotification();
}
}
}
private void sendNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext());
builder.setContentTitle("Attention").setContentText("Click to turn on GPS, or swipe to ignore")
.setSmallIcon(R.drawable.ic_notification).setContentIntent(getContentIntent());
NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notifyManager.notify(0, builder.build());
}
private PendingIntent getContentIntent() {
Intent gpsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
return PendingIntent.getActivity(getApplicationContext(), 0, gpsIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
private boolean activityChanged(int currentType) {
int previousType = mPrefs.getInt(ActivityUtils.KEY_PREVIOUS_ACTIVITY_TYPE, DetectedActivity.UNKNOWN);
if (previousType != currentType) {
return true;
} else {
return false;
}
}
private boolean isMoving(int type) {
switch (type) {
case DetectedActivity.STILL:
case DetectedActivity.TILTING:
case DetectedActivity.UNKNOWN:
return false;
default:
return true;
}
}
}
The specific android manifest entries are as follows :
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<service android:name=".ActivityTrackerService" >
</service>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
Has anybody tried using the com.google.android.gms.common.api.GoogleApiClient to request for ActivityUpdates using ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates or Is there some othe rway to use GoogleApiClient to request activity updates ??
I had the same problem, and even with explicit intent the onHandleIntent() would not be called.
I found that onStartCommand was called however, and could get around it by setting and checking the intent action.
It is not an explanation or solutions per se, but at least a workaound ;)
you should write your project's gradle (app)
dependencies{
compile 'com.google.firebase:firebase-appindexing:11.8.0'
....
}
then add libraries and import.
I have Developing Application of Full Caller Id. In that dynamic screen call at the time of Incoming call / After Missed Call. Now this is work one time. When i received call. Than after it is not work or Not call any dynamic screen at the time Incoming call/ Missed call.
I have very confuse about my problem.
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.v("idle state", "CALL_STATE_IDLE");
// CALL_STATE_IDLE;
if(ring == true && callReceived == true && CheckMissCall.isReject == true)
{
Intent inter = new Intent(c, callLog.class);
inter.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
c.startActivity(inter);
}
if (ring == true && callReceived == false && CheckMissCall.isRunning== false) {
Log.v("missed call", "Missed call from : " + incomingNumber);
if(CheckMissCall.isShown)
{
c.stopService(new Intent(c, Unlock_hud.class));
}
flag = true;
if (prefs.getBoolean("main_state", true))
{
Intent inter = new Intent(c, MissCall.class);
inter.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
inter.putExtra("CellNumber", incomingNumber);
c.startActivity(inter);
}
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// CALL_STATE_OFFHOOK;
callReceived = true;
Log.v("call received", "CALL_STATE_OFFHOOK " + incomingNumber);
break;
case TelephonyManager.CALL_STATE_RINGING:
ring = true;
// CALL_STATE_RINGING
Log.v("call ringing", "CALL_STATE_RINGING " + incomingNumber);
Log.d("flags", "flags: " + flag);
if (flag) {
//cut = true;
//flag = false;
CheckMissCall call = new CheckMissCall(c);
call.setName(incomingNumber);
call.setNumber4Sms(incomingNumber);
call.setContactPhoto();
Log.d("main", "state ringing");
//prefs = PreferenceManager.getDefaultSharedPreferences(c);
if (!prefs.getBoolean("main_state", false)) {
return;
}
/* if (!isScreenOn && CheckMissCall.isRunning) {
return;
}*/
if (CheckMissCall.isRunning) {
return;
}
else {
Log.d("main", "EEEEEEEEEEEEEEEE: Unlock hud");
Intent in = new Intent(c, Unlock_hud.class);
in.setFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
c.startService(in);
// c.stopService(new Intent(c, Unlock_hud.class));
}
}
break;
}
this is because when any call comes your app goes into background, while for the first time when you receive call your MyPhoneStateListener listens for the call and it ends..
now do one thing.. Run your code in service it will run in background and it will call your dynamic screen
in your main activity start service for this i have used toggle button(to enable or disable service)
tgl_switch.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(tgl_switch.isChecked()){
startService(new Intent(getApplicationContext(),LogsService.class));
Toast.makeText(getApplicationContext(), "Call Logger Active",
Toast.LENGTH_SHORT).show();
}else{
stopService(new Intent(getApplicationContext(),LogsService.class));
Toast.makeText(getApplicationContext(), "Call Logger Deactive",
Toast.LENGTH_SHORT).show();
}
}});
for example i did this
public class LogsService extends Service {
String name;
String phNumber;
String callType;
String callDate;
Date callDayTime;
String callDuration;
String dir ;
String fileName;
boolean wasRinging=false, wasoffHook=false, wasidle=false;
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, Intent intent) {
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)) {
// This code will execute when the phone has an incoming call
Log.d("ring ", "Detected");
wasRinging = true;
// get the phone number
// String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
// Toast.makeText(context, "Call from:" +incomingNumber, Toast.LENGTH_LONG).show();
} else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_OFFHOOK)){
wasoffHook=true;
// Toast.makeText(context, "hang up", Toast.LENGTH_LONG).show();
}
else if(intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_IDLE)) {
// This code will execute when the call is disconnected
wasidle=true;
// Toast.makeText(context, "IDLE STATE", Toast.LENGTH_LONG).show();
if((wasRinging && wasoffHook && wasidle)){
// this is received call event
startActivity(new Intent(getApplicationContext(), Incoming.class));
} else if(wasRinging && wasidle){
// this is missed call event
startActivity(new Intent(getApplicationContext(), MissCall.class));
}
wasidle = false;
wasoffHook = false;
wasRinging=false;
}
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
IntentFilter filter = new IntentFilter();
filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(receiver, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(receiver);
}
}
i used this code to get details of last call you can modify it in your way