HTC One issues with ACTION_CALL intent - android

I released an app on the app store that seems to run into problems with the HTC One. As soon as the app is opened, the app execute an intent to make a phone call, ACTION_CALL. I have a call intent but it's accessed after a button press followed by accessing the location services and then a 5 second sleep() call. But with the HTC Sense, it goes straight to the call, without even showing the layouts. I have a Galaxy S3 running 4.3 and the app's target SDK is 19, and the app is working without a hitch.
Why is this happening? Does the HTC Sense have issues with calling intents? Is there anyway of stopping the intent from occuring, sort of like a signalHandler if it's an HTC Sense device?
HTC Sense 5.0, Android: 4.3
Code (Activity that calls phone intent):
protected void onCreate(Bundle paramBundle) {
super.onCreate(paramBundle);
setContentView(R.layout.activity_test);
x=9;
final TextView localTextView = (TextView) findViewById(R.id.addr);
LocationManager localLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
localLocationManager.getLastKnownLocation("gps");
localLocationManager.requestLocationUpdates("gps", 2000L, 10.0F, new LocationListener() {
public void onLocationChanged(Location paramAnonymousLocation) {
double d1 = paramAnonymousLocation.getLatitude();
double d2 = paramAnonymousLocation.getLongitude();
Geocoder localGeocoder = new Geocoder(Test.this.getApplicationContext(), Locale.getDefault());
try {
List localList = localGeocoder.getFromLocation(d1, d2, 1);
if (localList.size() == 1) {
Address localAddress = (Address) localList.get(0);
Object[] arrayOfObject = new Object[3];
if (localAddress.getMaxAddressLineIndex() > 0) ;
for (String str1 = localAddress.getAddressLine(0); ; str1 = "") {
arrayOfObject[0] = str1;
arrayOfObject[1] = localAddress.getAddressLine(1);
arrayOfObject[2] = localAddress.getCountryName();
String str2 = String.format("%s, %s, %s", arrayOfObject);
localTextView.setText(str2);
if(x==9){
Test.this.waititout();}
return;
}
}
} catch (IOException localIOException) {
localIOException.printStackTrace();
return;
} catch (InterruptedException localInterruptedException) {
localInterruptedException.printStackTrace();
}
}
public void onProviderDisabled(String paramAnonymousString) {
localTextView.setText("TURN ON GPS DUMMY");
}
public void onProviderEnabled(String paramAnonymousString) {
}
public void onStatusChanged(String paramAnonymousString, int paramAnonymousInt, Bundle paramAnonymousBundle) {
}
});
}
public void waititout()
throws InterruptedException {
new Thread() {
public void run() {
try {
Date localDate = new Date();
Calendar localCalendar = GregorianCalendar.getInstance();
localCalendar.setTime(localDate);
int i = localCalendar.get(Calendar.HOUR_OF_DAY);
Thread.currentThread();
Thread.sleep(4000L);
Intent localIntent = new Intent("android.intent.action.CALL");
localIntent.setData(Uri.parse("tel:17325450900"));
Test.this.startActivity(localIntent);
return;
} catch (InterruptedException localInterruptedException) {
System.out.println(localInterruptedException);
}
}
}
.start();
}

Related

System.Threading.Tasks.TaskCanceledException in Xam.Plugin.GeoLocator [duplicate]

