android Refresh current Location - android

In my application I want to receive SMS and afert that, I want to get the the location of the phone and when I have the location, I want to send it By SMS...
by now, there is what I have :
package com.receiver;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
public class SMSReceiver extends BroadcastReceiver{
private final String ACTION_RECEIVE_SMS = "android.provider.Telephony.SMS_RECEIVED";
private String numero;
private String msg;
#Override
public void onReceive(Context context, Intent intent){
Log.i("ReceiveBootCompleted","****** Boot terminer ********************");
Log.i("ReceiveBootCompleted"," ***** lancement du service Test **************");
context.startService(new Intent().setComponent(new ComponentName(context.getPackageName(), SMSReceiver.class.getName())));
if (intent.getAction().equals(ACTION_RECEIVE_SMS)){
Bundle bundle = intent.getExtras();
if (bundle != null){
Object[] pdus = (Object[]) bundle.get("pdus");
final SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++){
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
if (messages.length > -1){
final String messageBody = messages[0].getMessageBody();
final String phoneNumber = >messages[0].getDisplayOriginatingAddress();
if(messageBody.equals("mollo")){
app.smartfinder.SmartFinderActivity.send_message(phoneNumber);
}
}
}
}
}
and :
package app.smartfinder;
import java.io.IOException;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.TextView;
import android.widget.Toast;
public class SmartFinderActivity extends Activity implements LocationListener {
LocationManager lm;
private Location location;
private double lat = 0;
private double lng = 0;
TextView position;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState){
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lm = (LocationManager) this.getSystemService(LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, this);
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0, this);
position = (TextView)findViewById(R.id.var_current_pos);
}
public void onClick_conf(View view){
Toast.makeText(SmartFinderActivity.this, "config", Toast.LENGTH_LONG).show();
Intent settingsActivity = new Intent(getBaseContext(), Preferences.class);
startActivity(settingsActivity);
}
public void onClick_hist (View view){
Toast.makeText(SmartFinderActivity.this, "history", Toast.LENGTH_LONG).show();
}
public void onLocationChanged(Location location) {
lat = location.getLatitude();
lng = location.getLongitude();
afficherAdresse();
position.setOnClickListener(new OnClickListener() { public void onClick(View v) {
Intent intent_map = new Intent(getBaseContext(), Map.class);
intent_map.putExtra("lat", lat);
intent_map.putExtra("lng", lng);
startActivity(intent_map);
}
});
lm.removeUpdates(this);
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
public void afficherAdresse() {
Geocoder geo = new Geocoder(SmartFinderActivity.this);
try {
List<Address> adresses = geo.getFromLocation(lat,lng,1);
if(adresses != null && adresses.size() == 1){
Address adresse = adresses.get(0);
//if geocoder find a adresse, we can use it
position.setText( adresse.getAddressLine(0) + " " + adresse.getPostalCode() + " " + adresse.getLocality());
}
else {
//else: no adress
position.setText("L'adresse n'a pu être déterminée");
}
} catch (IOException e) {
e.printStackTrace();
position.setText("L'adresse n'a pu être déterminée");
}
}
public static void send_message(String phoneNumber) {
// `refresh Location : that's the problem ! `
// send method : not difficult
}
}
My problem is that I want to refresh my position when method "send_message" is called.
thank you for your help

I think that you're asking how to get your current location when you receive an SMS message so that you can send back the current location in another SMS message. I think that you are assuming that your are able to just make a call to get your current location to report back.
GPS doesn't work that way. It needs to run for a little while to get enough messages from enough satellites to be able to determine a position and an accuracy for that position. So there is no single function call to simply get the device location instantly.
Instead it is necessary to run a background task (I use an Async Task) to listen to position updates and the iterate to the current location. My task turns off the listening (and the GPS hardware) when it has a good enough fix to save battery life.
See a previous related answer for more information.
It is possible to ask the Location Manager for the current position. However, this is the last position that it recorded. If no application has used the GPS hardware for a while then that postion fix could be very old and therefore not accurate at all. At work, my building shields the GPS signals (metal cladding) and so my phone currently believes that it is at my home many miles away which is where I last used a GPS enabled app.
As SMS takes a variable time to be delivered I think that it is probably correct to take a few extra seconds to fire off the GPS collection and wait for a good enough fix before responding. SMS is not an instant delivery vehicle so the extra few seconds delay in getting a good fix will not add much to the round-trip time of your SMS messages.

