I designed a chat application but if I write text and click on send the application is force closed. I send username, ip and port information to the other activity.
messaging code :
import java.io.UnsupportedEncodingException;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.android.chat.IAppManager;
import com.android.chat.IMService;
import com.android.chat.FriendController;
import com.android.chat.LocalStorageHandler;
import com.android.chat.FriendInfo;
import com.android.chat.MessageInfo;
import com.android.chats.R;
public class Messaging extends Activity {
private static final int MESSAGE_CANNOT_BE_SENT = 0;
public String username;
private EditText messageText;
private EditText messageHistoryText;
private Button sendMessageButton;
private IAppManager imService;
private FriendInfo friend = new FriendInfo();
private LocalStorageHandler localstoragehandler;
private Cursor dbCursor;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
imService = ((IMService.IMBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
imService = null;
Toast.makeText(Messaging.this, R.string.local_service_stopped,
Toast.LENGTH_SHORT).show();
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.messaging_screen); //messaging_screen);
messageHistoryText = (EditText) findViewById(R.id.messageHistory);
messageText = (EditText) findViewById(R.id.message);
messageText.requestFocus();
sendMessageButton = (Button) findViewById(R.id.sendMessageButton);
Bundle extras = this.getIntent().getExtras();
friend.userName = extras.getString(FriendInfo.USERNAME);
friend.ip = extras.getString(FriendInfo.IP);
friend.port = extras.getString(FriendInfo.PORT);
String msg = extras.getString(MessageInfo.MESSAGETEXT);
setTitle("Messaging with " + friend.userName);
// EditText friendUserName = (EditText) findViewById(R.id.friendUserName);
// friendUserName.setText(friend.userName);
localstoragehandler = new LocalStorageHandler(this);
dbCursor = localstoragehandler.get(friend.userName, IMService.USERNAME );
if (dbCursor.getCount() > 0){
int noOfScorer = 0;
dbCursor.moveToFirst();
while ((!dbCursor.isAfterLast())&&noOfScorer<dbCursor.getCount())
{
noOfScorer++;
this.appendToMessageHistory(dbCursor.getString(2) , dbCursor.getString(3));
dbCursor.moveToNext();
}
}
localstoragehandler.close();
if (msg != null)
{
this.appendToMessageHistory(friend.userName , msg);
((NotificationManager)getSystemService(NOTIFICATION_SERVICE)).cancel((friend.userName+msg).hashCode());
}
sendMessageButton.setOnClickListener(new OnClickListener(){
CharSequence message;
Handler handler = new Handler();
public void onClick(View arg0) {
message = messageText.getText();
if (message.length()>0)
{
appendToMessageHistory(imService.getUsername(), message.toString());
localstoragehandler.insert(imService.getUsername(), friend.userName, message.toString());
messageText.setText("");
Thread thread = new Thread(){
public void run() {
try {
if (imService.sendMessage(imService.getUsername(), friend.userName, message.toString()) == null)
{
handler.post(new Runnable(){
public void run() {
Toast.makeText(getApplicationContext(),R.string.message_cannot_be_sent, Toast.LENGTH_LONG).show();
//showDialog(MESSAGE_CANNOT_BE_SENT);
}
});
}
} catch (UnsupportedEncodingException e) {
Toast.makeText(getApplicationContext(),R.string.message_cannot_be_sent, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
};
thread.start();
}
}});
messageText.setOnKeyListener(new OnKeyListener(){
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (keyCode == 66){
sendMessageButton.performClick();
return true;
}
return false;
}
});
}
#Override
protected Dialog onCreateDialog(int id) {
int message = -1;
switch (id)
{
case MESSAGE_CANNOT_BE_SENT:
message = R.string.message_cannot_be_sent;
break;
}
if (message == -1)
{
return null;
}
else
{
return new AlertDialog.Builder(Messaging.this)
.setMessage(message)
.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* User clicked OK so do some stuff */
}
})
.create();
}
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(messageReceiver);
unbindService(mConnection);
FriendController.setActiveFriend(null);
}
#Override
protected void onResume()
{
super.onResume();
bindService(new Intent(Messaging.this, IMService.class), mConnection , Context.BIND_AUTO_CREATE);
IntentFilter i = new IntentFilter();
i.addAction(IMService.TAKE_MESSAGE);
registerReceiver(messageReceiver, i);
FriendController.setActiveFriend(friend.userName);
}
public class MessageReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Bundle extra = intent.getExtras();
String username = extra.getString(MessageInfo.USERID);
String message = extra.getString(MessageInfo.MESSAGETEXT);
if (username != null && message != null)
{
if (friend.userName.equals(username)) {
appendToMessageHistory(username, message);
localstoragehandler.insert(username,imService.getUsername(), message);
}
else {
if (message.length() > 15) {
message = message.substring(0, 15);
}
Toast.makeText(Messaging.this, username + " says '"+
message + "'",
Toast.LENGTH_SHORT).show();
}
}
}
};
private MessageReceiver messageReceiver = new MessageReceiver();
public void appendToMessageHistory(String username, String message) {
if (username != null && message != null) {
messageHistoryText.append(username + ":\n");
messageHistoryText.append(message + "\n");
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (localstoragehandler != null) {
localstoragehandler.close();
}
if (dbCursor != null) {
dbCursor.close();
}
}
}
logcat message:
if I write text and click on send the application is force closed. I send username, ip and port information to the other activity.
code messageing :
public class Messaging extends Activity {
private static final int MESSAGE_CANNOT_BE_SENT = 0;
public String username;
private EditText messageText;
private EditText messageHistoryText;
private Button sendMessageButton;
private IAppManager imService;
private FriendInfo friend = new ir.android.chat.FriendInfo();
private LocalStorageHandler localstoragehandler;
private Cursor dbCursor;
public static String res="";
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
imService = ((IMService.IMBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
imService = null;
Toast.makeText(Messaging.this, R.string.local_service_stopped,
Toast.LENGTH_SHORT).show();
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.messaging_screen); //messaging_screen);
messageHistoryText = (EditText) findViewById(R.id.messageHistory);
messageText = (EditText) findViewById(R.id.message);
messageText.requestFocus();
sendMessageButton = (Button) findViewById(R.id.sendMessageButton);
Bundle extras = this.getIntent().getExtras();
friend.userName = extras.getString(FriendInfo.USERNAME);
friend.userNamef = extras.getString(FriendInfo.USERNAMEF);
friend.ip = extras.getString(FriendInfo.IP);
friend.port = extras.getString(FriendInfo.PORT);
String msg = extras.getString(MessageInfo.MESSAGETEXT);
setTitle("Messaging with " + friend.userName);
// EditText friendUserName = (EditText) findViewById(R.id.friendUserName);
// friendUserName.setText(friend.userName);
localstoragehandler = new LocalStorageHandler(this);
dbCursor = localstoragehandler.get(friend.userName, IMService.USERNAME );
if (dbCursor.getCount() > 0){
int noOfScorer = 0;
dbCursor.moveToFirst();
while ((!dbCursor.isAfterLast())&&noOfScorer<dbCursor.getCount())
{
noOfScorer++;
this.appendToMessageHistory(dbCursor.getString(2) , dbCursor.getString(3));
dbCursor.moveToNext();
}
}
localstoragehandler.close();
if (msg != null)
{
this.appendToMessageHistory(friend.userName , msg);
((NotificationManager)getSystemService(NOTIFICATION_SERVICE)).cancel((friend.userName+msg).hashCode());
}
sendMessageButton.setOnClickListener(new OnClickListener(){
CharSequence message;
Handler handler = new Handler();
public void onClick(View arg0) {
message = messageText.getText();
if (message.length()>0)
{
//appendToMessageHistory(friend.userNamef, message.toString());
appendToMessageHistory(friend.userNamef, message.toString());
localstoragehandler.insert(friend.userNamef, friend.userName, message.toString());
messageText.setText("");
Thread thread = new Thread(){
public void run() {
try {
if (imService.sendMessage(friend.userNamef, friend.userName, message.toString()) == null)
{
handler.post(new Runnable(){
public void run() {
Toast.makeText(getApplicationContext(),R.string.message_cannot_be_sent, Toast.LENGTH_LONG).show();
//showDialog(MESSAGE_CANNOT_BE_SENT);
}
});
}
} catch (UnsupportedEncodingException e) {
Toast.makeText(getApplicationContext(),R.string.message_cannot_be_sent, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
};
thread.start();
}
}});
messageText.setOnKeyListener(new OnKeyListener(){
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (keyCode == 66){
sendMessageButton.performClick();
return true;
}
return false;
}
});
}
#Override
protected Dialog onCreateDialog(int id) {
int message = -1;
switch (id)
{
case MESSAGE_CANNOT_BE_SENT:
message = R.string.message_cannot_be_sent;
break;
}
if (message == -1)
{
return null;
}
else
{
return new AlertDialog.Builder(Messaging.this)
.setMessage(message)
.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* User clicked OK so do some stuff */
}
})
.create();
}
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(messageReceiver);
unbindService(mConnection);
FriendController.setActiveFriend(null);
}
#Override
protected void onResume()
{
super.onResume();
bindService(new Intent(Messaging.this, IMService.class), mConnection , Context.BIND_AUTO_CREATE);
IntentFilter i = new IntentFilter();
i.addAction(IMService.TAKE_MESSAGE);
registerReceiver(messageReceiver, i);
FriendController.setActiveFriend(friend.userName);
}
public class MessageReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Bundle extra = intent.getExtras();
String username = extra.getString(MessageInfo.USERID);
String message = extra.getString(MessageInfo.MESSAGETEXT);
if (username != null && message != null)
{
if (friend.userName.equals(username)) {
appendToMessageHistory(username, message);
localstoragehandler.insert(username,friend.userNamef, message);
}
else {
if (message.length() > 15) {
message = message.substring(0, 15);
}
Toast.makeText(Messaging.this, username + " says '"+
message + "'",
Toast.LENGTH_SHORT).show();
}
}
}
};
private MessageReceiver messageReceiver = new MessageReceiver();
public void appendToMessageHistory(String username, String message) {
if (username != null && message != null) {
messageHistoryText.append(username + ":\n");
messageHistoryText.append(message + "\n");
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (localstoragehandler != null) {
localstoragehandler.close();
}
if (dbCursor != null) {
dbCursor.close();
}
}
}
log chat :
http://i.stack.imgur.com/USsul.png
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.
I have this service which send my location to server and get some data from it.
package com.speed00.service;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.widget.Toast;
import com.google.gson.Gson;
import com.speed00.R;
import com.speed00.constant.AppConstant;
import com.speed00.helper.FunctionHelper;
import com.speed00.model.achivment.StepHelper;
import com.speed00.model.ride.RideResultResponse;
import com.speed00.model.ride.UpdateLocationData;
import com.speed00.model.ride.UpdateLocationResponse;
import com.speed00.prefrences.MyPreferences;
import com.speed00.prefrences.MySharedPreference;
import com.speed00.retrofit.ApiUtils;
import com.speed00.stepdetucter.StepDetector;
import com.speed00.stepdetucter.StepListener;
import com.speed00.ui.activity.HomeActivity;
import com.speed00.utils.Logger;
import com.speed00.utils.MySensorEventListener;
import com.speed00.utils.NetworkConnection;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MyService extends Service implements StepListener, SensorEventListener {
// constant
// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
private Timer mTimer = null;
private Double locationRange = 1.0;
private String oldDegree;
private boolean isServiceRunning;
private int numSteps = 0;
private final int FINAL_STEP = 15;
private SensorManager sensorManager;
private Sensor accel;
String speed_received = "0";
private boolean pedoMetterHasStarted = false;
String pLatitude;
String pLongitude;
private SensorEventListener eListener;
private Sensor accelerometer, magFieldSensor;
private StepDetector simpleStepDetector;
#Override
public IBinder onBind(Intent intent) {
return null;
}
private BroadcastReceiver message = new BroadcastReceiver() {
#Override
public void onReceive(Context context, final Intent intent) {
// TODO Auto-generated method stub
new Handler().post(new Runnable() {
#Override
public void run() {
speed_received = intent.getStringExtra("current speed");
Logger.e("speed__recv" + speed_received);
if (speed_received != null) {
// setSpeedValue(speed_received);//this method is calling to set speed.
//This method is calling to validate Timer For Ride
if (speed_received.equalsIgnoreCase("0")) {
if (!pedoMetterHasStarted) {
numSteps = 0;
statPedoMeter();
}
}
//Calculating distance value
String latitude = MySharedPreference.getInstance(MyService.this).getLatitude();
String longitude = MySharedPreference.getInstance(MyService.this).getLongitude();
if (TextUtils.isEmpty(pLatitude)) {
pLatitude = latitude;
pLongitude = longitude;
} else {
/*
* if distance is more then 2 km then its calculatiog.
*
* */
Location pLocation = new Location("P");
pLocation.setLongitude(Double.parseDouble(pLatitude));
pLocation.setLongitude(Double.parseDouble(pLongitude));
Location nLocation = new Location("N");
nLocation.setLongitude(Double.parseDouble(latitude));
nLocation.setLongitude(Double.parseDouble(longitude));
Logger.e("distance----" + pLocation.distanceTo(nLocation));
if (pLocation.distanceTo(nLocation) >= 10) {
pLatitude = latitude;
pLongitude = longitude;
}
}
}
}
});
}
};
#Override
public void onCreate() {
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
eListener = new MySensorEventListener(this, sensorManager);//for direction
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magFieldSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
//callback sensor of ui
sensorManager.registerListener(eListener, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(eListener, magFieldSensor, SensorManager.SENSOR_DELAY_NORMAL);
assert sensorManager != null;
accel = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
simpleStepDetector = new StepDetector();
simpleStepDetector.registerListener(this);
Toast.makeText(getApplicationContext(), "Service Started", Toast.LENGTH_SHORT).show();
isServiceRunning = true;
// Toast.makeText(getApplicationContext(), "service started", Toast.LENGTH_SHORT).show();
// cancel if already existed
if (mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
// new Timer().scheduleAtFixedRate(new TimeDisplayTimerTask(), 100, NOTIFY_INTERVAL);
runLoop();
LocalBroadcastManager.getInstance(this).registerReceiver(message,
new IntentFilter("send"));
}
private void runLoop() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
updateDriverLocation();
if (isServiceRunning)
runLoop();
}
}, 1000);
}
/*
*
* This method is calling to update driver location
* */
private void updateDriverLocation() {
//Get all user details data.
String userId = MySharedPreference.getInstance(getApplicationContext()).getDriverId();
String latitudeData = MySharedPreference.getInstance(getApplicationContext()).getLatitude();
String longitudeData = MySharedPreference.getInstance(getApplicationContext()).getLongitude();
String speedData = MySharedPreference.getInstance(getApplicationContext()).getSpeedData();//how to roinf
Logger.e("SERVER " + latitudeData + " " + longitudeData);
Logger.e("SPEED " + speedData);
String directionValue = MySharedPreference.getInstance(getApplicationContext()).getDirectionValue();
String speeding = MySharedPreference.getInstance(getApplicationContext()).getSpeeding();
String language = MyPreferences.newInstance(getApplicationContext()).getLanguage();//send speeding data to bakend.
String directionText = MySharedPreference.getInstance(getApplicationContext()).getDirectionText();
long driveTime = FunctionHelper.getDifference(MySharedPreference.getInstance(getApplicationContext()).getStartTime());
String validateUTurn = validateUTurn();
// Logger.e("update_request--" + request);
ApiUtils.getAPIService().updateDriverLocation(validateUTurn, directionText, speeding, "" + driveTime, language, userId,
AppConstant.START_RIDE, speedData, directionValue, latitudeData, longitudeData).enqueue(new Callback<UpdateLocationResponse>() {
#Override
public void onResponse(Call<UpdateLocationResponse> call, Response<UpdateLocationResponse> response) {
if (response.isSuccessful()) {
UpdateLocationResponse updateLocationResponse = response.body();
if (updateLocationResponse.getErrorCode().equalsIgnoreCase(AppConstant.ERROR_CODE)) {
if (updateLocationResponse.getData().size() > 0) {
UpdateLocationData updateLocationData = updateLocationResponse.getData().get(0);
String eventData = FunctionHelper.validateData(updateLocationData);
broadCastEventData(eventData, updateLocationResponse.getErrorCode());
broadCastResponseData(updateLocationResponse);
}
}
}
}
#Override
public void onFailure(Call<UpdateLocationResponse> call, Throwable t) {
}
});
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
/*
*
*This method is calling to validateUTurn.
*
*
* */
private String validateUTurn() {
String currentDegree = MySharedPreference.getInstance(this).getDirectionValue();
String uTurnStatus = "0";
if (TextUtils.isEmpty(oldDegree)) {
oldDegree = currentDegree;
uTurnStatus = "0";
return uTurnStatus;
} else {
if (oldDegree == "0.0") {
oldDegree = currentDegree;
}
if (Float.parseFloat(oldDegree) <= Float.parseFloat(currentDegree)) {
uTurnStatus = "1";
} else {
uTurnStatus = "0";
}
if (Float.parseFloat(oldDegree) == 360 || Float.parseFloat(oldDegree) > 270) {
if (Float.parseFloat(currentDegree) > 0 && Float.parseFloat(oldDegree) <= 90) {
uTurnStatus = "1";
}
}
oldDegree = currentDegree;
return uTurnStatus;
}
}
public synchronized void broadCastEventData(String eventData, String errorCode) {
Intent intent = new Intent("event_broad_cast");
intent.putExtra("data", eventData);
intent.putExtra("error", errorCode);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
/*
* This method is calling to broadcast event data
* */
/*
* This method is calling to broadcast event data
* */
public synchronized void broadCastResponseData(UpdateLocationResponse updateLocationData) {
Intent intent = new Intent("location_update");
Bundle args = new Bundle();
args.putSerializable("data", (Serializable) updateLocationData);
intent.putExtra("myvalue", args);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
#Override
public void onDestroy() {
super.onDestroy();
isServiceRunning = false;
LocalBroadcastManager.getInstance(this).unregisterReceiver(message);
// stopPedoMeter();
}
#Override
public void step(long timeNs) {
if (numSteps < 16)
Toast.makeText(this, "" + numSteps, Toast.LENGTH_SHORT).show();
saveStep();
if (calculateSteps()) {
stopRideAfter25step();
stopPedoMeter();//this method is calling to stop ResultActivity
} else if (Double.parseDouble(MySharedPreference.getInstance(this).getSpeedData()) > 10) {
MySharedPreference.getInstance(this).setSteps(new ArrayList<StepHelper>());
numSteps = 0;
} else {
Logger.e("stepsss " + numSteps);
numSteps = numSteps + 1;
}
}
private void stopRideAfter25step() {
MySharedPreference.getInstance(this).setSteps(new ArrayList<StepHelper>());
String speed = MySharedPreference.getInstance(this).getSpeedData();
String direction = MySharedPreference.getInstance(this).getDirectionValue();
String latitude = MySharedPreference.getInstance(this).getLatitude();
String longitude = MySharedPreference.getInstance(this).getLongitude();
String driverId = MySharedPreference.getInstance(this).getDriverId();
String language = MyPreferences.newInstance(this).getLanguage();
String speeding = MySharedPreference.getInstance(this).getSpeeding();
long driveTime = FunctionHelper.getDifference(MySharedPreference.getInstance(this).getStartTime());
//validate internet connection
if (NetworkConnection.isConnection(this)) {
stopRide("" + driveTime, language, speeding, driverId, latitude, longitude, AppConstant.STOP_RIDE, speed, direction);
} else {
Toast.makeText(this, getString(R.string.valid_please_check_network_connection), Toast.LENGTH_LONG).show();
}
}
public void stopRide(final String driveTime, final String languageKey, final String speedLimit, final String driverId, final String latitude, final String longitude, String rideStatus, final String speed, final String direction) {
String[] param = {driveTime, languageKey, speedLimit, driverId, speed, direction, latitude, longitude};
new stopLoc(this).execute(param);
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
simpleStepDetector.updateAccel(event.timestamp, event.values[0], event.values[1], event.values[2]);
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
private static class stopLoc extends AsyncTask<String[], Void, Void> {
Context mContext;
public stopLoc(Context mContext) {
this.mContext = mContext;
}
#Override
protected Void doInBackground(String[]... strings) {
Logger.e("stepsss stopingggg");
String driveTime = strings[0][0];
String languageKey = strings[0][1];
String speedLimit = strings[0][2];
String driverId = strings[0][3];
String speed = strings[0][4];
String direction = strings[0][5];
String latitude = strings[0][6];
String longitude = strings[0][7];
ApiUtils.getAPIService().stopTrip(driveTime, languageKey, speedLimit, driverId, AppConstant.STOP_RIDE, speed, direction, latitude, longitude).enqueue(new Callback<RideResultResponse>() {
#Override
public void onResponse(Call<RideResultResponse> call, Response<RideResultResponse> response) {
Logger.e("response----" + new Gson().toJson(response.body()));
if (response.isSuccessful()) {
String errorCode = response.body().getErrorCode();
if (errorCode.equalsIgnoreCase(AppConstant.ERROR_CODE)) {
tripSuccessData(response.body(), mContext);
} else {
Toast.makeText(mContext, "" + mContext.getString(R.string.text_some_erroroccurs), Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onFailure(Call<RideResultResponse> call, Throwable t) {
Toast.makeText(mContext, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
return null;
}
}
public static void tripSuccessData(Object data, Context context) {
RideResultResponse resultResponse = (RideResultResponse) data;
if (resultResponse.getErrorCode().equalsIgnoreCase(AppConstant.ERROR_CODE)) {
FunctionHelper.enableUserIntraction();
HomeActivity.bSpeedStatus = false;
Intent intent = new Intent("trip_ended");
intent.putExtra("trip_info", resultResponse.getData().get(0));
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
((MyService) context).stopSelf();
} else {
Toast.makeText(context, resultResponse.getErrorMsg(), Toast.LENGTH_SHORT).show();
}
}
private boolean calculateSteps() {
ArrayList<StepHelper> arrayList = MySharedPreference.getInstance(this).getSteps();
ArrayList<StepHelper> newList = new ArrayList<>();
for (int i = 0; i < arrayList.size(); i++) {
long seconds = FunctionHelper.getDifference(arrayList.get(i).getTime());
if ((int) seconds < 180) {
newList.add(arrayList.get(i));
}
}
if (numSteps - newList.get(0).getSteps() >= FINAL_STEP) {
return true;
} else {
MySharedPreference.getInstance(this).setSteps(newList);
return false;
}
}
private void saveStep() {
ArrayList<StepHelper> arrayList = MySharedPreference.getInstance(this).getSteps();
if (arrayList == null) {
arrayList = new ArrayList<>();
}
arrayList.add(new StepHelper(FunctionHelper.getCurrentDateWitTime(), numSteps));
MySharedPreference.getInstance(this).setSteps(arrayList);
}
private void statPedoMeter() {
// Toast.makeText(this, "start count", Toast.LENGTH_SHORT).show();
pedoMetterHasStarted = true;
MySharedPreference.getInstance(this).setStartPedoMeterTime(FunctionHelper.getCurrentDateWitTime());//store current time
if (sensorManager != null)
sensorManager.registerListener(this, accel, SensorManager.SENSOR_DELAY_NORMAL);
}
/*
* This method is calling to stop pedo meter
*
* */
private void stopPedoMeter() {
numSteps = 0;
pedoMetterHasStarted = false;
sensorManager.unregisterListener(this, accelerometer);
sensorManager.unregisterListener(this, accel);
sensorManager.unregisterListener(this, magFieldSensor);
sensorManager = null;
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
Logger.e("MyService --- " + "isRuning");
if (HomeActivity.bSpeedStatus) {
updateDriverLocation();
}
}
});
}
}
}
My app starts and use only 170 MB , but after starting this service , it becomes 220 MB and after finishing it, it still 220 and if i open it again , ram become 240 and if i finish it still 240 and if i open it again it become 260 and so on until app crash
what's the wrong in the service ?
i make sure that it's stopped but don't know why ram not reduced after this service is finished
Try this approache, don't put the stopSelf() inside a static method. Instead, you should call startService again and add an action to the Intent.
So this is how an example actionable service should look like:
public class ExampleService
extends Service {
public static final String START_SERVICE_ACTION = "com.example.action.START_SERVICE";
public static final String STOP_SERVICE_ACTION = "com.example.action.STOP_SERVICE";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String intentAction = intent.getAction();
switch (intentAction) {
case START_SERVICE_ACTION:
//
break;
case STOP_SERVICE_ACTION:
stopSelf();
break;
}
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
// Used only in case if services are bound (Bound Services).
return null;
}
}
Interact with the Service from somewhere:
Start with it like this:
Intent service = new Intent(context, ExampleService.class);
service.setAction(NotificationService.START_SERVICE_ACTION);
startService(service);
Stop it like this:
Intent service = new Intent(context, ExampleService.class);
service.setAction(NotificationService.STOP_SERVICE_ACTION);
startService(service);
You don't really need to pass the START_SERVICE_ACTION in this example, just added it to better understand the design.
I am using some of the samples provided on line which show how to write to a device. What i want to do is as it loads up the device services and characteristics the app writes data to the tag, rather than open up a dialog to do this.
Can anyone shed some light on this please as i am new to Android development.
I have tried to add edit the code within the following section...
private void displayGattServices(List<BluetoothGattService> gattServices) {
but this line causes the app to crash...
byte[] bytes = DeviceControlActivity.this.mWriteCharacteristic.getValue();
As i tried to move the write part of the code from
public class BleCharacterDialogFragment extends DialogFragment
as i thought that would write to the BLE device.
All help is much appreciated, thanks. Below is the code i have. It came from https://github.com/suzp1984/Light_BLE originally.
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.PendingIntent;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
//import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import tkr.lightble.utils.Log;
/**
* For a given BLE device, this Activity provides the user interface to connect, display data,
* and display GATT services and characteristics supported by the device. The Activity
* communicates with {#code BluetoothLeService}, which in turn interacts with the
* Bluetooth LE API.
*/
public class DeviceControlActivity extends Activity {
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
private TextView mConnectionState;
private TextView mDataField;
private TextView mRssiField;
private String mDeviceName;
private String mDeviceAddress;
private ExpandableListView mGattServicesList;
private BluetoothLeService mBluetoothLeService;
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics =
new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
private boolean mConnected = false;
private BluetoothGattCharacteristic mNotifyCharacteristic;
private BluetoothGattCharacteristic mWriteCharacteristic;
private final String LIST_NAME = "NAME";
private final String LIST_UUID = "UUID";
// Code to manage Service lifecycle.
private final ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
if (!mBluetoothLeService.initialize()) {
Log.e("Unable to initialize Bluetooth");
finish();
}
// Automatically connects to the device upon successful start-up initialization.
mBluetoothLeService.connect(mDeviceAddress);
mBluetoothLeService.setBLEServiceCb(mDCServiceCb);
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
}
};
// If a given GATT characteristic is selected, check for supported features. This sample
// demonstrates 'Read' and 'Notify' features. See
// http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for the complete
// list of supported characteristic features.
private final ExpandableListView.OnChildClickListener servicesListClickListner =
new ExpandableListView.OnChildClickListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
int childPosition, long id) {
if (mGattCharacteristics != null) {
final BluetoothGattCharacteristic characteristic =
mGattCharacteristics.get(groupPosition).get(childPosition);
final int charaProp = characteristic.getProperties();
if ((charaProp & BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
// If there is an active notification on a characteristic, clear
// it first so it doesn't update the data field on the user interface.
Log.d("BluetoothGattCharacteristic has PROPERTY_READ, so send read request");
if (mNotifyCharacteristic != null) {
mBluetoothLeService.setCharacteristicNotification(
mNotifyCharacteristic, false);
mNotifyCharacteristic = null;
}
mBluetoothLeService.readCharacteristic(characteristic);
}
if ((charaProp & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
Log.d("BluetoothGattCharacteristic has PROPERTY_NOTIFY, so send notify request");
mNotifyCharacteristic = characteristic;
mBluetoothLeService.setCharacteristicNotification(
characteristic, true);
}
if (((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE) |
(charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) > 0) {
Log.d("BluetoothGattCharacteristic has PROPERY_WRITE | PROPERTY_WRITE_NO_RESPONSE");
mWriteCharacteristic = characteristic;
// popup an dialog to write something.
showCharactWriteDialog();
}
return true;
}
return false;
}
};
private void showCharactWriteDialog() {
DialogFragment newFrame = new BleCharacterDialogFragment();
newFrame.show(getFragmentManager(), "blewrite");
}
private void writeCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothLeService != null) {
mBluetoothLeService.writeCharacteristic(characteristic);
}
}
private void clearUI() {
mGattServicesList.setAdapter((SimpleExpandableListAdapter) null);
mDataField.setText(R.string.no_data);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gatt_services_characteristics);
final Intent intent = getIntent();
mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
// Sets up UI references.
((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress);
mGattServicesList = (ExpandableListView) findViewById(R.id.gatt_services_list);
mGattServicesList.setOnChildClickListener(servicesListClickListner);
mConnectionState = (TextView) findViewById(R.id.connection_state);
mDataField = (TextView) findViewById(R.id.data_value);
mRssiField = (TextView) findViewById(R.id.signal_rssi);
getActionBar().setTitle(mDeviceName);
getActionBar().setDisplayHomeAsUpEnabled(true);
Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
}
#Override
protected void onResume() {
super.onResume();
//registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
if (mBluetoothLeService != null) {
final boolean result = mBluetoothLeService.connect(mDeviceAddress);
Log.d("Connect request result=" + result);
}
}
#Override
protected void onPause() {
super.onPause();
//unregisterReceiver(mGattUpdateReceiver);
}
#Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
mBluetoothLeService = null;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.gatt_services, menu);
if (mConnected) {
menu.findItem(R.id.menu_connect).setVisible(false);
menu.findItem(R.id.menu_disconnect).setVisible(true);
} else {
menu.findItem(R.id.menu_connect).setVisible(true);
menu.findItem(R.id.menu_disconnect).setVisible(false);
}
return true;
}
#TargetApi(Build.VERSION_CODES.ECLAIR)
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.menu_connect:
mBluetoothLeService.connect(mDeviceAddress);
return true;
case R.id.menu_disconnect:
mBluetoothLeService.disconnect();
return true;
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateConnectionState(final int resourceId) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mConnectionState.setText(resourceId);
}
});
}
private void displayData(String data) {
if (data != null) {
mDataField.setText(data);
}
}
private void displayRssi(String rssi) {
if (rssi != null) {
//Log.d("-- dispaly Rssi: " + rssi);
mRssiField.setText(rssi);
}
}
// Demonstrates how to iterate through the supported GATT Services/Characteristics.
// In this sample, we populate the data structure that is bound to the ExpandableListView
// on the UI.
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
private void displayGattServices(List<BluetoothGattService> gattServices) {
Log.d("displayGATTServices");
if (gattServices == null) return;
String uuid = null;
String unknownServiceString = getResources().getString(R.string.unknown_service);
String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData
= new ArrayList<ArrayList<HashMap<String, String>>>();
mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
// Loops through available GATT Services.
for (BluetoothGattService gattService : gattServices) {
HashMap<String, String> currentServiceData = new HashMap<String, String>();
uuid = gattService.getUuid().toString();
currentServiceData.put(
LIST_NAME, SampleGattAttributes.lookup(uuid, unknownServiceString));
currentServiceData.put(LIST_UUID, uuid);
gattServiceData.add(currentServiceData);
ArrayList<HashMap<String, String>> gattCharacteristicGroupData =
new ArrayList<HashMap<String, String>>();
List<BluetoothGattCharacteristic> gattCharacteristics =
gattService.getCharacteristics();
ArrayList<BluetoothGattCharacteristic> charas =
new ArrayList<BluetoothGattCharacteristic>();
// Loops through available Characteristics.
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
charas.add(gattCharacteristic);
HashMap<String, String> currentCharaData = new HashMap<String, String>();
uuid = gattCharacteristic.getUuid().toString();
currentCharaData.put(
LIST_NAME, SampleGattAttributes.lookup(uuid, unknownCharaString));
currentCharaData.put(LIST_UUID, uuid);
gattCharacteristicGroupData.add(currentCharaData);
}
mGattCharacteristics.add(charas);
gattCharacteristicData.add(gattCharacteristicGroupData);
}
SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(
this,
gattServiceData,
android.R.layout.simple_expandable_list_item_2,
new String[] {LIST_NAME, LIST_UUID},
new int[] { android.R.id.text1, android.R.id.text2 },
gattCharacteristicData,
android.R.layout.simple_expandable_list_item_2,
new String[] {LIST_NAME, LIST_UUID},
new int[] { android.R.id.text1, android.R.id.text2 }
);
mGattServicesList.setAdapter(gattServiceAdapter);
}
private DCServiceCb mDCServiceCb = new DCServiceCb();
public class DCServiceCb implements BluetoothLeService.BLEServiceCallback {
#Override
public void displayRssi(final int rssi) {
runOnUiThread(new Runnable() {
#Override
public void run() {
DeviceControlActivity.this.displayRssi(String.valueOf(rssi));
}
}
);
}
#Override
public void displayData(final String data) {
runOnUiThread(new Runnable() {
#Override
public void run() {
DeviceControlActivity.this.displayData(data);
}
});
}
#Override
public void notifyConnectedGATT() {
runOnUiThread(new Runnable() {
#Override
public void run() {
mConnected = true;
updateConnectionState(R.string.connected);
invalidateOptionsMenu();
}
});
}
#Override
public void notifyDisconnectedGATT() {
runOnUiThread(new Runnable() {
#Override
public void run() {
mConnected = false;
updateConnectionState(R.string.disconnected);
invalidateOptionsMenu();
clearUI();
}
});
}
#Override
public void displayGATTServices() {
Log.d("displayGATTServices.");
runOnUiThread(new Runnable() {
#Override
public void run() {
if (mBluetoothLeService != null) {
DeviceControlActivity.this.displayGattServices(
mBluetoothLeService.getSupportedGattServices());
}
}
});
}
}
public class BleCharacterDialogFragment extends DialogFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.write_charact_dialog, container, false);
final EditText ed = (EditText) v.findViewById(R.id.charact_value);
Button ok = (Button) v.findViewById(R.id.dialog_confirm);
Button cancel = (Button) v.findViewById(R.id.dialog_cancel);
ok.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// write characterist here.
String str = ed.getText().toString();
//mWriteCharactristc.
byte[] strBytes = str.getBytes();
byte[] bytes;
bytes = DeviceControlActivity.this.mWriteCharacteristic.getValue();
//mWriteCharacteristic.
if (strBytes == null) {
Log.w("Cannot get Value from EditText Widget");
dismiss();
return;
}
if (bytes == null) {
// maybe just write a byte into GATT
Log.w("Cannot get Values from mWriteCharacteristic.");
dismiss();
return;
} else if (bytes.length <= strBytes.length) {
for(int i = 0; i < bytes.length; i++) {
bytes[i] = strBytes[i];
}
} else {
for (int i = 0; i < strBytes.length; i++) {
bytes[i] = strBytes[i];
}
}
DeviceControlActivity.this.mWriteCharacteristic.setValue(bytes);
DeviceControlActivity.this.writeCharacteristic(
DeviceControlActivity.this.mWriteCharacteristic
);
dismiss();
return;
}
});
cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
return v;
}
}
}
To write a value to a device you have to know tow things
1-Service UUID
2-Characteristic UUID
You can read/write a value from/to Characteristic UUID
Here is the sample code to write a value to Characteristic.
public void writeCharacteristic(byte[] value)
{
BluetoothGattService service = mBluetoothGatt.getService(YOUR_SEVICE_UUID);
if (service == null) {
System.out.println("service null"); return;
}
BluetoothGattCharacteristic characteristic = service.getCharacteristic(YOUR_CHARACTERISTIC_UUID);
if (characteristic == null) {
System.out.println("characteristic null"); return;
}
characteristic.setValue(value);
boolean status = mBluetoothGatt.writeCharacteristic(characteristic);
System.out.println("Write Status: " + status);
}
Ok so first off, the issue is when i install my app and open it, it is starting a activity without being declared in my manifest as here below.
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
I know that this above declare the a activity to be the activity ran when the app is launched, therefore should be the only one. Well i have some source code that i didn't originally write, Its for a launcher replacement app, therefore inside the source code i cant figure out how it is being launcher when its not declared in the manifest for this activity to be ran from the intial start, Its declare, but there isnt even a intent filter for it.
Is there some sort of java code you can declare a activity to be ran when the app is launched for the first time??? thats mainly my question.
Here The source im working with
classic.java
import java.util.Locale;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnKeyListener;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.widget.Toast;
public class classic extends Activity {
/** Called when the activity is first created. */
private static String mPackageName = Constants.PACKAGE_LAUNCHER;
private ComponentName mCn = null;
private Activity currentActivity = null;
private boolean mApplyTheme = false;
private AlertDialog mConfirmDialog = null;
private ProgressDialog mProgressDialog = null;
private final String GOLAUNCHER_PKG_NAME = "com.gau.go.launcherex";
AttachInfo mAi = null;
class CustomAlertDialog extends AlertDialog {
public CustomAlertDialog(Context context) {
super(context);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
boolean ret = super.onKeyDown(keyCode, event);
finish();
return ret;
}
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
private Handler mHandler = new Handler()
{
public void handleMessage(Message msg)
{
super.handleMessage(msg);
AlertDialog.Builder localBuilder2 = new AlertDialog.Builder(
classic.this);
localBuilder2.setTitle("Go Launcher EX not Found");
localBuilder2
.setMessage("Do you want to vist the Go Launcher EX on Google Play?");
localBuilder2.setIcon(R.drawable.golauncherex);
localBuilder2.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface paramDialogInterface,
int paramInt) {
Intent localIntent = new Intent(
"android.intent.action.VIEW").setData(Uri
.parse("market://details?id=com.gau.go.launcherex"));
classic.this.startActivity(localIntent);
}
});
localBuilder2.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface paramDialogInterface,
int paramInt) {
}
});
localBuilder2.show();
}
};
#Override
protected void onResume() {
super.onResume();
currentActivity = this;
ThemeUtils.sendInactiveApplyThemeFlagBroadcast(this);
if (isExistGO(GOLAUNCHER_PKG_NAME))
{
final Result result = new Result();
displayStartGoLauncherDialog(result);
setVisible(false);
return;
}
setVisible(false);
mAi = MergeUtil.getAttachInfo(this);
// 判æ–é™„åŠ çš„æ˜¯åœ°å�€è¿˜æ˜¯apk
if(mAi != null && mAi.IsAttachApk())
{
// �动�并
MergeUtil.DoMergeFileTask(mHandler, this);
setVisible(false);
return;
}
AlertDialog.Builder localBuilder2 = new AlertDialog.Builder(
classic.this);
localBuilder2.setTitle("Go Launcher EX not Found");
localBuilder2
.setMessage("Do you want to vist the Go Launcher EX on Google Play?");
localBuilder2.setIcon(R.drawable.golauncherex);
localBuilder2.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface paramDialogInterface,
int paramInt) {
Intent localIntent = new Intent(
"android.intent.action.VIEW").setData(Uri
.parse("market://details?id=com.gau.go.launcherex"));
classic.this.startActivity(localIntent);
}
});
localBuilder2.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface paramDialogInterface,
int paramInt) {
}
});
localBuilder2.show();
}
private boolean isExistGO(String packageName) {
Result result = GoLauncherUtils.isGoLauncherExist(this);
mPackageName = result.packageName == null ? Constants.PACKAGE_LAUNCHER
: result.packageName;
mCn = result.componentName;
return result.isExist;
}
private void startGOLauncher(String packageName) throws Throwable {
GoLauncherUtils.startGoLauncher(this, packageName, mCn);
}
private void displayStartGoLauncherDialog(final Result result) {
String dialogtitle = null;
String dialogmsg = null;
String dialogok = null;
String dialogcancel = null;
String language = Locale.getDefault().getLanguage(); // zh
if(language.equals("zh"))
{
dialogtitle = "信�";
dialogmsg = "点击确定立刻�用桌�支�软件";
dialogok = "确定";
dialogcancel = "�消";
}
else
{
dialogtitle = "Go Launcher EX";
dialogmsg = "Press OK button to launch GO Launcher EX";
dialogok = "OK";
dialogcancel = "Cancel";
}
mConfirmDialog = new AlertDialog.Builder(this)
.setTitle(dialogtitle)
.setMessage(dialogmsg)
.setPositiveButton(dialogok, new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// NotificationActivity.this.finish();
startGoLauncher(
result.packageName == null ? Constants.PACKAGE_LAUNCHER
: result.packageName,
result.componentName);
}
})
.setNegativeButton(dialogcancel,
new OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
classic.this.finish();
}
}).setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
classic.this.finish();
}
return false;
}
}).show();
}
private void startGoLauncher(final String packageName,
final ComponentName componentName) {
mApplyTheme = true;
new AsyncTask<Void, Void, Boolean>() {
#Override
protected void onPreExecute() {
String msg = null;
String language = Locale.getDefault().getLanguage(); // zh
if(language.equals("zh"))
{
msg = "GOæ¡Œé�¢EXå�¯ç”¨ä¸ï¼Œè¯·ç¨�å�Ž";
}
else
{
msg = "Applying The Galaxy S3 Theme, Please Wait";
}
mProgressDialog = ProgressDialog.show(
classic.this,
null,
msg,
true);
}
#Override
protected Boolean doInBackground(Void... v) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
classic.this.finish();
try {
GoLauncherUtils.startGoLauncher(classic.this,
packageName, componentName);
} catch (Throwable e) {
return false;
}
return true;
}
protected void onPostExecute(Boolean success) {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
if (!success) {
String msg = null;
String language = Locale.getDefault().getLanguage();
// zh
if(language.equals("zh"))
{
msg = "GO桌��用失败,请�新安装GO桌�";
}
else
{
msg = "Start GO Launcher EX failed, please reinstall GO Launcher EX";
}
Toast.makeText(
classic.this,
msg,
Toast.LENGTH_LONG).show();
}
};
}.execute();
}
#Override
protected void onStop() {
super.onStop();
if (mApplyTheme) {
mApplyTheme = false;
ThemeUtils.sendApplyThemeBroadcast(this);
}
}
#Override
protected void onDestroy() {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
if (mConfirmDialog != null) {
mConfirmDialog.dismiss();
mConfirmDialog = null;
}
super.onDestroy();
}
}
GoLauncherUtils.java
import java.util.List;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
public class GoLauncherUtils {
public static final String NAME_GOLAUNCHER = "go_launcher";
public static final String KEY_UNINSTALLED = "uninstalled";
public static void startGoLauncher(Context context, String packageName,
ComponentName componentName) throws Throwable {
PackageManager packageMgr = context.getPackageManager();
Intent launchIntent = packageMgr.getLaunchIntentForPackage(packageName);
if (launchIntent != null) {
try {
context.startActivity(launchIntent);
} catch (Throwable t1) {
t1.printStackTrace();
if (componentName != null) {
Intent intent = new Intent(Intent.ACTION_MAIN);
//intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setComponent(componentName);
try {
context.startActivity(intent);
} catch (Throwable t2) {
t2.printStackTrace();
throw t2;
}
} else {
throw t1;
}
}
} else {
if (componentName != null) {
Intent intent = new Intent(Intent.ACTION_MAIN);
//intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setComponent(componentName);
try {
context.startActivity(intent);
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
}
}
public static void downloadGoLauncher(Context context , final String aUrl) {
Intent intent = new Intent();
intent.setClass(context, GoDownloadService.class);
String fileName = "GO Launcher EX";
intent.putExtra("downloadFileName", fileName);
intent.putExtra(Constants.DOWNLOAD_URL_KEY, aUrl);
context.startService(intent);
}
public static Result isGoLauncherExist(Context context) {
Result result = new Result();
PackageManager pm = context.getPackageManager();
// Launcher
Intent intent = new Intent("android.intent.action.MAIN");
intent.addCategory("android.intent.category.HOME");
intent.addCategory("android.intent.category.DEFAULT");
List<ResolveInfo> infos = pm.queryIntentActivities(intent, 0);
int launcherSz = infos.size();
for (int i = 0; i < launcherSz; i++) {
ResolveInfo info = infos.get(i);
if (null == info || null == info.activityInfo
|| null == info.activityInfo.packageName) {
continue;
}
String packageStr = info.activityInfo.packageName;
if (packageStr.contains(Constants.PACKAGE_LAUNCHER)) {
result.packageName = packageStr;
result.componentName = new ComponentName(packageStr,
info.activityInfo.name);
result.isExist = true;
return result;
}
}
return result;
}
public static boolean isGoLauncherRunning(Context context) {
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
// List<RunningAppProcessInfo> infos = am.getRunningAppProcesses();
// for (RunningAppProcessInfo info : infos) {
// System.out.println("---------------running process: "
// + info.processName);
//
// if
// ("com.gau.go.launcherex".equals(info.importanceReasonComponent.getPackageName()))
// {
// goLauncherRunning = true;
// break;
// }
// }
List<RunningServiceInfo> infos = am.getRunningServices(500);
for (RunningServiceInfo info : infos) {
if (Constants.PACKAGE_LAUNCHER
.equals(info.service.getPackageName())) {
return true;
}
}
return false;
}
public static boolean isGoLauncherUninstalled(Context context) {
SharedPreferences sp = context.getSharedPreferences(NAME_GOLAUNCHER,
Context.MODE_PRIVATE);
return sp.getBoolean(KEY_UNINSTALLED, false);
}
public static void setGoLauncherUninstalled(Context context,
boolean uninstalled) {
SharedPreferences sp = context.getSharedPreferences(NAME_GOLAUNCHER,
Context.MODE_PRIVATE);
Editor editor = sp.edit();
editor.putBoolean(KEY_UNINSTALLED, uninstalled);
editor.commit();
}
}
All i need help with is just disabling anything starting onstartup of the application, i only need this to be used when i send a intent over to it from a button click from another activity. please any help with find where i can disable this from the intial startup would be awesome.