I am building a native android app using xamarin. The issue is, that the application collects and displays the coordinates perfectly on the emulator but when I put it on a smartphone (tried 2 samsung phones) it comes up with can't determine the current address. Extra information data and locations are turned on so I am not sure where the issue is. Thanks for your help. here is the xammarin recipe encase that helps https://developer.xamarin.com/recipes/android/os_device_resources/gps/get_current_device_location/
[Activity(Label = "NewRoute")]
public class NewRouteActivity : Activity, ILocationListener
{
static readonly string TAG = "X:" + typeof(NewRouteActivity).Name;
TextView _addressText;
Location _currentLocation;
LocationManager _locationManager;
string _locationProvider;
TextView _locationText;
public async void OnLocationChanged(Location location) {
_currentLocation = location;
if (_currentLocation == null)
{
_locationText.Text = "Unable to determine your location. Try again in a short while.";
}
else
{
_locationText.Text = string.Format("{0:f6},{1:f6}", _currentLocation.Latitude, _currentLocation.Longitude);
Address address = await ReverseGeocodeCurrentLocation();
DisplayAddress(address);
}
}
public void OnProviderDisabled(string provider) { }
public void OnProviderEnabled(string provider) { }
public void OnStatusChanged(string provider, Availability status, Bundle extras) { }
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.CreatetRoute);
_addressText = FindViewById<TextView>(Resource.Id.address_text);
_locationText = FindViewById<TextView>(Resource.Id.location_text);
FindViewById<TextView>(Resource.Id.get_address_button).Click += AddressButton_OnClick;
InitializeLocationManager();
Button btnEndPoint = FindViewById<Button>(Resource.Id.btnEndPoint);
btnEndPoint.Click += new EventHandler(AfterPointsCollected);
}
//Location Stuff
void InitializeLocationManager()
{
_locationManager = (LocationManager)GetSystemService(LocationService);
Criteria criteriaForLocationService = new Criteria
{
Accuracy = Accuracy.Fine
};
IList<string> acceptableLocationProviders = _locationManager.GetProviders(criteriaForLocationService, true);
if (acceptableLocationProviders.Any())
{
_locationProvider = acceptableLocationProviders.First();
}
else
{
_locationProvider = string.Empty;
}
Log.Debug(TAG, "Using " + _locationProvider + ".");
}
//Override OnResume so that Activity1 will begin listening to the LocationManager when the activity comes into the foreground:
protected override void OnResume()
{
base.OnResume();
_locationManager.RequestLocationUpdates(_locationProvider, 0, 0, this);
}
async void AddressButton_OnClick(object sender, EventArgs eventArgs)
{
if (_currentLocation == null)
{
_addressText.Text = "Can't determine the current address. Try again in a few minutes.";
return;
}
Address address = await ReverseGeocodeCurrentLocation();
DisplayAddress(address);
}
async Task<Address> ReverseGeocodeCurrentLocation()
{
Geocoder geocoder = new Geocoder(this);
IList<Address> addressList =
await geocoder.GetFromLocationAsync(_currentLocation.Latitude, _currentLocation.Longitude, 10);
Address address = addressList.FirstOrDefault();
return address;
}
void DisplayAddress(Address address)
{
if (address != null)
{
StringBuilder deviceAddress = new StringBuilder();
for (int i = 0; i < address.MaxAddressLineIndex; i++)
{
deviceAddress.AppendLine(address.GetAddressLine(i));
}
// Remove the last comma from the end of the address.
_addressText.Text = deviceAddress.ToString();
}
else
{
_addressText.Text = "Unable to determine the address. Try again in a few minutes.";
}
}
//Override OnPause and unsubscribe Activity1 from the LocationManager when the activity goes into the background:
protected override void OnPause()
{
base.OnPause();
_locationManager.RemoveUpdates(this);
}
//Changing Activity
void AfterPointsCollected(object sender, EventArgs e)
{
//context //activity
Intent intent = new Intent(this, typeof(AfterPointsCollectedActivity));
//starts the activity with the intent above
this.StartActivity(intent);
}
Your phones are probably running MarshMallow which now require that you request permission for location services.
You can read more about it here https://blog.xamarin.com/requesting-runtime-permissions-in-android-marshmallow/. You might want to use this Nuget package that handles all that for you. https://github.com/jamesmontemagno/Xamarin.Plugins/tree/master/Geolocator

How do you determine the Android wifi startScan method is complete in order to calculate the time taken for the wifi scan?

code for calculating start and end time of scan. Calling scanTime as soon as the scan starts and retTime as soon as the results are received, however, getting two retTimes and the difference between scanTime and retTime is not consistent
public void startService() {
br = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent intent) {
if (location != null) {
retTime = System.currentTimeMillis() / 1000L;
Log.i("end", Long.toString(retTime));
sendResults(wifi.getScanResults(), androidID, Long.toString(retTime), location);
Long result = retTime - scanTime;
} else {
Log.i("Location", "is Missing");
}
}
};
context.registerReceiver(br, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
t = new Thread(new Runnable() {
public void run() {
try {
setSleepTime(dataTimeDifference);
while (!Thread.interrupted()) {
wifi.startScan();
scanTime = System.currentTimeMillis() / 1000L;
Log.i("start", Long.toString(scanTime));
Thread.sleep(sleepingTime);
}
} catch (InterruptedException e) {
}
}
});
t.start();
}
In short, you know the scan is complete when the BroadcastReceiver is triggered.
This may not directly answer your question, but it seems that this might be a better way of implementing the functionality that you want.
Instead of using Thread.sleep() and a while loop in your Runnable, just rely on the BroadcastReceiver in order to determine when to start a new scan.
Also keep in mind that both the user and the OS can initiate scans, and your BroadcastReceiver will be triggered when those scans complete as well.
private final Runnable mStartScan = new Runnable() {
#Override
public void run() {
wifi.startScan();
}
};
public void startService() {
br = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent intent) {
String action = intent.getAction();
if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)){
if (location != null) {
sendResults(wifi.getScanResults(), androidID, Long.toString(retTime), location);
} else {
Log.i("Location", "is Missing");
}
t = new Thread(mStartScan);
t.start();
}
}
};
context.registerReceiver(br, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
t = new Thread(mStartScan);
t.start();
}