Related

Custom SIP VoIP app keeps being closed by Android

I've developed a version of the native SIP Demo app provided by Google https://android.googlesource.com/platform/development/+/master/samples/SipDemo/
My Simple app registers with the SIP server and when a call invite is received on that SIP account a notification and Toast is displayed with the caller ID. I've not designed the app to run as a service or anything. After launching the activity the app registers with the SIP server and then I simple hit the home button and let the app run in the background, waiting for an incoming call.
The app functions correctly it's just that within ~ 12 - 24 hrs the app seems to have been stopped by the Android OS. I'm not sure if it's related to the native SIP stack or Android's resource manager shutting down the app but I've tried setting everything I can on the handset itself to prevent the app from being stopped like removing any battery saving settings etc.
Are there any tips to keep the app running in the background using the native SIP API?
My is code below:
CallerIDActivity.java -
package example.callerid;
//This app has been developed with a target API of 22 so as to avoid having to
//implement runtime permissions on the test handset with a higher API level.
import android.Manifest;
import android.app.Activity;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.sip.SipException;
import android.net.sip.SipManager;
import android.net.sip.SipProfile;
import android.net.sip.SipRegistrationListener;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Random;
public class CallerIDactivity extends Activity {
public SipManager manager = null;
public SipProfile me = null;
public IncomingCallReceiver callReceiver;
public CallerIDactivity (){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) createNotificationChannel();
}//end constructor
//define NotificationChannel method for use in the contructor above
//IncomingCallReciever will then use this channel to send notification of CID
public void createNotificationChannel(){
//Create the Notification but only on API 26+ as the
//notification class is new and not in the support lib
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
CharSequence name = "CHANNEL_NAME";
String description = "CID_NOTIFY";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel("CHANNEL_ID", name, importance);
channel.setDescription(description);
//Register the channel with the system: you can't change the importance
//or other notification behaviour after this
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if(notificationManager !=null) {
notificationManager.createNotificationChannel(channel);
}
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.callerid);
// Set up the intent filter. This will be used to trigger an
// IncomingCallReceiver when someone calls the SIP address used by this
// application.
IntentFilter filter = new IntentFilter();
filter.addAction("android.CallerID.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);
}//end onCreate
#Override
public void onStart() {
super.onStart();
// When we get back from the preference setting Activity, assume
// settings have changed, and re-login with new auth info.
initializeManager();
}
#Override
public void onDestroy() {
super.onDestroy();
closeLocalProfile();
if (callReceiver != null) {
this.unregisterReceiver(callReceiver);
Log.d("CallerID", "UnRegisteringReceiverOnDestroy ");
Toast toast = Toast.makeText(getApplicationContext(), "UnRegisteringReceiverOnDestroy", Toast.LENGTH_LONG);
toast.show();
}
}//end onDestroy
public void RegisterBtn(View callerid){
initializeManager();
Log.d("CallerIDactivity","RegisterBtn Press");
Toast toast = Toast.makeText(getApplicationContext(),"Registering", Toast.LENGTH_SHORT);
toast.show();
}
public void initializeManager() {
if(manager == null) {
manager = SipManager.newInstance(this);
}
initializeLocalProfile();
}
public void initializeLocalProfile() {
if (manager == null) {
return;
}
if (me != null) {
closeLocalProfile();
}
try {
SipProfile.Builder builder = new SipProfile.Builder("sipaccount", "my.sip.server");
builder.setPassword("pass");
me = builder.build();
Intent i = new Intent();
i.setAction("android.CallerID.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
manager.open(me,pi,null);
// This listener must be added AFTER manager.open is called,
// Otherwise the methods aren't guaranteed to fire.
manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
updateStatus("Registering with SIP Server...");
}
public void onRegistrationDone(String localProfileUri, long expiryTime) {
updateStatus("Ready");
}
public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
updateStatus("Registration failed. Please check settings.");
}
});
}catch (ParseException pe) {
updateStatus("Connection Error.");
} catch (SipException se) {
updateStatus("Connection error.");
}
}
/**
* Closes out your local profile, freeing associated objects into memory
* and unregistering your device from the server.
*/
public void closeLocalProfile() {
if (manager == null) {
Log.d("closeLocalProfile", "manager == null");
return;
}
try {
if (me != null) {
manager.close(me.getUriString());
Toast toast = Toast.makeText(getApplicationContext(), "ClosingProfileURI"+" "+me.getUriString(), Toast.LENGTH_SHORT);
toast.show();
}
} catch (Exception ee) {
Toast toast = Toast.makeText(getApplicationContext(), ee.getMessage(), Toast.LENGTH_SHORT);
toast.show();
Log.d("onDestroy", "Failed to close local profile.", ee);
}
}
/**
* Updates the status box at the top of the UI with a messege of your choice.
* #param status The String to display in the status box.
*/
public void updateStatus(final String status) {
this.runOnUiThread(new Runnable() {
public void run() {
Toast toast = Toast.makeText(getApplicationContext(), status, Toast.LENGTH_SHORT);
toast.show();
}});
/* Be a good citizen. Make sure UI changes fire on the UI thread.
this.runOnUiThread(new Runnable() {
public void run() {
Log.i("allenssip",status);
TextView labelView = (TextView) findViewById(R.id.sipLabel);
labelView.setText(status);
}
});
*/
}//end updateStatus
}//end Class
IncomingCallReceiver.java -
package example.callerid;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.sip.*;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.util.Log;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Random;
/**
* Listens for incoming SIP calls, intercepts and hands them off to CallerIDactivity.
*/
public class IncomingCallReceiver extends BroadcastReceiver {
public Calendar calendar;
public SimpleDateFormat dateFormat;
public String date;
public SipManager mSipManager;
public SipSession mSipSesion;
public SipProfile peerProfile;
static private int notifyNum = 1;
/**
* Processes the incoming call, answers it, and hands it over to the
* CallerIDactivity.
* #param context The context under which the receiver is running.
* #param intent The intent being received.
*/
#Override
public void onReceive(Context context, Intent intent) {
mSipManager = SipManager.newInstance(context);
try {
mSipSesion = mSipManager.getSessionFor(intent);
} catch (SipException e) {
e.printStackTrace();
}
peerProfile = mSipSesion.getPeerProfile();
calendar = Calendar.getInstance();
dateFormat = new SimpleDateFormat("dd/MM/yyyy");
date = dateFormat.format(calendar.getTime());
Log.d("CallerID", "OnReceive");
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, "CHANNEL_ID")
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle("CallerID" + " " + date)
.setContentText(peerProfile.getDisplayName())
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
if(notifyNum <= 9) {
notificationManager.notify(notifyNum++, mBuilder.build());
}else {notificationManager.notify(notifyNum, mBuilder.build());
notifyNum = 1;
}
int count = 0;
while (count <= 10) {
Toast toast = Toast.makeText(context, peerProfile.getDisplayName(), Toast.LENGTH_SHORT);
toast.show();
count++;
}//end while
}//end onReceive
}//end Class

