Updating the UI upon receiving an android push notification - java

I have a query regarding android push notification and i had asked it in another stackoverflow post and i did not get much help out of it [Query regarding Android push notifications. So i am posting it again, and it is as follows:
I have an android app that receives push notifications from Google push notification service. When i tap on the received notification, it opens an UI which displays this message, it is a list view. Now, when the user receives the push notification, and assuming that this screen is open, the UI should be refreshed automatically, such that it displays the latest notification. Could anybody let me know how i can solve this?
Below is my code that i have implemented:
Java code to receive the notification:
import java.util.Timer;
import java.util.TimerTask;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.util.Log;
import com.example.foodu.R;
import com.google.android.gcm.GCMBaseIntentService;
public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GCM ::Service";
// Use your PROJECT ID from Google API into SENDER_ID
public static final String SENDER_ID = "53340195486";
public GCMIntentService() {
super(SENDER_ID);
}
#Override
protected void onError(Context arg0, String errorId) {
Log.e(TAG, "onError: errorId=" + errorId);
}
#Override
protected void onMessage(Context context, Intent data) {
String message;
// Message from PHP server
message = data.getStringExtra("message");
// Open a new activity called GCMMessageView
Intent intent = new Intent(this, com.example.foodu.Notification.class);
// Pass data to the new activity
intent.putExtra("message", message);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// Starts the activity on notification click
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
// Create the notification with a notification builder
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_logo)
.setWhen(System.currentTimeMillis())
.setContentTitle("Deals")
.setContentText(message).setContentIntent(pIntent)
.getNotification();
// Remove the notification on click
notification.flags |= Notification.FLAG_AUTO_CANCEL;
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(R.string.app_name, notification);
{
// Wake Android Device when notification received
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
final PowerManager.WakeLock mWakelock = pm.newWakeLock(
PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP, "GCM_PUSH");
mWakelock.acquire();
// Timer before putting Android Device to sleep mode.
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
mWakelock.release();
}
};
timer.schedule(task, 5000);
}
}
#Override
protected void onRegistered(Context arg0, String registrationId) {
Log.i(TAG, "onRegistered: registrationId=" + registrationId);
}
#Override
protected void onUnregistered(Context arg0, String registrationId) {
Log.i(TAG, "onUnregistered: registrationId=" + registrationId);
}
}
The code for the corresponding activity that would be launched when the user taps on the notification:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.TimeZone;
import com.example.foodu.R;
import com.example.foodu.R.drawable;
import com.example.foodu.R.id;
import com.example.foodu.R.layout;
import com.example.foodu.R.menu;
import com.google.android.gcm.GCMRegistrar;
import android.support.v7.app.ActionBarActivity;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.CalendarContract;
import android.util.Log;
import android.view.ActionMode;
import android.view.ActionMode.Callback;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class Notification extends ActionBarActivity {
LinkedList<NotificationData> notificationList = new LinkedList<NotificationData>();
ListView listView = null;
NotificationListAdapter adaptor;
ActionMode mActionMode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification);
overridePendingTransition(R.anim.trans_left_in, R.anim.trans_left_out);
listView = (ListView) findViewById(R.id.listView1);
// Retrive the data from GCMIntentService.java
Intent i = getIntent();
String message = i.getStringExtra("message");
//getDataForDisplay();
if(message!=null)
{
parseData(message);
}else{
getDataToDisplay();
}
adaptor = new NotificationListAdapter(getApplicationContext(), notificationList);
listView.setAdapter(adaptor);
TextView emptyText = (TextView) findViewById(R.id.empty);
emptyText.setText("No Events Yet!");
listView.setEmptyView(emptyText);
listView.setOnItemLongClickListener(new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
onListitemSelect(position);
view.setSelected(true);
return true;
}
});
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
adaptor.notifyDataSetChanged();
}
#Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
}
void writeToFile(){
FileOutputStream fos;
try {
fos = openFileOutput("varun", Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(notificationList);
oos.close();
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
void readFromFile(){
try{
FileInputStream fis = openFileInput("varun");
ObjectInputStream ois = new ObjectInputStream(fis);
LinkedList<NotificationData> local = (LinkedList<NotificationData>) ois.readObject();
ois.close();
for (int i = 0; i < local.size(); i++) {
notificationList.add(local.get(i));
}
}catch(Exception e){
e.printStackTrace();
}
}
private void getDataToDisplay() {
// TODO Auto-generated method stub
readFromFile();
}
private void parseData(String message) {
try {
int len = 0;
String[] stringArr = new String[100];
StringTokenizer st = new StringTokenizer(message, ".");
len = st.countTokens();
for (int i = 0; i < len; i++) {
if (st.hasMoreTokens()) {
stringArr[i] = st.nextToken();
}
}
NotificationData data = new NotificationData();
data.title = stringArr[0];
data.venue = stringArr[1];
data.date = stringArr[2];
data.time = stringArr[3];
notificationList.add(data);
readFromFile();
} catch (Exception e) {
e.printStackTrace();
}
}
private void getDateToDisplay() {
// TODO Auto-generated method stub
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
writeToFile();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.notificationmenu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
if(id == R.id.action_register){
registerDevice();
return true;
}
return super.onOptionsItemSelected(item);
}
private void registerDevice() {
try {
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
GCMRegistrar
.register(Notification.this, GCMIntentService.SENDER_ID);
} catch (Exception e) {
e.printStackTrace();
}
}
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.notificationcontext, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_calender:
addToCalender();
mode.finish();
return true;
case R.id.menu_delete:
//deleteData();
showAlertBox();
return false;
case R.id.menu_share:
shareDate();
mode.finish();
return true;
case R.id.menu_copy:
copyToClip();
mode.finish();
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
adaptor.removeSelection();
}
};
void onListitemSelect(int position) {
adaptor.toggleSelection(position);
boolean hasCheckedItems = adaptor.getSelectedCount() > 0;
if (hasCheckedItems && mActionMode == null) {
mActionMode = startActionMode((Callback) mActionModeCallback);
} else if (!hasCheckedItems && mActionMode != null) {
mActionMode.finish();
}
if (mActionMode != null)
mActionMode.setTitle(String.valueOf(adaptor.getSelectedCount()));
}
protected void showAlertBox() {
// TODO Auto-generated method stub
AlertDialog.Builder builder1 = new AlertDialog.Builder(Notification.this);
builder1.setMessage("Delete " + adaptor.getSelectedIds().size()+ " events?");
builder1.setCancelable(true);
builder1.setIcon(R.drawable.alert);
builder1.setTitle("Caution");
builder1.setIcon(android.R.drawable.ic_dialog_alert);
builder1.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
deleteData();
mActionMode.finish();
}
});
builder1.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert11 = builder1.create();
alert11.show();
}
protected void copyToClip() {
StringBuilder shareText = new StringBuilder();
for (int i = 0; i < adaptor.getSelectedIds().size(); i++) {
NotificationData data = notificationList
.get(adaptor.getSelectedIds().keyAt(i));
shareText.append(data.title + " " + data.venue + " " + data.date
+ " " + data.time);
shareText.append("\n");
}
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("Notification App", shareText);
clipboard.setPrimaryClip(clip);
Toast.makeText(getApplicationContext(), "Data copied to ClipBoard",
Toast.LENGTH_LONG).show();
}
protected void shareDate() {
StringBuilder shareText = new StringBuilder();
for (int i = 0; i < adaptor.getSelectedIds().size(); i++) {
NotificationData data = notificationList
.get(adaptor.getSelectedIds().keyAt(i));
shareText.append(data.title + " " + data.venue + " " + data.date
+ " " + data.time);
shareText.append("\n");
}
String share = shareText.toString();
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, share);
sendIntent.setType("text/plain");
startActivity(sendIntent);
}
protected void deleteData() {
int count = 0;
int startPoint = adaptor.getSelectedIds().keyAt(0);
for (int i = 0; i < adaptor.getSelectedIds().size(); i++) {
adaptor.remove(notificationList.get(startPoint));
count++;
}
String message = " Event";
if(count>1)
{
message = " Events";
}
Toast.makeText(getApplicationContext(),
count + message+" deleted", Toast.LENGTH_LONG)
.show();
}
private void addToCalender() {
try {
int count = 0;
for (int i = 0; i < adaptor.getSelectedIds().size(); i++) {
NotificationData data = notificationList
.get(adaptor.getSelectedIds().keyAt(i));
ContentResolver cr = getApplicationContext()
.getContentResolver();
ContentValues values = new ContentValues();
String myDate = data.date + " " + data.time;
String timeArr[] = data.time.split("to");
SimpleDateFormat sfd = new SimpleDateFormat(
"' Date: 'MM/dd/yyyy 'Time: 'hh a", Locale.getDefault());
long time = sfd.parse(myDate).getTime();
values.put(CalendarContract.Events.DTSTART, time);
if (timeArr.length > 0) {
String endTime = timeArr[1];
SimpleDateFormat timeFormat = new SimpleDateFormat(
"' Date: 'MM/dd/yyyy hh a", Locale.getDefault());
long endtime = timeFormat.parse(data.date + " " + endTime)
.getTime();
values.put(CalendarContract.Events.DTEND, endtime);
}
values.put(CalendarContract.Events.TITLE, data.title);
values.put(CalendarContract.Events.DESCRIPTION, data.venue);
TimeZone timeZone = TimeZone.getDefault();
values.put(CalendarContract.Events.EVENT_TIMEZONE,
timeZone.getID());
values.put(CalendarContract.Events.CALENDAR_ID, 1);
Uri uri = cr
.insert(CalendarContract.Events.CONTENT_URI, values);
count++;
}
String message = " Event";
if(count>1)
{
message = " Events";
}
Toast.makeText(getApplicationContext(),
count + message + " added to Calender", Toast.LENGTH_LONG)
.show();
} catch (Exception e) {
e.printStackTrace();
}
}
}