android app scanning before press start

I have also posted in android Enthusiasts, not sure if its the correct place..
We have created an app to scan for wifi hotspots / AP so we can read the SSID and RSSI. We have some test phones with hotspot turned on and hard coded the SSID into the app. When the APP launches for the first time all works OK, we click the AP (checkbox) and hit start (button).When we close the app and launch it again, as soon as we click the AP (checkbox) it start scanning even though we haven't click the start button. we need to reinstall the app on the phone every time. Can anyone help us with this BUG/ unwanted feature as its slowing us up.
here is the code for the main Activity.
your help is greatly appreciated.
public class RssiMyActivity extends Activity{
// Declare global variables
private WifiManager mainWifiObj;
private WifiScanReceiver wifiReciever;
private ListView list;
private ArrayAdapter<String> adapter;
private List<String> ap_details = new ArrayList<String>();
private static String ssid;
private int testCount;
private CheckBox a1, a2, a3, a4, a5, a6;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rssi_my);
list = (ListView) findViewById(R.id.listView1);
mainWifiObj = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifiReciever = new WifiScanReceiver();
// Get make a connection to database to get test count
ReceiveFromDB receiver = new ReceiveFromDB();
receiver.execute();
// Update the test count
testCount = ReceiveFromDB.getCount();
testCount += 1;
// Check to see what value testCount is
Log.e("Values for testCount", String.valueOf(testCount));
Button start;
start = (Button) findViewById(R.id.start);
start.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
// Timer added to get new scan result once every 2 seconds
Timer myTimer = new Timer();
myTimer.schedule(new TimerTask()
{
#Override
public void run()
{
TimerMethod();
}
}, 0, 4000);
}
});
Button pause;
pause = (Button) findViewById(R.id.pause);
pause.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
onPause();
}
});
Button resume;
resume = (Button) findViewById(R.id.resume);
resume.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
onResume();
}
});
a1 = (CheckBox) findViewById(R.id.AP1);
a2 = (CheckBox) findViewById(R.id.AP2);
a3 = (CheckBox) findViewById(R.id.AP3);
a4 = (CheckBox) findViewById(R.id.AP4);
a5 = (CheckBox) findViewById(R.id.AP5);
a6 = (CheckBox) findViewById(R.id.AP6);
}
protected void onPause()
{
unregisterReceiver(wifiReciever);
super.onPause();
}
protected void onResume()
{
registerReceiver(wifiReciever, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
super.onResume();
}
// Timer method to run at the same time as the main activity
private void TimerMethod()
{
this.runOnUiThread(Timer_Tick);
}
/*
* Runnable method add code to here to refresh at specified time
*/
private Runnable Timer_Tick = new Runnable()
{
#Override
public void run()
{
try
{
// start a scan of ap's
mainWifiObj.startScan();
}
catch (Exception e)
{
e.getStackTrace();
}
}
};
class WifiScanReceiver extends BroadcastReceiver
{
#SuppressLint("UseValueOf")
public void onReceive(Context c, Intent intent)
{
// Clear details to refresh the screen for each new scan
if (ap_details.size() > 0)
{
try
{
ap_details.clear();
adapter.clear();
adapter.notifyDataSetChanged();
}
catch (Exception e)
{
e.printStackTrace();
}
}
try
{
// Get all Objects from the scan
List<ScanResult> wifiScanList = mainWifiObj.getScanResults();
List<ScanResult> temp = new ArrayList<ScanResult>();
// Run through each signal and retrieve the mac ssid rssi
for (ScanResult aWifiScanList : wifiScanList)
{
StringBuilder sb = new StringBuilder();
// Pull out the info we need
ssid = aWifiScanList.SSID;
// Check which ap's are selected
if (checkDisplay())
{
// Add info to StringBuilder
sb.append(aWifiScanList.SSID).append("\n");
sb.append(String.valueOf(aWifiScanList.level)).append("\n");
sb.append("Test: ").append(String.valueOf(testCount)).append("\n");
// Add to List that will be displayed to user
ap_details.add(sb.toString());
// Also add to a temporary ScanResult List to use later
temp.add(aWifiScanList);
}
}
// Create an String Array twice the size of the temporary
// ScanResult
// this will be the Array to use as the parameters for sending
// to the database
String[] items = new String[temp.size() + temp.size() + 1];
int num1 = 0;
int num2 = 1;
// Add the ssid and rssi of each object to the Array
for (ScanResult aTemp : temp)
{
items[num1] = aTemp.SSID;
items[num2] = String.valueOf(aTemp.level);
num1 += 2;
num2 += 2;
}
// Add the test value
items[num1] = String.valueOf(testCount);
// Pass Array to the Async method use executeOnExecutor this
// allows for the use
// of the Looper.prepare() method to stop app from crashing
new ConnectToDB().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, items);
// Display the list of all the signals on the device
adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, ap_details);
list.setAdapter(adapter);
}
catch (Exception e)
{
e.getStackTrace();
}
}
}
/*
* Method to check which AP's are been used
*/
public boolean checkDisplay()
{
if (a1.isChecked())
{
if (ssid.equalsIgnoreCase("TestPhone1"))
{
return true;
}
}
if (a2.isChecked())
{
if (ssid.equalsIgnoreCase("TestPhone2"))
{
return true;
}
}
if (a3.isChecked())
{
if (ssid.equalsIgnoreCase("TestPhone3"))
{
return true;
}
}
if (a4.isChecked())
{
if (ssid.equalsIgnoreCase("TestPhone4"))
{
return true;
}
}
if (a5.isChecked())
{
if (ssid.equalsIgnoreCase("TestPhone5"))
{
return true;
}
}
if (a6.isChecked())
{
if (ssid.equalsIgnoreCase("TestPhone6"))
{
return true;
}
}
return false;
}
You never call cancel() on your timer task to remove it from the Timer scheduler. Try inserting that in a button you use to stop it from scanning.
If that doesn't work, try calling cancel() on the timer itself.
ok got it working, not sure if its the right way but its working ok. I just unregister the reciecer and register it again by calling the two methods "onPause() and onResume()" one after the other and just before the startScan() method. see code:
private Runnable Timer_Tick = new Runnable()
{
#Override
public void run()
{
try
{
// unRegister Receiver wifiReciever
onPause();
// register Receiver wifiReciever
onResume();
// start a scan of ap's
mainWifiObj.startScan();
}
catch (Exception e)
{
e.getStackTrace();
}
}
};
would love to know if this is correct way to do it.