why is my SMS verification code not working properly?

I think I'm in a bit of a catch 22 situation. I'm making an app that verifies the user's phone number by sending a text message to the number the user entered and then checking - that way it's definitely the user's phone number. This activity should only appear once, at the beginning - for the user to verify, and from then on activity 2 should be loaded.
I am trying to do this with :
// when the form loads, check to see if phoneNo is in there
SharedPreferences sharedPreferences = getSharedPreferences("MyData", Context.MODE_PRIVATE);
String phoneNoCheck = sharedPreferences.getString("phonenumber","");
if (phoneNoCheck != null) {
// if it is in there, start the new Activity
Intent myIntent = new Intent(MainActivity.this, PopulistoContactList.class);
MainActivity.this.startActivity(myIntent);
}
But it doesn't seem to be working properly. For a start, I'm not even sure it should be null. When I turn off my phone and on again, it starts back at activity 1, asking for verification.
And I can't test it. I need to run the app on my device as I can't send an SMS from the emulator, and I'm unable to get to the files where sharedPreferences exist on my device, so I can't even see if it's being written correctly.
Any advice on how I might be able to see the MyData.xml on my phone and proceed with testing my app, or tell my how I may be able to improve my code ? I downloaded the Astro app but still couldn't find it.
Here's my code :
package com.example.chris.tutorialspoint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.app.Activity;
import android.provider.Telephony;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.tutorialspoint.R;
public class MainActivity extends Activity {
Button sendBtn;
EditText txtphoneNo;
String phoneNo;
String origNumber;
private BroadcastReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendBtn = (Button) findViewById(R.id.btnSendSMS);
txtphoneNo = (EditText) findViewById(R.id.editText);
// when the form loads, check to see if phoneNo is in there
SharedPreferences sharedPreferences = getSharedPreferences("MyData", Context.MODE_PRIVATE);
String phoneNoCheck = sharedPreferences.getString("phonenumber","");
if (phoneNoCheck != null) {
// if it is in there, start the new Activity
Intent myIntent = new Intent(MainActivity.this, PopulistoContactList.class);
MainActivity.this.startActivity(myIntent);
}
//if it is not in there, proceed with phone number verification
else {
sendBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
sendSMSMessage();
}
});
IntentFilter filter = new IntentFilter();
// the thing we're looking out for is received SMSs
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent)
{
Bundle extras = intent.getExtras();
if (extras == null)
return;
Object[] pdus = (Object[]) extras.get("pdus");
SmsMessage msg = SmsMessage.createFromPdu((byte[]) pdus[0]);
origNumber = msg.getOriginatingAddress();
Toast.makeText(getApplicationContext(), "Originating number" + origNumber, Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), "Sent to number" + phoneNo, Toast.LENGTH_LONG).show();
}
};
registerReceiver(receiver, filter);
}
}
protected void sendSMSMessage() {
phoneNo = txtphoneNo.getText().toString();
//this is the SMS received
String message = "Verification test code. Please ignore this message. Thank you.";
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNo, null, message, null, null);
Toast.makeText(getApplicationContext(), "SMS sent.", Toast.LENGTH_LONG).show();
//if originating phone number is the same as the sent to number, save
//and go to the next activity
if (origNumber.equals(phoneNo)) {
//save the phone number
SharedPreferences sharedPreferences = getSharedPreferences("MyData", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("phonenumber", phoneNo);
editor.commit();
Intent myIntent = new Intent(MainActivity.this, PopulistoContactList.class);
MainActivity.this.startActivity(myIntent);
}
}
catch (Exception e) {
Toast.makeText(getApplicationContext(), "SMS failed, please try again.", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
#Override
protected void onDestroy() {
if (receiver != null) {
unregisterReceiver(receiver);
receiver = null;
}
super.onDestroy();
}
What do you expect to happen here:
String phoneNoCheck = sharedPreferences.getString("phonenumber","");
if (phoneNoCheck != null) {
...
}
The method that you are calling, getString(String, String), uses the second parameter as the default value, that is, if no property is found, it will default to, as you have defined, an empty string, "".
You then try and compare this to null, which will never be equal.
Try changing it up to something like this:
String phoneNoCheck = sharedPreferences.getString("phonenumber", null);
// check if null or empty
if ( null == phoneNoCheck || phoneNoCheck.equals("") ) {
// unregistered
}

Global Variable Magically Getting Set To Null??

I am using a SMSReceiver class which receives an sms and then sends the sms as an extra to my main activity to use in the map application. In my onReceive method I toast the extra and I get the value perfectly fine, but when I try use the variable later down my code to reverse geoCode to get the coordinates from the address then suddenly the global variable is null again :(
The method is called showOnMapClicked on line 324 where the variable is null again.
The sms is being sent from the DDMS.
Somebody please help, I just cant figure it out!
OnReceive Class:
package com.example.maps;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast;
import android.content.Intent;
public class SMSReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
//Adding bundle extras to be used by the main class
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String str = "SMS from ";
//Adding the sms to the array to be stored
if (bundle != null)
{
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i = 0; i < msgs.length; i++) {
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
if (i == 0)
{
//Appending the information to the string to be displayed
str += msgs[i].getOriginatingAddress();
str += ": \n";
}
str += msgs[i].getMessageBody().toString();
}
Toast.makeText(context, str, Toast.LENGTH_LONG).show();
//Creating the new intent
Intent mainActivityIntent = new Intent(context, MainActivity.class);
mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mainActivityIntent);
//Making the intent broadcast to the main class and putting the extra in to be displayed
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("SMS_RECEIVED_ACTION");
//Setting the name of the string to "sms"
broadcastIntent.putExtra("sms", str);
context.sendBroadcast(broadcastIntent);
//Stops the sms from going directly into the inbox
this.abortBroadcast();
}
}
}
Main Activity Class:
package com.example.maps;
//Daniel Tromp - Assignment 2 - 12002076
//Imports for DAYS!
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import com.example.maps.R;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.text.InputFilter;
import android.text.InputType;
import android.text.method.DigitsKeyListener;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
//Implementing all the needed services
public class MainActivity extends Activity implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {
// Initializing the needed globals
Location mLocation;
String addressSms;
String addressText;
public GoogleMap mMap;
private TextView mAddress;
private ProgressBar mActivityIndicator;
private LocationClient mLocationClient;
BroadcastReceiver smsSentReceiver, smsDeliveredReceiver;
IntentFilter intentFilter;
// Milliseconds per second
private static final int MILLISECONDS_PER_SECOND = 1000;
// Update frequency in seconds
public static final int UPDATE_INTERVAL_IN_SECONDS = 5;
// Update frequency in milliseconds
private static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND
* UPDATE_INTERVAL_IN_SECONDS;
// The fastest update frequency, in seconds
private static final int FASTEST_INTERVAL_IN_SECONDS = 1;
// A fast frequency ceiling in milliseconds
private static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND
* FASTEST_INTERVAL_IN_SECONDS;
// Define an object that holds accuracy and frequency parameters
private LocationRequest mLocationRequest;
private BroadcastReceiver intentReceiver = new BroadcastReceiver() {
#Override
//On receiving a message, the textview is set to the sms message
public void onReceive(Context context, Intent intent) {
addressSms = intent.getStringExtra("sms");
//Toasting the variable where it displays my sms message
Toast.makeText(getBaseContext(), addressSms, Toast.LENGTH_LONG).show();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUpMapIfNeeded();
mAddress = (TextView) findViewById(R.id.address);
// As the app loads, the address bar will be displayed
mActivityIndicator = (ProgressBar) findViewById(R.id.address_progress);
// Setting the map type to be Hybrid
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
// Create the LocationRequest object
mLocationRequest = LocationRequest.create();
// Use high accuracy
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the update interval to 5 seconds
mLocationRequest.setInterval(UPDATE_INTERVAL);
// Set the fastest update interval to 1 second
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
/*
* Create a new location client, using the enclosing class to handle
* callbacks.
*/
mLocationClient = new LocationClient(this, this, this);
//Creating the new intent
intentFilter = new IntentFilter();
intentFilter.addAction("SMS_RECEIVED_ACTION");
registerReceiver(intentReceiver, intentFilter);
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the
// map.
if (mMap == null) {
mMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
// The Map is verified. It is now safe to manipulate the map.
}
}
}
// When the application is started
#Override
protected void onStart() {
super.onStart();
// Connect the client.
mLocationClient.connect();
}
private class GetAddressTask extends AsyncTask<Location, Void, String> {
Context mContext;
public GetAddressTask(Context context) {
super();
mContext = context;
}
protected String doInBackground(Location... params) {
Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());
// Get the current location from the input parameter list
Location loc = params[0];
// Create a list to contain the result address
List<Address> addresses = null;
try {
/*
* Return 1 address.
*/
addresses = geocoder.getFromLocation(loc.getLatitude(),
loc.getLongitude(), 1);
} catch (IOException e1) {
Log.e("LocationSampleActivity",
"IO Exception in getFromLocation()");
e1.printStackTrace();
return ("IO Exception trying to get address");
} catch (IllegalArgumentException e2) {
// Error message to post in the log
String errorString = "Illegal arguments "
+ Double.toString(loc.getLatitude()) + " , "
+ Double.toString(loc.getLongitude())
+ " passed to address service";
Log.e("LocationSampleActivity", errorString);
e2.printStackTrace();
return errorString;
}
// If the reverse geocode returned an address
if (addresses != null && addresses.size() > 0) {
// Get the first address
Address address = addresses.get(0);
/*
* Format the first line of address (if available), city, and
* country name.
*/
addressText = String.format(
"%s, %s, %s",
// If there's a street address, add it
address.getMaxAddressLineIndex() > 0 ? address
.getAddressLine(0) : "",
// Locality is usually a city
address.getLocality(),
// The country of the address
address.getCountryName());
// Return the text
return addressText;
} else {
return "No address found";
}
}
protected void onPostExecute(String address) {
// Set activity indicator visibility to "gone"
mActivityIndicator.setVisibility(View.GONE);
// Display the results of the lookup.
mAddress.setText(address);
}
}
// When the connection is made to get live updates
public void onConnected(Bundle dataBundle) {
// Display the connection status
Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
// Start periodic updates
mLocationClient.requestLocationUpdates(mLocationRequest, this);
}
// When the new coordinates are put into the DDMS, the map will change to
// that location and get the new address
public void onLocationChanged(Location location) {
// Report to the UI that the location was updated
LatLng latlng = new LatLng(location.getLatitude(),
location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLng(latlng));
mActivityIndicator.setVisibility(View.VISIBLE);
/*
* Reverse geocoding is long-running and synchronous. Run it on a
* background thread. Pass the current location to the background task.
* When the task finishes, onPostExecute() displays the address.
*/
(new GetAddressTask(this)).execute(location);
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
}
#Override
public void onDisconnected() {
}
// Click on button to get the read me file to know how to use the
// application
public void readMeClicked(View v) {
// Create a dialog to pop up and explain the application to the user
AlertDialog alertDialog = new AlertDialog.Builder(this).create(); // Read
// Update
alertDialog.setTitle("Read Me");
alertDialog
.setMessage("My app was created to be able to quickly send out an emergency SMS to a certain individual which will contain the emergency message as well as their current location. By using the DDMS, the coordinates can be input and then my app will go to that specific location and pull the most correct address of that location");
// Making the dialog show
alertDialog.show();
}
public void getFromLocationClicked(View v) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
MainActivity.this);
// Setting Dialog Title
alertDialog.setTitle("Emergency SMS");
// Setting Dialog Message
alertDialog.setMessage("Enter Emergency Contact Number");
final EditText input = new EditText(MainActivity.this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
alertDialog.setView(input);
// Setting Positive "Continue" Button
alertDialog.setPositiveButton("Continue",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String testing = input.getText().toString();
getFromLocation(testing);
}
});
// Setting Negative "Cancel" Button
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
};
public void getFromLocation(String strAddress) {
Geocoder coder = new Geocoder(this);
List<Address> address;
try {
address = coder.getFromLocationName(strAddress, 5);
if (address != null) {
Address location = address.get(0);
double recLat = location.getLatitude();
double recLng = location.getLongitude();
LatLng p = new LatLng(recLat, recLng);
Toast.makeText(getBaseContext(), p + "", Toast.LENGTH_LONG)
.show();
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(p, 16));
}
} catch (IOException ie) {
ie.printStackTrace();
}
}
//Showing the value when the show button is clicked
public void showOnMapClicked(View v)
{
//When it toasts, the addressSms value is now null!??
Toast.makeText(getBaseContext(), addressSms, Toast.LENGTH_LONG).show();
//getFromLocation(addressSms);
}
public void showToast(String message)
{
String test = message;
Toast.makeText(getBaseContext(), test, Toast.LENGTH_LONG).show();
}
// Click the button to start to generate the emergency SMS
public void sendAddressClicked(final View v) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
MainActivity.this);
// Setting Dialog Title
alertDialog.setTitle("Emergency SMS");
// Setting Dialog Message
alertDialog.setMessage("Enter Emergency Contact Number");
final EditText input = new EditText(MainActivity.this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
alertDialog.setView(input);
input.setFilters(new InputFilter[] {
// Maximum 2 characters.
new InputFilter.LengthFilter(10),
// Digits only.
DigitsKeyListener.getInstance(), // Not strictly needed, IMHO.
});
// Setting Positive "Continue" Button
alertDialog.setPositiveButton("Continue",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Setting the SMS message and adding the current
// location which is gathered by the map.
String textMessage = input.getText().toString();
// Checking if the phone number is not blank
if (textMessage.isEmpty()) {
// If the phone number is not entered
Toast.makeText(getBaseContext(),
"Cannot be blank. Enter phone number.",
Toast.LENGTH_LONG).show();
sendAddressClicked(v);
}
else {
enterMessage(textMessage);
}
}
});
// Setting Negative "Cancel" Button
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
};
// Method to send the emergency method and the current location
private void sendSMS(String phoneNumber, String message) {
// Sending the sms to the emulator number input
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, null, null);
}
// Once the user has input the number, the message now will be asked for
public void enterMessage(final String number) {
// Creating the dialog to input the emergency message
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
MainActivity.this);
// Setting Dialog Title
alertDialog.setTitle("Emergency SMS");
// Setting Dialog Message
alertDialog.setMessage("Enter Emergency SMS");
final EditText input = new EditText(MainActivity.this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
alertDialog.setView(input);
input.setInputType(InputType.TYPE_CLASS_TEXT);
// Setting Positive "SEND SMS" Button
alertDialog.setPositiveButton("SEND SMS",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Write your code here to execute after dialog
// Setting the SMS message and adding the current
// location which is gathered by the map.
String textMessage = input.getText().toString();
String SMS = textMessage + "\n\n"
+ "My Current Address Is: " + addressText;
String phoneNumber = number;
// Checking to see if the SMS is blank
if (textMessage.isEmpty()) {
Toast.makeText(getBaseContext(),
"Cannot be blank. Enter emergency SMS.",
Toast.LENGTH_LONG).show();
enterMessage(phoneNumber);
}
else {
// Sending the variables through to the sendSMS
// method to be sent
sendSMS(phoneNumber, SMS);
}
}
});
// Setting Negative "Cancel" Button
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Write your code here to execute after dialog
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
};
}
Try overriding the onSaveInstanceState(Bundle bundle) method in your MainActivity and use logs to see if it is getting called before your data is getting wiped out. I suspect that you'll see it is getting called. If so, just save your 'globals' in the bundle and retrieve them by overriding the onRestoreInstanceState(Bundle bundle)
The DOC should help you with how to save and restore. Whenever the activity needs to be killed for memory or orientation change, onCreate will be called and the 'globals' can be lost that way.
This might help with more details.

