Android Background Wifi Scanning Foreground Service - java

I am trying to scan Wifi every 10 seconds. I have produced an Android Foreground service to achieve this. The application has all of the right permissions and does get the list of local Wifi hotspots. However, it does this once. I have tried to implement a thread to do this every 10 seconds, as can be seen in the code below. The Log.d() message is logged every 10 seconds but the Wifi is not printed after the first time it is printed.
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.IBinder;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class ForegroundService extends Service {
private WifiManager wifiManager;
public static final String CHANNEL_ID = "ForegroundServiceChannel";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_stat_name)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
//do heavy work on a background thread
wifiManager = (WifiManager) getApplicationContext().getSystemService(getApplicationContext().WIFI_SERVICE);
if (!wifiManager.isWifiEnabled()) {
//Toast.makeText(this, "WiFi is disabled ... We need to enable it", Toast.LENGTH_LONG).show();
wifiManager.setWifiEnabled(true);
}
registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
new Thread(new Runnable() {
#Override
public void run() {
Looper.prepare();
while (true) {
Log.d("Test","00000000000000");
scanWifi();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
//stopSelf();
return START_NOT_STICKY;
}
private void scanWifi() {
wifiManager.startScan();
Toast.makeText(this, "Scanning WiFi ...", Toast.LENGTH_SHORT).show();
}
BroadcastReceiver wifiReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
List<ScanResult> results = wifiManager.getScanResults();
unregisterReceiver(this);
for (ScanResult scanResult : results) {
Log.d("WIFI",scanResult.SSID + " - " + scanResult.capabilities);
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
}

I think you should remove unregisterReceiver(this); from onRecieve and place it onDestroy()

public class NetworkStateChecker {
public static int TYPE_WIFI = 1;
public static int TYPE_MOBILE = 2;
public static int TYPE_NOT_CONNECTED = 0;
public static int getConnectivityStatus(Context context) {
try {
TimeUnit.SECONDS.sleep(10); // Sleeps 10 seconds.
} catch (InterruptedException e) {
e.printStackTrace();
}
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork!=null) {
if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
return TYPE_WIFI;
if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
return TYPE_MOBILE;
}
return TYPE_NOT_CONNECTED;
}
public static String getConnectivityStatusString(Context context) {
int conn = NetworkStateChecker.getConnectivityStatus(context);
String status = null;
if (conn == NetworkStateChecker.TYPE_WIFI) {
status = "Wifi enabled";
} else if (conn == NetworkStateChecker.TYPE_MOBILE) {
status = "Mobile data enabled";
} else if (conn == NetworkStateChecker.TYPE_NOT_CONNECTED) {
status = "Not connected to Internet";
}
return status;
}
}
use the above class to check the available network connections for every 10sec...
Next in broadcase reciever tyr the below code
String status = NetworkStateChecker.getConnectivityStatusString(context);
use the below permissions
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
..............
<receiver
android:name="in.phoenix.services.NetworkChangeReceiver"
android:label="NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
</intent-filter>
</receiver>

Related

java.lang.ClassCastException: com.example.BellasHBG.LocationService cannot be cast to com.google.android.gms.location.LocationListener

I'm getting
java.lang.ClassCastException: com.example.BellasHBG.LocationService cannot be cast to com.google.android.gms.location.LocationListener
but I don't know how to resolve. Removing keyword abstract does not fix the problem. This is new to me, and I'm not that knowledgeable of java so any help is appreciated. The error seems top be occurring in LocationService on the following line: LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mlocationRequest, (com.google.android.gms.location.LocationListener) this);
The intent is to get location updates and send a notification to the app user if the location sells this particular bakery product.
Below are my MainActivity, LocationService and AndroidManifest.xml
MainActivity
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.view.KeyEvent;
import android.webkit.WebViewClient;
import android.widget.TextView;
import com.google.android.gms.location.LocationRequest;
//import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private WebView webView = null;
public static boolean orignotifsetting = false;
//PendingIntent pendingIntent;
private Alarm alarm;
MyToolBox mtools = new MyToolBox();
LocationIntentService mLocationIntentService = new LocationIntentService();
public LocationManager mlocManager;
//LocationListener mlocListener = new MyLocationListener();
//LocationManager mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//public static GoogleApiClient mGoogleApiClient;
private Location mCurrentLocation;
LocationRequest mLocationRequest;
PendingIntent resultPendingIntent;
public Intent resultIntent = new Intent();
LocationServiceImpl mLocationService = new LocationServiceImpl();
public static boolean prevNotificationsSetting;
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.i("myTag", "in onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set the default values first time run but don't overwrite them if they have been set
// ----------------------------------------------------------------| - true will leave them alone, false will clear them every time
PreferenceManager.setDefaultValues(this, R.xml.pref_notification, true);
this.webView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
//myWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
//myWebView.setWebViewClient(new WebViewClient());
WebViewClientImpl webViewClient = new WebViewClientImpl(this);
webView.setWebViewClient(webViewClient);
webView.loadUrl("https://www.bellashbg.com");
mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && this.webView.canGoBack()) {
this.webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public void onResume() {
Log.i("myTag", "in onResume");
super.onResume();
Intent msgIntent = new Intent(MainActivity.this, LocationService.class);
if ((mtools.notificationsSetting(this)) & (prevNotificationsSetting == false)) {
prevNotificationsSetting = true;
startService(msgIntent);
}
else {
if ((!mtools.notificationsSetting(this)) & (prevNotificationsSetting == true)) {
// mLocationService.stopLocationUpdates();
prevNotificationsSetting = false;
boolean result = stopService(msgIntent);
if (result){
Log.d("MainActivity", "stopService true");
}
else {
Log.d("MainActivity", "stopService false");
}
//mLocationService.stopLocationUpdates();
//android.os.Process.killProcess(android.os.Process.myPid());
}
}
}
#Override
public void onPause() {
Log.i("myTag", "in onPause");
super.onPause();
}
#Override
public void onStop() {
Log.i("myTag", "in onStop");
super.onStop();
}
public void onDestroy() {
Log.i("myTag", "in onDestroy");
super.onDestroy();
//if (mSensorManager!=null){mSensorManager.unregisterListener(listener);}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.i("myTag", "in onCreateOptionsMenu");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.settings_menu, menu);
return super.onCreateOptionsMenu(menu); // cmnted 10/25/2015
//super.onCreateOptionsMenu(menu);
//return true;
// return true; stack overflow 6439085 says to return true to pop up menu
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.i("myTag", "in onOptionsItemSelected");
//LocationManager mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); //added 11/12/2015 to remove updates
switch (item.getItemId()) {
case R.id.settings:
Intent settingsintent = new Intent(MainActivity.this, SettingsActivity.class);
MainActivity.this.startActivity(settingsintent);
break;
case R.id.help:
break;
case R.id.about:
break;
}
return true;
}
// Get the notifications status bar setting
public boolean notificationsSettingNotificationBar() {
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean notificationsNewMessageNotificationBar = SP.getBoolean("notifications_new_message_notification_bar", true);
return notificationsNewMessageNotificationBar;
}
// Get the notifications ringtone
public String notificationsSettingRingtone() {
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String notificationsNewMessageRingtone = SP.getString("notifications_new_message_ringtone", "NULL");
return notificationsNewMessageRingtone;
}
// Get the notifications vibrate setting
public boolean notificationsNewMessageSetting() {
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean notificationNewMessageVibrate = SP.getBoolean("notifications_new_message_vibrate", true);
return notificationNewMessageVibrate;
}
private TextView latituteField;
private Context mContext;
}
LocationService
package com.example.BellasHBG;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import androidx.core.app.NotificationCompat;
import androidx.core.app.TaskStackBuilder;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
//import com.google.android.gms.location.LocationListener;
//import android.support.v7.app.AppCompatActivity;
//import android.support.v4.app.NotificationCompat;
//import android.support.v4.app.TaskStackBuilder;
//import com.google.android.gms.common.ConnectionResult;
//import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
//import com.google.android.gms.location.LocationListener;
//import com.google.android.gms.location.LocationRequest;
//import com.google.android.gms.location.LocationServices;
/**
* Created by craigmartensen on 4/7/16.
*/
public abstract class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 60000 * 1; // 1000 milliseconds in 1 second
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 5;
public static final long LOCATION_DISTANCE_IN_METERS = 3;
MyToolBox mtools = new MyToolBox();
public static GoogleApiClient mGoogleApiClient;
//public static GoogleSignInClient mSignInClient;
public static GoogleSignInAccount mSignInClient;
LocationRequest mlocationRequest;
private boolean isRemoving = false;
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#SuppressWarnings("static-access")
#Override
public void onCreate() {
isRemoving = false;
mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
//alarm.SetAlarm(this);
//return START_STICKY;
super.onStartCommand(intent, flags, startId);
//Toast.makeText(this, "onHandleIntent", Toast.LENGTH_SHORT).show();
//mGoogleApiClient.connect();
Log.d("onStartCommand", "Service Started");
return Service.START_STICKY;
}
#Override
public void onConnected(Bundle connectionHint) {
if (isRemoving) {
stopLocationUpdates();
}
else {
isRemoving = false;
mlocationRequest = new LocationRequest();
mlocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mlocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mlocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mlocationRequest.setSmallestDisplacement(LOCATION_DISTANCE_IN_METERS);
Intent locationIntent = new Intent(getApplicationContext(), LocationIntentService.class);
locationIntent.putExtra("ID", "FusedLcation");
PendingIntent locationPendingIntent = PendingIntent.getService(getApplicationContext(), 0, locationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mlocationRequest, locationPendingIntent);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mlocationRequest, (com.google.android.gms.location.LocationListener) this);
}
}
public void onLocationChanged(Location loc)
{
Log.d("onLocationChanged", "Entering method");
//Toast.makeText(this, "onLocationChanged", Toast.LENGTH_SHORT).show();
mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
//Toast.makeText(getApplicationContext(), "entering onLocationChanged", Toast.LENGTH_SHORT).show();
String myText;
double mlat = loc.getLatitude();
double mlong = loc.getLongitude();
DBHelper myDBHelper = new DBHelper(this);
// use the following line if you just want to know if the location is found ie, sells Bellas
//boolean soldHere = myDBHelper.doesLocationSellBellas("my_table",41.685471,-73.975393);
// the following line retrieves the name of the location that sells bellas, null if it's not found
//String locName = myDBHelper.getLocationName("my_table", 41.685471, -73.975393);
String locName = myDBHelper.getLocationName(DBHelper.LOCATION_TABLE_NAME, mlat, mlong);
// set up for notification in the notification status bar
if (locName != null) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Bella's sold here");
// .setStyle(new NotificationCompat.BigTextStyle().bigText("Bella's sold here"));
// .setSubText(todaysjolt);
// .setDefaults(Notification.DEFAULT_SOUND)
//.setContentText("Bella's sold here");
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mBuilder.setContentText(locName);
mBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(locName));
// new 10/14/2015 - set up to allow user to go to website from notification
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, MainActivity.class);
// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MainActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
// end new 10/14/2015
mNotifyMgr.notify(000, mBuilder.build());
Toast.makeText(getApplicationContext(), "You are at " + locName, Toast.LENGTH_SHORT).show();
//LocationManager mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
}
protected void startLocationUpdates() {
if (mtools.notificationsSetting(this)) {
MainActivity.orignotifsetting = true;
//LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
public void stopLocationUpdates() {
if(!mGoogleApiClient.isConnected()){
isRemoving = true; //added
mGoogleApiClient.connect();
}
else {
//if (mGoogleApiClient != null) {
// if (!mGoogleApiClient.isConnected()) {
PendingIntent locationPendingIntent = PendingIntent.getService(this, 0, new Intent(this, LocationIntentService.class), PendingIntent.FLAG_UPDATE_CURRENT);
//LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, locationPendingIntent); //moved below 1/28/2016
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, (com.google.android.gms.location.LocationListener) com.example.BellasHBG.LocationService.this);
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
stopSelf(); // stop the service
}
//}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Toast.makeText(this, "Connection Failed", Toast.LENGTH_SHORT).show();
}
#Override
public void onConnectionSuspended(int i) {
Log.d("LocationUpdateService", "Connection Suspended");
}
#Override
public void onDestroy(){
stopLocationUpdates();
//reportarGPS.interrupt();
//reportarGPS = null;
//LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, (com.google.android.gms.location.LocationListener) this);
//mGoogleApiClient.disconnect();
//mGoogleApiClient = null;
//mHandler.removeCallbacksAndMessages(null);
//Thread.currentThread().interrupt();
super.onDestroy();
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.BellasHBG">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="21"/>
<application
android:allowBackup="true"
android:icon="#drawable/bellas_logo_48x36"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.BellasHBG"
android:usesCleartextTraffic="true">
<activity
android:name="com.example.BellasHBG.SettingsActivity"
android:label="#string/action_settings"/>
<activity
android:name="com.example.BellasHBG.CreateNotificationOnBar"
android:label="create_notification_on_bar"/>
<activity
android:name="com.example.BellasHBG.CustomPreference"
android:label="custom_preference"/>
<activity
android:name=".MainActivity"
android:label="Bella's Home Baked Goods" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.example.BellasHBG.Alarm" />
<service android:enabled='true' android:name="com.example.BellasHBG.LocationService" />
</application>
</manifest>
Please uncomment the import for com.google.android.gms.location.LocationListener on LocationService and give a try again.

How to change firebase databse by connectivity status from background?

I tried to change database onDisconnect method.
I want to change the database when connectivity available from background.
For example,
Suppose currently i am in MainActivity and status is Online and in onPause and onDestroy it becomes offline. For my side it is not enough to set online/offline status.
For this i want
if i have connectivity (background and foreground) my status
is online
if i lost connectivity in the BACKGROUND, my status is offline. And whenever connectivity is available and app is in killed Mode, my status is online.
For this solution stackoverflow suggests me to use BroadCastReceiver, but i dont know how to use this class
We can easily do it by using a Service and a Broadcast Receiver simultaneously to get the output as you wish. This will work always i.e when app is running, app is minimized or when app is even removed from minimized apps.
1.Manifest Code :
<application
...
<service android:name=".MyService" />
</application>
2.MyService.java
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;
public class MyService extends Service {
static final String CONNECTIVITY_CHANGE_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
NotificationManager manager ;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (CONNECTIVITY_CHANGE_ACTION.equals(action)) {
//check internet connection
if (!ConnectionHelper.isConnectedOrConnecting(context)) {
if (context != null) {
boolean show = false;
if (ConnectionHelper.lastNoConnectionTs == -1) {//first time
show = true;
ConnectionHelper.lastNoConnectionTs = System.currentTimeMillis();
} else {
if (System.currentTimeMillis() - ConnectionHelper.lastNoConnectionTs > 1000) {
show = true;
ConnectionHelper.lastNoConnectionTs = System.currentTimeMillis();
}
}
if (show && ConnectionHelper.isOnline) {
ConnectionHelper.isOnline = false;
Log.i("NETWORK123","Connection lost");
//manager.cancelAll();
}
}
} else {
Log.i("NETWORK123","Connected");
showNotifications("APP" , "It is working");
// Perform your actions here
ConnectionHelper.isOnline = true;
}
}
}
};
registerReceiver(receiver,filter);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
3.ConnectionHelper.java
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class ConnectionHelper {
public static long lastNoConnectionTs = -1;
public static boolean isOnline = true;
public static boolean isConnected(Context context) {
ConnectivityManager cm =(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnected();
}
public static boolean isConnectedOrConnecting(Context context) {
ConnectivityManager cm =(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
}
}
4.Your Activity Code
startService(new Intent(getBaseContext(), MyService.class));
With this code, you will be able to check the connectivity when the app is onStart, On pause and even when the app is destroyed
You can use this method. It works fine for me.
DatabaseReference connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
boolean connected = snapshot.getValue(Boolean.class);
if (connected) {
Log.d("FirasChebbah", "connected");
} else {
Log.d("FirasChebbah", "not connected");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.w("FirasChebbah", "Listener was cancelled");
}
});

How to make an android app show notification even when it is closed

I want to make an app that shows a notification as soon as headphone is plugged in and remove it when it is plugged out. My app works fine when it is on or home button is pressed, but doesn't work when back is pressed or app is closed by long pressing home and swiping it away. What should I use in order to make it work?
This is my code
package com.example.earphone;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
public class HeadsetPlugReceiver extends BroadcastReceiver {
TextView t1;
#Override
public void onReceive(Context context, Intent intent) {
if (!intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
return;
}
boolean connectedHeadphones = (intent.getIntExtra("state", 0) == 1);
// boolean connectedMicrophone = (intent.getIntExtra("microphone", 0) == 1) && connectedHeadphones;
String headsetName = intent.getStringExtra("name");
Log.v("message", "headphone connected" + headsetName);
Intent i = new Intent(context, MainActivity.class);
PendingIntent p = PendingIntent.getActivity(context,0,i,0);
// Toast.makeText(context, "Headphone connected", Toast.LENGTH_SHORT).show();
if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
int state = intent.getIntExtra("state", -1);
if(state==1){
Intent intent1 = new Intent(context, ES.class);
context.startForegroundService(intent1);
}
switch (state) {
case 0:
Intent intent1 = new Intent(context, ES.class);
context.stopService( intent1);
Toast.makeText(context, "Headphone ejected", Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(context, "Headphone connected", Toast.LENGTH_SHORT).show();
break;
default:
Toast.makeText(context, "I have no idea what the headset state is", Toast.LENGTH_SHORT).show();
}
}
}}
package com.example.earphone;
import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
public class App extends Application {
public static final String C_ID = "noti";
#Override
public void onCreate() {
super.onCreate();
createnoti();
}
private void createnoti(){
if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){
NotificationChannel nc = new NotificationChannel(
C_ID,"ex", NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager nm= getSystemService(NotificationManager.class);
nm.createNotificationChannel(nc);
}
}
}
package com.example.earphone;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import static com.example.earphone.App.C_ID;
public class ES extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent ni = new Intent(this,HeadsetPlugReceiver.class);
PendingIntent pi = PendingIntent.getActivity(this,0,ni,0);
Notification notification = new NotificationCompat.Builder(this, C_ID)
.setContentTitle("Headphones plugged in")
.setContentText("currently plugged in")
.setSmallIcon(R.mipmap.ic_launcher).setContentIntent(pi).build();
startForeground(1,notification);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
public class MainActivity extends AppCompatActivity {
Button b;
HeadsetPlugReceiver headsetPlugReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b = findViewById(R.id.b);
// Intent intent = new Intent(this, ES.class);
//startService(intent);
headsetPlugReceiver = new HeadsetPlugReceiver();
IntentFilter i = new IntentFilter();
i.addAction("android.intent.action.HEADSET_PLUG");
registerReceiver(headsetPlugReceiver,i);
}
}

