i'm making a service
which works perfactly well so far,
but everytime the phone restarts, the service is lost,
how do i make the service restart every time the phone shuts off, and turns back on again , (if it was running out of battery, or if user has done a restart)
is there a simple way of making it ?
this is my service >
package com.greenroad.candidate.mywallpaperchanger;
import android.app.Service;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by pitsponet on 31/08/2015.
*/
public class myService extends Service {
int oneSecond = 1000;
int oneMinute = oneSecond*60;
int oneHour = oneMinute*60;
int pictureNumberToChoos = 0;
boolean isTimerRunning = false;
int timerDeley = oneHour;
private Timer timer;
private TimerTask timerTask = new TimerTask() {
#Override
public void run() {
//this timer will run again in 10 seconds
Log.d("MyLog", "timer entered ");
//shows a toast saying timer has entered
Handler mainHandler = new Handler(getApplicationContext().getMainLooper());
mainHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "timer listener Entered", Toast.LENGTH_LONG).show();
}
});
//takes picture modifier and updates it to +1 then stores it at var > pictureModifireInt
// Access the default SharedPreferences
SharedPreferences pref = getApplicationContext().getSharedPreferences("myGlobalPrefTable", MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
//open a boolean to tell if the service is activated for the first time it will say false
Integer pictureModifireInt = pref.getInt("pictureModifire", 0);
pictureModifireInt++;
/////holds a list with all the images
int displayPicture = R.drawable.captain;
ArrayList<Integer> pictureNames = new ArrayList<>();
pictureNames.add(R.drawable.captain);
pictureNames.add(R.drawable.flash);
pictureNames.add(R.drawable.superman);
pictureNames.add(R.drawable.thor);
pictureNames.add(R.drawable.wonder);
pictureNames.add(R.drawable.a);
pictureNames.add(R.drawable.b);
pictureNames.add(R.drawable.c);
pictureNames.add(R.drawable.d);
pictureNames.add(R.drawable.e);
pictureNames.add(R.drawable.f);
pictureNames.add(R.drawable.g);
pictureNames.add(R.drawable.h);
pictureNames.add(R.drawable.i);
pictureNames.add(R.drawable.j);
pictureNames.add(R.drawable.k);
pictureNames.add(R.drawable.l);
pictureNames.add(R.drawable.m);
pictureNames.add(R.drawable.n);
pictureNames.add(R.drawable.o);
//logs the stored prefrence and select the correct image at place > picture modifire
Log.d("myLog", "storedPreference: " + pictureModifireInt);
displayPicture = pictureNames.get(pictureModifireInt-1);
if(pictureModifireInt > 19){
// Edit the saved preferences
Log.d("myLog", "putting in pictureModifire : : " + 0);
editor.putInt("pictureModifire", 0); // getting String
editor.commit();
} else {
Log.d("myLog", "putting in pictureModifire : : " + pictureModifireInt);
editor.putInt("pictureModifire", pictureModifireInt); // getting String
editor.commit();
}
///////////////////////////start of wallpaper implemintation
WindowManager wm= (WindowManager) getSystemService(MainActivity.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Bitmap bmap2 = BitmapFactory.decodeResource(getResources(), displayPicture);
Bitmap bitmap = Bitmap.createScaledBitmap(bmap2, width, height, true);
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
wallpaperManager.setBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
//////////////////////////end of wallpaper implementation
mainHandler = new Handler(getApplicationContext().getMainLooper());
final Integer finalPictureModifireInt = pictureModifireInt-1;
mainHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "wallpaper changed to : "+ finalPictureModifireInt+" and started a new timer", Toast.LENGTH_LONG).show();
}
});
}
};
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(getApplicationContext(), "a new service created",
Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyLog", "a new service started");
final Handler mainHandler = new Handler(getApplicationContext().getMainLooper());
mainHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "serviceStarterd", Toast.LENGTH_LONG).show();
// Access the default SharedPreferences
SharedPreferences pref = getApplicationContext().getSharedPreferences("myGlobalPrefTable", MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
//open a boolean to tell if the service is activated for the first time it will say false
boolean serviceStateOn = pref.getBoolean("isServiceActivated", false);
if(serviceStateOn == false){
// Edit the saved preferences
Toast.makeText(getApplicationContext(), "a New Timer Started with Delay: "+timerDeley, Toast.LENGTH_LONG).show();
editor.putBoolean("isServiceActivated", true); // getting String
editor.commit();
timer = new Timer();
timer.scheduleAtFixedRate(timerTask, timerDeley, timerDeley);
} else {
Log.d ("myLog", "Service is on so do nothing");
}
}
});
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getApplicationContext(), "service stoped",
Toast.LENGTH_LONG).show();
}
}
and this is my Manifest >
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.greenroad.candidate.mywallpaperchanger" >
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".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"
android:exported="false"
/>
</application>
</manifest>
THANKX EVERYONE IN ADVANCe ! "_
i wouldn't know how to live without this site lol..
You need to make a receiver which will listen to intent.Boot complete.
And then in on receive(), you can start your service.
You need to add Receiver Class.
Add below permission in AndroidManifest.xml file.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Add below statements in Application Tag in AndroidManifest.xml
<receiver android:name=".YourBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter></receiver>
YourBroadcastReceiver.java
package com.test;
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, MyService.class);
context.startService(startServiceIntent);
}
}
Related
I'm building an Android Wear service which runs in the background and logs device data every three minutes. For this logging, I am using a Handler, which records the values and then has an interval of three minutes. This will be used to monitor user behaviour for one month, and as such it should not randomly stop.
I have also used android.intent.action.BOOT_COMPLETED in my manifest and this successfully runs the application whenever the watch is booted.
My issue is that the service can run correctly for 12 hours...and then just suddenly stop. The amount of time appears to be non-deterministic, as sometimes it will stop after 40 minutes. I suspect it's being killed by Android, but in this case I would like it to restart. I have included return START_STICKY in my service and this should minimise the chance of it being killed.
In some solutions, I have seen onDestroy() overridden and a refresh broadcast being sent to the service. While this appears to work, the onDestroy() function is being called every time the Handler completes one piece of work. This leads to the service restarting every three minutes, rather than when the application is actually killed by Android.
I have also looked at the intent actions to see whether my service could be called at regular intervals. However, aside from android.intent.action.BOOT_COMPLETED, all the useful ones cannot be registered in the Manifest file. Since the service will not be running, registerReceiver() would serve little purpose.
Does anybody know of a technique to either a) guarantee a service will not be killed by Android; or b) guarantee that a service will always be restarted after it has been killed. Any help would be greatly appreciated, as I've even started considering writing a Cron job on the device and setting it to execute my app every three minutes! I've also looked at the AlarmManager class, but I fear it is as likely to be killed if running for long periods.
Please find my code below: (AndroidManifest.xml)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.study">
<uses-feature android:name="android.hardware.type.watch" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#android:style/Theme.DeviceDefault">
<receiver android:name="com.example.study.MyServiceManager" android:enabled="true">
<intent-filter>
<action android:name="com.example.study.RestartAction" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<activity
android:name="com.example.study.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="com.example.study.RecordService"
android:exported="false" />
</application>
</manifest>
RecordService.java
package com.example.study;
import android.Manifest;
import android.app.AlarmManager;
import android.app.IntentService;
import android.app.KeyguardManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import com.google.android.gms.location.LocationServices;
import android.os.Build;
import android.os.Handler;
import android.os.PowerManager;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.text.TextUtils;
import com.google.android.gms.location.*;
import com.google.android.gms.tasks.OnSuccessListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class RecordService extends IntentService {
private static Context context;
private final static int INTERVAL = 1000 * 5; // 1 minutes
Handler handler = new Handler();
Location myLocation;
private FusedLocationProviderClient mFusedLocationClient;
SensorManager sensorManager;
SensorManager gyroSensorManager;
SensorManager compassSensorManager;
SensorEventListener sensorEventListener;
float[] accValues;
float[] gyroValues;
float[] compassValues;
Runnable handlerTask = new Runnable() {
#Override
public void run() {
try {
recordData();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.postDelayed(handlerTask, INTERVAL);
}
};
public RecordService() {
super("RecordService");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
handlerTask.run();
}
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
public void recordData() throws ExecutionException, InterruptedException {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(MainActivity.getAppContext());
boolean fineLocationGranted = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
boolean coarseLocationGranted = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
boolean isLocationEnabled = isLocationEnabled(this);
if(fineLocationGranted && coarseLocationGranted && isLocationEnabled) {
long startTime = System.currentTimeMillis();
long timeWaiting = 0L;
mFusedLocationClient.getLastLocation()
.addOnSuccessListener(MainActivity.getActivity(), new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if (location != null) {
myLocation = location;
} else {
System.out.print("");
}
}
});
do {
timeWaiting = System.currentTimeMillis() - startTime;
} while (myLocation == null && timeWaiting < 200);
}
List<PackageInfo> packages = getPackageManager().getInstalledPackages(PackageManager.GET_PERMISSIONS);
KeyguardManager kg = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
boolean isLocked = kg.isDeviceSecure();
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
gyroSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
compassSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorEventListener = new SensorEventListener() {
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
if(sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
accValues = sensorEvent.values;
} else if(sensorEvent.sensor.getType() == Sensor.TYPE_GYROSCOPE){
gyroValues = sensorEvent.values;
} else if(sensorEvent.sensor.getType() == Sensor.TYPE_ORIENTATION) {
compassValues = sensorEvent.values;
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {}
};
try {
sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
gyroSensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_NORMAL);
compassSensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL);
} catch(SecurityException e) {
e.printStackTrace();
}
long startTime2 = System.currentTimeMillis();
long timeWaiting2 = 0L;
do {
timeWaiting2 = System.currentTimeMillis() - startTime2;
} while((accValues == null || gyroValues == null || compassValues == null) && timeWaiting2 < 200);
StringBuilder builder = new StringBuilder();
builder.append("G" + (isLocationEnabled ? 1 : 0));
builder.append(" L" + (isLocked ? 1 : 0));
if(accValues != null && gyroValues != null && compassValues != null) {
builder.append(" ACX" + accValues[0]);
builder.append(" ACY" + accValues[1]);
builder.append(" ACZ" + accValues[2]);
builder.append(" GYX" + gyroValues[0]);
builder.append(" GYY" + gyroValues[1]);
builder.append(" GYZ" + gyroValues[2]);
builder.append(" CMX" + gyroValues[0]);
builder.append(" CMY" + gyroValues[1]);
builder.append(" CMZ" + gyroValues[2]);
}
if(myLocation != null) {
builder.append(" LT" + myLocation.getLatitude());
builder.append(" LN" + myLocation.getLongitude());
}
builder.append("\n");
for(PackageInfo info: packages) {
int lastDot = info.packageName.lastIndexOf('.');
builder.append(info.packageName + "\n");
if(info.requestedPermissions != null) {
for (String rqprm : info.requestedPermissions) {
int dot = rqprm.lastIndexOf('.');
builder.append(rqprm.substring(dot != -1 ? dot + 1 : 0) + " ");
}
builder.append("\n");
for (int permflag : info.requestedPermissionsFlags) {
builder.append("" + permflag + " ");
}
builder.append("\n");
}
}
SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd--HH-mm-ss");
String currentDateString = sdf.format(new Date());
File log = new File("/sdcard/Recordings/" + currentDateString);
try {
if (!log.exists()) {
log.createNewFile();
}
BufferedWriter writer = new BufferedWriter(new FileWriter(log, true));
writer.append(builder.toString());
writer.newLine();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static boolean isLocationEnabled(Context context) {
int locationMode = 0;
String locationProviders;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
try {
locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
return false;
}
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
} else {
locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
return !TextUtils.isEmpty(locationProviders);
}
}
MainActivity.java
package com.example.study;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView mTextView;
private static Context context;
private static MainActivity activity;
Intent serviceIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainActivity.context = getApplicationContext();
activity = this;
serviceIntent = new Intent(this, RecordService.class);
startForegroundService(serviceIntent)
startService(serviceIntent);
}
public static Context getAppContext() {
return MainActivity.context;
}
public static MainActivity getActivity() {
return activity;
}
}
MyServiceManager.java
package com.example.study;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
public class MyServiceManager extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, MainActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
}
}
}
I am basically working with Android Application , i have requirement to restrict to open others apps while my app is running, Means My app is running it will put some locks on other application while i am accessing the others app, Kind of Application Lock. I am trying but could not find good solution. If any buddy have some idea or link or sample code please share to me.
Basically you want Kiosk Mode .
Try this:
Home button press:
<category android:name="android.intent.category.HOME" /> //add in manifest
What id does: whenever you press the home button, all the applications installed in your phone which have category.HOME category in intent-filter in their AndroidManifest.xml will be listed .
then handle Long press Home Button:
#Override
protected void onPause() {
super.onPause();
ActivityManager activityManager = (ActivityManager) getApplicationContext()
.getSystemService(Context.ACTIVITY_SERVICE);
activityManager.moveTaskToFront(getTaskId(), 0);
}
for this add this line in manifest :
<uses-permission android:name="android.permission.REORDER_TASKS" />
3.handle BackButton :
#Override
public void onBackPressed() {
// Stop user to exit
// super.onBackPressed();
}
You can also try this for Kiosk Mode:
Read this document
import android.app.ActivityManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.provider.SyncStateContract;
import android.util.Log;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
public class HeartBeat extends Service {
private static final String TAG = HeartBeat.class.getSimpleName();
public Timer TIMER;
// private static Set<AccessGranted> mAccessGrantedList = new HashSet<AccessGranted>();
private Set<String> mLockedApps = new HashSet<String>();
private long lastModified = 0;
private BroadcastReceiver mScreenStateReceiver;
// private BroadcastReceiver mAccessGrantedReceiver;
private File mLockedAppsFile;
ArrayList<String> packagezList;
SharedPreferences sharedPrefs;
Map<String, ?> allEntries;
SharedPreferences sharedPrefsapp;
String prefix;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startService(new Intent(this, HeartBeat.class));
Log.i("LocalService", "Received start id " + startId + ": " + intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
if (TIMER == null) {
TIMER = new Timer(true);
TIMER.scheduleAtFixedRate(new LockAppsTimerTask(), 1000, 250);
mScreenStateReceiver = new BroadcastReceiver() {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
if (screenOff) {
//Log.i(TAG, "Cancel Timer");
TIMER.cancel();
} else {
// Log.i(TAG, "Restart Timer");
TIMER = new Timer(true);
TIMER.scheduleAtFixedRate(new LockAppsTimerTask(), 1000, 250);
}
}
};
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mScreenStateReceiver, filter);
}
// this.stopSelf();
//startforeground goes here
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
startService(new Intent(this, HeartBeat.class));
}
private class LockAppsTimerTask extends TimerTask {
#Override
public void run() {
sharedPrefs = getApplicationContext().getSharedPreferences(getApplicationContext().getPackageName(), Context.MODE_PRIVATE);
sharedPrefsapp = getApplicationContext().getSharedPreferences("appdb", Context.MODE_PRIVATE);
allEntries= null;
allEntries = sharedPrefsapp.getAll();
Set keySet = allEntries.keySet();
Iterator<String> keySetIter = keySet .iterator();
while (keySetIter.hasNext()) {
String keyEntry= keySetIter.next();
Log.e("Shared Vaues",keyEntry);
}
//prefix = "m";
packagezList= null;
packagezList = new ArrayList<String>();
for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
packagezList.add(entry.getKey());
Log.e("right key: ", entry.getKey().toString() + "right value: " + entry.getValue().toString());
}
/* for (Map.Entry<String, ?> entry : allEntries.entrySet())
{
//Check if the package name starts with the prefix.
if (entry.getKey().startsWith(prefix)) {
//Add JUST the package name (trim off the prefix).
packagezList.add(entry.getKey().substring(prefix.length()));
packagezList.add(entry.getKey());
}
}*/
for(Object object: packagezList){
Log.e("YO!", (String) object);
}
ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
try {
//List<RecentTaskInfo> recentTasks = activityManager.getRecentTasks(1, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> RunningTask = mActivityManager
.getRunningTasks(1);
ActivityManager.RunningTaskInfo ar = RunningTask.get(0);
String activityOnTop = ar.topActivity.getPackageName();
Log.e("activity on Top", "" + activityOnTop);
Log.e(" My package name", "" + getApplicationContext().getPackageName());
//for (Object data : newArrayList) {
for(Object object: packagezList){
// Provide the packagename(s) of apps here, you want to show password activity
if (!activityOnTop.contains(getApplicationContext().getPackageName()))
// if(!activityOnTop.contains(getApplicationContext().getPackageName()))
{ // you have to make this check even better
Intent i = new Intent(getApplicationContext(), LockScreenActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
i.putExtra( "", "");
startActivity(i);
}
}
} catch (Exception e) {
Log.e("Foreground App", e.getMessage(), e);
}
}
}
I coded an application to record user's location periodically (in the background). I used ActivityRecognitionClient. When activity is received it is compared to previous activity state and is recorded (or not) according to evaluation.
It's working as intended as long as my phone is awake. (log messages appear periodically in LogCat view on eclipse) Whenever screen goes off and device goes into stand by status it stops receiving activity recognition calls. On the other hand, I installed the app on my tablet too, and it keeps updating even the device goes into stand by status. (My phone is General Mobile Discovery btw)
I've been searching web (including stackoverflow questions) for 3 days and haven't been able to find anything that works for me so far. I'd appreciate any help... Thanks...
Following is my applications related code:
AndroidManifest.xml (some permissions are there even if not needed, they are probably leftovers from unsuccessful trials to fix the issue)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.o3n.android.familywathcer"
android:installLocation="internalOnly"
android:versionCode="2"
android:versionName="1.0.1" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<permission android:name="org.o3n.android.familywathcer.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
<uses-permission android:name="org.o3n.android.familywathcer.permission.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="***maps api key *****"/>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name="org.o3n.android.familywathcer.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>
<activity android:label="Settings" android:name=".SettingsActivity">
<intent-filter>
<action android:name="org.o3n.android.familywatcher.SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service android:enabled="true" android:name=".FamilyWatcherService" />
<service android:name=".ActivityRecognitionService" />
<receiver android:name=".StartFamilyWatcherServiceAtBootReceiver"
android:enabled="true"
android:exported="true"
android:label="StartFamilyWatcherServiceAtBootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
StartFamilyWatcherServiceAtBootReceiver.java (This receiver starts the FamilyWatcherService.java on device boot, also applications MainActivity.java class calls the FamilyWatcherService so it starts running when first installed.)
public class StartFamilyWatcherServiceAtBootReceiver extends BroadcastReceiver {
private static final String TAG = "o3nWatcherLog";
#Override
public void onReceive(Context context, Intent intent) {
//Toast.makeText(context, "StartFamilyWatcherServiceAtBootReceiver called", Toast.LENGTH_SHORT).show();
Log.d(TAG, "StartFamilyWatcherServiceAtBootReceiver onRecieve");
SettingsRetriever.getInstance(context);
Intent serviceIntent = new Intent(context, FamilyWatcherService.class);
context.startService(serviceIntent);
}
}
FamilyWatcherService.java (This service connects to ActivityRecognitionClient and registers a PendingIntend to be called with activity updates. When it works ActivityRecognitionService.onHandleIntend() method is called)
public class FamilyWatcherService extends Service implements ConnectionCallbacks, OnConnectionFailedListener {
private int period;
private static ActivityRecognitionClient arclient;
private static PendingIntent pIntent;
private static AlarmManager alarmManager;
private static PendingIntent alarmPI;
private static final String TAG = "o3nWatcherLog";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Log.d(TAG, "FamilyWatcherService onCreate");
period = SettingsRetriever.getInstance().getPeriod() * 60 * 1000;
}
#Override
public void onDestroy() {
Log.d(TAG, "FamilyWatcherService onDestroy");
if(arclient!=null){
arclient.removeActivityUpdates(pIntent);
arclient.disconnect();
}
}
#Override
public void onStart(Intent intent, int startid) {
Log.d(TAG, "FamilyWatcherService onStart");
processStart();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "FamilyWatcherService onStartCommand");
processStart();
return Service.START_STICKY;
}
public void processStart() {
int result = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (result != ConnectionResult.SUCCESS) {
Log.d("o3nWatcherLog", "Google Play service is not available (status=" + result + ")");
}
else{
arclient = new ActivityRecognitionClient(getApplicationContext(), this, this);
arclient.connect();
}
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
Log.d("o3nWatcherLog","Google activity recognition services connection failed");
}
#Override
public void onConnected(Bundle arg0) {
Log.d("o3nWatcherLog", "FamilyWathcerService onConnected method called...");
Intent intent = new Intent(this, ActivityRecognitionService.class);
pIntent = PendingIntent.getService(getApplicationContext(), 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
arclient.requestActivityUpdates(period, pIntent);
}
#Override
public void onDisconnected() {
Log.d("o3nWatcherLog", "Google activity recognition services disconnected");
}
}
ActivityRecognitionService.java (This service's onHandleIntent() method is called by Activity Recognition updates)
package org.o3n.android.familywathcer;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.location.ActivityRecognitionResult;
import com.google.android.gms.location.DetectedActivity;
import com.google.android.gms.location.LocationClient;
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
public class ActivityRecognitionService extends IntentService implements ConnectionCallbacks, OnConnectionFailedListener {
private String TAG = "o3nWatcherLog";
private Context context;
private static int activityEvaluation = 0;
//TODO MAKE THESE PREFERENCES
private static final int MIN_RECORD_DISTANCE = 750;
private static final int MIN_RECORD_INTERVAL = 10 * 1000 * 60;
private static final int MIN_POST_INTERVAL = 2 * 1000 * 60;
//END MAKE THESE PREFERENCES
private LocationClient locationClient;
private static Location lastRecordedLocation;
private static int previousActivityCode = DetectedActivity.UNKNOWN;
private int activityCode = -1000;
private int activityConfidence = -1000;
public ActivityRecognitionService() {
super("My Activity Recognition Service");
}
#Override
protected void onHandleIntent(Intent intent) {
if(ActivityRecognitionResult.hasResult(intent)){
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
Log.i(TAG, getType(result.getMostProbableActivity().getType()) +"t" + result.getMostProbableActivity().getConfidence());
this.context = getApplicationContext();
Log.d("o3nWatcherLog", "ActivityRecognitionService onHandleIntent called...");
activityConfidence = result.getMostProbableActivity().getConfidence();
activityCode = result.getMostProbableActivity().getType();
Log.d("o3nWatcherLog", " ACTIVITY CODE : " + activityCode + " ACTIVITY CONFIDENCE : " + activityConfidence);
// Evaluate the avtivity recognition result
evaluateActivityResult();
// Get current location
// check Google Play service APK is available and up to date.
final int googlePlayServiceAvailable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context);
if (googlePlayServiceAvailable != ConnectionResult.SUCCESS) {
Log.d("o3nWatcherLog", "Google Play service is not available (status=" + result + ")");
}
else {
locationClient = new LocationClient(context, this, this);
locationClient.connect();
}
}
}
// This method is only used in a log line to have readable status in logs
private String getType(int type){
if(type == DetectedActivity.UNKNOWN)
return "UNKNOWN";
else if(type == DetectedActivity.IN_VEHICLE)
return "IN_VEHICLE";
else if(type == DetectedActivity.ON_BICYCLE)
return "ON_BICYCLE";
else if(type == DetectedActivity.ON_FOOT)
return "ON_FOOT";
else if(type == DetectedActivity.STILL)
return "STILL";
else if(type == DetectedActivity.TILTING)
return "TILTING";
else
return "";
}
private void evaluateActivityResult() {
// (Based on previousActivityCode and current activityCode
// assign a value to activityEvaluation)
// compare activityCode to previousActivityCode
activityEvaluation = ...;
previousActivityCode = activityCode;
}
private void actOnEvaluation(Location loc) {
// Based on activityEvaluation decide to post or not
if ( activityEvaluation ....)
prepareTheLocationJsonAndRecord(loc);
}
private void prepareTheLocationJsonAndRecord(Location loc) {
// Record the location
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
//Toast.makeText(context, "Google location services connection failed", Toast.LENGTH_LONG).show();
Log.d("o3nWatcherLog","Google location services connection failed");
}
#Override
public void onDisconnected() {
//Toast.makeText(context, "Google location services disconnected", Toast.LENGTH_LONG).show();
Log.d("o3nWatcherLog", "Google location services disconnected");
}
#Override
public void onConnected(Bundle arg0) {
//Toast.makeText(context, "Google location services connected", Toast.LENGTH_LONG).show();
Log.d("o3nWatcherLog", "Google location services connected");
Location loc = locationClient.getLastLocation();
Log.d("o3nWatcherLog", "location= " + loc.toString());
if (loc!=null)
actOnEvaluation(loc);
}
}
I assume you need to set up some Power Wake lock to make phone to process GPS locations even in "sleep" mode. Like WiFi lock, etc. When I did something like that I used:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm!=null){
pmWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK+PowerManager.ON_AFTER_RELEASE, APP_TAG);
pmWakeLock.acquire();
}
But that was inside of a GPS-tracking activity. You need to alter params of newWakeLock for your needs. Maybe the service you are using has some code about it so you just need to declare using of WakeLock permission in the Manifest first.
I have a problem that when I run my Android App which has Broadcast Receiver for WiFi. it perform differently on different version of Android OS (Like 4.1.1 and 4.2.2).
When I run it on 4.1.1 it works perfect like Broadcast receiver receive the Broad cast when Wifi state changed.(on Disconnect wifi broadcast receive I have calculate Total time for wifi connection and store it in database).
but when I run it on 4.2.2 , Broadcast Receiver calls twice when Wifi is disconnected so at that time values(i.e time for wifi connection) store in database twice.
So I need to know why this happened?Why Broadcast Receiver calls twice at the time of wifi disconnect? I need code such that it works same for all Android Versions.
Here It is my code.
Android Menifest File
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.evowifiservice"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8" android:maxSdkVersion="17" android:targetSdkVersion="17"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.evowifiservice.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>
<receiver android:name=".WiFiReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
<!--
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
-->
</receiver>
<service android:name=".FirstService" >
</service>
</application>
</manifest>
CODE FOR Receiver which extends Broadcast Receiver(execute twice when wifi is dissconnected)
package com.example.evowifiservice;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;
import android.widget.Toast;
public class WiFiReceiver extends BroadcastReceiver {
SharedPreferences sharedpref;
SharedPreferences.Editor editor;
public static String PREFS_NAME = "WifiList";
WifiInfo connectionInfo;
Calendar calendar;
String strSSID;
ArrayList<String> arySSID;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
try {
MainActivity.mDatabase = context.openOrCreateDatabase(
"WifiDetails.db", SQLiteDatabase.CREATE_IF_NECESSARY, null);
MainActivity.mDatabase.setVersion(1);
MainActivity.mDatabase.setLocale(Locale.getDefault());
MainActivity.mDatabase.setLockingEnabled(true);
arySSID = new ArrayList<String>();
Cursor c = MainActivity.mDatabase.query("tbl_SSID", null, null, null, null,null, null);
arySSID.clear();
c.moveToFirst();
while (!c.isAfterLast()) {
arySSID.add(c.getString(1));
c.moveToNext();
}
Log.d("ArySSID","Array : "+arySSID+" Size "+arySSID.size());
} catch (Exception e) {
// TODO: handle exception
}
sharedpref = context.getSharedPreferences(PREFS_NAME, 0);
if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
NetworkInfo networkInfo = intent
.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()) {
// Wifi is connected
WifiManager wifiManager = (WifiManager) context
.getSystemService(Context.WIFI_SERVICE);
wifiManager.getConfiguredNetworks();
connectionInfo = wifiManager.getConnectionInfo();
strSSID = connectionInfo.getSSID();
Log.d("Currently Connected with", "" + strSSID);
// Retrieve the values
String comparestr=strSSID.replaceAll("^\"|\"$", "");
editor = sharedpref.edit();
editor.putString("CurrentSSID", "" + comparestr);
editor.commit();
if (arySSID.contains(comparestr)) {
Log.d("CONTAINSSSS", "CONTAINSSSS");
Date date = new Date();
long timeInMili = date.getTime();
editor.putLong("ConnectedTimeMili", timeInMili);
editor.commit();
Log.d("Connected Time", "" + timeInMili);
SimpleDateFormat df1 = new SimpleDateFormat("dd/MM/yyyy");
String connectedDateText = df1.format(date);
Log.d("Connected Date", connectedDateText);
SimpleDateFormat df2 = new SimpleDateFormat("HH:mm:ss");
String connectedTimeText = df2.format(date);
Log.d("Connected Time", connectedTimeText);
Toast.makeText(
context,
"You are Connected with Evosys Organization # "
+ "" + connectedTimeText, Toast.LENGTH_SHORT).show();
ContentValues myval = new ContentValues();
myval.put("SSID", "" + comparestr);
myval.put("Status", "CONNECTED");
myval.put("Date", connectedDateText);
myval.put("Time", connectedTimeText);
MainActivity.mDatabase.insert("tbl_WifiDet", null, myval);
Toast.makeText(context,
"Insert while Connected Successfully",
Toast.LENGTH_LONG).show();
}
Log.d("Inetify",
"Wifi is connected: " + String.valueOf(networkInfo));
}
} else if (intent.getAction().equals(
ConnectivityManager.CONNECTIVITY_ACTION)) {
NetworkInfo networkInfo = intent
.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI
&& !networkInfo.isConnected()) {
// Wifi is disconnected
strSSID = sharedpref.getString("CurrentSSID", "");
Log.d("Currently DisConnected with", "-----" + strSSID);
String comparestr=strSSID.replaceAll("^\"|\"$", "");
if (arySSID.contains(comparestr)) {
Date date = new Date();
long dctimemili = date.getTime();
Log.d("DCConnected Time", "" + dctimemili);
SimpleDateFormat df1 = new SimpleDateFormat("dd/MM/yyyy");
String DcdateText = df1.format(date);
Log.d("Disconnected Date", DcdateText);
SimpleDateFormat df2 = new SimpleDateFormat("HH:mm:ss");
String DctimeText = df2.format(date);
Log.d("Disconnected Time", DctimeText);
long ctimemili = sharedpref.getLong("ConnectedTimeMili", 0);
long diff = dctimemili - ctimemili;
Log.d("MILI SECOND You are connected upto", "" + diff);
// int seconds = (int) (diff / 1000) % 60 ;
// int minutes = (int) ((diff / (1000*60)) % 60);
// int hours = (int) ((diff / (1000*60*60)) % 24);
int mHour = (int) (diff / (1000*60*60));
int mMin = (int) ((diff % (1000*60*60)) / (1000*60));
int mSec = (int) (((diff % (1000*60*60)) % (1000*60)) / 1000);
String connectionTime = mHour + ":" + mMin + ":" + mSec;
Log.d("You are connected upto", "" + connectionTime);
ContentValues myval = new ContentValues();
myval.put("SSID", "" + comparestr);
myval.put("Status", "DISCONNECTED");
myval.put("Date", DcdateText);
myval.put("Time", DctimeText);
myval.put("Total_Connection_Time", diff);
MainActivity.mDatabase.insert("tbl_WifiDet", null, myval);
Toast.makeText(context, "Insert while D/C Successfully",
Toast.LENGTH_LONG).show();
Toast.makeText(context, "Wifi is disconnected.",
Toast.LENGTH_LONG).show();
Log.d("Inetify",
"Wifi is disconnected: "
+ String.valueOf(networkInfo));
}
}
}
}
}
Main Activity
package com.example.evowifiservice;
import java.util.ArrayList;
import java.util.Locale;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
SharedPreferences sharedpref;
SharedPreferences.Editor editor;
public static String PREFS_NAME = "WifiList";
static SQLiteDatabase mDatabase;
ListView list_wifiDet;
Button btn_wifiDetView,btn_delete_records,btn_tot_con_time;
ArrayList<String> arySSID,aryConStatus,aryDate,aryTime;
ArrayAdapter<String> adpt;
static final int CUSTOM_DIALOG_ID1 = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_wifiDetView=(Button) findViewById(R.id.btn_wifiDetView);
btn_delete_records=(Button) findViewById(R.id.btn_delete_records);
btn_tot_con_time=(Button) findViewById(R.id.btn_tot_con_time);
list_wifiDet=(ListView) findViewById(R.id.list_wifiDet);
try
{
mDatabase=openOrCreateDatabase("WifiDetails.db",SQLiteDatabase.CREATE_IF_NECESSARY, null);
mDatabase.setVersion(1);
mDatabase.setLocale(Locale.getDefault());
mDatabase.setLockingEnabled(true);
String s="Create table tbl_WifiDet(Id INTEGER PRIMARY KEY AUTOINCREMENT,SSID TEXT,Status TEXT,Date TEXT,Time TEXT,Total_Connection_Time INTEGER)";
mDatabase.execSQL(s);
String s1="Create table tbl_SSID(Id INTEGER PRIMARY KEY AUTOINCREMENT,SSID TEXT)";
mDatabase.execSQL(s1);
ContentValues myval = new ContentValues();
myval.put("SSID", "evosys1");
mDatabase.insert("tbl_SSID", null, myval);
myval.put("SSID", "evosys2");
mDatabase.insert("tbl_SSID", null, myval);
myval.put("SSID", "ROUTE-999");
mDatabase.insert("tbl_SSID", null, myval);
//
Toast.makeText(getApplicationContext(), "Insert SSID List Successfully",
Toast.LENGTH_LONG).show();
} catch (Exception e) {
// TODO: handle exception
}
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
sharedpref = getSharedPreferences(PREFS_NAME, 0);
Log.d("Starting Service", "in MainActivity");
startService(new Intent(this,FirstService.class));
btn_wifiDetView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Cursor c = mDatabase.query("tbl_WifiDet", null, null, null, null,null, null);
c.moveToFirst();
arySSID = new ArrayList<String>();
aryConStatus = new ArrayList<String>();
aryDate = new ArrayList<String>();
aryTime = new ArrayList<String>();
arySSID.clear();
aryConStatus.clear();
aryDate.clear();
aryTime.clear();
while (!c.isAfterLast()) {
arySSID.add(c.getString(1));
aryConStatus.add(c.getString(2));
aryDate.add(c.getString(3));
aryTime.add(c.getString(4));
c.moveToNext();
}
showDialog(CUSTOM_DIALOG_ID1);
adpt = new MyCustomBaseAdapteradptWifiDet(MainActivity.this, R.layout.wifi_list,arySSID,aryConStatus,aryDate,aryTime);
list_wifiDet.setAdapter(adpt);
}
});
btn_tot_con_time.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
// String[] columns = new String[]{ "sum(Total_Connection_Time) as " + "Total_Connection_Time" };
Cursor c = mDatabase.query("tbl_WifiDet", null, null, null, null,null, null);
c.moveToLast();
long contime=c.getLong(5);
Log.d("Chking Time", "-----"+contime);
c.moveToFirst();
long result = 0;
while(!c.isAfterLast()){
Log.d("SUMMM", ""+result+"+"+c.getLong(5));
result=(result + c.getLong(5));
Log.d("Answer:", "--"+result);
c.moveToNext();
}
Log.d("Toatal Con Time", ""+result);
int mHour = (int) (result / (1000*60*60));
int mMin = (int) ((result % (1000*60*60)) / (1000*60));
int mSec = (int) (((result % (1000*60*60)) % (1000*60)) / 1000);
String connectionTime = mHour + ":" + mMin + ":" + mSec;
Log.d("Formated Toatal Con Time", "" + connectionTime);
Toast.makeText(getApplicationContext(),"Connection Duration :: "+connectionTime, Toast.LENGTH_LONG).show();
}
});
btn_delete_records.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
new MyTask().execute();
}
});
}
public class MyTask extends AsyncTask<Void, Void, Void> {
ProgressDialog dialog = new ProgressDialog(MainActivity.this);
#Override
protected void onPreExecute() {
// update the UI immediately after the task is executed
dialog.setMessage("Please wait...");
dialog.setCancelable(false);
dialog.show();
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
mDatabase.delete("tbl_WifiDet",null,null);
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
try {
dialog.dismiss();
} catch (Exception e) {
// TODO: handle exception
}
Toast.makeText(getApplicationContext(), "Record Delete Successfully",Toast.LENGTH_LONG).show();
}
}
#Override
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
switch (id) {
case CUSTOM_DIALOG_ID1:
dialog = new Dialog(MainActivity.this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.setContentView(R.layout.wifi_list);
list_wifiDet = (ListView) dialog.findViewById(R.id.list_wifiDet);
break;
}
return dialog;
}
class MyCustomBaseAdapteradptWifiDet extends ArrayAdapter<String>
{
public MyCustomBaseAdapteradptWifiDet(Context context, int textViewResourceId,ArrayList<String> object, ArrayList<String> aryConStatus, ArrayList<String> aryDate, ArrayList<String> aryTime)
{
super(context, textViewResourceId, object);
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.wifi_list_cell, null);
final TextView lblSSID,lblStatus,lblDate,lblTime;
lblSSID = (TextView) v.findViewById(R.id.view_ssid);
lblStatus = (TextView) v.findViewById(R.id.view_connectionStatus);
lblDate = (TextView) v.findViewById(R.id.view_Date);
lblTime = (TextView) v.findViewById(R.id.view_Time);
lblSSID.append(arySSID.get(position));
lblStatus.append(aryConStatus.get(position));
lblDate.append(aryDate.get(position));
lblTime.append(aryTime.get(position));
return v;
}
}
}
If you want this BroadcastReciever to work for change in states (connected / disconnected) of wi-fi only, then below is your solution:
Instead of listening for actions - android.net.conn.CONNECTIVITY_CHANGE & android.net.wifi.STATE_CHANGE, you should listen for the broadcast of only android.net.wifi.WIFI_STATE_CHANGED
Modify <receiver> tag in your manifest.xml file as:
<receiver android:name=".WiFiReceiver" >
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
In your onReceive() method of BroadcastReceiver, handle the wi-fi state changes as below:
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
int newWifiState = intent.getIntExtra(
WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
switch(newWifiState){
case WifiManager.WIFI_STATE_ENABLED:
Toast.makeText(context, "Wi-fi is Connected", Toast.LENGTH_SHORT).show();
// Put your code here to perform actions when wi-fi is connected
break;
case WifiManager.WIFI_STATE_DISABLED:
Toast.makeText(context, "Wi-fi Disconnected", Toast.LENGTH_SHORT).show();
// Put your code here to perform actions when wi-fi is disconnected
break;
/* You can also handle cases for the states "Connecting" and "Disconnecting"
by switching for values WifiManager.WIFI_STATE_ENABLING and WifiManager.WIFI_STATE_DISABLING */
}
}
}
This works perfectly fine for me and code is executed only once when wi-fi is "Connected" or "Disconnected" :)
If you want to receive WiFi connection changes (not only disabled/enabled), you need to check only the android.net.wifi.STATE_CHANGE events (note, that it is not the same as android.net.wifi.WIFI_STATE_CHANGED, it is only sent when you disable or enable WiFi).
You can check if you're connected to a WiFi network for example by checking WifiManager.getConnectionInfo().getNetworkId(), if it's -1, then you are disconnected.
I tried it on my 4.1.2 device, it sent me the broadcasts only once.
public class WifiBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
int networkId = wifiManager.getConnectionInfo().getNetworkId();
boolean isConnected = networkId != -1;
if (isConnected)
{
Toast.makeText(context, "WiFi connected: " + wifiManager.getConnectionInfo().getSSID(), Toast.LENGTH_SHORT).show() ;
}
else
{
Toast.makeText(context, "WiFi disconnected.", Toast.LENGTH_SHORT).show() ;
}
}
}
If it sends more than 1 broadcasts on 4.2.2, you should get a bool value (myIsConnected in the example), which indicates if the last broadcast said you are connected, like this:
if (connected)
{
if (!myIsConnected)
{
myIsConnected = true ;
Toast.makeText(context, "WiFi connected: " + mWifiManager.getConnectionInfo().getSSID(), Toast.LENGTH_SHORT).show() ;
}
}
else
{
if (myIsConnected)
{
myIsConnected = false ;
Toast.makeText(context, "WiFi disconnected.", Toast.LENGTH_SHORT).show() ;
}
}
You need android.permission.ACCESS_WIFI_STATE in order to receive these broadcasts and access WifiManager.
Try checking SupplicantState of current Wifi connection
I am sure this is simple but I cannot figure it out. All I am trying to do is send a message via NFC. The code I have work perfectly if I am sending it to the main activity, but I don't know how to send it to a different activity. I have looked over both the NFC and Intent Filter articles on the Android Developer pages but am still not sure exactly how to do this. I am trying to send it to a NFC activity, I will post my manifest and NFC class below.
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.justbaumdev.tagsense"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.Holo" >
<activity
android:name=".TagSense"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.justbaumdev.tagsense.NFC" android:exported="false">
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/com.justbaumdev.tagsense" />
</intent-filter>
</activity>
</application>
</manifest>
NFC Class:
package com.justbaumdev.tagsense;
import org.json.JSONArray;
import org.json.JSONException;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.wifi.WifiManager;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcAdapter.OnNdefPushCompleteCallback;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.widget.Toast;
public class NFC extends Activity implements CreateNdefMessageCallback, OnNdefPushCompleteCallback {
private NfcAdapter mNfcAdapter;
private static final int MESSAGE_SENT = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nfc);
mNfcAdapter = NfcAdapter.getDefaultAdapter(this); // Check for available NFC Adapter
if (mNfcAdapter == null)
{
Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
else
{
mNfcAdapter.setNdefPushMessageCallback(this, this); // Register callback to set NDEF message
mNfcAdapter.setOnNdefPushCompleteCallback(this, this); // Register callback to listen for message-sent success
}
}
#Override
public void onResume() {
super.onResume();
// Check to see that the Activity started due to an Android Beam
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
processIntent(getIntent());
}
}
#Override
public void onNewIntent(Intent intent) {
// onResume gets called after this to handle the intent
setIntent(intent);
}
#Override
public NdefMessage createNdefMessage(NfcEvent event) {
WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
String mac = wm.getConnectionInfo().getMacAddress();
String newMac = mac.substring(0, 2);
mac = mac.substring(2);
int hex = Integer.parseInt(newMac, 16) + 0x2;
newMac = Integer.toHexString(hex);
String text = newMac + mac;
NdefMessage msg = new NdefMessage(NdefRecord.createMime(
"application/com.justbaumdev.tagsense", text.getBytes()));
return msg;
}
/**
* Implementation for the OnNdefPushCompleteCallback interface
*/
#Override
public void onNdefPushComplete(NfcEvent arg0) {
// A handler is needed to send messages to the activity when this
// callback occurs, because it happens from a binder thread
mHandler.obtainMessage(MESSAGE_SENT).sendToTarget();
}
/** This handler receives a message from onNdefPushComplete */
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_SENT:
Toast.makeText(getApplicationContext(), "Message sent!", Toast.LENGTH_LONG).show();
break;
}
}
};
/**
* Parses the NDEF Message from the intent and prints to the TextView
*/
//TODO Currently overwrites any previously saved mac addresses. Get FB ID as value. Auto end activity.
void processIntent(Intent intent) {
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
// only one message sent during the beam
NdefMessage msg = (NdefMessage) rawMsgs[0];
// record 0 contains the MIME type, record 1 is the AAR, if present
//textView.setText(new String(msg.getRecords()[0].getPayload()));
String payload = new String(msg.getRecords()[0].getPayload());
Toast.makeText(this, new String(msg.getRecords()[0].getPayload()), Toast.LENGTH_LONG).show();
SharedPreferences appData = getSharedPreferences("appData", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = appData.edit();
String addresses = appData.getString("mac_address", null);
if(addresses==null)
{
JSONArray addressArray = new JSONArray();
addressArray.put(payload);
addresses = addressArray.toString();
}
else
{
try {
if(!addresses.contains(payload))
{
JSONArray addressArray = new JSONArray(addresses);
addressArray.put(payload);
addresses = addressArray.toString();
}
} catch (JSONException e) {
Toast.makeText(this, "Error adding new friend. Please try again.", Toast.LENGTH_SHORT).show();
}
}
editor.putString("mac_address", addresses);
editor.commit();
}
}
Thanks for your help.
Remove the attribute android:exported="false". See also https://stackoverflow.com/a/12719621/1202968