Click on pause can‘t get respond when download

When I download,click on pause,but there isn't respond.
I don't konw how to description specific,in fact it is meaning stop,but really can't realize.
the code
public void onClick(View v) {
[color=#FF0000]if (flag == 0){//click mark[/color]
can't display,the red is only a mark.
code as follows
holder.btns .setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
[color=#FF0000]if (flag == 0){//judge the click mark[/color]
holder.ratingBarScore.setVisibility(View.GONE);
holder.pro.setVisibility(View.VISIBLE);
holder.textView.setVisibility(View.VISIBLE);
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
}else {
// Toast.makeText(this, "there is no SD card", 1000).show();
Log.v("wjp", "7889900");
}
final String downloadUrl =(String)v.getTag();
Thread thread = new Thread(){
int count = 0;
public void run(){
Log.v("ccf", "onClick");
try {
downLoadFile(context, downloadUrl, gameName, holder);
openFile(context, new File("/sdcard/9twan/"+ gameName +".apk"));
if(!WebHelper.REGISTER_FLAG){
Log.v("GamesInfoListAdapter", "WebHelper.REGISTER_FLAG == false");
String imei, mac, mobile_number, model, brand;
boolean flag;
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
imei = tm.getDeviceId();
if(imei == null){
imei = "CUSTOM" + WebHelper.generateRandomIMEIString(15);
}
mac = null;
// mac = tm.getDeviceId();
if(mac == null){
mac = "CUSTOM" + WebHelper.generateRandomMacString(17);
}
mobile_number = tm.getLine1Number();
model = tm.getLine1Number();
brand = tm.getLine1Number();
flag = WebHelper.regDevice(context, "install", imei, mac, mobile_number, model, brand);
if(flag){
WebHelper.REGISTER_FLAG = true;
Log.v("GamesInfoListAdapter", "WebHelper.REGISTER_FLAG == true");
}
}
}catch (Exception e){
e.printStackTrace();
}
}
};
Log.v("wjp", "running"+thread.getName());
thread.start();
Toast.makeText(context, "begin to download" + gameName, 0).show();
holder.btns.setBackgroundResource(R.drawable.tab_out);
[color=#FF0000]flag =1;[/color]//here is need to pause,how to write?
}else {
if(Thread.currentThread() !=null){
Thread.interrupted();
// Thread = null;
}
// thread.
// Thread.interrupted();//pause return boolean
// Thread.sleep(3000);
// Thread.
holder.btns.setBackgroundResource(R.drawable.tab_install);
flag =0;
}
}
});
}
return convertView;
You are trying to interrupt the current thread, You should interrupt the thread you have started. Also are you changing the value of flag. You seem to have multiple variables named flag
if(thread !=null){
thread.interrupt();
}

