I have got latlong values using shared preferences and stored it as double values.
Declared latlong values globally.
Getting null point Exception.
Tried different ways of declaring values globally,but nothing seems working.
MainActivity.java
public class MapsActivityConnect extends FragmentActivity {
ImageView emerg;
SharedPreferences pref;
String vechile;
Double deslatituded, deslongituded, srclatituded, srclongituded;
private GoogleMap mMap = null;
private final LatLng end = new LatLng(deslatituded, deslongituded);
private final LatLng start = new LatLng(srclatituded, srclongituded);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps_activity_connect);
pref = getSharedPreferences("gps", Context.MODE_PRIVATE);
Bundle extras = getIntent().getExtras();
if (extras != null) {
deslatituded = extras.getDouble("deslatitude");
deslongituded = extras.getDouble("deslongitude");
srclatituded = extras.getDouble("srclatitude");
srclongituded = extras.getDouble("srclongitude");
vechile = extras.getString("vechile");
if (!Utils.isConnected(getApplicationContext())) {
Toast.makeText(getApplicationContext(), "Internet not available. Cross check your internet connectivity and try again", Toast.LENGTH_LONG).show();
return;
}
if (!Utils.isGPSTurnOn(getApplicationContext())) {
showGPSDialog();
return;
}
}
}
#SuppressLint("NewApi")
#Override
protected void onResume() {
super.onResume();
if (Utils.isConnected(getApplicationContext())) {
mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
mMap.setMyLocationEnabled(true);
final TextView txtDistance = (TextView) findViewById(R.id.txtSpeed);
new Routing(getParent(), mMap, txtDistance).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, start, end);
}
}
private void showGPSDialog() {
new AlertDialog.Builder(new ContextThemeWrapper(this, R.style.AppBaseTheme)) // Theme
.setTitle(R.string.gps_lable_gps) // setTitle
.setMessage(R.string.gps_lable_warning_message) // setMessage
.setInverseBackgroundForced(false).setCancelable(false) //
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
#Override
public void onClick(final DialogInterface dialog, final int which) {
startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 0);
}
}).setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
#Override
public void onClick(final DialogInterface dialog, final int which) {
dialog.dismiss();
}
}).setIcon(android.R.drawable.ic_dialog_alert).show();
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (Utils.isGPSTurnOn(getApplicationContext())) {
onResume();
}
}
}
Logcat
9-29 13:40:56.383 32078- 32149/zybo.example.ramz.demo_location_tracking V/RenderScript﹕ Application requested CPU execution
09-29 13:40:56.393 32078- 32149/zybo.example.ramz.demo_location_tracking V/RenderScript﹕ 0xb7579cd8 Launching thread(s), CPUs 4
09-29 13:41:01.527 32078-32078/zybo.example.ramz.demo_location_tracking D/AndroidRuntime﹕ Shutting down VM
09-29 13:41:01.536 32078-32078/zybo.example.ramz.demo_location_tracking E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: zybo.example.ramz.demo_location_tracking, PID: 32078
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{zybo.example.ramz.demo_location_tracking/zybo.example.ramz.demo_location_tracking.MapsActivityConnect}: java.lang.NullPointerException: Attempt to invoke virtual method 'double java.lang.Double.doubleValue()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2250)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413)
at android.app.ActivityThread.access$800(ActivityThread.java:155)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'double java.lang.Double.doubleValue()' on a null object reference
at zybo.example.ramz.demo_location_tracking.MapsActivityConnect.<init>(MapsActivityConnect.java:62)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.Class.newInstance(Class.java:1606)
at android.app.Instrumentation.newActivity(Instrumentation.java:1089)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2240)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413)
at
android.app.ActivityThread.access$800(ActivityThread.java:155)
You need to initialize with values.
Double deslatituded, deslongituded, srclatituded, srclongituded;
You declare the doubles, but these are objects, not primitives. Therefore the default value is null. And the unboxing tries to get the primitive like
null.doubleValue()
Make them primitive or assign a default value like:
Double desLatituded = new Double(0);
I am not sure what is your error. But one of the scenario is
you declare class variables
private final LatLng end = new LatLng(deslatituded, deslongituded);
private final LatLng start = new LatLng(srclatituded, srclongituded);
Here deslatituded, deslongituded values must be null. Maybe this will the reason for the nullPoiner please check this.
You need to pass the values for this. Or just initialise the values like deslatituded=0 or something. This will save you from crash
Try this (and make sure your LatLng variables aren't final):
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps_activity_connect);
pref = getSharedPreferences("gps", Context.MODE_PRIVATE);
Bundle extras = getIntent().getExtras();
if (extras != null) {
deslatituded = extras.getDouble("deslatitude");
deslongituded = extras.getDouble("deslongitude");
srclatituded = extras.getDouble("srclatitude");
srclongituded = extras.getDouble("srclongitude");
// NEW CODE
end = new LatLng(deslatituded, deslongituded);
start = new LatLng(srclatituded, srclongituded);
// END NEW CODE
vechile = extras.getString("vechile");
if (!Utils.isConnected(getApplicationContext())) {
Toast.makeText(getApplicationContext(), "Internet not available. Cross check your internet connectivity and try again", Toast.LENGTH_LONG).show();
return;
}
if (!Utils.isGPSTurnOn(getApplicationContext())) {
showGPSDialog();
return;
}
}
}
Please check if your extras has the key "deslatitude"
like:
if(getIntent().hasCategory("deslatitude"))
{
deslatituded = extras.getDouble("deslatitude");
}
Log.e(TAG, "deslatitude: " + deslatituded );
And if your log prints the valuew then check it for all (deslat,deslong,srclat,srclong)
Are there any values in
extras.getDouble("deslatitude");
extras.getDouble("deslongitude");
extras.getDouble("srclatitude");
extras.getDouble("srclongitude");
there is nothing in intent extras.
Related
I am new to Android Studio and learning how to create SharedPreference variables. I'm stuck that,updating the value of the string in SharedPreference raises a NullPointerException when I execute below code. Any help will be much appreciated. Thanks in advance.
This is my SettingPage
#Override //Creating the setting page
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settingpage);
setMinsBar = findViewById(R.id.numMinsBar);
setTimeEnterButton = findViewById(R.id.setTimeButton);
musicYesSwitch = findViewById(R.id.musicSwitch);
soundYesSwitch = findViewById(R.id.soundSwitch);
minsLeftTV = findViewById(R.id.minsLeftTV);
timerEndsTV = findViewById(R.id.timerEndsTV);
varAcrossApp = this.getSharedPreferences(SP, Context.MODE_PRIVATE);
//Setting on click listener for the enter button for the time set
setTimeEnterButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
timeInInt = Integer.parseInt(setMinsBar.getText().toString());
saveData();
}
});
}
public void saveData(){ //Declaring method saveData
varEditor = varAcrossApp.edit();
varEditor.putInt(timeInStringSP, timeInInt);
varEditor.putBoolean(musicYesSP, musicYesSwitch.isChecked());
varEditor.putBoolean(soundYesSP, soundYesSwitch.isChecked());
varEditor.apply();
Toast.makeText(getApplicationContext(), "Duration set", Toast.LENGTH_SHORT).show();
}
public void loadData(){ //Declaring method loadData
finalTimeInMins = varAcrossApp.getInt(timeInStringSP, 0);
musicYes = varAcrossApp.getBoolean(musicYesSP, false);
soundYes = varAcrossApp.getBoolean(soundYesSP, false);
}
public void updateView() {
minsLeftTV.setText(finalTimeInMins);
if (musicYes = true) {
timerEndsTV.setText("-Turn off music");
} else if (soundYes = true) {
timerEndsTV.setText("-Change sound profile to 'Sound'");
} else if (musicYes && soundYes) {
timerEndsTV.setText("-Turn off music /n-Change sound profile to 'Sound'");
} else {
timerEndsTV.setText("-Do nothing");
}
}
This is MainActivity
#Override //Creating the app here
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.homepage);
startButton = findViewById(R.id.startButton);
SettingPage settingPage = new SettingPage();
settingPage.loadData();
settingPage.updateView();
}
Error Code and Stack trace given below:
Process: com.example.sleep, PID: 6935
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.sleep/com.example.sleep.MainActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'int android.content.SharedPreferences.getInt(java.lang.String, int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3260)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3396)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2009)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7319)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:934)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'int android.content.SharedPreferences.getInt(java.lang.String, int)' on a null object reference
at com.example.sleep.SettingPage.loadData(SettingPage.java:77)
at com.example.sleep.MainActivity.onCreate(MainActivity.java:25)
at android.app.Activity.performCreate(Activity.java:7783)
at android.app.Activity.performCreate(Activity.java:7772)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3235)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3396)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2009)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7319)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:934)
You should not call varAcrossApp.getInt before varAcrossApp = this.getSharedPreferences(SP, Context.MODE_PRIVATE);
This is how shared preferences should/can be used in android.
class SettingsSpDao { // shared preferences data access object
private static final String SP = "SP";
private static final String MUSIC_YES = "music_yes";
public static boolean isMusicYes(Context context) {
// you can initialize sp beforehand so you don't have to pass in context but I prefer it this way, so I don't have to initialize it before using it
SharedPreferences sp = context.getSharedPreferences(SP, Context.MODE_PRIVATE);
return sp.getBoolean(MUSIC_YES , false);
}
// add your methods here
}
// call it anywhere as long as you can pass a context, such as Activity.
musicYes = SettingsSpDao.isMusicYes(this); // in your case `this` since it's in an Activity
I have an activity that has voice function. which lets you say 4 words and these words are added into an array. I am want only the second and the last word.
I am converting the second word into a string and the last word into an int (last word is always a number from 1-5).
The code is working fine as long as I don't say 2 or 4. as soon I say those two numbers the app crashes.
how can I fix this?
I tried of thinking of inserting an if statement. for example - if string contains word for, four then it = 4. (rough code).
I have posted the code and stack trace below.
public class Report extends AppCompatActivity {
private static final int REQ_CODE_SPEECH_INPUT = 100;
private TextView mVoiceInputTv;
private ImageButton mSpeakBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.report);
mVoiceInputTv = (TextView) findViewById(R.id.voiceInput);
mSpeakBtn = (ImageButton) findViewById(R.id.btnSpeak);
mSpeakBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startVoiceInput();
}
});
final String carreg = mVoiceInputTv.getText().toString();
}
private void startVoiceInput() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "e.g- Report fpg563 rating 3");
try {
startActivityForResult(intent, REQ_CODE_SPEECH_INPUT);
} catch (ActivityNotFoundException a) {
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQ_CODE_SPEECH_INPUT: {
if (resultCode == RESULT_OK && null != data) {
ArrayList<String> result = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
mVoiceInputTv.setText(result.get(0));
}
break;
}
}
if(mVoiceInputTv.getText().toString().contains("report")) {
input();
}
}
public void input() {
String test = mVoiceInputTv.getText().toString();
String[] ms = test.split(" ");
List<String> selectedWords = new ArrayList<>();
for (int i = 0; i < ms.length; i++) {
selectedWords.add(ms[i]);
final String carreg = ms[1];
final String newrating = ms[3];
final int rating = Integer.parseInt(newrating);
Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
boolean success = jsonResponse.getBoolean("success");
if (success) {
Intent intent = new Intent(Report.this, Report.class);
Report.this.startActivity(intent);
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(Report.this);
builder.setMessage("Reporting Failed")
.setNegativeButton("Retry", null)
.create()
.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
Report_request registerRequest = new Report_request(carreg, rating, responseListener);
RequestQueue queue = Volley.newRequestQueue(Report.this);
queue.add(registerRequest);
}
}
}
Stack Trace:
10-25 17:45:41.449 32501-32501/com.example.naveen.loginregister E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.naveen.loginregister, PID: 32501
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=Intent { launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 }(has extras) }} to activity {com.example.naveen.loginregister/com.example.naveen.loginregister.Report}: java.lang.NumberFormatException: For input string: "for"
at android.app.ActivityThread.deliverResults(ActivityThread.java:4472)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4515)
at android.app.ActivityThread.-wrap22(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1687)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
Caused by: java.lang.NumberFormatException: For input string: "for"
at java.lang.Integer.parseInt(Integer.java:521)
at java.lang.Integer.parseInt(Integer.java:556)
at com.example.naveen.loginregister.Report.input(Report.java:103)
at com.example.naveen.loginregister.Report.onActivityResult(Report.java:85)
at android.app.Activity.dispatchActivityResult(Activity.java:7256)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4468)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4515)
at android.app.ActivityThread.-wrap22(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1687)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
whats up with this downvotes? im asking an honest question. ofcourse the grammer might be bad. but im still learning english. u want me to go to a english classs before i post a question?
This is must be happening because 2 is also the word "to" or "too" which is not going to be convertable into an int unless you are catching those cases. Similarly, as you pointed out 4 is probably being converted to the word "for" which again won't convert to an int unless you specifically catch that case.
I think you're on the right track, catching those cases where the voice to text is going to hand you a word that sounds like a number but isn't one.
BUT if you want your code to not crash you need to prepare for any possible input. So you should be catching the exception if it is thrown and then doing the right thing.
try {
final int rating = Integer.parseInt(newrating);
} catch ( NumberFormatException e ) {
//uhoh couldn't get the number
//prompt the user to try again or
//do something else that makes sense
}
I'm working on a term project and I'm new to java and android app development. I have experience in other programming languages, though. I'm trying to reverse engineer an app to make it able to connect and send data via bluetooth. I want to make a list with all the available bluetooth devices, a button to turn on/off bluetooth, one for making the phone discoverable for other devices and another to search for unpaired devices. But every time I add an OnClickListener to the onCreate method, the app crashes before it opens. Could anyone help me out?
The source code for the app I am trying to modify can be found here:
https://github.com/pazaan/600SeriesAndroidUploader
Here is the part that seems to makes it crash:
lvNewDevices.setOnItemClickListener(MainActivity.this);
btnONOFF.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d(TAG, "onClick: enabling/disabling bluetooth.");
enableDisableBT();
}
});
btnStartConnection.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startConnection();
}
});
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
byte[] bytes = etSend.getText().toString().getBytes(Charset.defaultCharset());
mBluetoothConnection.write(bytes);
}
});
And here is all of OnCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate called");
super.onCreate(savedInstanceState);
Button btnONOFF = (Button) findViewById(R.id.btnONOFF);
btnEnableDisable_Discoverable = (Button) findViewById(R.id.btnDiscoverable_on_off);
lvNewDevices = (ListView) findViewById(R.id.lvNewDevices);
mBTDevices = new ArrayList<>();
btnStartConnection = (Button) findViewById(R.id.btnStartConnection);
//Broadcasts when bond state changes (ie:pairing)
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(mBroadcastReceiver4, filter);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//FUCKUP:
lvNewDevices.setOnItemClickListener(MainActivity.this);
btnONOFF.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d(TAG, "onClick: enabling/disabling bluetooth.");
enableDisableBT();
}
});
btnStartConnection.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startConnection();
}
});
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
byte[] bytes = etSend.getText().toString().getBytes(Charset.defaultCharset());
mBluetoothConnection.write(bytes);
}
});
mRealm = Realm.getDefaultInstance();
RealmResults<PumpStatusEvent> data = mRealm.where(PumpStatusEvent.class)
.findAllSorted("eventDate", Sort.DESCENDING);
if (data.size() > 0)
dataStore.setLastPumpStatus(data.first());
setContentView(R.layout.activity_main);
PreferenceManager.getDefaultSharedPreferences(getBaseContext()).registerOnSharedPreferenceChangeListener(this);
prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
if (!prefs.getBoolean(getString(R.string.preference_eula_accepted), false)) {
stopCgmService();
}
// setup preferences
configurationStore.setPollInterval(Long.parseLong(prefs.getString("pollInterval", Long.toString(MedtronicCnlIntentService.POLL_PERIOD_MS))));
configurationStore.setLowBatteryPollInterval(Long.parseLong(prefs.getString("lowBatPollInterval", Long.toString(MedtronicCnlIntentService.LOW_BATTERY_POLL_PERIOD_MS))));
configurationStore.setReducePollOnPumpAway(prefs.getBoolean("doublePollOnPumpAway", false));
chartZoom = Integer.parseInt(prefs.getString("chartZoom", "3"));
configurationStore.setMmolxl(prefs.getBoolean("mmolxl", false));
configurationStore.setMmolxlDecimals(prefs.getBoolean("mmolDecimals", false));
// Disable battery optimization to avoid missing values on 6.0+
// taken from https://github.com/NightscoutFoundation/xDrip/blob/master/app/src/main/java/com/eveningoutpost/dexdrip/Home.java#L277L298
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final String packageName = getPackageName();
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
Log.d(TAG, "Requesting ignore battery optimization");
try {
// ignoring battery optimizations required for constant connection
// to peripheral device - eg CGM transmitter.
final Intent intent = new Intent();
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.d(TAG, "Device does not appear to support battery optimization whitelisting!");
}
}
}
LocalBroadcastManager.getInstance(this).registerReceiver(
statusMessageReceiver,
new IntentFilter(MedtronicCnlIntentService.Constants.ACTION_STATUS_MESSAGE));
LocalBroadcastManager.getInstance(this).registerReceiver(
new UpdatePumpReceiver(),
new IntentFilter(MedtronicCnlIntentService.Constants.ACTION_UPDATE_PUMP));
mEnableCgmService = Eula.show(this, prefs);
IntentFilter batteryIntentFilter = new IntentFilter();
batteryIntentFilter.addAction(Intent.ACTION_BATTERY_LOW);
batteryIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
batteryIntentFilter.addAction(Intent.ACTION_BATTERY_OKAY);
registerReceiver(batteryReceiver, batteryIntentFilter);
IntentFilter usbIntentFilter = new IntentFilter();
usbIntentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
usbIntentFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
usbIntentFilter.addAction(MedtronicCnlIntentService.Constants.ACTION_USB_PERMISSION);
registerReceiver(usbReceiver, usbIntentFilter);
LocalBroadcastManager.getInstance(this).registerReceiver(
usbReceiver,
new IntentFilter(MedtronicCnlIntentService.Constants.ACTION_NO_USB_PERMISSION));
LocalBroadcastManager.getInstance(this).registerReceiver(
usbReceiver,
new IntentFilter(MedtronicCnlIntentService.Constants.ACTION_USB_REGISTER));
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setElevation(0);
getSupportActionBar().setTitle("Nightscout");
}
final PrimaryDrawerItem itemSettings = new PrimaryDrawerItem()
.withName("Settings")
.withIcon(GoogleMaterial.Icon.gmd_settings)
.withSelectable(false);
final PrimaryDrawerItem itemRegisterUsb = new PrimaryDrawerItem()
.withName("Registered devices")
.withIcon(GoogleMaterial.Icon.gmd_usb)
.withSelectable(false);
final PrimaryDrawerItem itemStopCollecting = new PrimaryDrawerItem()
.withName("Stop collecting data")
.withIcon(GoogleMaterial.Icon.gmd_power_settings_new)
.withSelectable(false);
final PrimaryDrawerItem itemGetNow = new PrimaryDrawerItem()
.withName("Read data now")
.withIcon(GoogleMaterial.Icon.gmd_refresh)
.withSelectable(false);
final PrimaryDrawerItem itemUpdateProfile = new PrimaryDrawerItem()
.withName("Update pump profile")
.withIcon(GoogleMaterial.Icon.gmd_insert_chart)
.withSelectable(false);
final PrimaryDrawerItem itemClearLog = new PrimaryDrawerItem()
.withName("Clear log")
.withIcon(GoogleMaterial.Icon.gmd_clear_all)
.withSelectable(false);
final PrimaryDrawerItem itemCheckForUpdate = new PrimaryDrawerItem()
.withName("Check for App update")
.withIcon(GoogleMaterial.Icon.gmd_update)
.withSelectable(false);
assert toolbar != null;
new DrawerBuilder()
.withActivity(this)
.withAccountHeader(new AccountHeaderBuilder()
.withActivity(this)
.withHeaderBackground(R.drawable.drawer_header)
.build()
)
.withTranslucentStatusBar(false)
.withToolbar(toolbar)
.withActionBarDrawerToggle(true)
.withSelectedItem(-1)
.addDrawerItems(
itemSettings,
//itemUpdateProfile, // TODO - re-add when we to add Basal Profile Upload
itemRegisterUsb,
itemCheckForUpdate,
itemClearLog,
itemGetNow,
itemStopCollecting
)
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
#Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
if (drawerItem.equals(itemSettings)) {
openSettings();
} else if (drawerItem.equals(itemRegisterUsb)) {
openUsbRegistration();
} else if (drawerItem.equals(itemStopCollecting)) {
mEnableCgmService = false;
stopCgmService();
finish();
} else if (drawerItem.equals(itemGetNow)) {
// It was triggered by user so start reading of data now and not based on last poll.
sendStatus("Requesting poll now...");
startCgmService(System.currentTimeMillis() + 1000);
} else if (drawerItem.equals(itemClearLog)) {
clearLogText();
} else if (drawerItem.equals(itemCheckForUpdate)) {
checkForUpdateNow();
}
return false;
}
})
.build();
mTextViewLog = (TextView) findViewById(R.id.textview_log);
mScrollView = (ScrollView) findViewById(R.id.scrollView);
mScrollView.setSmoothScrollingEnabled(true);
mChart = (GraphView) findViewById(R.id.chart);
// disable scrolling at the moment
mChart.getViewport().setScalable(false);
mChart.getViewport().setScrollable(false);
mChart.getViewport().setYAxisBoundsManual(true);
mChart.getViewport().setMinY(80);
mChart.getViewport().setMaxY(120);
mChart.getViewport().setXAxisBoundsManual(true);
final long now = System.currentTimeMillis(),
left = now - chartZoom * 60 * 60 * 1000;
mChart.getViewport().setMaxX(now);
mChart.getViewport().setMinX(left);
// due to bug in GraphView v4.2.1 using setNumHorizontalLabels reverted to using v4.0.1 and setOnXAxisBoundsChangedListener is n/a in this version
/*
mChart.getViewport().setOnXAxisBoundsChangedListener(new Viewport.OnXAxisBoundsChangedListener() {
#Override
public void onXAxisBoundsChanged(double minX, double maxX, Reason reason) {
double rightX = mChart.getSeries().get(0).getHighestValueX();
hasZoomedChart = (rightX != maxX || rightX - chartZoom * 60 * 60 * 1000 != minX);
}
});
*/
mChart.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if (!mChart.getSeries().isEmpty() && !mChart.getSeries().get(0).isEmpty()) {
double rightX = mChart.getSeries().get(0).getHighestValueX();
mChart.getViewport().setMaxX(rightX);
mChart.getViewport().setMinX(rightX - chartZoom * 60 * 60 * 1000);
}
hasZoomedChart = false;
return true;
}
});
mChart.getGridLabelRenderer().setNumHorizontalLabels(6);
// due to bug in GraphView v4.2.1 using setNumHorizontalLabels reverted to using v4.0.1 and setHumanRounding is n/a in this version
// mChart.getGridLabelRenderer().setHumanRounding(false);
mChart.getGridLabelRenderer().setLabelFormatter(
new DefaultLabelFormatter() {
DateFormat mFormat = new SimpleDateFormat("HH:mm", Locale.US); // 24 hour format forced to fix label overlap
#Override
public String formatLabel(double value, boolean isValueX) {
if (isValueX) {
return mFormat.format(new Date((long) value));
} else {
return MainActivity.strFormatSGV(value);
}
}
}
);
}
Here is the logcat output:
09-26 12:38:19.826 6324-6324/? I/art: Late-enabling -Xcheck:jni
09-26 12:38:20.157 6324-6324/info.nightscout.android E/Fabric: Failure onPreExecute()
java.lang.IllegalArgumentException: Fabric could not be initialized, API key missing from AndroidManifest.xml. Add the following tag to your Application element
<meta-data android:name="io.fabric.ApiKey" android:value="YOUR_API_KEY"/>
at io.fabric.sdk.android.services.common.ApiKey.logErrorOrThrowException(ApiKey.java:110)
at io.fabric.sdk.android.services.common.ApiKey.getValue(ApiKey.java:61)
at com.crashlytics.android.core.CrashlyticsCore.onPreExecute(CrashlyticsCore.java:219)
at com.crashlytics.android.core.CrashlyticsCore.onPreExecute(CrashlyticsCore.java:207)
at io.fabric.sdk.android.InitializationTask.onPreExecute(InitializationTask.java:44)
at io.fabric.sdk.android.services.concurrency.AsyncTask.executeOnExecutor(AsyncTask.java:611)
at io.fabric.sdk.android.services.concurrency.PriorityAsyncTask.executeOnExecutor(PriorityAsyncTask.java:43)
at io.fabric.sdk.android.Kit.initialize(Kit.java:69)
at io.fabric.sdk.android.Fabric.initializeKits(Fabric.java:440)
at io.fabric.sdk.android.Fabric.init(Fabric.java:384)
at io.fabric.sdk.android.Fabric.setFabric(Fabric.java:342)
at io.fabric.sdk.android.Fabric.with(Fabric.java:313)
at info.nightscout.android.UploaderApplication.onCreate(UploaderApplication.java:32)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1046)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5402)
at android.app.ActivityThread.-wrap2(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1541)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
09-26 12:38:20.202 6324-6379/info.nightscout.android E/Fabric: Error dealing with settings
java.lang.IllegalArgumentException: Fabric could not be initialized, API key missing from AndroidManifest.xml. Add the following tag to your Application element
<meta-data android:name="io.fabric.ApiKey" android:value="YOUR_API_KEY"/>
at io.fabric.sdk.android.services.common.ApiKey.logErrorOrThrowException(ApiKey.java:110)
at io.fabric.sdk.android.services.common.ApiKey.getValue(ApiKey.java:61)
at io.fabric.sdk.android.services.settings.Settings.initialize(Settings.java:78)
at io.fabric.sdk.android.Onboarding.retrieveSettingsData(Onboarding.java:124)
at io.fabric.sdk.android.Onboarding.doInBackground(Onboarding.java:99)
at io.fabric.sdk.android.Onboarding.doInBackground(Onboarding.java:45)
at io.fabric.sdk.android.InitializationTask.doInBackground(InitializationTask.java:63)
at io.fabric.sdk.android.InitializationTask.doInBackground(InitializationTask.java:28)
at io.fabric.sdk.android.services.concurrency.AsyncTask$2.call(AsyncTask.java:311)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
09-26 12:38:20.252 6324-6324/info.nightscout.android W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
09-26 12:38:20.349 6324-6324/info.nightscout.android I/MainActivity: onCreate called
09-26 12:38:20.652 6324-6324/info.nightscout.android D/AndroidRuntime: Shutting down VM
09-26 12:38:20.652 6324-6324/info.nightscout.android E/AndroidRuntime: FATAL EXCEPTION: main
Process: info.nightscout.android, PID: 6324
java.lang.RuntimeException: Unable to start activity ComponentInfo{info.nightscout.android/info.nightscout.android.medtronic.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2659)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at info.nightscout.android.medtronic.MainActivity.onCreate(MainActivity.java:349)
at android.app.Activity.performCreate(Activity.java:6672)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1140)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2612)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
Move the code setContentView(R.layout.activity_main);
under the super.onCreate(savedInstanceState);
you are mapping the views before adding layout in your code.
your onCreate() should be
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate called");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Do mapping all views
Your Error log is showing you your solution. The project is using Fabric API. So naturally you need to add Fabric API key to your project.
Do as suggested in Error log. Add following line in Android Manifest.
<meta-data android:name="io.fabric.ApiKey" android:value="YOUR_API_KEY"/>
For your API key, make a project using Fabric account and get your API key.
So basically I want the app to: after pressing a button opens the gallery, the user selects one image and after that saves the uri in a variable. That's all it needs to do but what I found is that after calling startActivityForResult() subsequent code still runs in the background creating a NullPointerException error, since the variable I wanted has not yet been retrieved from the intent.
public class MainActivity extends AppCompatActivity {
final static int PICK_IMAGE_REQUEST = 1;
private String imageUriStr;
SharedPreferences prefs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prefs = this.getSharedPreferences("MyPreferences",MODE_PRIVATE);
ImageView addImgButton = (ImageView) findViewById(R.id.add_img_button);
addImgButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
if (prefs.contains(imageUriStr)) {
imageUriStr = prefs.getString("imageUriStr", ""); //Get the data from prefs
}
Log.d("Value",imageUriStr); //verify if it is correct
prefs.edit().clear();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
imageUriStr = data.getData().toString(); //convert to string to use it with SharedPreferences
prefs.edit().putString("imageUriStr",imageUriStr).apply();
}
}
}
One solution would be to do everything inside the onActivityresult, but I also want to later user another intent to crop the image based on that uri, but I think an Intent inside an onActivityresult will be too messy or is it acceptable? I guess I'm missing something.
Keeping with my code will generate this
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.prototypeapp, PID: 17826
java.lang.NullPointerException: println needs a message
at android.util.Log.println_native(Native Method)
at android.util.Log.d(Log.java:154)
at com.example.android.prototypeapp.MainActivity$1$override.onClick(MainActivity.java:41)
at com.example.android.prototypeapp.MainActivity$1$override.access$dispatch(MainActivity.java)
at com.example.android.prototypeapp.MainActivity$1.onClick(MainActivity.java:0)
at android.view.View.performClick(View.java:5264)
at android.view.View$PerformClick.run(View.java:21297)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
Your private String imageUriStr; is null.Since it is null you are getting null pointer exception. Assign it with the empty string like : private String imageUriStr = "";.
AND
Check in shared preference like :
if(prefs.contains("imageUriStr"))
Your Code is crashing on this line:
Log.d("Value",imageUriStr);
Reason: imageUriStr value is null and a valid message is required to print the log
You can either use Log as :
Log.d("Value","Image URI Value: "+imageUriStr);
or you can put your Log inside if block like:
if (prefs.contains(imageUriStr)) {
imageUriStr = prefs.getString("imageUriStr", "");//Get the data from prefs
Log.d("Value",imageUriStr); //verify if it is correct
}
why I dont know,I take this fault.The program was running before.But now I take this fault.Thank you for help...
MenuActivity.java:
final Context context = this;
private LocationManager mLocationManager;
private String PROVİDER = LocationManager.GPS_PROVIDER;
private GoogleMap googleHarita;
Location mLocation;
public class MenuActivity extends FragmentActivity {
final Context context = this;
private static final int CAMERA_REQUEST = 1888;
TextView e_kor, b_kor, acikAdres;
Fragment harita;
RadarView mRadarView = null;
private LocationManager mLocationManager;
private String PROVİDER = LocationManager.GPS_PROVIDER;
private GoogleMap googleHarita=null;
Location mLocation = null;
TelephonyManager telemamanger;
String getSimSerialNumber;
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
// telefon numarası nesnesi
telemamanger = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
e_kor = (TextView) findViewById(R.id.enlmkor);
b_kor = (TextView) findViewById(R.id.bylmkor);
acikAdres = (TextView) findViewById(R.id.acikAdres);
// resim metodu
mRadarView = (RadarView) findViewById(R.id.radarView);
// radar çalıştırma metodları
mRadarView.setShowCircles(true);
mRadarView.startAnimation();
// Konum-lokasyon kodları
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
final Location mLocation = mLocationManager
.getLastKnownLocation(PROVİDER);
if (googleHarita == null) {
googleHarita = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.haritafragment)).getMap();
if (googleHarita != null) {
LatLng koordinat = new LatLng(mLocation.getLatitude(),
mLocation.getLongitude());
googleHarita.addMarker(new MarkerOptions().position(koordinat));
googleHarita.moveCamera(CameraUpdateFactory.newLatLngZoom(
koordinat, 10));
}
}
showLocation(mLocation);
new GetAddressTask().execute(mLocation);
}
// Lokasyon işlemleri
private void showLocation(Location location) {
if (location == null) {
Toast.makeText(getApplicationContext(), "Konum Bulunamadı",
Toast.LENGTH_SHORT).show();
} else {
e_kor.setText(location.getLatitude() + "");
b_kor.setText(location.getLongitude() + "");
}
}
#Override
protected void onPause() {
super.onPause();
mLocationManager.removeUpdates(listener);
}
#Override
protected void onResume() {
super.onResume();
mLocationManager.requestLocationUpdates(PROVİDER, 0, 0, listener);
}
// Konum listener
private LocationListener listener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
showLocation(location);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
public class GetAddressTask extends AsyncTask<Location, Void, String> {
#Override
protected String doInBackground(Location... locations) {
Geocoder geocoder = new Geocoder(MenuActivity.this);
Location location = locations[0];
List<Address> addresses;
String addrStr = null;
try {
addresses = (List<Address>) geocoder.getFromLocation(
location.getLatitude(), location.getLongitude(), 5);
Address addr = addresses.get(0);
addrStr = addr.getAddressLine(0) + ", " + addr.getAdminArea()
+ ", " + addr.getCountryName();
} catch (IOException e) {
e.printStackTrace();
}
return addrStr;
}
#Override
protected void onPostExecute(String result) {
acikAdres.setText(result);
}
}
My Log Cat:
11-10 02:20:50.508: E/AndroidRuntime(29376): FATAL EXCEPTION: main
11-10 02:20:50.508: E/AndroidRuntime(29376): Process: com.gpsacilbildirim, PID: 29376
11-10 02:20:50.508: E/AndroidRuntime(29376): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gpsacilbildirim/com.gpsacilbildirim.MainActivity}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gpsacilbildirim/com.gpsacilbildirim.MenuActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
11-10 02:20:50.508: E/AndroidRuntime(29376): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2658)
11-10 02:20:50.508: E/AndroidRuntime(29376): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2723)
11-10 02:20:50.508: E/AndroidRuntime(29376): at android.app.ActivityThread.access$900(ActivityThread.java:172)
11-10 02:20:50.508: E/AndroidRuntime(29376): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1422)
The exception you're seeing in logcat points to a problem in the onCreate method of your activity.
The interesting part is this:
java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference. It's telling you that whatever object you're calling getLatitude() on is null.
Looking at the body of the method, it's only possible on this line: LatLng koordinat = new LatLng(mLocation.getLatitude(), mLocation.getLongitude());. Therefore you can tell that the crash is caused by mLocation being null.
You're initializing mLocation like this: mLocationManager.getLastKnownLocation(PROVİDER);.
The documentation tells you it's possible to get a null return value if the provider is disabled.
That should answer the "why". Now you can think about the best way to work around this for your application. Can you try another provider? If none of the providers are enabled, can you default to a generic location? Do you want to show an error message instructing the user to enable location services and provide a way to try again?
the getLastKnownLocation() method can and will return null. The main problem is that it doesn't prompt a request to the OS for a new location lock, instead it just checks if there was a last known location from some other app's location request. If no other app had recently made a location request, then you get a null location returned to you.
The only way to guarantee that you actually get a location is to request one, and this is done with a call to requestLocationUpdates().
The location passed into the onLocationChanged() callback method will not be null, since the callback only occurs on a successful location lock.