Use LocalBroadcastManager
Check following code / steps
1) Add in your activity (UI refresh Activity)
private BroadcastReceiver mMyBroadcastReceiver;
Then ,
2) In onResume
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
mMyBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent)
{
// Here you can refresh your listview or other UI
Toast.makeText(getApplicationContext(), "Receiver", 2000).show();
}
};
try {
LocalBroadcastManager.getInstance(this).registerReceiver(mMyBroadcastReceiver,new IntentFilter("your_action"));
} catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
}}
// and your other code
3) Then unregister in onPause
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMyBroadcastReceiver);
}
4) Finally add in your GCM reciver class.
first check your activity is Visible or not using static variable
if visible add
Intent gcm_rec = new Intent("your_action"); LocalBroadcastManager.getInstance(arg0).sendBroadcast(gcm_rec);
else
use Notification Manager for notification.
I think this is easy and best way to refresh your listview UI / call Fetching method.

Related

Application has Stoppped (Android Studio Bluetooth)

I try to make communication between two devices by using Bluteooth but always the application stopped when i try to test it.
I just try to send simple string (for exemple 'A') but also I have errors.
Also i can't turn on/off bluetooth manually.
the error is : Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.bluetooth.BluetoothAdapter.isEnabled()' on a null object reference
at com.example.pfe.reglages.onCreate(reglages.java:53).
I need help because it's my project to get graduated
Thank you.
entrainement.java
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Handler;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
import android.os.Message;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import static android.bluetooth.BluetoothAdapter.getDefaultAdapter;
import static android.content.ContentValues.TAG;
public class entrainement extends AppCompatActivity {
private boolean CONTINUE_READ_WRITE = true;
private boolean CONNECTION_ENSTABLISHED = false;
private boolean DEVICES_IN_LIST = true;
private static String NAME = "pfe.fawez";
private static UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
Button btn6, btn7, btn8, btn16, btn9, btn5;
EditText txt;
TextView logview;
ListView lv;
ArrayList<String> listItems;
ArrayAdapter<String> listAdapter;
private BluetoothAdapter adapter;
private BluetoothSocket socket;
private InputStream is;
private OutputStream os;
private BluetoothDevice remoteDevice;
private Set<BluetoothDevice> pairedDevices;
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.entrainement);
btn6 = findViewById(R.id.button6);
btn7 = findViewById(R.id.button7);
btn8 = findViewById(R.id.button8);
btn16 = findViewById(R.id.button16);
btn9 = findViewById(R.id.button9);
btn5 = findViewById(R.id.button5);
txt = findViewById(R.id.editText2);
logview = findViewById(R.id.textView14);
lv = (ListView)findViewById(R.id.listView);
listItems = new ArrayList<String>(); //shows messages in list view
listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listItems);
lv.setAdapter(listAdapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() //list onclick selection process
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
if(DEVICES_IN_LIST)
{
String name = (String) parent.getItemAtPosition(position);
selectBTdevice(name); //selected device will be set globally
//Toast.makeText(getApplicationContext(), "Selected " + name, Toast.LENGTH_SHORT).show();
//do not automatically call OpenBT(null) because makes troubles with server/client selection
}
else //message is selected
{
String message = (String) parent.getItemAtPosition(position);
txt.setText(message);
}
}
/*adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter == null) //If the adapter is null, then Bluetooth is not supported
{
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_SHORT).show();
finish();
return;
}
list(null);*/
});
btn9.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = txt.getText().toString();
byte[] b = textToSend.getBytes();
try {
os.write(b);
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
logview.append("\nConnection !\n");
}
});
btn6.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = "R";
byte[] b = textToSend.getBytes();
try {
os.write(b);
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
}
});
btn16.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = "L";
byte[] b = textToSend.getBytes();
try {
os.write(b);
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
}
});
btn7.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = "X";
byte[] b = textToSend.getBytes();
try {
os.write(b);
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
}
});
btn8.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = "Y";
byte[] b = textToSend.getBytes();
try {
os.write(b);
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
}
});
}
private Runnable writter = new Runnable() {
#Override
public void run() {
while (CONTINUE_READ_WRITE) //reads from open stream
{
try
{
os.flush();
Thread.sleep(2000);
} catch (Exception e)
{
Log.e(TAG, "Writer failed in flushing output stream...");
CONTINUE_READ_WRITE = false;
}
}
}
};
public void list(View v) //shows paired devices to UI
{
CONNECTION_ENSTABLISHED = false; //protect from failing
listItems.clear(); //remove chat history
listAdapter.notifyDataSetChanged();
pairedDevices = adapter.getBondedDevices(); //list of devices
for(BluetoothDevice bt : pairedDevices) //foreach
{
listItems.add(0, bt.getName());
}
listAdapter.notifyDataSetChanged(); //reload UI
}
public void selectBTdevice(String name) //for selecting device from list which is used in procedures
{
if(pairedDevices.isEmpty()) {
list(null);
Toast.makeText(getApplicationContext(), "Selecting was unsucessful, no devices in list." ,Toast.LENGTH_SHORT ).show();
}
for(BluetoothDevice bt : pairedDevices) //foreach
{
if(name.equals(bt.getName()))
{
remoteDevice = bt;
Toast.makeText(getApplicationContext(), "Selected " + remoteDevice.getName(), Toast.LENGTH_SHORT ).show();
}
}
}
public void openBT(View v) //opens right thread for server or client
{
if(adapter == null)
{
adapter = getDefaultAdapter();
Log.i(TAG, "Backup way of getting adapter was used!");
}
CONTINUE_READ_WRITE = true; //writer tiebreaker
socket = null; //resetting if was used previously
is = null; //resetting if was used previously
os = null; //resetting if was used previously
if(pairedDevices.isEmpty() || remoteDevice == null)
{
Toast.makeText(this, "Paired device is not selected, choose one", Toast.LENGTH_SHORT).show();
return;
}
}
public void closeBT(View v) //for closing opened communications, cleaning used resources
{
/*if(adapter == null)
return;*/
CONTINUE_READ_WRITE = false;
CONNECTION_ENSTABLISHED = false;
if (is != null) {
try {is.close();} catch (Exception e) {}
is = null;
}
if (os != null) {
try {os.close();} catch (Exception e) {}
os = null;
}
if (socket != null) {
try {socket.close();} catch (Exception e) {}
socket = null;
}
try {
Handler mHandler = new Handler();
mHandler.removeCallbacksAndMessages(writter);
mHandler.removeCallbacksAndMessages(serverListener);
mHandler.removeCallbacksAndMessages(clientConnecter);
Log.i(TAG, "Threads ended...");
}catch (Exception e)
{
Log.e(TAG, "Attemp for closing threads was unsucessfull.");
}
Toast.makeText(getApplicationContext(), "Communication closed" ,Toast.LENGTH_SHORT).show();
list(null); //shows list for reselection
txt.setText(getResources().getString(R.string.demo));
}
private Runnable serverListener = new Runnable()
{
public void run()
{
try //opening of BT connection
{
android.util.Log.i("TrackingFlow", "Server socket: new way used...");
socket =(BluetoothSocket) remoteDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class}).invoke(remoteDevice,1);
socket.connect();
CONNECTION_ENSTABLISHED = true; //protect from failing
} catch(Exception e) //obsolete way how to open BT
{
try
{
android.util.Log.e("TrackingFlow", "Server socket: old way used...");
BluetoothServerSocket tmpsocket = adapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
socket = tmpsocket.accept();
CONNECTION_ENSTABLISHED = true; //protect from failing
android.util.Log.i("TrackingFlow", "Listening...");
}
catch (Exception ie)
{
Log.e(TAG, "Socket's accept method failed", ie);
ie.printStackTrace();
}
}
Log.i(TAG, "Server is ready for listening...");
runOnUiThread(new Runnable() {
#Override
public void run() { //Show message on UIThread
listItems.clear(); //remove chat history
listItems.add(0, String.format(" Server opened! Waiting for clients..."));
listAdapter.notifyDataSetChanged();
}});
try //reading part
{
is = socket.getInputStream();
os = socket.getOutputStream();
new Thread(writter).start();
int bufferSize = 1024;
int bytesRead = -1;
byte[] buffer = new byte[bufferSize];
while(CONTINUE_READ_WRITE) //Keep reading the messages while connection is open...
{
final StringBuilder sb = new StringBuilder();
bytesRead = is.read(buffer);
if (bytesRead != -1) {
String result = "";
while ((bytesRead == bufferSize) && (buffer[bufferSize-1] != 0))
{
result = result + new String(buffer, 0, bytesRead - 1);
bytesRead = is.read(buffer);
}
result = result + new String(buffer, 0, bytesRead - 1);
sb.append(result);
}
android.util.Log.e("TrackingFlow", "Read: " + sb.toString());
runOnUiThread(new Runnable() {
#Override
public void run() { //Show message on UIThread
Toast.makeText(entrainement.this, sb.toString(), Toast.LENGTH_SHORT).show();
listItems.add(0, String.format("< %s", sb.toString())); //showing in history
listAdapter.notifyDataSetChanged();
}
});
}
}
catch(IOException e){
Log.e(TAG, "Server not connected...");
e.printStackTrace();
}
}
};
private Runnable clientConnecter = new Runnable()
{
#Override
public void run()
{
try
{
socket = remoteDevice.createRfcommSocketToServiceRecord(MY_UUID);
socket.connect();
CONNECTION_ENSTABLISHED = true; //protect from failing
Log.i(TAG, "Client is connected...");
runOnUiThread(new Runnable() {
#Override
public void run() { //Show message on UIThread
listItems.clear(); //remove chat history
listItems.add(0, String.format(" ready to communicate! Write something..."));
listAdapter.notifyDataSetChanged();
}});
os = socket.getOutputStream();
is = socket.getInputStream();
new Thread(writter).start();
Log.i(TAG, "Preparation for reading was done");
int bufferSize = 1024;
int bytesRead = -1;
byte[] buffer = new byte[bufferSize];
while(CONTINUE_READ_WRITE) //Keep reading the messages while connection is open...
{
final StringBuilder sb = new StringBuilder();
bytesRead = is.read(buffer);
if (bytesRead != -1)
{
String result = "";
while ((bytesRead == bufferSize) && (buffer[bufferSize-1] != 0))
{
result = result + new String(buffer, 0, bytesRead - 1);
bytesRead = is.read(buffer);
}
result = result + new String(buffer, 0, bytesRead - 1);
sb.append(result);
}
android.util.Log.e("TrackingFlow", "Read: " + sb.toString());
runOnUiThread(new Runnable() {
#Override
public void run() { //Show message on UIThread
Toast.makeText(entrainement.this, sb.toString(), Toast.LENGTH_SHORT).show();
listItems.add(0, String.format("< %s", sb.toString()));
listAdapter.notifyDataSetChanged();
}
});
}
}
catch (IOException e)
{
Log.e(TAG, "Client not connected...");
e.printStackTrace();
}
}
};
}
reglages.java
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Set;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class reglages extends AppCompatActivity {
private static final int REQUEST_ENABLE_BT = 0;
private static final int REQUEST_DISCOVER_BT = 1;
TextView mStatusBlueTv, mPairedTv;
ImageView mBlueIv;
Button mOnBtn, mOffBtn, mDiscoverBtn, mPairedBtn;
BluetoothAdapter mBlueAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.reglages);
mStatusBlueTv = findViewById(R.id.statusBluetoothTv);
mPairedTv = findViewById(R.id.pairedTv);
mBlueIv = findViewById(R.id.bluetoothIv);
mOnBtn = findViewById(R.id.onBtn);
mOffBtn = findViewById(R.id.offBtn);
mDiscoverBtn = findViewById(R.id.discoverableBtn);
mPairedBtn = findViewById(R.id.pairedBtn);
//adapter
mBlueAdapter = BluetoothAdapter.getDefaultAdapter();
//check if bluetooth is available or not
if (mBlueAdapter == null){
mStatusBlueTv.setText("Bluetooth is not available");
}
else {
mStatusBlueTv.setText("Bluetooth is available");
}
//set image according to bluetooth status(on/off)
if (mBlueAdapter.isEnabled()){
mBlueIv.setImageResource(R.drawable.ic_action_on);
}
else {
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
//on btn click
mOnBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mBlueAdapter.isEnabled()){
showToast("Turning On Bluetooth...");
//intent to on bluetooth
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, REQUEST_ENABLE_BT);
}
else {
showToast("Bluetooth is already on");
}
}
});
//discover bluetooth btn click
mDiscoverBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mBlueAdapter.isDiscovering()){
showToast("Making Your Device Discoverable");
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(intent, REQUEST_DISCOVER_BT);
}
}
});
//off btn click
mOffBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mBlueAdapter.isEnabled()){
mBlueAdapter.disable();
showToast("Turning Bluetooth Off");
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
else {
showToast("Bluetooth is already off");
}
}
});
//get paired devices btn click
mPairedBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mBlueAdapter.isEnabled()){
mPairedTv.setText("Paired Devices");
Set<BluetoothDevice> devices = mBlueAdapter.getBondedDevices();
for (BluetoothDevice device: devices){
mPairedTv.append("\nDevice: " + device.getName()+ ", " + device);
}
}
else {
//bluetooth is off so can't get paired devices
showToast("Turn on bluetooth to get paired devices");
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
case REQUEST_ENABLE_BT:
if (resultCode == RESULT_OK){
//bluetooth is on
mBlueIv.setImageResource(R.drawable.ic_action_on);
showToast("Bluetooth is on");
}
else {
//user denied to turn bluetooth on
showToast("could't on bluetooth");
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
//toast message function
private void showToast(String msg){
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
}
Then change this lines:
//check if bluetooth is available or not
if (mBlueAdapter == null){
mStatusBlueTv.setText("Bluetooth is not available");
}
else {
mStatusBlueTv.setText("Bluetooth is available");
}
//set image according to bluetooth status(on/off)
if (mBlueAdapter.isEnabled()){
mBlueIv.setImageResource(R.drawable.ic_action_on);
}
else {
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
To this:
//check if bluetooth is available or not
if (mBlueAdapter == null) {
mStatusBlueTv.setText("Bluetooth is not available");
mBlueIv.setImageResource(R.drawable.ic_action_off);
} else {
mStatusBlueTv.setText("Bluetooth is available");
//set image according to bluetooth status(on/off)
if (mBlueAdapter.isEnabled()) {
mBlueIv.setImageResource(R.drawable.ic_action_on);
} else {
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
}
And each time you check isEnabled check for null first, changing:
if (mBlueAdapter.isEnabled()){
to:
if (mBlueAdapter != null && mBlueAdapter.isEnabled()) {
This way you'll prevent having NullPointers when the Bluetooth is not available (mBlueAdapter == null) as you can not check isEnabled() in this cases.

thread.sleep has suddenly stopped working

I am currently working on my finals project on android.
the project is about a SimonSays game:
in my Simon Says game a have a section where the application is supposed to sleep
but it does , i think its because my teacher added all of these try and catch
functions, how do i fix it?
package com.gabie212.simonsays;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
public class GameActivity extends AppCompatActivity implements View.OnClickListener,View.OnLongClickListener {
private int i = 0, pNum = 0, pIndex = 0,score;
private Thread t = new Thread();
private Thread bt = new Thread();
private Button greenButton;
private Button redButton;
private Button blueButton;
private Button yellowButton;
private Button startButton;
private TextView Score;
private boolean startActivated = false;
private MediaPlayer greenBeep;
private MediaPlayer redBeep;
private MediaPlayer blueBeep;
private MediaPlayer yellowBeep;
private ArrayList<Integer> userColors = new ArrayList<Integer>();
// change backgroud
final String imagefile = "savedImageLocation";//for background
private ImageButton btPhoto; // for background
private android.support.constraint.ConstraintLayout background; // for background
private int yellowish = Color.rgb(0, 191, 255);// for background
private Handler handler = new Handler();
final int SECOND_ACTIVITY = 10;
// game manager
private GameManger gm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
Score = (TextView) findViewById(R.id.ScoreNum);
greenButton = (Button) findViewById(R.id.btnGreen);
redButton = (Button) findViewById(R.id.btnRed);
blueButton = (Button) findViewById(R.id.btnBlue);
yellowButton = (Button) findViewById(R.id.btnYellow);
startButton = (Button) findViewById(R.id.btnStart);
greenButton.setOnClickListener(this);
redButton.setOnClickListener(this);
blueButton.setOnClickListener(this);
yellowButton.setOnClickListener(this);
startButton.setOnClickListener(this);
greenBeep = MediaPlayer.create(this, R.raw.greenbeep);
redBeep = MediaPlayer.create(this, R.raw.redbeep);
blueBeep = MediaPlayer.create(this, R.raw.bluebeep);
yellowBeep = MediaPlayer.create(this, R.raw.yellowbeep);
greenButton.setOnLongClickListener(this);
redButton.setOnLongClickListener(this);
blueButton.setOnClickListener(this);
yellowButton.setOnClickListener(this);
/*
SharedPreferences sp = getSharedPreferences("score", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
editor.apply();
*/
// for change background
btPhoto = (ImageButton) findViewById(R.id.btPhoto);
btPhoto.setOnLongClickListener(this);
background = (android.support.constraint.ConstraintLayout) findViewById(R.id.background);
}
public void start() {
startActivated=true;
gm = new GameManger(this);
Score.setText("0");
lightUp(0);
}
public void beepStop(){
greenBeep.stop();
redBeep.stop();
blueBeep.stop();
yellowBeep.stop();
}
public void lightUp(final int i) {
android.os.Handler handler = new android.os.Handler();
if (i < gm.getRandomColors().size()) //light up code
{
switch (gm.getRandomColors().get(i)) {
case 1:
greenButton.setBackgroundResource(R.drawable.greenlightup);
greenBeep.start();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
greenButton.setBackgroundResource(R.drawable.green);
lightUp(i+1);
}
}, 500);
break;
case 2:
redButton.setBackgroundResource(R.drawable.redlightup);
redBeep.start();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
redButton.setBackgroundResource(R.drawable.red);
lightUp(i+1);
}
}, 500);
break;
case 3:
blueButton.setBackgroundResource(R.drawable.bluelightup);
blueBeep.start();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
blueButton.setBackgroundResource(R.drawable.blue);
lightUp(i+1);
}
}, 500);
break;
case 4:
yellowButton.setBackgroundResource(R.drawable.yellowlightup);
yellowBeep.start();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
yellowButton.setBackgroundResource(R.drawable.yellow);
lightUp(i+1);
}
}, 500);
break;
}
}
pIndex = 0;
}
#Override
public void onClick(View v) {
if (v.getId() == startButton.getId()) {
start();
} else {
if (startActivated) {
if (v.getId() == greenButton.getId()) {
greenBeep.start();
pNum = 1;
}
if (v.getId() == redButton.getId()) {
redBeep.start();
pNum = 2;
}
if (v.getId() == blueButton.getId()) {
blueBeep.start();
pNum = 3;
}
if (v.getId() == yellowButton.getId()) {
yellowBeep.start();
pNum = 4;
}
if (!gm.check(pNum, pIndex)) {
beepStop();
SharedPreferences sp = getSharedPreferences("score", Context.MODE_PRIVATE);
Intent i = null;
score = gm.getRandomColors().size()-1;
if(score > sp.getInt("scoreP3",0)) {
i = new Intent(GameActivity.this, InsertScoreActivity.class);
i.putExtra("score", gm.getRandomColors().size() - 1);
startActivity(i);
}
else {
i = new Intent(GameActivity.this, GameOverActivity.class);
i.putExtra("score", gm.getRandomColors().size() - 1);
startActivity(i);
}
}
pIndex++;
if (pIndex == gm.getRandomColors().size()) {
Score.setText("" + gm.getRandomColors().size() + "");
gm.addColor();
//this is the sleep that doesn't work
try {
t.sleep(500);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
//this is the sleep that doesn't work
lightUp(0);
}
}
}
}
// for background
public void getPhoto(View v)
{
//brings user to gallery to select image for background of screen
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"),0);
}
//for background
#Override
public boolean onLongClick(View view)
{
AlertDialog.Builder info = new AlertDialog.Builder(this);
info.setTitle("Remove Background Image?");
info.setMessage("Are you sure you wish to revert to the default background?");
info.setCancelable(true);
info.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{ //erases current background image location
try {
FileOutputStream fos = openFileOutput(imagefile, Context.MODE_PRIVATE);
OutputStreamWriter osw = new OutputStreamWriter(fos);
BufferedWriter writer = new BufferedWriter(osw);
writer.close();
osw.close();
fos.close();
background.setBackgroundColor(yellowish);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
info.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel();
}
});
info.show();
return false;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(requestCode == 0 && resultCode == RESULT_OK)
{
try
{
Uri selectedImage = data.getData();
grantUriPermission("com.example.memorygame", selectedImage,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
InputStream imageStream;
imageStream = getContentResolver().openInputStream(selectedImage);
Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
Drawable image = new BitmapDrawable(getResources(), bitmap);
background.setBackground(image);
//saves location of background image
try
{
FileOutputStream fos = openFileOutput(imagefile, Context.MODE_PRIVATE);
OutputStreamWriter osw = new OutputStreamWriter(fos);
BufferedWriter writer = new BufferedWriter(osw);
String imageUri = selectedImage.toString();
writer.append(imageUri);
writer.close();
osw.close();
fos.close();
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
so this is my code and the i will put two notes on the thread.sleep that doesn't work for me.
basically i have this function that lights up a series of buttons (switches their color in a certain order) ,
then i have a function which receives the user input ( what buttons the user pressed and in what order).
what i want to do by that sleep is to put a little break between the end of the color input(when the user finishes to press stuff), and the beginning of the light up ( when the buttons lightup/change their color).
i think the problem comes with all of the these try and catch functions or however they're called (sorry i am a beginner) however i don't know hwo to overcome this.
You should avoid Thread.sleep(). Use handler for doing UI related operation.
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
//Do something here
}
}, 5000);
If you get some time please go through the below link. This will give an idea of handler and thread.
Android, Handler is running in main thread or other thread?
In android, you can use Handler to wait for as much as you want, here's an example of 2 seconds (2000 milliseconds) delay:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// this code will run after 2 seconds
}
}, 2000);
Just insert this code anywhere you need to wait/sleep your thread.
It's better to use Handler instead to Thread.sleep();
Just Replace this
//this is the sleep that doesn't work
try {
t.sleep(500);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
//this is the sleep that doesn't work
With
Handler handler1=new Handler();
handler1.postDelayed(new Runnable() {
#Override
public void run() {
lightUp(0);
}
},500);

How to do realtime network in Doze Mode

I am trying to do realtime bluetooth location tracking using Android. I want to scan for bluetooth le and upload to a server in real time even when the phone is locked.
When running the app however, after 30 minutes the network request queue stops being processed because of Android's built-in Doze Mode.
I've tried moving my background service to the foreground but to no avail.
Any ideas how I can do constant network in Doze Mode? This won't be a public app so won't be submitted to Google Play, it will only be installed to Enterprise devices.
My Service Class:
package REDACTED.beaconlistener;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.RejectedExecutionException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
public class BroadcastService extends Service {
private static final String TAG = "BROADCAST";
private static final String strURL = "REDACTED";
private long lastAlertTimestamp;
private ScanCallback callback;
private Timer timer;
private BluetoothLeScanner scanner;
private ScanSettings settings;
private PowerManager.WakeLock wakeLock;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new Notification.Builder(this)
.setContentTitle("My Notification")
.setContentText("My Message")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentIntent(pendingIntent)
.setTicker("TICKER TEXT")
.build();
startForeground(999, notification);
lastAlertTimestamp = Calendar.getInstance().getTime().getTime() / 1000;
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Log.e(TAG, "Bluetooth LE not supported!");return;
}
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
if (!bluetoothAdapter.isEnabled()) {
bluetoothAdapter.enable();
}
scanner = bluetoothAdapter.getBluetoothLeScanner();
settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
callback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
if (result.getDevice().getAddress().substring(0, 8).equals("0C:F3:EE")) {
// Its a pill!
String[] vcodeArr = result.getDevice().getAddress().substring(9).split(":");
String vcode = vcodeArr[2] + vcodeArr[1] + vcodeArr[0];
Log.d("SCANNER", vcode + " : " + String.valueOf(result.getRssi() + 128));
Long ts = System.currentTimeMillis()/1000;
PingUrlTask task = new PingUrlTask();
try {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, strURL, vcode, String.valueOf(result.getRssi() + 128), getUniquePsuedoID(), ts.toString());
} catch(RejectedExecutionException e) {
Log.e("BROADCAST", "RejectedExecutionException");
}
}
}
#Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult sr : results) {
this.onScanResult(0, sr);
}
}
#Override
public void onScanFailed(int errorCode) {
// Do Nothing.
Log.e("SCANNER", String.valueOf(errorCode));
}
};
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
try {
new PingUrlTask().execute(strURL, null, String.valueOf(0), getUniquePsuedoID());
} catch(Exception e) {
Log.e("BROADCAST", e.getMessage());
e.printStackTrace();
}
}
}, 10000, 10000);
try {
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "BeaconListener");
} catch(NullPointerException e) {
// Do nothing.
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
ping("Service Started");
try {
wakeLock.acquire();
} catch(Exception e) {
// Do nothing.
}
// bluetoothAdapter.startLeScan(callback);
List<ScanFilter> filter = new ArrayList<ScanFilter>();
scanner.startScan(filter, settings, callback);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
try {
wakeLock.release();
} catch(Exception e) {
// Do nothing.
}
// bluetoothAdapter.stopLeScan(callback);
scanner.stopScan(callback);
timer.cancel();
ping("Service Stopped");
}
public String getUniquePsuedoID() {
// If all else fails, if the user does have lower than API 9 (lower
// than Gingerbread), has reset their device or 'Secure.ANDROID_ID'
// returns 'null', then simply the ID returned will be solely based
// off their Android device information. This is where the collisions
// can happen.
// Thanks http://www.pocketmagic.net/?p=1662!
// Try not to use DISPLAY, HOST or ID - these items could change.
// If there are collisions, there will be overlapping data
String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);
// Thanks to #Roman SL!
// https://stackoverflow.com/a/4789483/950427
// Only devices with API >= 9 have android.os.Build.SERIAL
// http://developer.android.com/reference/android/os/Build.html#SERIAL
// If a user upgrades software or roots their device, there will be a duplicate entry
String serial = null;
try {
serial = android.os.Build.class.getField("SERIAL").get(null).toString();
// Go ahead and return the serial for api => 9
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
} catch (Exception exception) {
// String needs to be initialized
serial = "serial"; // some value
}
// Thanks #Joe!
// https://stackoverflow.com/a/2853253/950427
// Finally, combine the values we have found by using the UUID class to create a unique identifier
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}
private void ping(String text) {
Log.d("BROADCAST", text);
// new PingUrlTask().execute(strURL);
}
private void createPushNotification(String title, String text) {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder b = new NotificationCompat.Builder(getApplicationContext());
b.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setTicker("Hearty365")
.setContentTitle(title)
.setContentText(text)
.setDefaults(Notification.DEFAULT_LIGHTS| Notification.DEFAULT_SOUND)
.setContentIntent(contentIntent)
.setContentInfo("Info")
.setPriority(Notification.PRIORITY_HIGH);
NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, b.build());
}
private class PingUrlTask extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(final String... strURL) {
Log.d("BROADCAST", "PingUrlTask");
Log.d("BROADCAST", strURL[0]);
try {
URL requestUrl = new URL(strURL[0]);
HttpsURLConnection conn = (HttpsURLConnection) requestUrl.openConnection();
conn.setRequestMethod("POST");
conn.setReadTimeout(95 * 1000);
conn.setConnectTimeout(95 * 1000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("X-Environment", "android");
conn.setHostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
conn.setSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault());
if (strURL.length != 5) {
return null;
}
// Write Post data
StringBuilder queryParams = new StringBuilder();
queryParams.append("vcode=");
queryParams.append(strURL[1]);
queryParams.append("&rssi=");
queryParams.append(strURL[2]);
queryParams.append("&deviceId=");
queryParams.append(strURL[3]);
queryParams.append("&timestamp=");
queryParams.append(strURL[4]);
queryParams.append("&time=");
queryParams.append(lastAlertTimestamp);
Log.d("BROADCAST", queryParams.toString());
DataOutputStream dStream = new DataOutputStream(conn.getOutputStream());
dStream.writeBytes(queryParams.toString());
conn.connect();
// Read response
Log.d(TAG, String.valueOf(conn.getResponseCode()));
if (conn.getResponseCode() == 200) {
StringBuilder result = new StringBuilder();
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line;
while((line = reader.readLine()) != null) {
result.append(line);
}
Log.d(TAG, result.toString());
try {
JSONObject obj = new JSONObject(result.toString());
lastAlertTimestamp = obj.getLong("serverTime");
JSONArray alerts = obj.getJSONArray("alerts");
for(int i = 0; i < alerts.length(); i++) {
JSONObject alert = alerts.getJSONObject(i);
createPushNotification(alert.getString("alert_title"), alert.getString("alert_message"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
dStream.flush();
dStream.close();
Log.d("BROADCAST", String.valueOf(conn.getResponseCode()));
} catch(Exception e) {
Log.e("BROADCAST", e.getMessage());
e.printStackTrace();
}
// Handler handler = new Handler(Looper.getMainLooper());
// handler.post(new Runnable() {
// #Override
// public void run() {
// if (MainActivity.mWebView != null) {
// try {
// JSONObject payload = new JSONObject();
// payload.put("vcode", strURL[1]);
// payload.put("rssi", strURL[2]);
// payload.put("deviceId", strURL[3]);
// payload.put("timestamp", strURL[4]);
// payload.put("time", lastAlertTimestamp);
// String command = String.format("androidData(%s)", payload.toString());
//
// Log.d(TAG, command);
// MainActivity.mWebView.evaluateJavascript(command, null);
// } catch(Exception e) {
// Log.d(TAG, e.getMessage());
// e.printStackTrace();
// }
// } else {
// Log.w(TAG, "No WebView!");
// }
// }
// });
return null;
}
}
}

When I trying to Click on Paired device list of bluetooth then it will unfortunately , MyApp has stopped message display and my application is closed

When I click on paired device list of Bluetooth, application crashes , and I get a message saying 'MyApp has stopped
When I start my application first time it doesn't show my Paired devices in paired devices list but when i switch off the display and switch it on again it shows.
package com.example.bluetoothapp;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Set;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
ListView listViewPaired;
ListView listViewDetected;
ArrayList<String> arrayListpaired;
Button buttonSearch, buttonOn, buttonDesc, buttonOff;
ArrayAdapter<String> adapter, detectedAdapter;
static HandleSeacrh handleSeacrh;
BluetoothDevice bdDevice;
BluetoothClass bdClass;
ArrayList<BluetoothDevice> arrayListPairedBluetoothDevices;
private ButtonClicked clicked;
ListItemClickedonPaired listItemClickedonPaired;
BluetoothAdapter bluetoothAdapter = null;
ArrayList<BluetoothDevice> arrayListBluetoothDevices = null;
ListItemClicked listItemClicked;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listViewDetected = (ListView) findViewById(R.id.listViewDetected);
listViewPaired = (ListView) findViewById(R.id.listViewPaired);
buttonSearch = (Button) findViewById(R.id.buttonSearch);
buttonOn = (Button) findViewById(R.id.buttonOn);
buttonDesc = (Button) findViewById(R.id.buttonDesc);
buttonOff = (Button) findViewById(R.id.buttonOff);
arrayListpaired = new ArrayList<String>();
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
clicked = new ButtonClicked();
handleSeacrh = new HandleSeacrh();
arrayListPairedBluetoothDevices = new ArrayList<BluetoothDevice>();
/*
* the above declaration is just for getting the paired bluetooth
* devices; this helps in the removing the bond between paired devices.
*/
listItemClickedonPaired = new ListItemClickedonPaired();
arrayListBluetoothDevices = new ArrayList<BluetoothDevice>();
adapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_list_item_1, arrayListpaired);
detectedAdapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_list_item_single_choice);
listViewDetected.setAdapter(detectedAdapter);
listItemClicked = new ListItemClicked();
adapter.notifyDataSetChanged();
listViewPaired.setAdapter(adapter);
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
getPairedDevices();
buttonOn.setOnClickListener(clicked);
buttonSearch.setOnClickListener(clicked);
buttonDesc.setOnClickListener(clicked);
buttonOff.setOnClickListener(clicked);
listViewDetected.setOnItemClickListener(listItemClicked);
listViewPaired.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
TextView txt = (TextView) arg1;
Toast.makeText(MainActivity.this,
"" + txt.getText().toString(), 1000).show();
}
});
}
private void getPairedDevices() {
Set<BluetoothDevice> pairedDevice = bluetoothAdapter.getBondedDevices();
if (pairedDevice.size() > 0) {
for (BluetoothDevice device : pairedDevice) {
arrayListpaired.add(device.getName() + "\n"
+ device.getAddress());
arrayListPairedBluetoothDevices.add(device);
}
}
}
class ListItemClicked implements OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
bdDevice = arrayListBluetoothDevices.get(position);
// bdClass = arrayListBluetoothDevices.get(position);
Log.i("Log", "The dvice : " + bdDevice.toString());
/*
* here below we can do pairing without calling the callthread(), we
* can directly call the connect(). but for the safer side we must
* usethe threading object.
*/
// callThread();
// connect(bdDevice);
Boolean isBonded = false;
try {
isBonded = createBond(bdDevice);
if (isBonded) {
// arrayListpaired.add(bdDevice.getName()+"\n"+bdDevice.getAddress());
getPairedDevices();
}
} catch (Exception e) {
e.printStackTrace();
}// connect(bdDevice);
Log.i("Log", "The bond is created: " + isBonded);
}
}
class ListItemClickedonPaired implements OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
bdDevice = arrayListPairedBluetoothDevices.get(position);
try {
Boolean removeBonding = removeBond(bdDevice);
if (removeBonding) {
arrayListpaired.remove(position);
}
Log.i("Log", "Removed" + removeBonding);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/*
* private void callThread() { new Thread(){ public void run() { Boolean
* isBonded = false; try { isBonded = createBond(bdDevice); if(isBonded) {
* arrayListpaired.add(bdDevice.getName()+"\n"+bdDevice.getAddress());
* adapter.notifyDataSetChanged(); } } catch (Exception e) { // TODO
* Auto-generated catch block e.printStackTrace(); }//connect(bdDevice);
* Log.i("Log", "The bond is created: "+isBonded); } }.start(); }
*/
private Boolean connect(BluetoothDevice bdDevice) {
Boolean bool = false;
try {
Log.i("Log", "service method is called ");
Class cl = Class.forName("android.bluetooth.BluetoothDevice");
Class[] par = {};
Method method = cl.getMethod("createBond", par);
Object[] args = {};
bool = (Boolean) method.invoke(bdDevice);// , args);// this invoke
// creates the detected
// devices paired.
// Log.i("Log", "This is: "+bool.booleanValue());
// Log.i("Log", "devicesss: "+bdDevice.getName());
} catch (Exception e) {
Log.i("Log", "Inside catch of serviceFromDevice Method");
e.printStackTrace();
}
return bool.booleanValue();
};
public boolean removeBond(BluetoothDevice btDevice) throws Exception {
Class btClass = Class.forName("android.bluetooth.BluetoothDevice");
Method removeBondMethod = btClass.getMethod("removeBond");
Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
public boolean createBond(BluetoothDevice btDevice) throws Exception {
Class class1 = Class.forName("android.bluetooth.BluetoothDevice");
Method createBondMethod = class1.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
class ButtonClicked implements OnClickListener {
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.buttonOn:
onBluetooth();
break;
case R.id.buttonSearch:
arrayListBluetoothDevices.clear();
startSearching();
break;
case R.id.buttonDesc:
makeDiscoverable();
break;
case R.id.buttonOff:
offBluetooth();
break;
default:
break;
}
}
}
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Message msg = Message.obtain();
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
Toast.makeText(context, "ACTION_FOUND", Toast.LENGTH_SHORT)
.show();
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
try {
// device.getClass().getMethod("setPairingConfirmation",
// boolean.class).invoke(device, true);
// device.getClass().getMethod("cancelPairingUserInput",
// boolean.class).invoke(device);
} catch (Exception e) {
Log.i("Log", "Inside the exception: ");
e.printStackTrace();
}
if (arrayListBluetoothDevices.size() < 1) // this checks if the
// size of bluetooth
// device is 0,then
// add the
{ // device to the arraylist.
detectedAdapter.add(device.getName() + "\n"
+ device.getAddress());
arrayListBluetoothDevices.add(device);
} else {
boolean flag = true; // flag to indicate that particular
// device is already in the arlist
// or not
for (int i = 0; i < arrayListBluetoothDevices.size(); i++) {
if (device.getAddress().equals(
arrayListBluetoothDevices.get(i).getAddress())) {
flag = false;
}
}
if (flag == true) {
detectedAdapter.add(device.getName() + "\n"
+ device.getAddress());
arrayListBluetoothDevices.add(device);
}
}
}
}
};
private void startSearching() {
Log.i("Log", "in the start searching method");
IntentFilter intentFilter = new IntentFilter(
BluetoothDevice.ACTION_FOUND);
MainActivity.this.registerReceiver(myReceiver, intentFilter);
bluetoothAdapter.startDiscovery();
}
private void onBluetooth() {
if (!bluetoothAdapter.isEnabled()) {
bluetoothAdapter.enable();
Log.i("Log", "Bluetooth is Enabled");
}
}
private void offBluetooth() {
if (bluetoothAdapter.isEnabled()) {
bluetoothAdapter.disable();
}
}
private void makeDiscoverable() {
Intent discoverableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(
BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
Log.i("Log", "Discoverable ");
}
class HandleSeacrh extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 111:
break;
default:
break;
}
}
}
}