Using IntentService instead of AsyncTask for Broadcast Receiver?

I am in the process of trying to get an email sent using BroadcastReceiver, the code is working correct using AsyncTask when using onClick but does not work when AlarmReceiver is being called.
Would it be better to use IntentService for this method? If so, what is the best way to write this?
Can anyone help with this problem? I am still new to java and want to help improve my knowledge. :)
Any help would be appreciated! Thank you!
AlarmReceiver.java
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.content.BroadcastReceiver;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
import static android.graphics.Color.GREEN;
public class AlarmReceiver extends BroadcastReceiver {
Context cxt;
Activity context;
#Override
public void onReceive(Context arg0, Intent arg1) {
cxt = arg0;
addNotification();
new SendMail().execute();
}
private class SendMail extends AsyncTask<String, Integer, Void> {
protected Void doInBackground(String... params) {
Mail m = new Mail("youremail#gmail.com", "password");
String[] toArr = {"toemail#outlook.com"};
m.setTo(toArr);
m.setFrom("fromemail#gmail.com");
m.setSubject("Achieve Alert!");
m.setBody("This is a reminder about your upcoming assignment or examination!");
try {
if(m.send()) {
Toast.makeText(context.getApplicationContext(), "Email was sent successfully.", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context.getApplicationContext(), "Email was not sent.", Toast.LENGTH_LONG).show();
}
} catch(Exception e) {
Log.e("MailApp", "Could not send email", e);
}
return null;
}
}
}
First start Intent service from Alarm manager :
private void setAlarm(Calendar targetCal){
/* HERE */ Intent intent = new Intent(getBaseContext(), AlarmService.class);
final int _id = (int) System.currentTimeMillis();
/* HERE */ PendingIntent pendingIntent = PendingIntent.getService(this,_id,intent,PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
......
.....
Now Intent Service class:
public class AlarmService extends IntentService {
PowerManager powerManager;
PowerManager.WakeLock wakeLock;
public AlarmService() {
super("");
}
#Override
protected void onHandleIntent(Intent intent) {
powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "FCFCFCFC");
wakeLock.acquire();
addNotification();
sendMAIL();
}
public void addNotification() {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.icon_transperent)
.setLights(GREEN, 700, 700)
.setContentTitle("Achieve - Alert!")
.setContentText("This is a reminder for your deadline!");
Intent notificationIntent = new Intent(getApplicationContext(), MainMenu.class);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
// Add as notification
NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
builder.setVibrate(new long[] { 0, 1000, 1000, 1000, 1000 });
manager.notify(0, builder.build());
}
public void sendMAIL(){
Mail m = new Mail("youremail#gmail.com", "password");
String[] toArr = {"toemail#outlook.com"};
m.setTo(toArr);
m.setFrom("fromemail#gmail.com");
m.setSubject("Achieve Alert!");
m.setBody("This is a reminder about your upcoming assignment or examination!");
try {
if(m.send()) {
Toast.makeText(getApplicationContext(), "Email was sent successfully.", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Email was not sent.", Toast.LENGTH_LONG).show();
}
} catch(Exception e) {
Log.e("MailApp", "Could not send email", e);
}
wakeLock.release();
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
Now, Manifest add:
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<service android:name=".AlarmService" android:exported="true" android:enabled="true"/>

Service don't run like it should on real device

Problem is when I run service on emulator(android 4.0.3), then all is working(data is sent once per hour), but when i run it on my phone it's start sending data every minute. I can't figure out why, hope someone can help me with this.
The service is sending data to http://gprsbtn.herokuapp.com/coordinates where it's going to database.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.aravov.gprsbtn"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.aravov.gprsbtn.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="MyService"></service>
<receiver android:name=".AlarmReciever"/>
</application>
</manifest>
MainActivity.java
package com.aravov.gprsbtn;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
final String LOG_TAG = "myLogs";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void btnClc(View v) {
startService(new Intent(this, MyService.class));
Toast.makeText(this, "Service started", Toast.LENGTH_SHORT).show();
}
public void btnClc2(View v) {
stopService(new Intent(this, MyService.class));
}
}
GPSTracker.java
package com.aravov.gprsbtn;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
/**
* Stop using GPS listener
* Calling this function will stop using GPS in your app
* */
public void stopUsingGPS(){
if(locationManager != null){
locationManager.removeUpdates(GPSTracker.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
* #return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog
* On pressing Settings button will lauch Settings Options
* */
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS is settings");
// Setting Dialog Message
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing Settings button
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
MyService.java
package com.aravov.gprsbtn;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.json.JSONObject;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class MyService extends Service {
PendingIntent pendingIntent;
AlarmManager alarmManager;
BroadcastReceiver mReceiver;
final String LOG_TAG = "myLogs";
public void onCreate() {
super.onCreate();
Log.d(LOG_TAG, "onCreate");
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(LOG_TAG, "onStartCommand");
someTask();
sendNotif();
return super.onStartCommand(intent, flags, startId);
}
public void sendNotif() {
Notification notification = new Notification(R.drawable.ic_stat_gprsbtn, "Text in status bar",
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, "Notification's title", "Notification's text", pendingIntent);
startForeground(1992, notification);
}
public void onDestroy() {
stop();
super.onDestroy();
Log.d(LOG_TAG, "onDestroy");
}
public IBinder onBind(Intent intent) {
Log.d(LOG_TAG, "onBind");
return null;
}
void someTask() {
mReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
action();
}
};
registerReceiver(mReceiver, new IntentFilter("gprs.post"));
pendingIntent = PendingIntent.getBroadcast( this, 0, new Intent("gprs.post"),0 );
alarmManager = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
// timer here <<< 1000 * 60 = 1 minute
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000, 1000 * 60 * 60 , pendingIntent);
}
public void action() {
GPSTracker gps = new GPSTracker(MyService.this);
//final double latitude = gps.getLatitude();
//final double longitude = gps.getLongitude();
final String lat = Double.toString(gps.latitude);
final String lon = Double.toString(gps.longitude);
// check if GPS enabled
if(gps.canGetLocation())
{
//posting
Thread t = new Thread(){
public void run(){
postData(lat, lon);
}
};
t.start();
}
else
{
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
}
}
public void postData(String latitude, String longitude) {
try {
HttpParams p = new BasicHttpParams();
HttpClient client = new DefaultHttpClient(p);
HttpPost post = new HttpPost("http://gprsbtn.herokuapp.com/coordinates");
JSONObject params = new JSONObject();
params.put("latitude",latitude);
params.put("longitude",longitude);
StringEntity ent = new StringEntity(params.toString());
post.setEntity(ent);
post.setHeader("Content-type", "application/json");
client.execute(post);
Log.d(LOG_TAG, "onDataSent");
} catch (Exception e) {
e.printStackTrace();
}
}
// stop the alarm receiver
public void stop() {
try {
unregisterReceiver(mReceiver);
Toast.makeText(this, "Service stoped", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
}
}
}

Categories

Resources