NullPointerException when using getInt(String) - java

I'm android beginner so please be easy on me. I'm doing some "exercises" and i'm writing simple app which will tell RSSI strength of home wifi network. Getting that number is pretty easy, but updating it and showing that on screen it's a little more complicated as i thought.
First this is my onCreate Activity. In this activity i'm launching another android component - Service. Because the code will run in background (i know i could use thread or something else, but this is for "practice" sake, and i have a few ideas what to do with this app, while running service and not interacting with UI )
public class MainActivity extends Activity {
TextView wifi_check;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
referenceViews();
startService(new Intent(this, CheckingWifiService.class));
//wifi_check.setText(""+getIntent().getExtras().getInt("RSSI"));
}
private void referenceViews() {
wifi_check = (TextView) findViewById(R.id.wifiCheck_TV);
}
}
Because my code will run every second or so, i will use TimerTask for this purpose. And here is my TimerTask class, which includes run() method, and code for executing inside
public class TimerTsk extends TimerTask {
Context act;
WifiManager wifiMan;
WifiInfo info;
Bundle sendInfo;
Intent intent;
int rssi;
public TimerTsk(Context context) {
act = context;
}
#Override
public void run() {
intent = new Intent();
sendInfo = new Bundle();
wifiMan = (WifiManager) act.getSystemService(Activity.WIFI_SERVICE);
info = wifiMan.getConnectionInfo();
rssi = info.getRssi();
Log.d("WORKED", "RUNNING SUCESSFULLY");
// i want to send info to my activity
sendInfo.putInt("RSSI", rssi);
intent.putExtras(sendInfo);
}
}
From this class , i want to send result of RSSI to my activity and then update a text. But when i call this code below, on activity i always get NullPointerException.
wifi_check.setText(""+getIntent().getExtras().getInt("RSSI"));
To be honest i had hard time figuring out which part of code is throwing an exepction. And i found that more exactly, this part of code is throwing an exepction.
getInt("RSSI")
Overall i see that service is running, because in my LOGCAT i see a message that i create with Log.d in TimerTsk class.
Any ideas why is this happening?
Here is my service class:
public class CheckingWifiService extends Service{
int rssi;
Timer time;
TimerTsk ttsk;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
time = new Timer();
time.schedule(new TimerTsk(getApplicationContext()), 500);
return START_STICKY;
}
}
Here is my LogCat:

I see a common mistake. Don't do this:
sendInfo.putInt("RSSI", rssi);
intent.putExtras(sendInfo); // This adds a Bundle to your existing Bundle!
You are creating an Intent, with a Bundle of extras, with a Bundle that holds rssi. Leave out this unnecessary Bundle:
intent.putExtras("RSSI", rssi);
Now in your next Activity you can use:
getIntent().getIntExtra("RSSI", 0);
However you should always check to make sure there aren't any surprise null variables:
Intent in = getIntent();
if(in != null) {
int rssi = in.getIntExtra("RSSI", -1);
if(rssi < 0)
wifi_check.setText(""+rssi);
else
wifi_check.setText("Unknown");
}

is your activity starting? I don't see any call to startActivity(). In any case as mentioned by Sam you just need to call putExtra for your intent. don't forget to call
is your activity starting? I don't see any call to startActivity(). In any case as mentioned by Sam you just need to call putExtra for your intent. don't forget to call
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
you need to put this flag when start activies from background

Related

Android using broadcastReceiver, but when I force close the app, I don't get anything in the Activity

Not sure how to get the receiver to work on the activity once the app is forced closed.
What am I missing to get this to work even if the app was forced closed? Any help would be appreciated.
I am getting the BroadcastReceiver service to work, Just not getting anything to pick up on the activity level.
I have my receiver (Service):
public class MyReceiver extends BroadcastReceiver {
public static final String SEND_NOTIFICATION_ACTION = "com.clover.sdk.app.intent.action.APP_NOTIFICATION";
#Override
public void onReceive(Context context, Intent intent) {
Log.i("MyReceiver", "Triggered MyReceiver");
String action = intent.getAction();
Bundle getIntent = intent.getExtras();
if (action.equals(SEND_NOTIFICATION_ACTION)) {
Log.i("MyReceiver Gotten", "Found");
intent = new Intent("broadCastName");
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("orderId", getIntent.getString("payload"));
Log.i("Receiver OrderID", getIntent.getString("payload"));
context.sendBroadcast(intent);
}
}
}
My Activity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerReceiver(broadcastReceiver, new IntentFilter("broadCastName"));
}
}
Then my broadcastReceiver in my activity:
// Add this inside your class
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("MyReceiver Gotten 2", "Found");
Bundle b = intent.getExtras();
Log.i("MyReceiver Gotten 3", b.getString("orderId"));
new SpecificOrderAsyncTask(MainActivity.this).execute(b.getString("orderId"));
}
};
Not sure how to get the receiver to work on the activity once the app is forced closed. What am I missing to get this to work even if the app was forced closed?
That's contradictory - you can't get a receiver to work in an Activity that registered it at runtime if that Activity that is hosting the receiver is killed. When you force close, every in the app process - including the Activity and the receiver you registered with it - disappears.
The point of calling registerReceiver is to listen for broadcasts only during a specific time frame or lifecycle.
If you want the receiver to work even when the app is closed, don't register it at runtime - register it in the manifest.
Simple,
Registering service in an activity is temporary, registering service in a manifest will run even after closing the application.
But the broadcast you use is a simple message transfer system, that won't work even after you register in manifest and close the application. You have to create a background service that runs always in background in android system and should awake listening to some events passed.

