Kiosk mode is not working.? - android

I am creating sample app with kiosk mode in my app to check that is kiosk mode work or not.?. But in sample app kiosk mode is not working. I means after screen goes off activity is not starting.
I have taken this from [http://www.andreas-schrade.de/2015/02/16/android-tutorial-how-to-create-a-kiosk-mode-in-android/][here]
THis is my main activity
public class MainActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(!hasFocus) {
// Close every kind of system dialog
Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
sendBroadcast(closeDialog);
}
}
}
THis is my Application class
public class AppContext extends Application {
private AppContext instance;
private PowerManager.WakeLock wakeLock;
private OnScreenOffReceiver onScreenOffReceiver;
PowerManager pm;
#Override
public void onCreate() {
super.onCreate();
instance = this;
registerKioskModeScreenOffReceiver();
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
startKioskService();
}
private void registerKioskModeScreenOffReceiver() {
// register screen off receiver
final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
onScreenOffReceiver = new OnScreenOffReceiver();
registerReceiver(onScreenOffReceiver, filter);
}
public PowerManager.WakeLock getWakeLock() {
if(wakeLock == null) {
// lazy loading: first call, create wakeLock via PowerManager.
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "wakeup");
}
return wakeLock;
}
private void startKioskService() { // ... and this method
startService(new Intent(this, KioskService.class));
}
}
This is receiver class
public class OnScreenOffReceiver extends BroadcastReceiver {
private static final String PREF_KIOSK_MODE = "pref_kiosk_mode";
#Override
public void onReceive(Context context, Intent intent) {
if(Intent.ACTION_SCREEN_OFF.equals(intent.getAction())){
AppContext ctx = (AppContext) context.getApplicationContext();
// is Kiosk Mode active?
if(isKioskModeActive(ctx)) {
wakeUpDevice(ctx);
}
}
}
private void wakeUpDevice(AppContext context) {
PowerManager.WakeLock wakeLock = context.getWakeLock(); // get WakeLock reference via AppContext
if (wakeLock.isHeld()) {
wakeLock.release(); // release old wake lock
}
// create a new wake lock...
wakeLock.acquire();
// ... and release again
wakeLock.release();
}
private boolean isKioskModeActive(final Context context) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
return sp.getBoolean(PREF_KIOSK_MODE, false);
}
}
THis is Service class
public class KioskService extends Service {
private static final long INTERVAL = TimeUnit.SECONDS.toMillis(2); // periodic interval to check in seconds -> 2 seconds
private static final String TAG = KioskService.class.getSimpleName();
private static final String PREF_KIOSK_MODE = "pref_kiosk_mode";
private Thread t = null;
private Context ctx = null;
private boolean running = false;
#Override
public void onDestroy() {
Log.i(TAG, "Stopping service 'KioskService'");
running =false;
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Starting service 'KioskService'");
running = true;
ctx = this;
// start a thread that periodically checks if your app is in the foreground
t = new Thread(new Runnable() {
#Override
public void run() {
do {
handleKioskMode();
try {
Thread.sleep(INTERVAL);
} catch (InterruptedException e) {
Log.i(TAG, "Thread interrupted: 'KioskService'");
}
}while(running);
stopSelf();
}
});
t.start();
return Service.START_NOT_STICKY;
}
private void handleKioskMode() {
// is Kiosk Mode active?
if(isKioskModeActive(ctx)) {
// is App in background?
if(isInBackground()) {
restoreApp(); // restore!
}
}
}
private boolean isInBackground() {
ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
return (!ctx.getApplicationContext().getPackageName().equals(componentInfo.getPackageName()));
}
private void restoreApp() {
// Restart activity
Intent i = new Intent(ctx, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ctx.startActivity(i);
}
public boolean isKioskModeActive(final Context context) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
return sp.getBoolean(PREF_KIOSK_MODE, false);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
This is my manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.kioskmode"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:name=".AppContext"
android:icon="#drawable/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="com.example.kioskmode.KioskService" android:exported="false"></service>
<receiver android:name="com.example.kioskmode.OnScreenOffReceiver" android:enabled="true" >
<intent-filter android:priority="1000" >
<action android:name="android.app.action.SCREEN_OFF" />
<action android:name="android.app.action.SCREEN_ON" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
</manifest>
Any one can solve this... for me..?? Thanks in advance..

Your method isKioskModeActive is always false. So it won't restore your app.

Related

How to get the activity which called the BroadcastReceiver?

I have a BroadcastReceiver which checks for NetworkChange, whether connected to Internet or not.
So in my application when the network is disconnected or connected, I want to know which activity has called the BroadcastReceiver, so that I can go back to previous activity after showing an alert informing about the network.
My code,
public class NetworkChangeReceiver extends BroadcastReceiver {
private android.widget.Toast Toast;
#Override
public void onReceive(final Context context, final Intent intent) {
try {
boolean isVisible = MyApplication.isActivityVisible();
Context appContext = context.getApplicationContext();
if (isVisible == true) {
if (checkInternet(context)) {
/*Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);*/
Toast.makeText(context, "Network Available Do operations", Toast.LENGTH_LONG).show();
} else {
Intent i = new Intent(context, NoNetworkAlert.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Toast.makeText(context, "Network NOT Available Do operations", Toast.LENGTH_LONG).show();
}
.........
......
Here in the above code, when Internet is reconnected,
if (checkInternet(context))I just want to get to the activity which triggered this.
I assume the current activity on the top is the one which triggers the NetworkChangeListener. If so you can use below code snippet,
ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
which will give the current Activity on the top.
Do something like this in your activity
BroadcastReceiver br=new NetworkChangeReceiver ();
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
this.registerReceiver(br, filter);
And in your menifest
<receiver
android:name=".NetworkChangeReceiver "
android:exported="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
I have a BroadcastReceiver which checks for NetworkChange, whether connected to Internet or not.
So in my application when the network is disconnected or connected, I want to know which activity has called the BroadcastReceiver, so that I can go back to previous activity after showing an alert informing about the network.
To get the current Activity in Broadcast receiver use the ActivityManager in Broadcast receiver to get the Activity without instance
ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
Log.i("ActivityManager ", "ActivityManager" + cn.toString());
To get Activity in the preferred Activity with instance better use Getter and Setter.
MyApplication.Java:
public class MyApplication extends Application {
private Activity mCurrentActivity = null;
// Gloabl declaration of variable to use in whole app
public static boolean activityVisible; // Variable that will check the
// current activity state
public static boolean isActivityVisible() {
return activityVisible; // return true or false
}
public static void activityResumed() {
activityVisible = true;// this will set true when activity resumed
}
public static void activityPaused() {
activityVisible = false;// this will set false when activity paused
}
public Activity getCurrentActivity(){
return mCurrentActivity;
}
public void setCurrentActivity(Activity mCurrentActivity){
this.mCurrentActivity = mCurrentActivity;
}
}
MainActivity.Java:
public class MainActivity extends AppCompatActivity {
private static TextView internetStatus;
protected MyApplication mMyApp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMyApp = (MyApplication) this.getApplicationContext();
internetStatus = (TextView) findViewById(R.id.internet_status);
// At activity startup we manually check the internet status and change
// the text status
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
changeTextStatus(true);
} else {
changeTextStatus(false);
}
}
// Method to change the text status
public void changeTextStatus(boolean isConnected) {
// Change status according to boolean value
if (isConnected) {
internetStatus.setText("Internet Connected.");
internetStatus.setTextColor(Color.parseColor("#00ff00"));
} else {
internetStatus.setText("Internet Disconnected.");
internetStatus.setTextColor(Color.parseColor("#ff0000"));
}
}
#Override
protected void onPause() {
super.onPause();
MyApplication.activityPaused();// On Pause notify the Application
clearReferences();
}
#Override
protected void onResume() {
super.onResume();
MyApplication.activityResumed();// On Resume notify the Application
mMyApp.setCurrentActivity(this);
}
protected void onDestroy() {
clearReferences();
super.onDestroy();
}
private void clearReferences() {
Activity currActivity = mMyApp.getCurrentActivity();
Log.e("Activity", "Activity" + currActivity);
if (this.equals(currActivity))
mMyApp.setCurrentActivity(null);
}
}
InternetConnector_Receiver.Java:
public class InternetConnector_Receiver extends BroadcastReceiver {
public InternetConnector_Receiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
try {
boolean isVisible = MyApplication.isActivityVisible();
Log.i("Activity is Visible ", "Is activity visible : " + isVisible);
ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
Log.i("ActivityManager", "Activity Name:" + cn.toString());
// If it is visible then trigger the task else do nothing
if (isVisible == true) {
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager
.getActiveNetworkInfo();
// Check internet connection and accrding to state change the
// text of activity by calling method
if (networkInfo != null && networkInfo.isConnected()) {
new MainActivity().changeTextStatus(true);
} else {
new MainActivity().changeTextStatus(false);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Manifest Permission:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name="com.internetconnection_demo.MyApplication"
android:allowBackup="true"
android:icon="#drawable/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>
<!-- Broadcast receiver declaration in manifest file and make sure to enable it -->
<receiver
android:name="com.internetconnection_demo.InternetConnector_Receiver"
android:enabled="true" >
<intent-filter>
<!-- Intent filters for broadcast receiver -->
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
</receiver>
</application>

onCreate() and onPause() called incorrectly from other activities

My problem is that onCreate() and onPause() in a closed activity gets called when they shouldn't.
I the Start activity i call:
Intent intent = new Intent(this, SelectTransportActivity.class);
startActivity(intent);
this.finish();
when i want to start the SelectTransport activity.
But when i want to start the Stop Activity from the SelectTransport activity and i call
Intent i = new Intent(this, StopActivity.class);
startActivity(i);
this.finish();
I can see in the debugger that the onCreate() in the Start activity is called before the Stop activity starts.
Similarly, when I finishes the Stop activity, the onPause() in the Start activity is called, after which the Start activity starts.
Why are the onCreate() and onPause() called in the Start activity from the other activities when they shouldn't and I have finished the activity?
The manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.greenenergy"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<!-- Launching -->
<uses-permission android:name="android.permission.BATTERY_STATS" />
<!-- All probes -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Location probe -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:name=".GreenEnergyApplication">
<service android:name="edu.mit.media.funf.FunfManager" >
<meta-data
android:name="default"
android:value="#string/default_pipeline" />
</service>
<receiver
android:name="edu.mit.media.funf.Launcher"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.DOCK_EVENT" />
<action android:name="android.intent.action.ACTION_SCREEN_ON" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<activity
android:name="com.example.greenenergy.StartupActivity"
android:screenOrientation="portrait"
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.example.greenenergy.StartActivity"
android:screenOrientation="portrait"
android:label="#string/title_activity_start" >
</activity>
<activity
android:name="com.example.greenenergy.WaysActivity"
android:screenOrientation="portrait"
android:label="#string/title_activity_ways" >
</activity>
<activity
android:name="com.example.greenenergy.StopActivity"
android:screenOrientation="portrait"
android:label="#string/title_activity_stop">
</activity>
<activity
android:name="com.example.greenenergy.StatisticsActivity"
android:screenOrientation="portrait"
android:label="#string/title_activity_statistics">
</activity>
</application>
The Start activity:
public class StartActivity extends BaseActivity implements OnClickListener {
private Button bStart, bStats;
Controller controller;
GPSCollectorSingleton gpsCollectorSingleton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
autoDetect();
}
private void init() {
setContentView(R.layout.activity_main);
bStart = (Button) findViewById(R.id.bStart);
bStats = (Button) findViewById(R.id.bStatisticsStart);
bStart.setOnClickListener(this);
bStats.setOnClickListener(this);
controller = new Controller(); // Init controller
Database database = new Database(getApplicationContext());
controller.controlDatabase(database);
controller.createTable(); // Create table if not exist
gpsCollectorSingleton = GPSCollectorSingleton.getInstance(); // Init model
// Bind to the service, to create the connection with FunfManager
getApplicationContext().bindService(new Intent(this, FunfManager.class), funfManagerConn, BIND_AUTO_CREATE);
}
private void autoDetect() {
boolean auto = ((GreenEnergyApplication) getApplication()).getAutoPreference(getApplicationContext());
boolean started = ((GreenEnergyApplication) getApplication()).getStartPreference(getApplicationContext());
if (auto && !started) {
controller.enableAutoDetection(getApplicationContext(), gpsCollectorSingleton);
}
}
#Override
protected void onPause() {
super.onPause();
this.finish();
}
#Override
public void onClick(View v) {
Intent intent;
switch (v.getId()) {
case R.id.bStart:
startDataCollector();
break;
case R.id.bStatisticsStart:
intent = new Intent(this, StatisticsActivity.class);
startActivity(intent);
break;
}
}
private void startDataCollector() {
if (((GreenEnergyApplication) getApplication()).getStartPreference(getApplicationContext()) == false) {
controller.datahandlerObserver(getApplicationContext(), gpsCollectorSingleton); // Observer
((GreenEnergyApplication) getApplication()).setStartPreference(getApplicationContext(), true);
}
Intent intent = new Intent(this, WaysActivity.class);
startActivity(intent);
}
}
The SelectTransport activity:
public class SelectTransportActivity extends BaseActivity implements OnItemClickListener {
GridView gridview;
private static int DATABASE_ID_OFFSET = 2;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ways);
gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(this);
}
#Override
protected void onPause() {
super.onPause();
this.finish();
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
((GreenEnergyApplication)getApplication()).setTransportationPreference(getApplicationContext(), arg2+DATABASE_ID_OFFSET);
Log.i("WayActivity",
"ARG0: " + arg0.toString() + " Arg1: " + arg1.toString() + " "
+ " Arg2: " + arg2 + " Arg3: " + arg3);
Intent i = new Intent(this, StopActivity.class);
startActivity(i);
}
}
The Stop activity:
public class StopActivity extends StartActivity implements OnClickListener, Observer {
Button stopButton, statsButton;
TextView statusTextView;
int distance, time, transportTypeEstimate, transportType;
int sessionStartTime = 0;
int sessionStartDistance = 0;
GPSCollectorSingleton gpsCollectorSingleton;
LocationData location;
boolean transportEstimation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GPSCollectorSingleton gps = GPSCollectorSingleton.getInstance();
if (((GreenEnergyApplication) getApplication()).getStartPreference(getApplicationContext()) == false) {
Log.i("STOP - STOP", "hasspeed");
stopDataCollector();
}
setContentView(R.layout.activity_stop);
stopButton = (Button) findViewById(R.id.bStop);
statsButton = (Button) findViewById(R.id.bStatisticsStop);
statusTextView = (TextView) findViewById(R.id.tvStatus);
stopButton.setOnClickListener(this);
statsButton.setOnClickListener(this);
gpsCollectorSingleton = GPSCollectorSingleton.getInstance(); // Init model
gpsCollectorSingleton.addObserver(this); // Observe on models state
initTransportTypeDetection();
}
/**
* Initializes estimating of transport type or manually chosen transport type
*/
private void initTransportTypeDetection() {
transportType = ((GreenEnergyApplication) getApplication())
.getTransportationPreference(getApplicationContext());
transportTypeEstimate = transportType;
if (transportType == TransportationDefinerSingleton.TRANSPORT_UNKNOWN) { // Start transport type estimation
TransportationDefinerSingleton transport = TransportationDefinerSingleton.getInstance(); // Get model
transport.addObservable(gpsCollectorSingleton); // Add observer for estimating transport type
transportEstimation = true;
} else { // Transport type manually specified
setSessionStartDistanceAndTime();
transportEstimation = false;
}
}
private void setSessionStartDistanceAndTime() {
Controller controller = new Controller();
Database database = new Database(getApplicationContext());
controller.controlDatabase(database);
sessionStartDistance = controller.getDistanceFromID(transportType);
sessionStartTime = controller.getTimeFromID(transportType);
}
#Override
public void onClick(View v) {
Intent intent;
switch (v.getId()) {
case R.id.bStop:
stopDataCollector();
break;
case R.id.bStatisticsStop:
intent = new Intent(this, StatisticsActivity.class);
startActivityForResult(intent, -1);
break;
}
}
private void stopDataCollector() {
((GreenEnergyApplication) getApplication()).setTransportationPreference(getApplicationContext(),
TransportationDefinerSingleton.TRANSPORT_UNKNOWN);
((GreenEnergyApplication) getApplication()).setStartPreference(getApplicationContext(), false);
gpsCollectorSingleton.deleteObservers(); // Delete all observers
Controller controller = new Controller();
Database database = new Database(getApplicationContext());
controller.controlDatabase(database);
// Get unknown data. From estimate of transport type or data collected while deciding transport type.
int distance = controller.getDistanceFromID(TransportationDefinerSingleton.TRANSPORT_UNKNOWN);
int time = controller.getTimeFromID(TransportationDefinerSingleton.TRANSPORT_UNKNOWN);
if (transportEstimation) { // Estimate
controller.updateTable(transportTypeEstimate, distance, time);
} else { // Manually chosen transport type
controller.updateTable(transportType, distance, time);
}
controller.resetTable(TransportationDefinerSingleton.TRANSPORT_UNKNOWN);
Intent intent = new Intent(this, StartActivity.class);
startActivity(intent);
this.finish();
}
#Override
public void update(Observable observable, Object data) {
Controller controller = new Controller();
Database database = new Database(getApplicationContext());
controller.controlDatabase(database);
transportTypeEstimate = getTransportType();
distance = controller.getDistanceFromID(transportType) - sessionStartDistance;
time = controller.getTimeFromID(transportType) - sessionStartTime;
location = (LocationData) data;
runOnUiThread(new Runnable() {
#Override
public void run() {
String transportName = getTransportName(transportTypeEstimate);
statusTextView.setText("Transport type: " + transportName + " Distance: " + distance + " Time: " + time
+ "\nTimeStamp: " + location.getTime() + "\nSpeed: " + location.getSpeed()
+ " Seconds since last: " + location.getSecondsSinceLastSample());
}
});
}
private int getTransportType() {
if (transportEstimation) {
TransportationDefinerSingleton transport = TransportationDefinerSingleton.getInstance();
Controller controller = new Controller();
controller.controlTransportationDefinerSingleton(transport);
transportTypeEstimate = controller.getTransportType();
}
return transportTypeEstimate;
}
private String getTransportName(int type) {
switch (type) {
case TransportationDefinerSingleton.TRANSPORT_UNKNOWN:
return "Unknown";
case TransportationDefinerSingleton.TRANSPORT_WALK:
return "Walking";
case TransportationDefinerSingleton.TRANSPORT_BIKE:
return "Bike";
case TransportationDefinerSingleton.TRANSPORT_CAR:
return "Car";
case TransportationDefinerSingleton.TRANSPORT_BUS:
return "Bus";
case TransportationDefinerSingleton.TRANSPORT_TRAIN:
return "Train";
case TransportationDefinerSingleton.TRANSPORT_MOTORCYCLE:
return "Motor Cycle";
case TransportationDefinerSingleton.TRANSPORT_CARPOOL:
return "Carpool";
}
return "";
}
}
The Base activity, which is the superclass for the other activities. It just sets up the option menu and other basic stuff.
public class BaseActivity extends Activity {
private Controller controller;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GPSCollectorSingleton gpsCollectorSingleton = GPSCollectorSingleton.getInstance(); // Init model
controller = new Controller();
controller.controlGPSCollectorSingleton(gpsCollectorSingleton); // Init controller
}
protected ServiceConnection funfManagerConn = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("OnServiceConnected", "MainActivity");
controller.onServiceConnected(service);
}
#Override
public void onServiceDisconnected(ComponentName name) {
controller.onServiceDisconnected();
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
disableService();
closeActivity();
return true;
case R.id.action_clear:
Database database = new Database(getApplicationContext());
database.dropTable();
return true;
case R.id.action_toggle_auto:
if (item.isChecked()) {
item.setChecked(false);
((GreenEnergyApplication) getApplication()).setAutoPreference(getApplicationContext(), false);
} else {
item.setChecked(true);
((GreenEnergyApplication) getApplication()).setAutoPreference(getApplicationContext(), true);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
if (((GreenEnergyApplication) getApplication()).getAutoPreference(getApplicationContext()) == true) {
menu.findItem(R.id.action_toggle_auto).setChecked(true);
}
return true;
}
/**
* Disables the service and the pipeline
*/
private void disableService() {
controller.disablePipeline(); // Disable pipeline
boolean isBound = false;
isBound = getApplicationContext().bindService(new Intent(getApplicationContext(), FunfManager.class),
funfManagerConn, BIND_AUTO_CREATE);
if (isBound) {
getApplicationContext().unbindService(funfManagerConn); // Disable
// service
}
}
private void closeActivity() {
this.finish();
}
}
Let's start with the easy things: Your StopActivity extends StartActivity
public class StopActivity extends StartActivity {...
It should either extend BaseActivity or a call to super.onCreate() will run the code in StartActivity.onCreate().

AIDL, bind and unbind IExtendedNetworkService Service

I use AIDL interface IExtendedNetworkService to get USSD code. But application only work after reboot device. I tried bindservice after install app but it didn't work. So my problem is how way to bind service without reboot device . This is my code:
interface:
package com.android.internal.telephony;
interface IExtendedNetworkService {
void setMmiString(String number);
CharSequence getMmiRunningText();
CharSequence getUserMessage(CharSequence text);
void clearMmiString();
}
Service
public class CDUSSDService extends Service {
private String TAG = "THANG-NGUYEN";
private boolean mActive = false;
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_INSERT)) {
// activity wishes to listen to USSD returns, so activate this
mActive = true;
Log.d(TAG, "activate ussd listener");
} else if (intent.getAction().equals(Intent.ACTION_DELETE)) {
mActive = false;
Log.d(TAG, "deactivate ussd listener");
}
}
};
private final IExtendedNetworkService.Stub mBinder = new IExtendedNetworkService.Stub() {
public void clearMmiString() throws RemoteException {
Log.d(TAG, "called clear");
}
public void setMmiString(String number) throws RemoteException {
Log.d(TAG, "setMmiString:" + number);
}
public CharSequence getMmiRunningText() throws RemoteException {
if (mActive == true) {
return null;
}
return "USSD Running";
}
public CharSequence getUserMessage(CharSequence text)
throws RemoteException {
Log.d(TAG, "get user message " + text);
if (mActive == false) {
// listener is still inactive, so return whatever we got
Log.d(TAG, "inactive " + text);
return text;
}
// listener is active, so broadcast data and suppress it from
// default behavior
// build data to send with intent for activity, format URI as per
// RFC 2396
Uri ussdDataUri = new Uri.Builder()
.scheme(getBaseContext().getString(R.string.uri_scheme))
.authority(
getBaseContext().getString(R.string.uri_authority))
.path(getBaseContext().getString(R.string.uri_path))
.appendQueryParameter(
getBaseContext().getString(R.string.uri_param_name),
text.toString()).build();
sendBroadcast(new Intent(Intent.ACTION_GET_CONTENT, ussdDataUri));
mActive = false;
return null;
}
};
public void onCreate() {
Log.i(TAG, "called onCreate");
};
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "called onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "called onbind");
// the insert/delete intents will be fired by activity to
// activate/deactivate listener since service cannot be stopped
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_INSERT);
filter.addAction(Intent.ACTION_DELETE);
filter.addDataScheme(getBaseContext().getString(R.string.uri_scheme));
filter.addDataAuthority(
getBaseContext().getString(R.string.uri_authority), null);
filter.addDataPath(getBaseContext().getString(R.string.uri_path),
PatternMatcher.PATTERN_LITERAL);
registerReceiver(receiver, filter);
return mBinder;
}
}
MainActivity:
public class MainActivity extends Activity {
private Button btnCheckUSSD;
private Context mContext;
private IExtendedNetworkService mService;
private EditText inputUSSD;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.activity_main);
btnCheckUSSD = (Button) findViewById(R.id.btn_check);
inputUSSD = (EditText) findViewById(R.id.input_ussd);
btnCheckUSSD.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if (!inputUSSD.getText().toString().isEmpty()) {
Intent service = new Intent(
"com.android.ussd.IExtendedNetworkService");
bindService(service, mConnecton, Context.BIND_AUTO_CREATE);
startActivity(new Intent("android.intent.action.CALL", Uri
.parse("tel:" + inputUSSD.getText().toString()
+ Uri.encode("#"))));
}
}
});
}
ServiceConnection mConnecton = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder iBinder) {
mService = IExtendedNetworkService.Stub
.asInterface((IBinder) iBinder);
}
};
protected void onDestroy() {
super.onDestroy();
Log.d("THANG-NGUYEN", "onDestroy");
unbindService(mConnecton);
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.example.checkussdcode"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="info.example.checkussdcode.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="info.example.checkussdcode.service.UssdCodeService"
android:process=":remote" >
<intent-filter>
<action android:name="com.android.ussd.IExtendedNetworkService" >
</action>
</intent-filter>
</service>
<receiver android:name="info.example.checkussdcode.RebootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>

Service is being started but OnCreate or OnStart are not being called

I am currently working on an android project and I am trying to start a service and when the service has started running some code to initialise some stuff.
Below is the code I am using for the service.
Context context;
PowerManager.WakeLock wakeLock;
public PowerDetectionService(Context context)
{
this.context = context;
}
public PowerDetectionService()
{}
public void onCreate()
{
super.onCreate();
PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
}
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void receivedPowerConnected()
{
try
{
Toast.makeText(context, "Power connected", Toast.LENGTH_LONG).show();
wakeLock.acquire();
}
catch (Exception ex)
{
Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
}
}
public void receivedPowerDisconnected()
{
try
{
Toast.makeText(context, "Power disconnected", Toast.LENGTH_LONG).show();
wakeLock.release();
}
catch (Exception ex)
{
Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
}
}
The wake lock is always null as that bit of code never gets executed in the oncreate or onstart. I've tried putting it in the bind function but still no joy.
When I go into the android settings I can see that my app has the service running but I need that code to be initialised before anything would work.
Thanks for any help you can provide.
UPDATE
I've discovered that the functions are being called thanks to the previous comment. For some reason the debugger doesn't get fired.
Below is the code that shows how to create the server as requested.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(this);
}
public void onResume()
{
super.onResume();
startService(this);
}
private void startService(Context context)
{
Intent service = new Intent(context, PowerDetectionService.class);
context.startService(service);
}
UPDATE 2
As requested below is all the code that starts the service and performs the wake lock.
Below is the main activity that starts the service
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StartPowerService(this);
//getActionBar().setDisplayHomeAsUpEnabled(true);
}
public void onResume()
{
super.onResume();
StartPowerService(this);
}
private void StartPowerService(Context context)
{
Intent service = new Intent(context, PowerDetectionService.class);
startService(service);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
//case android.R.id.home:
// NavUtils.navigateUpFromSameTask(this);
// return true;
}
return super.onOptionsItemSelected(item);
}
}
Below is the class for the service
public class PowerDetectionService extends Service {
Context context;
PowerManager.WakeLock wakeLock;
public PowerDetectionService(Context context)
{
this.context = context;
}
public PowerDetectionService()
{}
public void onCreate()
{
super.onCreate();
Log.d("SERVICE", "ON CREATE CALLED");
PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
}
public int OnStartCommand(Intent intent, int flags, int startId)
{
Log.d("SERVICE", "ONSTARTCOMMAND Called");
PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
return START_STICKY;
}
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
Log.d("SERVICE", "ON START CALLED");
PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void receivedPowerConnected()
{
try
{
Toast.makeText(context, "Power connected", Toast.LENGTH_LONG).show();
wakeLock.acquire();
}
catch (Exception ex)
{
Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
}
}
public void receivedPowerDisconnected()
{
try
{
Toast.makeText(context, "Power disconnected", Toast.LENGTH_LONG).show();
wakeLock.release();
}
catch (Exception ex)
{
Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
}
}
}
And below is the mainfest file.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.BoardiesITSolutions.ScreeenStay"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="PowerDetectionService"
android:process=":ScreenStay"
android:icon="#drawable/ic_launcher"
android:label="Screen Stay">
</service>
<receiver android:name="BroadcastReceiveDetection">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
</application>
</manifest>
Hope this helps.
You are starting service in different process.
<service android:name="PowerDetectionService"
android:process=":ScreenStay"
android:icon="#drawable/ic_launcher"
android:label="Screen Stay">
The debugger is attached to your main process. When the new one starts, it has no debugger attached, so it will ignore your breakpoints. If you want to debug remote process, you can do it via Eclipse in DDMS perspective. Under devices, you can see its processes. Then you can select one and press debug selected process (green bug icon). This is also useful when you only want to start debugging your app at some point.
As for debugging onCreate(), you have to attach debugger after the process started, but before onCreate() is called. You can for example put some Thread.sleep() in the beginning of onCreate() for few seconds so you can attach debugger.
Which class are you extending? Service?
The method onStart() is only used for old Android versions (<2.0). For more recent versions you should use onStartCommand() as bellow:
#Override
public int onStartCommand(Intent intent, int flags, int startId)
And you need to return START_STICKY from the method above if you want the service to keeps running after executing the code. If service is not kept alive the PowerManager.FULL_WAKE_LOCK will be released. Probably you can also get away making wakeLock static.
To start service use:
Intent i=new Intent(this, PowerDetectionService.class);
startService(i);
--EDITED--
As per the topic here: getApplication() vs. getApplicationContext() you may get different Context object when getting the context using getApplicationContext(). Try change the following line:
PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
by:
PowerManager pm = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
regrads.
Just a note :
onStart() method is deprecated, and you should use onStartCommand() instead (which will be called only if you start your service with Context.startService().
However, onCreate() should called if your service does run (but only once).

Can't call a Bluetooth BroadcastReceiver method in a Service

I have this Service class:
public class BluetoothService extends Service {
private static Activity mActivity;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
this.registerReceiver(bluetoothReceiver, intentFilter);
}
#Override
public void onDestroy() {
if (bluetoothReceiver != null) {
this.unregisterReceiver(bluetoothReceiver);
}
}
#Override
public void onStart(Intent intent, int startid) {
//
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public static BroadcastReceiver bluetoothReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
TextView tvStatus = (TextView) mActivity.findViewById(R.id.tvtatus);
Messaging.appendMessage(tvStatus, Bluetooth.getDeviceState(state));
if (Bluetooth.isBluetoothEnabled()) {
Messaging.appendMessage(tvStatus, Bluetooth.showMessage());
}
}
}
};
}
And in my Activity class, I have this:
public class MainActivity extends Activity {
private TextView tvStatus;
private Intent intentBluetooth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvStatus = (TextView)findViewById(R.id.tvtatus);
intentBluetooth = new Intent(this, BluetoothService.class);
startService(intentBluetooth);
}
}
The BroadcastReceiver method (bluetoothReceiver) in the Service class is never called. I don't know why. If I have the IntentFilter and the BroadcastReceiver codes above all in an Activity, then it works - but not in a [separate] Service. I'm stumped.
My AndroidManifest.xml is:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.onegoal.androidexample"
android:versionCode="1"
android:versionName="1.0.0"
android:installLocation="auto"
android:hardwareAccelerated="true">
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-feature android:name="android.hardware.bluetooth" android:required="false" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:debuggable="true" >
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".BluetoothService">
</service>
</application>
</manifest>
I'm new to Android so what I'm doing may not be the best. Hope someone can help me.
maybe the fact that your receiver is static causing the problem.
BroadcastReceiver should never be static. it can cause lots of problems.
other really bad design problem with your code - holding reference to activity inside service, and using it to modify views is really wrong thing to do. it can cause easily to memory leek.
the right why to communicate between Service and Activity is by implement android's Messanger, or sending broadcasts between them via BroadcastReceiver.
if you'll listen to my advice - you won't be have to make your receiver static (I guess you've made it static only because you are using the mActivity static instance inside)
and I'm pretty sure it will solve your problem
you can read about Messanger here: http://developer.android.com/reference/android/os/Messenger.html
sure you'll find lots of usage examples in the net.
example of broadcasting updates to the activity from service:
public class MyService extends Service {
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
this.registerReceiver(bluetoothReceiver, intentFilter);
}
#Override
public void onDestroy() {
if (bluetoothReceiver != null) {
this.unregisterReceiver(bluetoothReceiver);
}
super.onDestroy();
}
public BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
updateUIWithNewState(state);
}
}
};
protected void updateUIWithNewState(int state) {
Intent intent = new Intent("serviceUpdateReceivedAction");
intent.putExtra("state", state);
sendBroadcast(intent);
}
}
and that's the activity:
public class MyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MyService.class);
startService(intent);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(mServiceUpdatesReceiver, new IntentFilter("serviceUpdateReceivedAction"));
}
#Override
protected void onPause() {
unregisterReceiver(mServiceUpdatesReceiver);
super.onPause();
}
private BroadcastReceiver mServiceUpdatesReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra("state", -1);
// do what ever you want in the UI according to the state
}
};
}

Categories

Resources