Inverting audio in Java

I am new to Java and I want to know how to invert audio (fixed voice inversion) coming from the input through a loopback to the output after a delay. How and where would I do this, and would I be able to set a frequency of the inversion somehow. Thanks.
package net.bitplane.android.microphone;
import java.nio.ByteBuffer;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.IBinder;
import android.util.Log;
public class MicrophoneService extends Service implements OnSharedPreferenceChangeListener {
private static final String APP_TAG = "Microphone";
private static final int mSampleRate = 44100;
private static final int mFormat = AudioFormat.ENCODING_PCM_16BIT;
private AudioTrack mAudioOutput;
private AudioRecord mAudioInput;
private int mInBufferSize;
private int mOutBufferSize;
SharedPreferences mSharedPreferences;
private static boolean mActive = false;
private NotificationManager mNotificationManager;
private MicrophoneReceiver mBroadcastReceiver;
private class MicrophoneReceiver extends BroadcastReceiver {
// Turn the mic off when things get loud
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action != null && action.equals(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
SharedPreferences prefs = context.getSharedPreferences(APP_TAG, Context.MODE_PRIVATE);
SharedPreferences.Editor e = prefs.edit();
e.putBoolean("active", false);
e.commit();
}
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
Log.d(APP_TAG, "Creating mic service");
// notification service
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mBroadcastReceiver = new MicrophoneReceiver();
// create input and output streams
mInBufferSize = AudioRecord.getMinBufferSize(mSampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, mFormat);
mOutBufferSize = AudioTrack.getMinBufferSize(mSampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, mFormat);
mAudioInput = new AudioRecord(MediaRecorder.AudioSource.MIC, mSampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, mFormat, mInBufferSize);
mAudioOutput = new AudioTrack(AudioManager.STREAM_MUSIC, mSampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, mFormat, mOutBufferSize, AudioTrack.MODE_STREAM);
// listen for preference changes
mSharedPreferences = getSharedPreferences(APP_TAG, MODE_PRIVATE);
mSharedPreferences.registerOnSharedPreferenceChangeListener(this);
mActive = mSharedPreferences.getBoolean("active", false);
if (mActive)
record();
}
#Override
public void onDestroy() {
Log.d(APP_TAG, "Stopping mic service");
// close the service
SharedPreferences.Editor e = mSharedPreferences.edit();
e.putBoolean("active", false);
e.commit();
// disable the listener
mSharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
mAudioInput.release();
mAudioOutput.release();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.d(APP_TAG, "Service sent intent");
// if this is a stop request, cancel the recording
if (intent != null && intent.getAction() != null) {
if (intent.getAction().equals("net.bitplane.android.microphone.STOP")) {
Log.d(APP_TAG, "Cancelling recording via notification click");
SharedPreferences.Editor e = mSharedPreferences.edit();
e.putBoolean("active", false);
e.commit();
}
}
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
// intercept the preference change.
if (!key.equals("active"))
return;
boolean bActive = sharedPreferences.getBoolean("active", false);
Log.d(APP_TAG, "Mic state changing (from " + mActive + " to " + bActive + ")");
if (bActive != mActive) {
mActive = bActive;
if (mActive)
record();
if (!mActive)
mNotificationManager.cancel(0);
}
}
public void record() {
Thread t = new Thread() {
public void run() {
Context context = getApplicationContext();
CharSequence titleText = getString(R.string.mic_active);
CharSequence statusText = getString(R.string.cancel_mic);
long when = System.currentTimeMillis();
Intent cancelIntent = new Intent();
cancelIntent.setAction("net.bitplane.android.microphone.STOP");
cancelIntent.setData(Uri.parse("null://null"));
cancelIntent.setFlags(cancelIntent.getFlags() | Notification.FLAG_AUTO_CANCEL);
PendingIntent pendingCancelIntent = PendingIntent.getService(context, 0, cancelIntent, 0);
Notification notification = new Notification(R.drawable.status, titleText, when);
notification.setLatestEventInfo(context, titleText, statusText, pendingCancelIntent);
mNotificationManager.notify(0, notification);
// allow the
registerReceiver(mBroadcastReceiver, new IntentFilter(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY));
Log.d(APP_TAG, "Entered record loop");
recordLoop();
Log.d(APP_TAG, "Record loop finished");
}
private void recordLoop() {
if ( mAudioOutput.getState() != AudioTrack.STATE_INITIALIZED || mAudioInput.getState() != AudioTrack.STATE_INITIALIZED) {
Log.d(APP_TAG, "Can't start. Race condition?");
}
else {
try {
try { mAudioOutput.play(); } catch (Exception e) { Log.e(APP_TAG, "Failed to start playback"); return; }
try { mAudioInput.startRecording(); } catch (Exception e) { Log.e(APP_TAG, "Failed to start recording"); mAudioOutput.stop(); return; }
try {
ByteBuffer bytes = ByteBuffer.allocateDirect(mInBufferSize);
int o = 0;
byte b[] = new byte[mInBufferSize];
while(mActive) {
o = mAudioInput.read(bytes, mInBufferSize);
bytes.get(b);
bytes.rewind();
mAudioOutput.write(b, 0, o);
}
Log.d(APP_TAG, "Finished recording");
}
catch (Exception e) {
Log.d(APP_TAG, "Error while recording, aborting.");
}
try { mAudioOutput.stop(); } catch (Exception e) { Log.e(APP_TAG, "Can't stop playback"); mAudioInput.stop(); return; }
try { mAudioInput.stop(); } catch (Exception e) { Log.e(APP_TAG, "Can't stop recording"); return; }
}
catch (Exception e) {
Log.d(APP_TAG, "Error somewhere in record loop.");
}
}
// cancel notification and receiver
mNotificationManager.cancel(0);
try {
unregisterReceiver(mBroadcastReceiver);
} catch (IllegalArgumentException e) { Log.e(APP_TAG, "Receiver wasn't registered: " + e.toString()); }
}
};
t.start();
}
}

Categories