Call Control Example Issue on Emulator

I am testing call control example given on: http://prasanta-paul.blogspot.com/2010/09/call-control-in-android.html on emultaor.
Code is as below:
package com.example.callblock;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
import android.widget.Toast;
import com.android.internal.telephony.ITelephony;
public class CallBlock extends BroadcastReceiver{
String[] blockedNumbers = {"5556"};
String incommingNumber;
Context context;
String incomingNumber;
ITelephony telephonyService;
public void onReceive(Context context, Intent intent) {
//Log.v(TAG, "Incoming Call BroadCast received...");
// Log.v(TAG, "Intent: ["+ intent.getAction() +"]");
Bundle b = intent.getExtras();
incommingNumber = b.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Toast.makeText(context, "Phone no:"+incomingNumber, Toast.LENGTH_LONG).show();
// Additional Step
// Check whether this number matches with your defined Block List
// If yes, Reject the Call
if(incommingNumber.equals(blockedNumbers[0])){
try {
telephonyService.endCall();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
When i tried to run this example ie make call from one emulator(5556) to the second emulator(5554). It shows Phoneno:null.
I am unable to understand the reason for this.

Android: cant create handler inside thread that has not called looper.prepare

I know this kind of question exist but I'm confused in this case. I'm using the following code:
package com.example.GetALocation2;
import com.example.GetALocation2.MyLocation.LocationResult;
import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
public class GetALocation2 extends Activity {
public static final String LOG_TAG = "------------------GetALocation2";
Double latitude;
TextView tv;
MyLocation myLocation = new MyLocation();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView) this.findViewById(R.id.thetext);
tv.setText("Yo there!");
Log.e(LOG_TAG, "Toast will be shown");
Toast.makeText(getBaseContext(), "This is the start!", Toast.LENGTH_SHORT).show();
Log.e(LOG_TAG, "Toast was shown");
locationClick();
}
private void locationClick() {
Log.e(LOG_TAG, "Triggered location click");
myLocation.getLocation(this, locationResult);
}
public void yoThereNull(){
Toast.makeText(getBaseContext(), "Location is unknown.", Toast.LENGTH_SHORT).show();
}
public void yoThereNotNull(){
Toast.makeText( getBaseContext(), "I got the location! Yeah! >>> " + GetALocation2.this.latitude, Toast.LENGTH_SHORT).show();
}
public LocationResult locationResult = new LocationResult(){
#Override
public void gotLocation(final Location location){
//Got the location!
Log.d(LOG_TAG, "Entered gotLocation()");
try{
if( location == null ){
Log.d( LOG_TAG, "Null Location is returned" );
yoThereNull();
}else{
Log.d( LOG_TAG, "A location is found/returned" );
GetALocation2.this.latitude = location.getLatitude();
yoThereNotNull();
}
}catch (NullPointerException e) {
Log.e(LOG_TAG, e.toString());
}catch(Exception e){
Log.e(LOG_TAG, e.toString());
}
};
};
}
when location returns null and call yoThereNull() method, the logcat says: cant create handler inside thread that has not called looper.prepare
but when location returns a value, all is okay. the toast appear.
Anyone knows how to handle this in my case? I'm kinda new to java and android, many thanks for any help! :)
Can you replace
yoThereNotNull();
with
GetALocation2.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
yoThereNotNull();
}
});
You have a problem in this line:
Toast.makeText( getBaseContext(), "I got the location! Yeah! >>> " + GetALocation2.this.latitude, Toast.LENGTH_SHORT).show();
Try using the activity.
Toast.makeText( this, "I got the location! Yeah! >>> " + GetALocation2.this.latitude, Toast.LENGTH_SHORT).show();
This error comes when you create a thread manually inside another thread and so on.. This is one condition that Android can't handle.. Thats why they have given something called AsyncTask, which you can use for doin things in Background.. when this ecxeption arrises u cannot always say that you have error in your code.. sometimes your code is clean but still Android OS will throw this Exception.. So make sure to use AsyncTask instead of creating a Thread by yourself..

Categories

Resources