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..
Related
I am working with the iBeacon technology, and I am trying to create a RangingService that will search for nearby iBeacons every five seconds and run in the background of my application. The code below is not working. I'm sure I'm making some dumb mistake somewhere, but I can see in my log files that Checkpoint 3 and 4 are being reached every five seconds, while Checkpoints 1 and 2 are never being reached. Thus, the nearby beacons are not being detected. I don't have much experience with Services or Beacons, so I would appreciate any help, especially from #davidgyoung.
Please forgive me if the code below isn't indented perfectly :) Thanks so much to anyone who can help me.
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;
import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;
import java.util.Collection;
public class RangingService extends Service implements BeaconConsumer {
private BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this);
Handler handler;
String b = "";
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onStart(Intent intent, int startId) {
// Let it continue running until it is stopped.
Log.d("Service", "Started");
handler = new Handler(){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
Log.d("Checkpoint", "5 seconds have passed");
}
};
new Thread(new Runnable(){
public void run() {
// TODO Auto-generated method stub
while(true)
{
try {
startJob();
Log.d("Checkpoint", "Job has started");
Thread.sleep(5000);
handler.sendEmptyMessage(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
//return START_STICKY;
}
public void startJob() {
beaconManager.bind(this);
Log.d("The first beacon", "Starting job for realzies");
onBeaconServiceConnect();
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("Service", "Ended");
}
#Override
public void onBeaconServiceConnect() {
Log.d("Checkpoint3", "Checkpoint3");
beaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
Log.d("Checkpoint1", "Checkpoint1");
if (beacons.size() > 0) {
Log.d("Checkpoint2", "Checkpoint2");
//EditText editText = (EditText)RangingActivity.this.findViewById(R.id.rangingText);
Beacon firstBeacon = beacons.iterator().next();
String a = "The first beacon " + firstBeacon.toString() + " is about " + firstBeacon.getDistance() + " meters away. RSSI = " + firstBeacon.getRssi();
Log.d("Service", a);
//logToDisplay(a);
}
}
});
try {
beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));
Log.d("Checkpoint4", "Checkpoint4");
} catch (RemoteException e) { }
}
}// Update code formatting
Main Activity:
public void didEnterRegion(Region arg0) {
// In this example, this class sends a notification to the user whenever a Beacon
// matching a Region (defined above) are first seen.
Log.d(TAG, "did enter region.");
startService(new Intent(this, RangingService.class));
}
A few tips:
Don't call onBeaconServiceConnect(); manually. This is a callback method that gets called by the Android Beacon Library when the beacon scanning service is ready to go as a result of the call to beaconManager.bind(this); If you call it yourself, you defeat its purpose, and will cause problems.
You should not call beaconManager.bind(this); every five seconds -- just call it once when the service starts up. Calling it repeatedly will cause problems.
Make sure that the Android Beacon Library is configured for the types of beacons you are using. By default it will only detect open source AltBeacon packets. If you are using a proprietary beacon type, you need to create a BeaconParser and add configure it with the library. You can do a Google search for "BeaconParser" and your proprietary beacon type to get the proper line of code to configure the library.
I searched for some websites and learned that the way to communicate between android device(phone) and PC via USB is to have an app implementing serversocket on the phone and another app implementing client socket on PC. I kinda fixed the phone side's app(no exception now), but I got an exception "Ljava.lang.StackTraceElement" trying to initiate a socket("localhost", 38300). Does anybody know what's going on with this and how I can fix it? I attached both side's of the code below.
My step to get it to run is as follows
: environment:
Samsung Android phone, Linux PC, Android Studio developer run on Linux
: connection step
open android studio
install one app on phone
install another app on pc android emulator
launch phone side app and click on button to attempt to wait for connection
at this step, adb devices will have two devices
adb -s emulator-5554 -s 1234567890(my phone) forward tcp:38300 tcp:38300
launch pc side android emulator app and click on the button to initiate client socket
NOTE: as you all can see that I can use android studio "Android Monitor" window to see both phone's and PC's app shell's log.
phone side
package com.example.seanhsu.androiddevice_serversocket;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Scanner;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
public class AndroidDevice_ServerSocket extends AppCompatActivity implements OnClickListener{
public static final String TAG = "Connection";
public static final int TIMEOUT = 10;
Intent i = null;
TextView tv = null;
private String connectionStatus = null;
private String socketData = null;
private Handler mHandler = null;
ServerSocket server = null;
String msg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_android_device__server_socket);
// Set up click listeners for the buttons
View connectButton = findViewById(R.id.connect_button);
connectButton.setOnClickListener(this);
View onBtn = findViewById(R.id.hdmi_on);
onBtn.setOnClickListener(this);
View offBtn = findViewById(R.id.hdmi_off);
offBtn.setOnClickListener(this);
// i = new Intent(this, Connected.class);
mHandler = new Handler();
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.connect_button:
tv = (TextView) findViewById(R.id.connection_text);
// initialize server socket in a new separate thread
new Thread(initializeConnection).start();
msg = "Attempting to connect...";
Log.e(TAG, "1 "+msg);
Toast.makeText(this, msg, Toast.LENGTH_SHORT/*msg.length()*/).show();
break;
case R.id.hdmi_on:
Log.e(TAG, "disconnect" + Globals.socketOut);
if (Globals.socketOut != null) {
Globals.socketOut.println("hdmiOn");
Globals.socketOut.flush();
msg = "disconnect hdmi on";
Log.e(TAG, "2 "+msg);
Toast.makeText(this, msg, Toast.LENGTH_SHORT/*msg.length()*/).show();
}
else
{
msg = "disconnect hdmi on is null";
Log.e(TAG, "3 "+msg);
Toast.makeText(this, msg, Toast.LENGTH_SHORT/*msg.length()*/).show();
}
break;
case R.id.hdmi_off:
Log.e(TAG, "disconnect" + Globals.socketOut);
if (Globals.socketOut != null) {
Globals.socketOut.println("hdmiOff!!");
Globals.socketOut.flush();
msg = "disconnect hdmi off";
Log.e(TAG, "4 "+msg);
Toast.makeText(this, msg, Toast.LENGTH_SHORT/*msg.length()*/).show();
}
else
{
msg = "disconnect hdmi off is null";
Log.e(TAG, "5 "+msg);
Toast.makeText(this, msg, Toast.LENGTH_SHORT/*msg.length()*/).show();
}
break;
}
}
private Runnable initializeConnection = new Thread() {
public void run() {
Socket client = null;
// initialize server socket
try {
server = new ServerSocket(38300);
server.setSoTimeout(TIMEOUT * 5000);
// attempt to accept a connection
client = server.accept();
Globals.socketIn = new Scanner(client.getInputStream());
Globals.socketOut = new PrintWriter(client.getOutputStream(),
true);
// Globals.socketIn.
} catch (SocketTimeoutException e) {
// print out TIMEOUT
Log.e(TAG, "aaa=== " + e);
msg = "Connection has timed out! Please try again";
Log.e(TAG, "6 "+msg);
//Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();//method error, this causes program terminated
mHandler.post(showConnectionStatus);
} catch (IOException e) {
Log.e(TAG, "bbb=== " + e);
msg = "IO Exception";
Log.e(TAG, "7 "+msg);
//Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();//method error, this causes program terminated
} finally {
// close the server socket
try {
if (server != null)
server.close();
} catch (IOException ec) {
Log.e(TAG, "ccc=== " + ec);
Log.e(TAG, "Cannot close server socket" + ec);
msg = "Cannot close server socket";
Log.e(TAG, "8 "+msg);
//Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();//method error, this causes program terminated
}
}
if (client != null) {
Globals.connected = true;
// print out success
connectionStatus = "Connection was succesful!";
Log.e(TAG, "9 "+connectionStatus);
mHandler.post(showConnectionStatus);
while (Globals.socketIn.hasNext()) {
socketData = Globals.socketIn.next();
mHandler.post(socketStatus);
}
// startActivity(i);
}
}
};
/**
* Pops up a "toast" to indicate the connection status
*/
private Runnable showConnectionStatus = new Runnable() {
public void run() {
Log.e(TAG, "10 "+connectionStatus);
Toast.makeText(getBaseContext(), connectionStatus,
Toast.LENGTH_SHORT).show();
}
};
private Runnable socketStatus = new Runnable() {
public void run() {
TextView tv = (TextView) findViewById(R.id.connection_text);
tv.setText(socketData);
}
};
public static class Globals {
public static boolean connected;
public static Scanner socketIn;
public static PrintWriter socketOut;
}
}
PC side
package com.example.seanhsu.pchost_clientsocket_withactivity;
import android.support.v7.app.AppCompatActivity;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.Scanner;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
public class PCHost_ClientSocket_with_Activity extends AppCompatActivity implements OnClickListener{
Socket socket;
PrintWriter out;
Scanner sc;
String msg;
private String TAG = "PCHost_ClientSocket_withActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pchost__client_socket_with_);
View connectButton = findViewById(R.id.connect_button);
connectButton.setOnClickListener(this);
//when the emulator start running, it's already in the emulator shell, so it cann't execute adb command
//execAdb();
}
public void onClick(View v) {
//cannot run on main thread
//need to run on another thread, otherwise it will get android.os.NetworkOnMainThreadException exception
new Thread(initializeConnection).start();
//initializeConnection();
/*while(sc.hasNext()) {
System.out.println(System.currentTimeMillis() + " / " + sc.nextLine());
Log.e(TAG, "12 "+System.currentTimeMillis() + " / " + sc.nextLine());
}*/
}
//cannot run on main thread
//need to run on another thread, otherwise it will get android.os.NetworkOnMainThreadException exception
private Runnable initializeConnection = new Thread() {
public void run() {
msg = "initializeConnection";
Log.e(TAG, msg);
//Create socket connection
try{
Log.e(TAG, "============0============");
socket = new Socket("localhost", 38300);
Log.e(TAG, "============1============");
out = new PrintWriter(socket.getOutputStream(), true);
Log.e(TAG, "============2============");
//in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
sc=new Scanner(socket.getInputStream());
Log.e(TAG, "============3============");
// add a shutdown hook to close the socket if system crashes or exists unexpectedly
Thread closeSocketOnShutdown = new Thread() {
public void run() {
try {
Log.e(TAG, "============4============");
socket.close();
msg = "closeSocketOnShutdown socket close";
Log.e(TAG, msg);
Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Log.e(TAG, "============5============");
e.printStackTrace();
msg = "closeSocketOnShutdown IOException";
Log.e(TAG, msg);
Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
}
}
};
Log.e(TAG, "============6============");
Runtime.getRuntime().addShutdownHook(closeSocketOnShutdown);
Log.e(TAG, "============7============");
} catch (UnknownHostException e) {
//Print.fatalError(“Socket connection problem (Unknown host)”+e.getStackTrace());
msg = "Socket connection problem (Unknown host)"+e.getStackTrace();
Log.e(TAG, msg);
Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
//Print.fatalError(“Could not initialize I/O on socket “+e.getStackTrace());
msg = "Could not initialize I/O on socket "+e.getStackTrace();
Log.e(TAG, msg);
Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
}
}
};
}
I keep getting exception:
Could not initialize I/O on socket [Ljava.lang.StackTraceElement;#14710f5
Originally I also has IO exception on phone side app, but I add <uses-permission android:name="android.permission.INTERNET"/> in the manifest, it's OK now. Therefore, I also add <uses-permission android:name="android.permission.INTERNET"/> in PC side app's manifest, but still can't fix this problem.
I am working with an android database oriented program. This activity is from one of my tab. When i press that particular tab it will get the value from the db and if any null values from the db it will catch it and show an alertbox and changing to another tab. This is my logic. But it is not executing the catch block. It is going straight to the webview and showing there a null value. Please anyone help me to fix this error.Here is my class...
LocationActivity
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.ProgressBar;
#SuppressLint("SetJavaScriptEnabled")
public class LocationActivity extends Activity {
MainTabActivity mainTab;
WebView mWebView;
GPSTracker g;
double my_lat, my_lon;
String lat, lon, to_lat, to_lon, addressText, temp_lat, temp_lon;
DatabaseHandler db;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
db = new DatabaseHandler(this);
g = new GPSTracker(this);
Log.d("Reading: ", "Location Activity Reading all Values");
List<Datas> datas = db.getAllDatas();
for (Datas dat : datas) {
try{
to_lat = dat.getlat();
to_lon = dat.getlon();
}catch(NullPointerException e){
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Oops!");
// set dialog message
alert
.setMessage("Please select a destination before finding your route!")
.setCancelable(false)
.setPositiveButton("ok",new DialogInterface.OnClickListener() {
#SuppressWarnings("deprecation")
public void onClick(DialogInterface dialog,int id) {
((MainTabActivity)getParent()).getTabHost().setCurrentTab(0);
}
});
// create alert dialog
AlertDialog alertDialog = alert.create();
// show it
alertDialog.show();
Log.d(to_lat, to_lon);
System.out.println("Frim thap thee "+ to_lat + " " + to_lon);
}
}
setContentView(R.layout.webview);
getWindow().setFeatureInt(Window.FEATURE_PROGRESS,Window.PROGRESS_VISIBILITY_ON);
final ProgressBar pb = (ProgressBar) findViewById(R.id.progressBar1);
pb.setVisibility(View.VISIBLE);
my_lat = g.getLatitude();
my_lon = g.getLongitude();
lat = String.valueOf(my_lat);
lon = String.valueOf(my_lon);
mWebView = (WebView)findViewById(R.id.webview1);
mWebView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
pb.setProgress(progress);
if (progress == 100) {
pb.setVisibility(View.GONE);
}
}
});
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.setWebViewClient(new HelloWebViewClient());
addressText = lat + "," + lon + "+to:" + to_lat + ","+ to_lon;
addressText = addressText.replaceAll(" ", "%20");
addressText = addressText.replaceAll("#", "%23");
mWebView.loadUrl("http://maps.google.com/maps?q=from:"+ addressText);
}
}
getlat and getlon may be null, and therefore not throw an exception. You should replace your try/catch with a if statement which checks for null.
Furthermore the real problem of you NullPointerException is:
Log.d(to_lat, to_lon);
Log.d should be used with the TAG as first param, and the String as second:
Log.d("LOCATION", "From " + to_lat + ", to " + to_lon);
If to_lat and to_lon are null:
log.d(null, null);
will definately cause a crash.
Setting strings to null is by itself not an issue and will not throw a NullPointerException.
However if you would try to call a method on String that is null you would get an Exception.
String s = null; //no problem
s.isEmpty(); //Would throw a nullpointer exception
Remove the try catch clause and do a simple check with if statements
to_lat = dat.getlat();
to_lon = dat.getlon();
if(to_lat == null || to_long == null()
{
//Show the alert
}
first check if you are getting anything in the datas using
if(datas.size()>0)
and then use the for loop.
to_lat, to_lon are Strings and they can be null. So why do you expect to have NPE in the catch block?
I want to display a progressdialog when a client sends request to the server..the request should be done in background...but i am getting a force close when i use the AsyncTask..Please help ..Thank you
package com.example.client;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
public static ProgressDialog Dialog;
String s1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// sendreq();
new SendUserTask().execute();
}
});
}
public String sendreq() {
try {
// TODO Auto-generated method stub
SocketAddress sockaddr = new InetSocketAddress("192.168.7.116",
9011);
Socket serversocket = new Socket();
serversocket.connect(sockaddr, 10000);
serversocket.setSoTimeout(10000);
DataOutputStream out = new DataOutputStream(
serversocket.getOutputStream());
out.flush();
DataInputStream in = new DataInputStream(
serversocket.getInputStream());
out.flush();
String msg = "";
msg = "hi";
out.writeBytes(msg);
out.flush();
byte[] message = new byte[100];
in.read(message);
s1 = new String(message);
Toast.makeText(getApplicationContext(), s1, Toast.LENGTH_LONG)
.show();
((TextView) findViewById(R.id.textView1)).setText(s1);
in.close();
out.close();
serversocket.close();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), String.valueOf(e),
Toast.LENGTH_LONG).show();
}
return null;
}
private class SendUserTask extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
Dialog = ProgressDialog.show(MainActivity.this, "",
"Logging In....", true);
super.onPreExecute();
}
protected void onPostExecute(String s) {
if (Dialog.isShowing())
Dialog.dismiss();
}
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
return sendreq();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), String.valueOf(e),
Toast.LENGTH_SHORT).show();
}
return null;
}
}
}
this ((TextView) findViewById(R.id.textView1)).setText(s1); is executed from the background thread. you cannot access UI elements outside the UI thread.
You need to move that part to either onProgressUpdate or onPostExecute, or to run it in a runOnUiThread Runnable.
doInBackgorund() is a non-UI thread and you cannot access UI elements inside it. The code inside doInBackground() runs on a separate non-ui thread which does not have access to the UI elements defined in your layout. Also, since you are calling another Activity via intents, you should always keep in mind that an Activity runs on the UI thread and hence you should never start another Activity from inside a non-ui thread.
So, remove the code " ((TextView) findViewById(R.id.textView1)).setText(s1); " accessing the UI elements from inside of doInBackground() and instead put it inside onPostExecute(), which is a UI thread and is called after doInBackground() finishes the background processing.
Ok.... After googling a lot i finally came to understand that you cant access UI elements from main thread into a new non-UI thread....So you cant use elements like textview or even getApplicationContext mtd tht v use for toast in the dobackground mtd or even in anyother mts that the dobackground is calling....This also applies for the new Thread() using runnable..Thank you njzk2 for your help :)
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.