Why calling a class that extends Activity does not work when called from one that extends Plugin?

I have a java Class that extends Plugin (PhoneGap), but when inside this class, i call another class that extends Activity, it just doesn't work !. i mean, it seems like it doesn't get called. To confirm this, i have change my second class, this time, not extending from Activity and it works fine. i need teh second one to extends from Activity because i am using this two utilities (getFileStreamPath and openFileOutput) to create a file
File filepath = getFileStreamPath("filename.CPCL"); and openFileOutput
FileOutputStream os = this.openFileOutput(fileName, Context.MODE_PRIVATE);
I have an app with a class which extends a custom Service that calls another class which extends Activity.
First I instantiate the Activity. In the onCreate of your Plugin class use:
// get a handle on your Application
Application app = getApplication();
Intent intent = new Intent(getApplicationContext(), YourActivity.class);
app.startActivity(intent);
This will start your Activity and call the standard Lifecycle events.
The way I handle continued communication with the running Activity is by using a Handler to send a broadcast from your plugin which the Activity picks up in its receiver. In the onCreate of your plugin:
mHandler.post(new Runnable() {
#Override
public void run() {
Log.d(TAG, "Call the Activity");
Intent intent = new Intent(YourActivity.CALL_FROM_PLUGIN);
intent.putExtra("request", <<Any extras you might want to send through>>);
sendBroadcast(intent);
}
});
In the Activity I declare the variable:
public static final String CALL_FROM_PLUGIN= "CALL_FROM_PLUGIN";
then in onCreate() I added the following;
IntentFilter filter = new IntentFilter();
filter.addAction(CALL_FROM_PLUGIN);
registerReceiver(mBroadcastReceiver, filter);
and then implemented a BroadcastReceiver:
BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "BroadcastReceiver.onReceive()");
if (CALL_FROM_PLUGIN.equals(action)) {
Log.d(TAG, "Received call from Plugin");
// DO YOUR STUFF HERE
}
}
};
Someone else might be able to point out why this is necessary from a framework point of view, but this is the way I understand that Activities should be called. I hope this applies to your plugin class the way it does with my service class!

Android :: why getBooleanExtra java.lang.NullPointerException

PROBLEM
As topic mention, I don't know why getBooleanExtra() java.lang.NullPointerException.
I understand that sometimes intent may not contains extras.
However, from the below code as you can see there is a default value for each getBooleanExtra() which is false.
So, that's the reason why I don't understand. please advice. thx!
SOME CODE FROM MY SERVICE CLASS
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("onStartCommand()->","Intent Service.... " + intent);
final boolean SLEEP_MODE_ON = intent.getBooleanExtra("SLEEP_MODE_ON",false);
final boolean SLEEP_MODE_OFF = intent.getBooleanExtra("SLEEP_MODE_OFF",false);
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
connectIfNecessary();
if (SLEEP_MODE_ON){
doSleepMode_on();
} else if (SLEEP_MODE_OFF) {
doSleepMode_off();
}
}
});
thread.start();
return START_STICKY;
}
EDIT as some ask Where I call My service?? First, from activity. Second, from broadcastReceiver
ACTIVITY in onCreate()
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Remove title bar
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
startService(new Intent(this,mqttPushService.class)); //Setup MQTT Service
}//END of onCreate()
BroadcastReceiver
public class SleepModeReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent sleepModeIntent;
int broadcastID = intent.getIntExtra("BROADCAST_ID",0);
switch (broadcastID) {
case DataManager.BROADCAST_ID_SLEEP_MODE_START :
sleepModeIntent = new Intent(context, mqttPushService.class);
sleepModeIntent.putExtra("SLEEP_MODE_ON",true);
context.startService(sleepModeIntent);
break;
case DataManager.BROADCAST_ID_SLEEP_MODE_STOP :
sleepModeIntent = new Intent(context, mqttPushService.class);
sleepModeIntent.putExtra("SLEEP_MODE_OFF",true);
context.startService(sleepModeIntent);
break;
}
}
}
I ran into this recently. The issue is that even services can be killed and restarted by the system , thats why you have START_STICKY. Unlike when you start the service and you pass a valid intent, when the system restarts the service, the intent is null. I just check for a null intent before trying to extract any extras.
Here is the link to the official android developers blog.
http://android-developers.blogspot.com/2010/02/service-api-changes-starting-with.html
and here is the paragraph which basically says what I say above
START_STICKY is basically the same as the previous behavior, where the service is left "started" and will later be restarted by the system. The only difference from previous versions of the platform is that it if it gets restarted because its process is killed, onStartCommand() will be called on the next instance of the service with a null Intent instead of not being called at all. Services that use this mode should always check for this case and deal with it appropriately.

