Hey here is the code in which is for placeId by nearest places but I want to take location by its name. Like if I want any location and write its name it will give locations containing name of location because i cant get desired locations if i search by lat and long. I just get some popular locations only.
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import android.widget.AdapterView.OnItemClickListener;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
#SuppressWarnings("deprecation")
public class Places extends Activity implements OnItemClickListener {
private Handler mHandler;
private JSONObject location;
protected ListView placesList;
protected LocationManager lm;
protected MyLocationListener locationListener;
protected static JSONArray jsonArray;
final static double TIMES_SQUARE_LAT = 40.756;
final static double TIMES_SQUARE_LON = -73.987;
protected ProgressDialog dialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler();
location = new JSONObject();
setContentView(R.layout.places_list);
Bundle extras = getIntent().getExtras();
String default_or_new = extras.getString("LOCATION");
if (default_or_new.equals("times_square")) {
try {
location.put("latitude", new Double(TIMES_SQUARE_LAT));
location.put("longitude", new Double(TIMES_SQUARE_LON));
} catch (JSONException e) {
}
fetchPlaces();
} else {
getLocation();
}
}
public void getLocation() {
/*
* launch a new Thread to get new location
*/
new Thread() {
#Override
public void run() {
Looper.prepare();
dialog = ProgressDialog.show(Places.this, "",
getString(R.string.fetching_location), false, true,
new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
showToast("No location fetched.");
}
});
if (lm == null) {
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
if (locationListener == null) {
locationListener = new MyLocationListener();
}
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
String provider = lm.getBestProvider(criteria, true);
if (provider != null && lm.isProviderEnabled(provider)) {
lm.requestLocationUpdates(provider, 1, 0, locationListener,
Looper.getMainLooper());
} else {
/*
* GPS not enabled, prompt user to enable GPS in the
* Location menu
*/
new AlertDialog.Builder(Places.this)
.setTitle(R.string.enable_gps_title)
.setMessage(getString(R.string.enable_gps))
.setPositiveButton(R.string.gps_settings,
new DialogInterface.OnClickListener() {
#Override
public void onClick(
DialogInterface dialog,
int which) {
startActivityForResult(
new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS),
0);
}
})
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
#Override
public void onClick(
DialogInterface dialog,
int which) {
dialog.dismiss();
Places.this.finish();
}
}).show();
}
Looper.loop();
}
}.start();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
/*
* User returning from the Location settings menu. try to fetch location
* again.
*/
dialog.dismiss();
getLocation();
}
/*
* Fetch nearby places by providing the search type as 'place' within 1000
* mtrs of the provided lat & lon
*/
private void fetchPlaces() {
if (!isFinishing()) {
dialog = ProgressDialog.show(Places.this, "",
getString(R.string.nearby_places), true, true,
new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
showToast("No places fetched.");
}
});
}
/*
* Source tag: fetch_places_tag
*/
Bundle params = new Bundle();
params.putString("type", "place");
try {
params.putString("center", location.getString("latitude") + ","
+ location.getString("longitude"));
} catch (JSONException e) {
showToast("No places fetched.");
return;
}
params.putString("distance", "1000");
Utility.mAsyncRunner.request("search", params,
new placesRequestListener());
}
/*
* Callback after places are fetched.
*/
public class placesRequestListener extends BaseRequestListener {
#Override
public void onComplete(final String response, final Object state) {
Log.d("Facebook-FbAPIs", "Got response: " + response);
dialog.dismiss();
try {
jsonArray = new JSONObject(response).getJSONArray("data");
if (jsonArray == null) {
showToast("Error: nearby places could not be fetched");
return;
}
} catch (JSONException e) {
showToast("Error: " + e.getMessage());
return;
}
mHandler.post(new Runnable() {
#Override
public void run() {
placesList = (ListView) findViewById(R.id.places_list);
placesList.setOnItemClickListener(Places.this);
placesList.setAdapter(new PlacesListAdapter(Places.this));
}
});
}
public void onFacebookError(FacebookError error) {
dialog.dismiss();
showToast("Fetch Places Error: " + error.getMessage());
}
}
#Override
public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
if (!Utility.mFacebook.isSessionValid()) {
Util.showAlert(this, "Warning", "You must first log in.");
} else {
try {
final String message = "Check-in from the "
+ getString(R.string.app_name);
final String name = jsonArray.getJSONObject(position)
.getString("name");
final String placeID = jsonArray.getJSONObject(position)
.getString("id");
new AlertDialog.Builder(this)
.setTitle(R.string.check_in_title)
.setMessage(
String.format(getString(R.string.check_in_at),
name))
.setPositiveButton(R.string.checkin,
new DialogInterface.OnClickListener() {
/*
* Source tag: check_in_tag Check-in user at
* the selected location posting to the
* me/checkins endpoint. More info here:
* https://developers.facebook
* .com/docs/reference/api/user/ - checkins
*/
#Override
public void onClick(DialogInterface dialog,
int which) {
Bundle params = new Bundle();
params.putString("place", placeID);
params.putString("message", message);
params.putString("coordinates",
location.toString());
Utility.mAsyncRunner.request(
"me/checkins", params, "POST",
new placesCheckInListener(),
null);
}
}).setNegativeButton(R.string.cancel, null)
.show();
} catch (JSONException e) {
showToast("Error: " + e.getMessage());
}
}
}
public class placesCheckInListener extends BaseRequestListener {
#Override
public void onComplete(final String response, final Object state) {
showToast("API Response: " + response);
}
public void onFacebookError(FacebookError error) {
dialog.dismiss();
showToast("Check-in Error: " + error.getMessage());
}
}
public void showToast(final String msg) {
mHandler.post(new Runnable() {
#Override
public void run() {
Toast toast = Toast.makeText(Places.this, msg,
Toast.LENGTH_LONG);
toast.show();
}
});
}
/**
* Definition of the list adapter
*/
public class PlacesListAdapter extends BaseAdapter {
private LayoutInflater mInflater;
Places placesList;
public PlacesListAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return jsonArray.length();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
JSONObject jsonObject = null;
try {
jsonObject = jsonArray.getJSONObject(position);
} catch (JSONException e1) {
e1.printStackTrace();
}
View hView = convertView;
if (convertView == null) {
hView = mInflater.inflate(R.layout.place_item, null);
ViewHolder holder = new ViewHolder();
holder.name = (TextView) hView.findViewById(R.id.place_name);
holder.location = (TextView) hView
.findViewById(R.id.place_location);
hView.setTag(holder);
}
ViewHolder holder = (ViewHolder) hView.getTag();
try {
holder.name.setText(jsonObject.getString("name"));
} catch (JSONException e) {
holder.name.setText("");
}
try {
String location = jsonObject.getJSONObject("location")
.getString("street")
+ ", "
+ jsonObject.getJSONObject("location")
.getString("city")
+ ", "
+ jsonObject.getJSONObject("location").getString(
"state");
holder.location.setText(location);
} catch (JSONException e) {
holder.location.setText("");
}
return hView;
}
}
class ViewHolder {
TextView name;
TextView location;
}
class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
dialog.dismiss();
if (loc != null) {
try {
location.put("latitude", new Double(loc.getLatitude()));
location.put("longitude", new Double(loc.getLongitude()));
} catch (JSONException e) {
}
showToast("Location acquired: "
+ String.valueOf(loc.getLatitude()) + " "
+ String.valueOf(loc.getLongitude()));
lm.removeUpdates(this);
fetchPlaces();
}
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
}
Related
I am trying to create an Android activity which sends data through the serial port as a product test. I have some code for doing so, which, so far, finds no serial ports on my device which definitely has a serial port. I intend to use this activity with a loopback connector on the serial port of the device to verify both the read and write functionalities. I have tried these two programs:
import android.app.Activity;
import com.symbol.emdk.EMDKManager;
import com.symbol.emdk.EMDKManager.EMDKListener;
import com.symbol.emdk.EMDKManager.FEATURE_TYPE;
import com.symbol.emdk.EMDKResults;
import com.symbol.emdk.serialcomm.SerialComm;
import com.symbol.emdk.serialcomm.SerialCommException;
import com.symbol.emdk.serialcomm.SerialCommManager;
import com.symbol.emdk.serialcomm.SerialCommResults;
import com.symbol.emdk.serialcomm.SerialPortInfo;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import java.util.HashMap;
import java.util.List;
public class SerialTry3 extends Activity implements EMDKListener{
private String TAG = SerialTry3.class.getSimpleName();
private EMDKManager emdkManager = null;
private SerialComm serialCommPort = null;
private SerialCommManager serialCommManager = null;
private EditText txtDataToSend = null;
private TextView txtStatus = null;
private Button btnRead = null;
private Button btnWrite = null;
private Spinner spinnerPorts = null;
public HashMap<String, SerialPortInfo> supportedPorts = null;
#Override #SuppressWarnings("SetTextI18n")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.serial_try);
txtDataToSend = (EditText) findViewById(R.id.txtDataToSend);
txtDataToSend.setText("Serial Communication Write Data Testing.");
spinnerPorts = (Spinner)findViewById(R.id.spinnerPorts);
btnWrite = (Button) findViewById(R.id.btnWrite);
btnRead = (Button) findViewById(R.id.btnRead);
txtStatus = (TextView) findViewById(R.id.statusView);
txtStatus.setText("");
txtStatus.requestFocus();
EMDKResults results = EMDKManager.getEMDKManager(getApplicationContext(), this);
if (results.statusCode != EMDKResults.STATUS_CODE.SUCCESS) {
new AsyncStatusUpdate().execute("EMDKManager object request failed!");
}
new AsyncUiControlUpdate().execute(false);
}
#Override
public void onOpened(EMDKManager emdkManager) {
this.emdkManager = emdkManager;
Log.d(TAG, "EMDK opened");
try{
serialCommManager = (SerialCommManager) this.emdkManager.getInstance(FEATURE_TYPE.SERIALCOMM_EX);
if(serialCommManager != null) {
populatePorts();
}
else
{
new AsyncStatusUpdate().execute(FEATURE_TYPE.SERIALCOMM_EX.toString() + " Feature not supported.");
}
}
catch(Exception e)
{
Log.d(TAG, e.getMessage());
new AsyncStatusUpdate().execute(e.getMessage());
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.splash_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
super.onDestroy();
deinitSerialComm();
if (emdkManager != null) {
emdkManager.release();
emdkManager = null;
}
}
#Override
protected void onPause()
{
super.onPause();
deinitSerialComm();
serialCommManager = null;
supportedPorts = null;
// Release the serialComm manager resources
if (emdkManager != null) {
emdkManager.release(FEATURE_TYPE.SERIALCOMM_EX);
}
}
#Override
protected void onResume()
{
super.onResume();
// Acquire the serialComm manager resources
if (emdkManager != null) {
serialCommManager = (SerialCommManager) emdkManager.getInstance(FEATURE_TYPE.SERIALCOMM_EX);
if (serialCommManager != null) {
populatePorts();
if (supportedPorts != null)
initSerialComm();
}
}
}
void populatePorts()
{
try {
if(serialCommManager != null) {
List<SerialPortInfo> serialPorts = serialCommManager.getSupportedPorts();
if(serialPorts.size()>0) {
supportedPorts = new HashMap<String, SerialPortInfo> ();
String[] ports = new String[serialPorts.size()];
int count = 0;
for (SerialPortInfo info : serialPorts) {
supportedPorts.put(info.getFriendlyName(), info);
ports[count] = info.getFriendlyName();
count++;
}
spinnerPorts.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_dropdown_item, ports));
spinnerPorts.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
//Disabling previous serial port before getting the new one
deinitSerialComm();
initSerialComm();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
else
{
new AsyncStatusUpdate().execute("Failed to get available ports");
Toast.makeText(this, "Failed to get available ports, serial communication may not be supported.", Toast.LENGTH_LONG).show();
finish();
}
}
else
{
new AsyncStatusUpdate().execute("SerialCommManager is null");
}
}
catch (Exception ex)
{
Log.d(TAG, ex.getMessage());
new AsyncStatusUpdate().execute(ex.getMessage());
}
}
void initSerialComm() {
new AsyncEnableSerialComm().execute(supportedPorts.get(spinnerPorts.getSelectedItem()));
}
#Override
public void onClosed() {
if(emdkManager != null) {
emdkManager.release();
}
new AsyncStatusUpdate().execute("EMDK closed unexpectedly! Please close and restart the application.");
}
public void btnReadOnClick(View arg)
{
new AsyncReadData().execute();
}
public void btnWriteOnClick(View arg)
{
new AsyncUiControlUpdate().execute(false);
try {
String writeData = txtDataToSend.getText().toString();
int bytesWritten = serialCommPort.write(writeData.getBytes(), writeData.getBytes().length);
new AsyncStatusUpdate().execute("Bytes written: "+ bytesWritten);
} catch (SerialCommException e) {
new AsyncStatusUpdate().execute("write: "+ e.getResult().getDescription());
}
catch (Exception e) {
new AsyncStatusUpdate().execute("write: "+ e.getMessage() + "\n");
}
new AsyncUiControlUpdate().execute(true);
}
void deinitSerialComm() {
if (serialCommPort != null) {
try {
serialCommPort.disable();
serialCommPort = null;
} catch (Exception ex) {
Log.d(TAG, "deinitSerialComm disable Exception: " + ex.getMessage());
}
}
}
#SuppressWarnings("StaticFieldLeak")
private class AsyncStatusUpdate extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
return params[0];
}
#Override
protected void onPostExecute(String result) {
txtStatus.setText(result);
}
}
#SuppressWarnings("StaticFieldLeak")
private class AsyncUiControlUpdate extends AsyncTask<Boolean, Void, Boolean> {
#Override
protected Boolean doInBackground(Boolean... arg0) {
return arg0[0];
}
#Override
protected void onPostExecute(Boolean bEnable) {
btnRead.setEnabled(bEnable);
btnWrite.setEnabled(bEnable);
txtDataToSend.setEnabled(bEnable);
spinnerPorts.setEnabled(bEnable);
}
}
#SuppressWarnings("StaticFieldLeak")
private class AsyncEnableSerialComm extends AsyncTask<SerialPortInfo, Void, SerialCommResults>
{
#Override
protected SerialCommResults doInBackground(SerialPortInfo... params) {
SerialCommResults returnvar = SerialCommResults.FAILURE;
try {
serialCommPort = serialCommManager.getPort(params[0]);
} catch (Exception ex) {
ex.printStackTrace();
}
if (serialCommPort != null) {
try {
serialCommPort.enable();
returnvar = SerialCommResults.SUCCESS;
} catch (SerialCommException e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
returnvar = e.getResult();
}
}
return returnvar;
}
#Override #SuppressWarnings("SetTextI18n")
protected void onPostExecute(SerialCommResults result) {
super.onPostExecute(result);
if (result == SerialCommResults.SUCCESS) {
new AsyncStatusUpdate().execute("Serial comm channel enabled: (" + spinnerPorts.getSelectedItem().toString() + ")");
txtDataToSend.setText("Serial Communication Write Data Testing " + spinnerPorts.getSelectedItem().toString() + ".");
new AsyncUiControlUpdate().execute(true);
} else {
new AsyncStatusUpdate().execute(result.getDescription());
new AsyncUiControlUpdate().execute(false);
}
}
}
#SuppressWarnings("StaticFieldLeak")
private class AsyncReadData extends AsyncTask<Void, Void, String>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
new AsyncUiControlUpdate().execute(false);
new AsyncStatusUpdate().execute("Reading..");
}
#Override
protected String doInBackground(Void... params) {
String statusText = "";
try {
byte[] readBuffer = serialCommPort.read(10000); //Timeout after 10 seconds
if (readBuffer != null) {
String tempString = new String(readBuffer);
statusText = "Data Read:\n" + tempString;
} else {
statusText = "No Data Available";
}
} catch (SerialCommException e) {
statusText = "read:" + e.getResult().getDescription();
} catch (Exception e) {
statusText = "read:" + e.getMessage();
}
return statusText;
}
#Override
protected void onPostExecute(String statusText) {
super.onPostExecute(statusText);
new AsyncUiControlUpdate().execute(true);
new AsyncStatusUpdate().execute(statusText);
}
}
}
and
import android.app.Activity;
import com.symbol.emdk.EMDKManager;
import com.symbol.emdk.EMDKManager.FEATURE_TYPE;
import com.symbol.emdk.EMDKResults;
import com.symbol.emdk.serialcomm.SerialComm;
import com.symbol.emdk.serialcomm.SerialCommException;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.symbol.emdk.serialcomm.SerialCommManager;
import com.symbol.emdk.serialcomm.SerialPortInfo;
import java.util.List;
public class SerialTry extends Activity implements EMDKManager.EMDKListener {
private String TAG = SerialTry.class.getSimpleName();
private EMDKManager emdkManager = null;
private SerialComm serialComm = null;
private SerialCommManager serialCommMan = null;
private EditText editText = null;
private TextView statusView = null;
private Button readButton = null;
private Button writeButton = null;
#Override #SuppressWarnings("SetTextI18n")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.serial_try);
editText = (EditText) findViewById(R.id.editText1);
editText.setText("Serial Communication Write Data Testing.");
statusView = (TextView) findViewById(R.id.statusView);
statusView.setText("");
statusView.requestFocus();
EMDKResults results = EMDKManager.getEMDKManager(getApplicationContext(), this);
if (results.statusCode != EMDKResults.STATUS_CODE.SUCCESS) {
statusView.setText("Failed to open EMDK");
} else {
statusView.setText("Opening EMDK...");
}
//
// Get the serialComm/port object by passing a SerialPortInfo object:
addReadButtonEvents();
writeButtonEvents();
setEnabled(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.splash_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (emdkManager != null) {
emdkManager.release();
emdkManager = null;
}
}
#Override
public void onOpened(EMDKManager emdkManager) {
this.emdkManager = emdkManager;
Log.d(TAG, "EMDK opened");
try{
serialCommMan = (SerialCommManager) this.emdkManager.getInstance(EMDKManager.FEATURE_TYPE.SERIALCOMM_EX);
List<SerialPortInfo> serialPorts = serialCommMan.getSupportedPorts();
serialComm = serialCommMan.getPort(serialPorts.get(0));
System.out.println("Supported Ports::::::" + serialPorts);
Thread readThread = new Thread(new Runnable() {
#Override
public void run() {
String statusText;
if (serialComm != null) {
try{
serialComm.enable();
statusText = "Serial comm channel enabled";
setEnabled(true);
} catch(SerialCommException e){
Log.d(TAG, e.getMessage());
e.printStackTrace();
statusText = e.getMessage();
setEnabled(false);
}
} else {
statusText = FEATURE_TYPE.SERIALCOMM_EX.toString() + " Feature not supported or initilization error.";
setEnabled(false);
}
displayMessage(statusText);
}
});
readThread.start();
}
catch(Exception e)
{
Log.d(TAG, e.getMessage());
e.printStackTrace();
displayMessage(e.getMessage());
}
}
#Override
public void onClosed() {
if(emdkManager != null) {
emdkManager.release();
}
displayMessage("EMDK closed abruptly.");
}
private void addReadButtonEvents() {
readButton = (Button) findViewById(R.id.btnRead);
readButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Thread readThread = new Thread(new Runnable() {
#Override
public void run() {
setEnabled(false);
String statusText;
try {
byte[] readBuffer = serialComm.read(10000); //Timeout after 10 seconds
if(readBuffer != null) {
String tempString = new String(readBuffer);
statusText = "Data Read:\n" + tempString;
} else {
statusText = "No Data Available";
}
}catch (SerialCommException e) {
statusText ="read:"+ e.getResult().getDescription();
e.printStackTrace();
}
catch (Exception e) {
statusText = "read:"+ e.getMessage();
e.printStackTrace();
}
setEnabled(true);
displayMessage(statusText);
}
});
readThread.start();
}
});
}
#SuppressWarnings("SetTextI18n")
private void writeButtonEvents() {
writeButton = (Button) findViewById(R.id.btnWrite);
writeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
setEnabled(false);
try {
String writeData = editText.getText().toString();
int bytesWritten = serialComm.write(writeData.getBytes(), writeData.getBytes().length);
statusView.setText("Bytes written: "+ bytesWritten);
} catch (SerialCommException e) {
statusView.setText("write: "+ e.getResult().getDescription());
}
catch (Exception e) {
statusView.setText("write: "+ e.getMessage() + "\n");
}
setEnabled(true);
}
});
}
#SuppressWarnings("SetTextI18n")
void displayMessage(String message) {
final String tempMessage = message;
runOnUiThread(new Runnable() {
public void run() {
statusView.setText(tempMessage + "\n");
}
});
}
void setEnabled(boolean enableState) {
final boolean tempState = enableState;
runOnUiThread(new Runnable() {
public void run() {
readButton.setEnabled(tempState);
writeButton.setEnabled(tempState);
editText.setEnabled(tempState);
}
});
}
}
Does the problem seem to be with my code or is there something I am not understanding about the device itself? Any help would be appreciated. Thank you for your time.
I have written an android app which basically allows me to keep track of times and address of GPS coordinates.
I have 3 Lists each corresponding to Lyft, Uber and Other.
But I believe my app starts slowing down my Smart Phone (Samsung Galaxy S7 Edge, with Android O)
can someone look at my code and tell me why is it slowing my smart phone.
My assumption is that, possibly thread synchronization issue.
Attached is my code
1) MainActivity.java
package com.milind.myapp.gpstrackingservice;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.PowerManager;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.ActionMode;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements AddressListener
{
private static final String TAG = MainActivity.class.getSimpleName();
private PowerManager.WakeLock wakeLock;
private TextView labelAddress;
private TextView multiTextLyft;
private TextView multiTextUber;
private TextView multiTextOther;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
labelAddress = findViewById(R.id.label_address);
multiTextLyft = findViewById(R.id.multi_text_lyft);
multiTextUber = findViewById(R.id.multi_text_uber);
multiTextOther = findViewById(R.id.multi_text_other);
if (MyService.isServiceStarted())
{
MyService.getInstance().load(getSharedPrefs());
refreshAllViews();
}
PowerManager powerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "myapp:My Lock");
}
#Override
protected void onStart()
{
super.onStart();
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.WAKE_LOCK}, 1);
if (!MyService.isServiceStarted())
{
Intent intent = new Intent(this, MyService.class);
intent.setAction(MyService.ACTION_START_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
startForegroundService(intent);
}
else
{
startService(intent);
}
}
}
#Override
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
if (hasFocus)
{
if (MyService.isServiceStarted())
{
MyService.getInstance().registerAddressListener(this);
}
wakeLock.acquire();
}
else
{
if (MyService.isServiceStarted())
{
MyService.getInstance().unregisterAddressListener(this);
}
wakeLock.release();
}
}
public void onRequestPermissionsResult(int requestCode, String permissions[],
int[] grantResults)
{
switch (requestCode)
{
case 1:
{
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
}
else
{
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
#Override
public void onLocationChanged(Location loc)
{
final String address = MyService.getAddress(this, loc);
final CharSequence text = labelAddress.getText();
if (text.toString().equals(address))
{
return;
}
MyService.getInstance().load(getSharedPrefs());
labelAddress.setText(address);
refreshAllViews();
new Tone().play(880);
}
private void refreshAllViews()
{
runOnUiThread(new Runnable()
{
public void run()
{
refereshEditTextLyft();
refereshEditTextUber();
refereshEditTextOther();
}
});
}
private void refereshEditTextLyft()
{
multiTextLyft.setText(MyService.getInstance().getLyftAddresses());
}
private void refereshEditTextUber()
{
multiTextUber.setText(MyService.getInstance().getUberAddresses());
}
private void refereshEditTextOther()
{
multiTextOther.setText(MyService.getInstance().getOtherAddresses());
}
private SharedPreferences getSharedPrefs()
{
return getSharedPreferences("name", MODE_PRIVATE);
}
public void onLyftButtonClicked(View view)
{
MyService.getInstance().addLyftAddress(labelAddress.getText());
new Tone().play(440);
refereshEditTextLyft();
MyService.getInstance().save(getSharedPrefs());
}
public void onUberButtonClicked(View view)
{
MyService.getInstance().addUberAddress(labelAddress.getText());
new Tone().play(440);
refereshEditTextUber();
MyService.getInstance().save(getSharedPrefs());
}
public void onOtherButtonClicked(View view)
{
MyService.getInstance().addOtherAddress(labelAddress.getText());
new Tone().play(440);
refereshEditTextOther();
MyService.getInstance().save(getSharedPrefs());
}
public void onClearButtonClicked(View view)
{
if (MyService.isServiceStarted())
{
SharedPreferences sharedPreferences = getSharedPrefs();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.clear();
editor.commit();
MyService.getInstance().clear();
refereshEditTextLyft();
refereshEditTextUber();
refereshEditTextOther();
}
}
public void onDelLyftButtonClicked(View view)
{
MyService.getInstance().delLyftEntry();
new Tone().play(440);
refereshEditTextLyft();
MyService.getInstance().save(getSharedPrefs());
}
public void onDelUberButtonClicked(View view)
{
MyService.getInstance().delUberEntry();
new Tone().play(440);
refereshEditTextUber();
MyService.getInstance().save(getSharedPrefs());
}
public void onDelOtherButtonClicked(View view)
{
MyService.getInstance().delOtherEntry();
new Tone().play(440);
refereshEditTextOther();
MyService.getInstance().save(getSharedPrefs());
}
#Override
protected void onRestart()
{
super.onRestart();
}
#Override
public void onActionModeFinished(ActionMode mode)
{
super.onActionModeFinished(mode);
}
#Override
public void onBackPressed()
{
super.onBackPressed();
}
}
2) The MyService.java
package com.milind.myapp.gpstrackingservice;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class MyService extends Service implements LocationListener
{
private static final String TAG = MyService.class.getSimpleName();
public static final String ACTION_START_SERVICE = "ACTION_START_SERVICE";
public static final String ACTION_STOP_SERVICE = "ACTION_STOP_SERVICE";
public static final String ACTION_UBER = "ACTION_UBER";
public static final String ACTION_LYFT = "ACTION_UBER";
public static final String ACTION_END = "ACTION_END";
public static final String LYFT_PREFIX = "Lyft";
public static final String OTHER_PREFIX = "Other";
public static final String UBER_PREFIX = "Uber";
private static MyService mInstance = null;
private List<AddressListener> listeners = new ArrayList<>();
private List<AddressPoint> lyftAddresses = new ArrayList<>();
private List<AddressPoint> uberAddresses = new ArrayList<>();
private List<AddressPoint> otherAddresses = new ArrayList<>();
private Location mLastLocation;
public MyService()
{
super();
Log.d(TAG, "MyService(): constructor called");
}
public static boolean isServiceStarted()
{
Log.d(TAG, "isServiceStarted()");
return mInstance != null;
}
public static final MyService getInstance()
{
return mInstance;
}
#Override
public IBinder onBind(Intent intent)
{
Log.d(TAG, "onBind(Intent intent)");
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d(TAG, "onStartCommand(Intent, flags, startId) : " + hashCode());
Log.d(TAG, "onStartCommand(...) intent=" + intent + "=" + ", flags=" + flags + ", startId=" + startId);
Log.d(TAG, "onStartCommand(...) isServiceStarted=" + isServiceStarted());
String action = null;
if (intent != null)
{
Log.d(TAG, intent.toString());
action = intent.getAction();
}
else
{
Log.d(TAG, "onStartCommand(...): early return");
return super.onStartCommand(intent, flags, startId);
}
if (isServiceStarted() == false && action == ACTION_START_SERVICE)
{
Log.d(TAG, "onStartCommand(...): Service starting=" + startId);
//startForegroundServivceNotification()
startRunningInForeground();
requestLocationUpdates();
mInstance = this;
Log.d(TAG, "onStartCommand(...): Service started=" + startId);
}
else if (isServiceStarted() == true && action == ACTION_STOP_SERVICE)
{
Log.d(TAG, "onStartCommand(...): Service stopping=" + startId);
stopLocationUpdates();
stopSelf();
Log.d(TAG, "onStartCommand(...): Service stop requested" + startId);
mInstance = null;
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy()
{
Log.d(TAG, "onDestroy(): Service destroyed");
super.onDestroy();
mInstance = null;
}
private void stopLocationUpdates()
{
Log.d(TAG, "stopLocationUpdates()");
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.removeUpdates(this);
}
private void requestLocationUpdates()
{
Log.d(TAG, "requestLocationUpdates()");
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
try
{
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 1500, 0, this);
Log.w(TAG, "requestLocationUpdates(): ended gracefully");
}
catch (SecurityException ex)
{
Log.w(TAG, "requestLocationUpdates(): Exception");
ex.printStackTrace();
}
}
#Override
public void onLocationChanged(Location location)
{
Log.v(TAG, "onLocationChanged(Location location): started, location=" + location.toString());
dispatchLocationChange(location);
mLastLocation = location;
Log.v(TAG, "onLocationChanged: completed");
}
private void dispatchLocationChange(Location loc)
{
Log.v(TAG, "dispatchLocationChange(Location)");
for (AddressListener listener : listeners)
{
listener.onLocationChanged(loc);
}
}
public static String getAddress(Context context, Location loc)
{
Log.v(TAG, "getAddress(Location loc) started");
List<Address> addresses;
Geocoder gcd = new Geocoder(context, Locale.getDefault());
try
{
addresses = gcd.getFromLocation(loc.getLatitude(),
loc.getLongitude(), 1);
String strReturnAddress = "";
if (addresses != null && addresses.size() > 0)
{
final Address address = addresses.get(0);
Log.d(TAG, address.toString());
String addressLines = "";
Log.v(TAG, "Locale: " + address.getLocale());
for (int i = 0; i <= address.getMaxAddressLineIndex(); ++i)
{
Log.v(TAG, "AddressLine " + i + ": " + address.getAddressLine(i));
addressLines += address.getAddressLine(i) + ", ";
Log.v(TAG, "addressLines:" + addressLines);
}
String strAddress =
addressLines
;
Log.v(TAG, "strAddress:" + strAddress);
strReturnAddress = strAddress.substring(0, strAddress.length() - 2);
Log.v(TAG, "strReturnAddress:" + strReturnAddress);
}
Log.d(TAG, "getAddress(Location loc) completed with return=" + strReturnAddress);
return strReturnAddress;
}
catch (IOException e)
{
e.printStackTrace();
Log.d(TAG, "Exception", e);
}
Log.d(TAG, "getAddress(Location loc) completed with return=null");
return "";
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
Log.d(TAG, "onStatusChanged(provider, status, extras): status=" + status + ", extras=" + extras);
}
#Override
public void onProviderEnabled(String provider)
{
Log.d(TAG, "onProviderEnabled(provider) ");
}
#Override
public void onProviderDisabled(String provider)
{
Log.d(TAG, "onProviderDisabled(provider) ");
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
private static void logGetProperties(final String tag, final Object obj)
{
Log.v(tag, "logGetProperties(...)");
Class cls = obj.getClass();
Method[] methods = cls.getMethods();
Log.v(tag, "methods.length = " + methods.length);
for (Method method : methods)
{
String methodName = method.getName();
Log.v(tag, "methodName = " + methodName);
if (methodName.startsWith("get")
&& (method.getParameters() == null || method.getParameters().length == 0)
&& method.getReturnType() != Void.class)
{
try
{
Log.v(tag, methodName + " = " + method.invoke(obj, new Object[0]));
}
catch (Exception ex)
{
Log.e(tag, methodName + " Failed (exception)");
}
}
}
}
public AddressListener registerAddressListener(AddressListener listener)
{
Log.d(TAG, "registerAddressListener(AddressListener)");
if (!listeners.contains(listener))
{
listeners.add(listener);
}
return listener;
}
public AddressListener unregisterAddressListener(AddressListener listener)
{
Log.d(TAG, "unregisterAddressListener(AddressListener)");
if (listeners.contains(listener))
{
listeners.remove(listener);
Log.d(TAG, "unregisterAddressListener(AddressListener): Listener removed");
return listener;
}
Log.d(TAG, "unregisterAddressListener(AddressListener): Listener not found");
return null;
}
public void addLyftAddress(CharSequence text)
{
Log.d(TAG, "addLyftAddress(CharSequence text): text: " + text);
lyftAddresses.add(new AddressPoint(System.currentTimeMillis(), text));
}
public void addUberAddress(CharSequence text)
{
Log.d(TAG, "addUberAddress(CharSequence text): text: " + text);
uberAddresses.add(new AddressPoint(System.currentTimeMillis(), text));
}
public void addOtherAddress(CharSequence text)
{
Log.d(TAG, "addOtherAddress(CharSequence text): text: " + text);
otherAddresses.add(new AddressPoint(System.currentTimeMillis(), text));
}
String getLyftAddresses()
{
return getAddresses(lyftAddresses);
}
String getUberAddresses()
{
return getAddresses(uberAddresses);
}
String getOtherAddresses()
{
return getAddresses(otherAddresses);
}
private String getAddresses(List<AddressPoint> addresses)
{
Log.d(TAG, "getAddresses(List<AddressPoint>)");
String strAddresses = "" + addresses.size() + "\n--------\n";
for (int i = 0; i < addresses.size(); ++i)
{
AddressPoint addresspoint = addresses.get(i);
strAddresses += addresspoint + "\n--------\n";
if ((i % 2) != 0)
{
strAddresses += "\n\n";
}
}
return strAddresses;
}
private void startRunningInForeground()
{
//if more than or equal to 26
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
//if more than 26
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O)
{
String CHANNEL_ONE_ID = "Package.Service";
String CHANNEL_ONE_NAME = "Screen service";
NotificationChannel notificationChannel = null;
notificationChannel = new NotificationChannel(CHANNEL_ONE_ID,
CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_MIN);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setShowBadge(true);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (manager != null)
{
manager.createNotificationChannel(notificationChannel);
}
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground);
Notification notification = new Notification.Builder(getApplicationContext())
.setChannelId(CHANNEL_ONE_ID)
.setContentTitle("Recording data")
.setContentText("App is running background operations")
.setSmallIcon(R.drawable.ic_launcher_background)
.setLargeIcon(icon)
.build();
Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
notification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
startForeground(101, notification);
}
//if version 26
else
{
startForeground(101, updateNotification());
}
}
//if less than version 26
else
{
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("App")
.setContentText("App is running background operations")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setOngoing(true).build();
startForeground(101, notification);
}
}
private Notification updateNotification()
{
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
return new NotificationCompat.Builder(this)
.setContentTitle("Activity log")
.setTicker("Ticker")
.setContentText("app is running background operations")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentIntent(pendingIntent)
.setOngoing(true).build();
}
public void load(final SharedPreferences lSharedPrefs)
{
Log.w(TAG, "load(SharedPreferences): started");
load(lSharedPrefs, lyftAddresses, LYFT_PREFIX);
load(lSharedPrefs, uberAddresses, UBER_PREFIX);
load(lSharedPrefs, otherAddresses, OTHER_PREFIX);
Log.w(TAG, "load(SharedPreferences): completed");
}
private void load(final SharedPreferences lSharedPrefs, final List<AddressPoint> lAddrPoints, final String lPrefix)
{
Log.w(TAG, "load(SharedPreferences, lAddrPoints, lPrefix)");
lAddrPoints.clear();
final int count = lSharedPrefs.getInt(lPrefix + "Count", lAddrPoints.size());
for (int i = 0; i < count; ++i)
{
String address = lSharedPrefs.getString(lPrefix + "Address" + i, null);
final long time = lSharedPrefs.getLong(lPrefix + "Time" + i, 0);
//if address or time is invalid skip to the next entry
if (address == null || time == 0)
{
continue;
}
final AddressPoint addressPoint = new AddressPoint(time, address);
lAddrPoints.add(addressPoint);
}
}
private void save(final SharedPreferences lSharedPrefs, final List<AddressPoint> lAddrPoints, final String lPrefix)
{
Log.w(TAG, "save(SharedPreferences, lAddrPoints, lPrefix)");
SharedPreferences.Editor editor = lSharedPrefs.edit();
final int count = lAddrPoints.size();
//Save the count
editor.putInt(lPrefix + "Count", count);
for (int i = 0; i < count; ++i)
{
//Save the entry
AddressPoint lAddrPoint = lAddrPoints.get(i);
editor.putLong(lPrefix + "Time" + i, lAddrPoint.getTime());
editor.putString(lPrefix + "Address" + i, (String) lAddrPoint.getAddress());
}
Log.w(TAG, "save(sharedFrefs, List, String): commit");
editor.commit();
}
public void save(final SharedPreferences sharedPreferences)
{
Log.w(TAG, "save(SharedPreferences): started");
Log.w(TAG, "save: lyftAddresses");
save(sharedPreferences, lyftAddresses, LYFT_PREFIX);
Log.w(TAG, "save: uberAddresses");
save(sharedPreferences, uberAddresses, UBER_PREFIX);
Log.w(TAG, "save: otherAddresses");
save(sharedPreferences, otherAddresses, OTHER_PREFIX);
Log.w(TAG, "save(SharedPreferences) completed");
}
public void clear()
{
lyftAddresses.clear();
uberAddresses.clear();
otherAddresses.clear();
}
public void delLyftEntry()
{
if (lyftAddresses.size() > 0)
{
lyftAddresses.remove(lyftAddresses.size() - 1);
}
}
public void delUberEntry()
{
if (uberAddresses.size() > 0)
{
uberAddresses.remove(uberAddresses.size() - 1);
}
}
public void delOtherEntry()
{
if (otherAddresses.size() > 0)
{
otherAddresses.remove(otherAddresses.size() - 1);
}
}
}
3) activity_main.xml
4) AndroidManifest.xml
This (likely) isn't a threading issue, in the normal sense of the word. What's happening is you've got a GeoCoder.getFromLocation() call executing on the main thread. Per the documentation:
The returned values may be obtained by means of a network lookup. ...It may be useful to call this method from a thread separate from your primary UI thread.
That means the method could block for several seconds each time it is called. That's more likely if you're driving through an area of spotty cell coverage. Since the method is called with each location update (roughly every 2 seconds), it's understandable that the UI is hanging.
SUGGESTED FIX
Replace your getAddress() function with an AsyncTask, which moves the getFromLocation() call to a background thread (now your app will truly be multithreaded). Something like this should work:
private class GetFromLocationTask extends AsyncTask<Location, Void, List<Address>> {
protected List<Address> doInBackground(Location... locs) {
return gcd.getFromLocation(locs[ 0 ].getLatitude(), locs[ 0 ].getLongitude(), 1);
}
protected void onProgressUpdate(Void... progress) {}
protected void onPostExecute(List<Address> result) {
//execute the remainder of your getAddress() logic here
}
}
Then, execute it using new GetFromLocationTask().execute(location). Call this instead of getAddress(). You don't need to pass a Context to getAddress(), since Service.this will work just as well (it is a Context).
Bonus hint: Note that onLocationChanged() runs on the UI thread, and so does refreshAllViews(). That means your call to runOnUiThread() is superfluous, and it will just execute the given Runnable synchronously.
So here I want to have click event on pressing which i will have particular Category of location rather than search box for searching places. On pressing OnClickGPS it will open PlacePickerFragment of Facebook with search box at the top. But i want to search places category wise like Restaurent, Theatre, etc. on button click. Any assistance in this will be highly appreciable.
package com.priyank.checkin;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.facebook.model.GraphLocation;
import com.facebook.model.GraphPlace;
import com.facebook.widget.PlacePickerFragment;
import com.facebook.Session;
public class PlacePickerSampleActivity extends FragmentActivity implements LocationListener {
private static final int PLACE_ACTIVITY = 1;
private static final Location SEATTLE_LOCATION = new Location("") {
{
setLatitude(47.6097);
setLongitude(-122.3331);
}
};
private static final Location SAN_FRANCISCO_LOCATION = new Location("") {
{
setLatitude(37.7750);
setLongitude(-122.4183);
}
};
private static final Location PARIS_LOCATION = new Location("") {
{
setLatitude(48.857875);
setLongitude(2.294635);
}
};
private TextView resultsTextView;
private LocationManager locationManager;
private Location lastKnownLocation;
private String NameEditTextValue;
private EditText NameEditText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main7);
try {
PackageInfo info = getPackageManager().getPackageInfo(
"com.facebook.samples.hellofacebook",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (NameNotFoundException e) {
} catch (NoSuchAlgorithmException e) {
}
Button b=(Button) findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
NameEditTextValue = NameEditText.getText().toString();
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_SUBJECT, "Alert Message");
i.putExtra(Intent.EXTRA_TEXT, NameEditTextValue +"- via Security Android App");
startActivity(Intent.createChooser(i, "Alert Status"));
}
});
NameEditText = (EditText) findViewById(R.id.editText1);
resultsTextView = (TextView) findViewById(R.id.resultsTextView);
Button button = (Button) findViewById(R.id.seattleButton);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
onClickSeattle();
}
});
button = (Button) findViewById(R.id.sanFranciscoButton);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
onClickSanFrancisco();
}
});
button = (Button) findViewById(R.id.gpsButton);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
onClickGPS();
}
});
if (Session.getActiveSession() == null ||
Session.getActiveSession().isClosed()) {
Session.openActiveSession(this, true, null);
}
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
#Override
protected void onStart() {
super.onStart();
// Update the display every time we are started (this will be "no place selected" on first
// run, or possibly details of a place if the activity is being re-created).
displaySelectedPlace(RESULT_OK);
}
private void onError(Exception exception) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Error").setMessage(exception.getMessage()).setPositiveButton("OK", null);
builder.show();
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PLACE_ACTIVITY:
displaySelectedPlace(resultCode);
break;
default:
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
break;
}
}
private void displaySelectedPlace(int resultCode) {
String results = "";
PlacePickerApplication application = (PlacePickerApplication) getApplication();
GraphPlace selection = application.getSelectedPlace();
if (selection != null) {
GraphLocation location = selection.getLocation();
results = String.format("Name: %s\nCategory: %s\nLocation: (%f,%f)\nStreet: %s, %s, %s, %s, %s",
selection.getName(), selection.getCategory(),
location.getLatitude(), location.getLongitude(),
location.getStreet(), location.getCity(), location.getState(), location.getZip(),
location.getCountry());
} else {
results = "<No place selected>";
}
resultsTextView.setText(results);
NameEditText.setText(results);
}
public void onLocationChanged(Location location) {
lastKnownLocation = location;
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
private void startPickPlaceActivity(Location location) {
PlacePickerApplication application = (PlacePickerApplication) getApplication();
application.setSelectedPlace(null);
Intent intent = new Intent(this, PickPlaceActivity.class);
PickPlaceActivity.populateParameters(intent, location, null);
startActivityForResult(intent, PLACE_ACTIVITY);
}
private void onClickSeattle() {
try {
startPickPlaceActivity(SEATTLE_LOCATION);
} catch (Exception ex) {
onError(ex);
}
}
private void onClickSanFrancisco() {
try {
startPickPlaceActivity(SAN_FRANCISCO_LOCATION);
} catch (Exception ex) {
onError(ex);
}
}
private void onClickGPS() {
try {
if (lastKnownLocation == null) {
Criteria criteria = new Criteria();
String bestProvider = locationManager.getBestProvider(criteria, false);
if (bestProvider != null) {
lastKnownLocation = locationManager.getLastKnownLocation(bestProvider);
}
}
if (lastKnownLocation == null) {
String model = android.os.Build.MODEL;
if (model.equals("sdk") || model.equals("google_sdk") || model.contains("x86")) {
// Looks like they are on an emulator, pretend we're in Paris if we don't have a
// location set.
lastKnownLocation = PARIS_LOCATION;
} else {
new AlertDialog.Builder(this)
.setTitle(R.string.error_dialog_title)
.setMessage(R.string.no_location)
.setPositiveButton(R.string.ok_button, null)
.show();
return;
}
}
startPickPlaceActivity(lastKnownLocation);
} catch (Exception ex) {
onError(ex);
}
}
}
The best way to do this is to use the PlacePickerFragment, and call setSearchText("restaurant"). While it doesn't necessarily restrict it to a category, it will search everything that is categorized as a restaurant.
You can also see an example of this in the Scrumptious sample app (in the PickerActivity class).
i m getting null jsonarray , using official android Facebook api example code Hackbook for user Check in and nearest places list.
public class Places extends Activity implements OnItemClickListener {
private Handler mHandler;
private JSONObject location;
protected ListView placesList;
private Facebook mFacebook;
protected LocationManager lm;
protected MyLocationListener locationListener;
private AsyncFacebookRunner mAsyncRunner;
protected static JSONArray jsonArray;
final static double TIMES_SQUARE_LAT = 40.756;
final static double TIMES_SQUARE_LON = -73.987;
protected ProgressDialog dialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler();
location = new JSONObject();
setContentView(R.layout.places_list);
mFacebook = new Facebook(Constants.FB_APP_ID);
mAsyncRunner = new AsyncFacebookRunner(mFacebook);
Bundle extras = getIntent().getExtras();
String default_or_new = extras.getString("LOCATION");
if (default_or_new.equals("times_square")) {
try {
location.put("latitude",new Double(TIMES_SQUARE_LAT) );
location.put("longitude",new Double(TIMES_SQUARE_LON));
} catch (JSONException e) {
}
fetchPlaces();
} else {
getLocation();
}
}
public void getLocation() {
/*
* launch a new Thread to get new location
*/
new Thread() {
#Override
public void run() {
Looper.prepare();
dialog = ProgressDialog.show(Places.this, "","Fetching Location", false, true,
new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
showToast("No location fetched.");
}
});
if (lm == null) {
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
if (locationListener == null) {
locationListener = new MyLocationListener();
}
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
String provider = lm.getBestProvider(criteria, true);
if (provider != null && lm.isProviderEnabled(provider)) {
lm.requestLocationUpdates(provider, 1, 0, locationListener,
Looper.getMainLooper());
} else {
/*
* GPS not enabled, prompt user to enable GPS in the
* Location menu
*/
new AlertDialog.Builder(Places.this)
.setTitle("enable_gps_title")
.setMessage("enable_gps")
.setPositiveButton("GPS Settings",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
startActivityForResult(
new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS),
0);
}
})
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Places.this.finish();
}
}).show();
}
Looper.loop();
}
}.start();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
/*
* User returning from the Location settings menu. try to fetch location
* again.
*/
dialog.dismiss();
getLocation();
}
/*
* Fetch nearby places by providing the search type as 'place' within 1000
* mtrs of the provided lat & lon
*/
private void fetchPlaces() {
if (!isFinishing()) {
dialog = ProgressDialog.show(Places.this, "", "nearby_places", true,
true, new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
showToast("No places fetched.");
}
});
}
/*
* Source tag: fetch_places_tag
*/
Bundle params = new Bundle();
params.putString("type", "place");
try {
params.putString("center",
location.getString("latitude") + "," + location.getString("longitude"));
} catch (JSONException e) {
showToast("No places fetched.");
return;
}
params.putString("distance", "1000");
mAsyncRunner.request("search", params, new placesRequestListener());
}
/*
* Callback after places are fetched.
*/
public class placesRequestListener extends BaseRequestListener {
#Override
public void onComplete(final String response, final Object state) {
Log.d("Facebook-FbAPIs", "Got response: " + response);
dialog.dismiss();
try {
jsonArray = new JSONObject(response).getJSONArray("data");
if (jsonArray == null) {
showToast("Error: nearby places could not be fetched");
return;
}
} catch (JSONException e) {
showToast("Error: " + e.getMessage());
return;
}
mHandler.post(new Runnable() {
#Override
public void run() {
placesList = (ListView) findViewById(R.id.places_list);
placesList.setOnItemClickListener(Places.this);
placesList.setAdapter(new PlacesListAdapter(Places.this));
}
});
}
public void onFacebookError(FacebookError error) {
dialog.dismiss();
showToast("Fetch Places Error: " + error.getMessage());
}
}
#Override
public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
if (!mFacebook.isSessionValid()) {
Util.showAlert(this, "Warning", "You must first log in.");
} else {
try {
final String message = "Check-in from the " + getString(R.string.app_name);
final String name = jsonArray.getJSONObject(position).getString("name");
final String placeID = jsonArray.getJSONObject(position).getString("id");
new AlertDialog.Builder(this).setTitle("check_in_title")
.setMessage(String.format("check_in_at"))
.setPositiveButton("Chaeck in", new DialogInterface.OnClickListener() {
/*
* Source tag: check_in_tag Check-in user at the
* selected location posting to the me/checkins
* endpoint. More info here:
* https://developers.facebook
* .com/docs/reference/api/user/ - checkins
*/
#Override
public void onClick(DialogInterface dialog, int which) {
Bundle params = new Bundle();
params.putString("place", placeID);
params.putString("message", message);
params.putString("coordinates", location.toString());
mAsyncRunner.request("me/checkins", params, "POST",
new placesCheckInListener(), null);
}
}).setNegativeButton(R.string.cancel, null).show();
} catch (JSONException e) {
showToast("Error: " + e.getMessage());
}
}
}
public class placesCheckInListener extends BaseRequestListener {
#Override
public void onComplete(final String response, final Object state) {
showToast("API Response: " + response);
}
public void onFacebookError(FacebookError error) {
dialog.dismiss();
showToast("Check-in Error: " + error.getMessage());
}
}
public void showToast(final String msg) {
mHandler.post(new Runnable() {
#Override
public void run() {
Toast toast = Toast.makeText(Places.this, msg, Toast.LENGTH_LONG);
toast.show();
}
});
}
/**
* Definition of the list adapter
*/
public class PlacesListAdapter extends BaseAdapter {
private LayoutInflater mInflater;
Places placesList;
public PlacesListAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return jsonArray.length();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
JSONObject jsonObject = null;
try {
jsonObject = jsonArray.getJSONObject(position);
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
View hView = convertView;
if (convertView == null) {
hView = mInflater.inflate(R.layout.place_item, null);
ViewHolder holder = new ViewHolder();
holder.name = (TextView) hView.findViewById(R.id.place_name);
holder.location = (TextView) hView.findViewById(R.id.place_location);
hView.setTag(holder);
}
ViewHolder holder = (ViewHolder) hView.getTag();
try {
holder.name.setText(jsonObject.getString("name"));
} catch (JSONException e) {
holder.name.setText("");
}
try {
String location = jsonObject.getJSONObject("location").getString("street") + ", "
+ jsonObject.getJSONObject("location").getString("city") + ", "
+ jsonObject.getJSONObject("location").getString("state");
holder.location.setText(location);
} catch (JSONException e) {
holder.location.setText("");
}
return hView;
}
}
class ViewHolder {
TextView name;
TextView location;
}
class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
dialog.dismiss();
if (loc != null) {
try {
location.put("latitude", new Double(loc.getLatitude()));
location.put("longitude", new Double(loc.getLongitude()));
} catch (JSONException e) {
}
showToast("Location acquired: " + String.valueOf(loc.getLatitude()) + " "
+ String.valueOf(loc.getLongitude()));
lm.removeUpdates(this);
fetchPlaces();
}
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
Getting Jsonarray null in below line:
jsonArray = new JSONObject(response).getJSONArray("data");
let me know what is wrong in this above code thnx a lot
I just used a code for camera application in android. In this application, the photo that clicked is saved in to SD Card.My code for saving as shown bellow $
Camera.PictureCallback jpegCallback = new PictureCallback()
{
public void onPictureTaken(byte[] data, Camera camera)
{
FileOutputStream outStream = null;
try
{
outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
Log.d(TAG, "on pictureTaken" + data.length);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{}
Log.d(TAG, "on pictureTaken-jpeg");
}
};
I just upload that image from sd card to facebook by using another activity by using FacebookSDK as shown bellow.
public class Upload extends Activity implements OnItemClickListener
{
/* Your Facebook Application ID must be set before running this example
* See http://www.facebook.com/developers/createapp.php
*/
public static final String APP_ID = "146770088755283";
private LoginButton mLoginButton;
private TextView mText;
private ImageView mUserPic;
private Handler mHandler;
ProgressDialog dialog;
final int AUTHORIZE_ACTIVITY_RESULT_CODE = 0;
final int PICK_EXISTING_PHOTO_RESULT_CODE = 1;
private ListView list;
String[] main_items = {"Upload Photo"};
String[] permissions = {"offline_access", "publish_stream", "user_photos", "publish_checkins", "photo_upload"};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (APP_ID == null)
{
Util.showAlert(this, "Warning", "Facebook Applicaton ID must be " +
"specified before running this example: see FbAPIs.java");
return;
}
setContentView(R.layout.main);
mHandler = new Handler();
mText = (TextView) Upload.this.findViewById(R.id.txt);
mUserPic = (ImageView)Upload.this.findViewById(R.id.user_pic);
//Create the Facebook Object using the app id.
Utility.mFacebook = new Facebook(APP_ID);
//Instantiate the asynrunner object for asynchronous api calls.
Utility.mAsyncRunner = new AsyncFacebookRunner(Utility.mFacebook);
mLoginButton = (LoginButton) findViewById(R.id.login);
//restore session if one exists
SessionStore.restore(Utility.mFacebook, this);
SessionEvents.addAuthListener(new FbAPIsAuthListener());
SessionEvents.addLogoutListener(new FbAPIsLogoutListener());
/*
* Source Tag: login_tag
*/
mLoginButton.init(this, AUTHORIZE_ACTIVITY_RESULT_CODE, Utility.mFacebook, permissions);
if(Utility.mFacebook.isSessionValid())
{
requestUserData();
}
list = (ListView)findViewById(R.id.main_list);
list.setOnItemClickListener(this);
list.setAdapter(new ArrayAdapter<String>(this, R.layout.main_list_item, main_items));
}
#Override
public void onResume()
{
super.onResume();
if(Utility.mFacebook != null && !Utility.mFacebook.isSessionValid())
{
mText.setText("You are logged out! ");
mUserPic.setImageBitmap(null);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode)
{
/*
* if this is the activity result from authorization flow, do a call back to authorizeCallback
* Source Tag: login_tag
*/
case AUTHORIZE_ACTIVITY_RESULT_CODE:
{
Utility.mFacebook.authorizeCallback(requestCode, resultCode, data);
break;
}
/*
* if this is the result for a photo picker from the gallery, upload the image after scaling it.
* You can use the Utility.scaleImage() function for scaling
*/
case PICK_EXISTING_PHOTO_RESULT_CODE:
{
if (resultCode == Activity.RESULT_OK)
{
Uri photoUri = data.getData();
if(photoUri != null) {
Bundle params = new Bundle();
try
{
params.putByteArray("photo", Utility.scaleImage(getApplicationContext(), photoUri));
} catch (IOException e)
{
e.printStackTrace();
}
params.putString("caption", "FbAPIs Sample App photo upload");
Utility.mAsyncRunner.request("me/photos", params, "POST", new PhotoUploadListener(), null);
}
else
{
Toast.makeText(getApplicationContext(), "Error selecting image from the gallery.", Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(getApplicationContext(), "No image selected for upload.", Toast.LENGTH_SHORT).show();
}
break;
}
}
}
public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3)
{
switch(position)
{
/*
* Source Tag: upload_photo
* You can upload a photo from the media gallery or from a remote server
* How to upload photo: https://developers.facebook.com/blog/post/498/
*/
case 0:
{
if(!Utility.mFacebook.isSessionValid())
{
Util.showAlert(this, "Warning", "You must first log in.");
}
else
{
dialog = ProgressDialog.show(Upload.this, "", getString(R.string.please_wait), true, true);
new AlertDialog.Builder(this)
.setTitle(R.string.gallery_title)
.setMessage(R.string.gallery_msg)
.setPositiveButton(R.string.gallery_button, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
Intent intent = new Intent(Intent.ACTION_PICK, (MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
startActivityForResult(intent, PICK_EXISTING_PHOTO_RESULT_CODE);
}
})
.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface d) {
dialog.dismiss();
}
})
.show();
}
break;
}
}
}
/*
* callback for the feed dialog which updates the profile status
*/
public class UpdateStatusListener extends BaseDialogListener {
public void onComplete(Bundle values) {
final String postId = values.getString("post_id");
if (postId != null) {
new UpdateStatusResultDialog(Upload.this, "Update Status executed", values).show();
} else {
Toast toast = Toast.makeText(getApplicationContext(), "No wall post made", Toast.LENGTH_SHORT);
toast.show();
}
}
public void onFacebookError(FacebookError error) {
Toast.makeText(getApplicationContext(), "Facebook Error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
public void onCancel() {
Toast toast = Toast.makeText(getApplicationContext(), "Update status cancelled", Toast.LENGTH_SHORT);
toast.show();
}
}
/*
* callback for the apprequests dialog which sends an app request to user's friends.
*/
public class AppRequestsListener extends BaseDialogListener {
public void onComplete(Bundle values) {
Toast toast = Toast.makeText(getApplicationContext(), "App request sent", Toast.LENGTH_SHORT);
toast.show();
}
public void onFacebookError(FacebookError error) {
Toast.makeText(getApplicationContext(), "Facebook Error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
public void onCancel() {
Toast toast = Toast.makeText(getApplicationContext(), "App request cancelled", Toast.LENGTH_SHORT);
toast.show();
}
}
/*
* callback for the photo upload
*/
public class PhotoUploadListener extends BaseRequestListener {
public void onComplete(final String response, final Object state) {
dialog.dismiss();
mHandler.post(new Runnable() {
public void run() {
new UploadPhotoResultDialog(Upload.this, "Upload Photo executed", response).show();
}
});
}
public void onFacebookError(FacebookError error) {
dialog.dismiss();
Toast.makeText(getApplicationContext(), "Facebook Error: " + error.getMessage(), Toast.LENGTH_LONG).show();
}
}
public class FQLRequestListener extends BaseRequestListener {
public void onComplete(final String response, final Object state) {
mHandler.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Response: " + response, Toast.LENGTH_LONG).show();
}
});
}
public void onFacebookError(FacebookError error) {
Toast.makeText(getApplicationContext(), "Facebook Error: " + error.getMessage(), Toast.LENGTH_LONG).show();
}
}
/*
* Callback for fetching current user's name, picture, uid.
*/
public class UserRequestListener extends BaseRequestListener {
public void onComplete(final String response, final Object state) {
JSONObject jsonObject;
try {
jsonObject = new JSONObject(response);
final String picURL = jsonObject.getString("picture");
final String name = jsonObject.getString("name");
Utility.userUID = jsonObject.getString("id");
mHandler.post(new Runnable() {
public void run() {
mText.setText("Welcome " + name + "!");
mUserPic.setImageBitmap(Utility.getBitmap(picURL));
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
}
/*
* The Callback for notifying the application when authorization
* succeeds or fails.
*/
public class FbAPIsAuthListener implements AuthListener {
public void onAuthSucceed() {
requestUserData();
}
public void onAuthFail(String error) {
mText.setText("Login Failed: " + error);
}
}
/*
* The Callback for notifying the application when log out
* starts and finishes.
*/
public class FbAPIsLogoutListener implements LogoutListener {
public void onLogoutBegin() {
mText.setText("Logging out...");
}
public void onLogoutFinish() {
mText.setText("You have logged out! ");
mUserPic.setImageBitmap(null);
}
}
/*
* Request user name, and picture to show on the main screen.
*/
public void requestUserData() {
mText.setText("Fetching user name, profile pic...");
Bundle params = new Bundle();
params.putString("fields", "name, picture");
Utility.mAsyncRunner.request("me", params, new UserRequestListener());
}
/**
* Definition of the list adapter
*/
public class MainListAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public MainListAdapter() {
mInflater = LayoutInflater.from(Upload.this.getBaseContext());
}
public int getCount() {
return main_items.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
View hView = convertView;
if(convertView == null) {
hView = mInflater.inflate(R.layout.main_list_item, null);
ViewHolder holder = new ViewHolder();
holder.main_list_item = (TextView) hView.findViewById(R.id.main_api_item);
hView.setTag(holder);
}
ViewHolder holder = (ViewHolder) hView.getTag();
holder.main_list_item.setText(main_items[position]);
return hView;
}
}
class ViewHolder {
TextView main_list_item;
}
}
I want to upload that photo to facebook without save to SD Card and from the same activity that photo clicked. If anyone knows about it, please help me....
It is not possible in your case. The reason looks to be you are using native camera to capture a snap.So by default your snap will be saved to sdcard in the default location. There is no way you can stop it. But still you can delete the image after it is captured using the data returned from the Activity Result.