Android : Samsung Galaxy Tabs and Android 2.2 Devices Showing GPS date 1 Day Advance from 1st jan 2012

I have the Galaxy tab GT-P1000 7 inch with firmware version 2.3.3 and Phones running Android 2.2. In both versions when ever I am trying to get the time from GPS, its showing 1 day advance from 1st jan 2012. Same code is working fine on Samsung, LG and Motorola Phones.
The Sample code for the App is,
package com.vxceed.dateTime;
import java.util.Calendar;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class SampleDateTimeActivity extends Activity {
private LocationManager locationManager;
private TextView tv;
String varTime="";
/**
* Location Listener
*/
LocationListener locationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(SampleDateTimeActivity.this,"GPS off", Toast.LENGTH_SHORT).show();
}
#Override
public void onLocationChanged(Location location) {
setCurrentLocation(location);
}
};
private void setCurrentLocation(Location location) {
varTime=String.valueOf(location.getTime());
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
locationManager=(LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,0, locationListener);
tv=(TextView)findViewById(R.id.textView1);
}
public void refreshTime(View v)
{
String currentGPSTime="";
currentGPSTime=varTime;
if(currentGPSTime.compareTo("")==0)
{
tv.setText("Time Not Available");
}
else
{
Calendar cal=Calendar.getInstance();
cal.setTimeInMillis(new Long(currentGPSTime));
long currentDeviceTime=Calendar.getInstance().getTimeInMillis();
Calendar cal2=Calendar.getInstance();
cal2.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE)-1,cal.get(Calendar.HOUR_OF_DAY),cal.get(Calendar.MINUTE));
long currentGPSTime_less_one_Day=cal2.getTimeInMillis();
tv.setText( "GPSTIME:"+cal.getTime().toString() +" \n GPS_TIME_in_Millis:"+varTime+"\nDevice_Time_in_millis:"+String.valueOf(currentDeviceTime) +"\nGPS Time -1 day:"+String.valueOf(currentGPSTime_less_one_Day));
}
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if (locationManager != null && locationListener != null){
locationManager.removeUpdates(locationListener);
locationManager = null;
}
}
}
I have searched the Google and then referring the NMEA official document I figure out How to Use the NMEA data. Here is the Working Code for the NMEA listener:
NmeaListener nmeaListener = new NmeaListener() {
#Override
public void onNmeaReceived(long timestamp, String nmea) {
parse(nmea);
}
};
private boolean parse(String strNMEA) {
// Discard the sentence if its checksum does not match our calculated
// checksum
boolean bStatus = false;
try {
if (!IsValid(strNMEA)) {
return false;
}
String[] sArrNMEA = strNMEA.split(",");
String strNMEAType = sArrNMEA[0];
if (strNMEAType.equals("$GPRMC")) {
bStatus = ParseGPRMC(sArrNMEA);
} else {
bStatus = false;
}
sArrNMEA = null;
} catch (Exception e) {
}
return bStatus;
}
private boolean ParseGPRMC(String[] sArrNMEA) {
boolean result = false;
try {
if (sArrNMEA.length > 9) {
int Hr = 0;
int Mins = 0;
int Secs = 0;
if (!sArrNMEA[1].equals("")) {
Hr = Integer.parseInt(sArrNMEA[1].substring(0, 2));
Mins = Integer.parseInt(sArrNMEA[1].substring(2, 4));
if (sArrNMEA[1].length() > 6) {
Secs = Integer.parseInt(sArrNMEA[1].substring(4, 6));
} else {
Secs = Integer.parseInt(sArrNMEA[1].substring(4));
}
}
if (!sArrNMEA[9].equals("")) {
int Day = Integer.parseInt(sArrNMEA[9].substring(0, 2));
int Month = Integer.parseInt(sArrNMEA[9].substring(2, 4));
if (Month > 0) {
Month = Month - 1;
}
int Year = Integer.parseInt(sArrNMEA[9].substring(4));
Year = 2000 + Year;
if (!sArrNMEA[1].equals("")) {
Calendar cal = Calendar.getInstance(TimeZone
.getTimeZone("UTC"));
cal.set(Year, Month, Day, Hr, Mins, Secs);
nmeaTime = String.valueOf(cal.getTimeInMillis());
}
}
result = true;
}
} catch (Exception e) {
}
return result;
}
private boolean IsValid(String strNMEA) {
// Compare the characters after the asterisk to the calculation
strNMEA = strNMEA.replace("\r", "");
strNMEA = strNMEA.replace("\n", "");
return strNMEA.substring(0, strNMEA.length())
.substring(strNMEA.indexOf("*") + 1)
.equalsIgnoreCase(GetChecksum(strNMEA));
}
private String GetChecksum(String strNMEA) {
// Loop through all chars to get a checksum
int Checksum = 0;
try {
char ch = '\0';
for (int i = 0; i < strNMEA.length(); i++) {
ch = strNMEA.charAt(i);
if (ch == '$') {
// Ignore the dollar sign
} else if (ch == '*') {
// Stop processing before the asterisk
break;
} else {
// Is this the first value for the checksum?
if (Checksum == 0) {
// Yes. Set the checksum to the value
Checksum = (byte) ch;
} else {
// No. XOR the checksum with this character's value
Checksum = Checksum ^ (byte) ch;
}
}
}
} catch (Exception e) {
}
// Return the checksum formatted as a two-character hexadecimal
return Integer.toHexString(Checksum);
}
This seems to be affecting all stock Samsung firmwares, i am logging a concern with Samsung about this. It seems to be isolated to Samsung devices. So if you can test on another device, or install custom firmware. both of those have worked for me. and your code looks good, nothing wrong there, this is a firmware issue
EDIT: I have contacted the Korean Engineers - they have said they weren't aware of the problem but have patched and it should be fixed in the latest update for the SGS and other affected products. (unless of course that device hasn't had an update for a while - so not sure about the SGT) They have said the problem lies with the devices using Broadcomm chips...so yeah
Use the above code. it seems to work for me will have to check it on a few other devices but yeah
I suspect that Samsung were hoping that it was a leap year issue which would just go away after March 1st, 2012.
Sorry to disappoint - but it hasn't! We have been seeing this problem with the app PhoneTrack installed on Samsung phones since January 1st and it is still there today.
Hopefully, Samsung will now act responsibly and issue updates for all devices affected by this GPS driver bug.
I hit this bug on my Nexus S running Android 4.0.3 (annoyingly causing a whole bunch of data to be incorrectly timestamped).
I was upgraded to 4.0.4 yesterday and this seems to have fixed the issue. Not sure if there is a plan to issue fixes to previous Android versions.
A real howler of a bug though...
It worked for me and I replaced IsValid(String strNMEA) method with this function:
private boolean checksum(String strNMEA)
{
int checksum = 0;
strNMEA = strNMEA.replace("\r", "");
strNMEA = strNMEA.replace("\n", "");
String strChecksum = strNMEA.substring(strNMEA.indexOf("*") + 1);
String str = strNMEA.substring(1, strNMEA.indexOf("*"));
for (int i = 0; i < str.length(); i++) {
checksum = checksum ^ str.charAt(i);
}
return checksum == Integer.valueOf(strChecksum, 16);
}

Categories

Resources