Sending intents from service to activity only when activity is running

I have a service and application. There is communication between them by sending intents on specific situations. In activity I register and unregister broadcast receiver to collect this intents. Intents from service are sending when particular callback method is executed. Is there a possibility to send this intents only when activity is in the foreground? Because when this is hide there is no need to gather this intents (it helpful only to show some situations in real time)? I figure out that in activity could be static field that indicates about such situation, but I don't know how to get access to activity from service and additionally I found information that this is vary bad design practise.. Thank for any suggestions!
Declare this in your Activity:
public static boolean isRunning;
Then in your onPause to set isRunning = false;
and in onResume set it to isRunning = true;
Then from your Service you can simply call ActivityName.isRunning to know if it is in foreground or not!
you can use a static variable within the activity.
class MyActivity extends Activity {
static boolean active = false;
#Override
public void onStart() {
super.onStart();
active = true;
}
#Override
public void onStop() {
super.onStop();
active = false;
}
}
Add just check in service as
if(MyActivity.active)
{
//send broadcast.
}
OR
go with this to check status of activity is it active or not
public boolean isRunning(Context ctx) {
ActivityManager activityManager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (RunningTaskInfo task : tasks) {
if (ctx.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName()))
return true;
}
return false;
}
I'd have a local boolean variable in service:
protected boolean mIsAppRunning;
Call startService() with true/false extra when app resumes/stops:
#Override
protected void onResume() {
super.onResume();
Intent service = new Intent("my.service.ACTION");
service.putExtra("IS_MY_ACTIVITY_RUNNING", true);
startService(service);
}
#Override
protected void onPause() {
Intent service = new Intent("my.service.ACTION");
service.putExtra("IS_MY_ACTIVITY_RUNNING", false);
startService(service);
}
Check that extra in service's onStartCommand() and assign its value to mIsAppRunning:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
mIsAppRunning = intent.getBooleanExtra("IS_MY_ACTIVITY_RUNNING", false);
}
return START_STICKY;
}
If you design the logic in the service a little carefully, you may even get rid of the local variable, mIsAppRunning, and call the required methods depending on the intent extra value.
Hope this helps.

Can I launch an activity from boot-up and have it go into the background without the user seeing it, android

At the moment I have code that starts an application from boot-up but opens it into the foreground.
This was done by
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent start = new Intent(context, ApolloMobileActivity.class);
start.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(start);
Then to get it sent to the background at boot-up I created another java file called, StartAtBootService
so I changed the receiver class to:
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i = new Intent();
i.setAction("com.example.ssab.StartAtBootService");
context.startService(i);
}
And the Service class was
public class StartAtBootService extends Service
{
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public void onCreate()
{
Log.v("StartServiceAtBoot", "StartAtBootService Created");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.v("StartServiceAtBoot", "StartAtBootService -- onStartCommand()");
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
/*
* In Android 2.0 and later, onStart() is depreciated. Use
* onStartCommand() instead, or compile against API Level 5 and
* use both.
* http://android-developers.blogspot.com/2010/02/service-api-changes-starting-with.html
#Override
public void onStart(Intent intent, int startId)
{
Log.v("StartServiceAtBoot", "StartAtBootService -- onStart()");
}
*/
#Override
public void onDestroy()
{
Log.v("StartServiceAtBoot", "StartAtBootService Destroyed");
}
}
Is it possible to change the StartAtBootService to run an activity in another java file called ApolloMobileActivity in the background?
I have tested this code and even though it runs in the background at boot-up it doesn't run the code in ApolloMobileActivity.
Please help! Thanks guys :)
An Activity is an application component that provides a screen with
which users can interact in order to do something, such as dial the
phone, take a photo, send an email, or view a map. Each activity is
given a window in which to draw its user interface. The window
typically fills the screen, but may be smaller than the screen and
float on top of other windows.
from Activities
You can start an Activity, but there is no such thing as an invisible Activity. These are UI-components. If you want to do invisible work in the background, you have to do it in your service.

Categories

Resources