I have the following lines of code. I'm trying to access the Strings deviceName and deviceHarwareAddress. Do I need to construct a class that extends BroadcastReceiver and create a method within that which will return the code for me?
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
}
}
};
Not necessary. If you are limiting its use within a single component (say activity/fragment/service), you can keep "mReceiver" inside that component and then register mReceiver for that. That will work fine.
This is the case if you are doing it inside an activity.
public class BluetoothTest extends AppCompatActivity {
private ArrayList<BluetoothDevice> deviceList;
private BluetoothAdapter mBluetoothAdapter;
private ArrayList<DeviceItem> deviceItemList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.abc);
/**
* Do necessary coding to enable bluetooth
*/
registerReceiver();
startBluetoothDiscovery();
}
private void registerReceiver() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
IntentFilter dintentFilter = new IntentFilter();
dintentFilter.addAction(BluetoothDevice.ACTION_FOUND);
dintentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
dintentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mDiscoveryBroadcastReceiver, dintentFilter);
}
public void startBluetoothDiscovery() {
if (!mBluetoothAdapter.isDiscovering())
mBluetoothAdapter.startDiscovery();
}
public void setBluetoothDevice(BluetoothDevice device) {
if (!deviceList.contains(device))
deviceList.add(device);
}
public ArrayList<BluetoothDevice> getBluetoothDeviceList() {
return deviceList;
}
private void resetAll() {
deviceItemList.clear();
unregisterReceiver(mDiscoveryBroadcastReceiver);
}
private final BroadcastReceiver mDiscoveryBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
Toast.makeText(getApplicationContext(), "Started discovery!!!", Toast.LENGTH_SHORT).show();
deviceList = new ArrayList<>();
deviceItemList.clear();
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Toast.makeText(getApplicationContext(), "Finished discovery!!!", Toast.LENGTH_SHORT).show();
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
DeviceItem deviceItem = new DeviceItem(device.getName(),
device.getAddress(), device.getBluetoothClass(), device);
deviceItem.setBluetoothDevice(device);
/**
* To check if the device is in paired list or not
*/
if (mBluetoothAdapter.getBondedDevices().contains(device))
deviceItem.setPaired(true);
else
deviceItem.setPaired(false);
if (!deviceItemList.contains(deviceItem))
deviceItemList.add(deviceItem);
/**
* Once the device is found,it is added to a list
*/
setBluetoothDevice(device);
}
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
return id == R.id.action_settings;
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
}
}
In case of "service" you can make use of the binder or observer pattern for make the data available to the activity.
Related
I'm trying to send a message via bluetooth in Android Studio. I've googled but I cannot find the answer. I want to send a message to a connected device.
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
private ImageView bluetoothOnImageView;
private ImageView bluetoothOffImageView;
private TextView bluetoothOnOffTextView;
private BluetoothAdapter bluetoothAdapter;
private ListView listView;
private EditText messageEditText;
private ArrayList<String> deviceList = new ArrayList<String>();
private ArrayList<BluetoothDevice> deviceListBluetooth = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bluetoothOnImageView = findViewById(R.id.bluetoothOnImageView);
bluetoothOffImageView = findViewById(R.id.bluetoothOffImageView);
bluetoothOnOffTextView = findViewById(R.id.bluetoothOnOffTextView);
listView = findViewById(R.id.listView);
messageEditText = findViewById(R.id.messageEditText);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.startDiscovery();
checkBluetooth();
Toast.makeText(this, "Scanning devices...", Toast.LENGTH_SHORT).show();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filter);
IntentFilter filterChange = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(receiverChange, filter);
listView.setOnItemClickListener(MainActivity.this);
}
private final BroadcastReceiver receiverChange = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 3 Cases
// 1: Bonded already
if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
Log.d("BroadcastReceiver", "BOND_BONDED");
Toast.makeText(MainActivity.this, "Already connected to this device.", Toast.LENGTH_SHORT).show();
}
// 2: Creating a bond
if (device.getBondState() == BluetoothDevice.BOND_BONDING) {
Log.d("BroadcastReceiver", "BOND_BONDING");
}
// 3: Breaking a bond
if (device.getBondState() == BluetoothDevice.BOND_NONE) {
Log.d("BroadcastReceiver", "BOND_NONE");
Toast.makeText(MainActivity.this, "Broke connection to this device.", Toast.LENGTH_SHORT).show();
}
}
}
};
public void bluetoothSearchOnClick(View view) {
Toast.makeText(this, "Rescanning devices...", Toast.LENGTH_SHORT).show();
// Reset devices
deviceList.clear();
deviceListBluetooth.clear();
bluetoothAdapter.startDiscovery();
checkBluetooth();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filter);
}
#Override
protected void onDestroy() {
unregisterReceiver(receiver);
unregisterReceiver(receiverChange);
super.onDestroy();
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String newDevice = device.getName() + "\n" + device.getAddress();
boolean duplicate = false;
// No duplicate devices
for (int i = 0; i < deviceList.size(); i++) {
if (newDevice.equals(deviceList.get(i))) {
duplicate = true;
}
}
if (!duplicate) {
deviceList.add(newDevice);
deviceListBluetooth.add(device);
}
Log.i("BT", device.getName() + "\n" + device.getAddress());
listView.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, deviceList));
}
}
};
public void bluetoothOnOnClick(View view) {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.disable();
// Wait x milliseconds
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
checkBluetooth();
}
}, 500);
}
public void bluetoothOffOnClick(View view) {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.enable();
// Wait x milliseconds
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
checkBluetooth();
}
}, 500);
}
private void checkBluetooth() {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
// Device does not support Bluetooth
Toast.makeText(this, "This device does not support Bluetooth", Toast.LENGTH_SHORT).show();
} else if (!bluetoothAdapter.isEnabled()) {
// Bluetooth is not enabled :)
bluetoothOnImageView.setVisibility(View.GONE);
bluetoothOffImageView.setVisibility(View.VISIBLE);
bluetoothOnOffTextView.setText("OFF");
bluetoothOnOffTextView.setTextColor(Color.RED);
} else {
// Bluetooth is enabled
bluetoothOffImageView.setVisibility(View.GONE);
bluetoothOnImageView.setVisibility(View.VISIBLE);
bluetoothOnOffTextView.setText("ON");
bluetoothOnOffTextView.setTextColor(Color.GREEN);
}
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
checkBluetooth();
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
bluetoothAdapter.cancelDiscovery();
Log.d("Bluetooth Adapter", "onItemClick: You Clicked on a device.");
String[] device = deviceList.get(position).split("\n");
String deviceName = device[0];
// Bond
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
Log.d("Bluetooth Adapter", "Trying to pair with " + deviceName);
deviceListBluetooth.get(position).createBond();
}
}
public void sendButtonOnClick(View view) {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// Send message
}
}
In the method sendButtonOnClick(View view) is where I want to send the message. You can find this method at the bottom of the code.
Can anyone help me?
this is not so simple as you think (packing up messaging feature into one method). you need to connect to BluetoothSocket obtained from BluetoothDevice using createRfcommSocketToServiceRecord and knowing "messaging" UUID (you can list them with getUuids() method). after proper socket connection you can obtain input and output streams (getInputStream and getOutputStream), from which you can read and write bytes converting to text if you want. found pretty good sample in HERE, which is using separated Threads for Bluetooth communication making whole feature async and not hanging main/UI thread
I am developing the attendance system using Bluetooth that allow the user to scan Bluetooth to get the Bluetooth address and compare it with registered Bluetooth address. The problem is, it only scan and display the registered list of student but not listing the available Bluetooth and also not compare with the register Bluetooth address.
here is the code for BluetoothScanActivity
public class BluetoothScanActivity extends AppCompatActivity {
public static final String TAG = BluetoothScanActivity.class.getSimpleName();
BluetoothAdapter mBluetoothAdapter;
IntentFilter filter;
BroadcastReceiver mReceiver;
String name[];
ArrayList<String> macID;
Bundle scan_data;
int countScans=0;
int numCountScans;
int value;
RippleBackground rippleBackground;
String classID;
boolean selectDateCheck = false;
Date selectedDate;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth_scan);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(ContextCompat.getColor(getBaseContext(), R.color.main_blue));
}
classID = getIntent().getStringExtra("Class ID");
numCountScans = getIntent().getIntExtra("Number Scans",3);
value = getIntent().getIntExtra("Value",1);
selectDateCheck = getIntent().getBooleanExtra("Manual Date",false);
selectedDate = (Date)getIntent().getSerializableExtra("Selected Date");
Toast.makeText(this, numCountScans + " " + value, Toast.LENGTH_LONG).show();
rippleBackground = (RippleBackground)findViewById(R.id.content);
int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1;
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
init();
if(mBluetoothAdapter==null)
{
Toast.makeText(getApplicationContext(),"Your device doesn't support bluetooth!",Toast.LENGTH_SHORT).show();
finish();
}
else
{
if (!mBluetoothAdapter.isEnabled()) {
turnOnBT();
}
}
scan_data=new Bundle();
name=new String[100];
macID = new ArrayList<String>();
Log.d(TAG, "onCreate: ");
searchDevices();
}
private void turnOnBT() {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
public void init()
{
mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
//Create a BroadCastReceiver for ACTION_FOUND
mReceiver=new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
//When discovery finds a device
if(BluetoothDevice.ACTION_FOUND.equals((action)))
{
//Get the BluetoothDevice object from the Intent
BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//Add the name and address to an array adapter to show in a ListView
if(!macID.contains(device.getAddress().toUpperCase()))
macID.add(device.getAddress().toUpperCase());
Toast.makeText(context,device.getName(),Toast.LENGTH_SHORT).show();
}
else if(BluetoothAdapter.ACTION_STATE_CHANGED.equals((action)))
{
if(mBluetoothAdapter.getState()== BluetoothAdapter.STATE_OFF) {
turnOnBT();
}
}
else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals((action)))
{
if(countScans == numCountScans-1)
{
rippleBackground.stopRippleAnimation();
Intent in = new Intent(BluetoothScanActivity.this, MarkStudentsActivity.class);
in.putExtra("Class ID", classID);
in.putExtra("Value",value);
in.putStringArrayListExtra("MAC ID's", macID);
intent.putExtra("Manual Date",selectDateCheck);
intent.putExtra("Selected Date",selectedDate);
startActivity(in);
finish();
}
else
{
countScans++;
Log.d("Mark","" + countScans);
mBluetoothAdapter.startDiscovery();
}
}
}
};
filter=new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter);
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
if(mBluetoothAdapter!=null)
mBluetoothAdapter.cancelDiscovery();
unregisterReceiver(mReceiver);
}
I am just trying to implement Wifi P2P and I'm stuck on getting the peer list.
When I click on discover device Button then I just want to fetch all the devices append the list of devices to a string which I can output using a text view.
MainActivity.java
package com.example.lrmah.wifip2p;
public class MainActivity extends AppCompatActivity implements
WifiP2pManager.PeerListListener {
private List<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
WifiP2pManager mManager;
WifiP2pManager.Channel mChannel;
BroadcastReceiver mReceiver;
Button B;
TextView t;
IntentFilter mIntentFilter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t=(TextView) findViewById(R.id.displayTextView);
B=(Button) findViewById(R.id.discoverPeers);
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);
mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
B.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(getApplicationContext(),"success",Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(int reasonCode) {
}
});
}
});
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
/* unregister the broadcast receiver */
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}
#Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
List<WifiP2pDevice> refreshedPeers = (List<WifiP2pDevice>) peerList.getDeviceList();
if (!refreshedPeers.equals(peers)) {
peers.clear();
peers.addAll(refreshedPeers);
}
WifiP2pDevice device= refreshedPeers.get(0);
t.setText(device.deviceName);
if (peers.size() == 0) {
return;
}
}}
WifiDirectBroadcastReceiver
package com.example.lrmah.wifip2p;
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private MainActivity mActivity;
WifiP2pManager.PeerListListener myPeerListListener;
public WiFiDirectBroadcastReceiver(WifiP2pManager manager, WifiP2pManager.Channel channel,
MainActivity activity) {
super();
this.mManager = manager;
this.mChannel = channel;
this.mActivity = activity;
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
Toast.makeText(mActivity,"wifi is on",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(mActivity,"Please turn on wifi",Toast.LENGTH_LONG).show();
}
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
if (mManager != null) {
mManager.requestPeers(mChannel, mActivity);
}
}
else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
// Respond to new connection or disconnections
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
// Respond to this device's wifi state changing
}
}}
I may be wrong but I think the onPeerAvailable is not being called.
Some points:
else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
// here you should call
NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected() && isSender) {
// connected with the other device, request connection info to find group owner IP
manager.requestConnectionInfo(channel, yourWifiP2pManager.ConnectionInfoListene);
}
else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
// call discoverPeers here
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
if (manager != null) {
manager.requestPeers(channel, yourWifiP2pManager.PeerListListener);
}
}
#Override
public void onFailure(int reasonCode) {}
});
then the device list will be broadcast in
else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
WifiP2pDeviceList list = intent.getParcelableExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST);
for (WifiP2pDevice d : list.getDeviceList()) { //...
I am trying to develop an application where the user can know the status of his/her Bluetooth Le device once he/she launches the app and the connection status is updated in text view in Home Fragment.I have tried to implement it by sending Broadcast from Ble service and catching it in onResume of Home fragment and subsequently updating it in status text view. The status does gets updated but if I change the fragment and come back to the home fragment the text view to show the status gets blank although the Bluetooth Le device is connected.How can I resolve this problem so that the status shows connected all through out if the device is connected and disconnected if it is disconnected?
Any Kind of guidance will be highly appreciated.
here are the code segments I have used to implement the above
In Bleservice.java
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
In HomeFragment.java
public class HomeFragment extends Fragment
{
private BroadcastReceiver mReceiver;
#Override
protected void onResume() {
super.onResume();
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Bleservice.ACTION_GATT_CONNECTED.equals(action)) {
mConnected = true;
updateConnectionState(R.string.connected);
} else if (Bleservice.ACTION_GATT_DISCONNECTED.equals(action)) {
mConnected = false;
updateConnectionState(R.string.disconnected);
}
}
};
getActivity().registerReceiver(mReceiver,makeGattUpdateIntentFilter());
}
private void updateConnectionState(final int resourceId) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
tv_connected_disconnected.setText(resourceId);
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
getActivity().unregisterReceiver(mReceiver);
}
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Bleservice.ACTION_GATT_CONNECTED);
intentFilter.addAction(Bleservice.ACTION_GATT_DISCONNECTED);
return intentFilter;
}
Connect to your BleService by bindService. Check out example with Activity and Service.
private BleService mBluetoothLeService;
private boolean isConnected;
#Override
protected void onStart() {
super.onStart();
Intent bindIntent = new Intent(this, BleService.class);
startService(bindIntent);
bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
registerServiceReceiver(); //register here your mGattCallback that get actions from BleService
}
#Override
protected void onStop() {
super.onStop();
unbindService(mServiceConnection);
mBluetoothLeService = null;
LocalBroadcastManager.getInstance(this).unregisterReceiver(mGattUpdateReceiver);
}
In method bindService you need to pass a ServiceConnection that manage Service Lifecycle.
// Code to manage Service lifecycle.
private final ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
mBluetoothLeService = ((BleService.LocalBinder) service).getService();
isConnected = (mBluetoothLeService.getConnectionState() != BleService.STATE_CONNECTED)
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
}
};
In Service you need to declare Binder.
private final IBinder mBinder = new LocalBinder();
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder {
public BleService getService() {
return BleService.this;
}
}
public int getConnectionState() {
return mConnectionState;
}
So now, after binding to BleService, you can get a connection state.
I am Trying to start a service if the DetectedActivity returned from Activity recognition returned is IN_VEHICLE. I have downloaded a code sample
from :
http://tutsberry.com/activity-recognition-implementation-on-android/
But i'm not sure where to put code in to start my service.
I am Trying to the check the user activity in the background using the Activity Recognition and then
start a service all in the background.
ActivityRecognitionIntentService Class
public class ActivityRecognitionIntentService extends IntentService {
//LogCat
private static final String TAG = ActivityRecognitionIntentService.class.getSimpleName();
public ActivityRecognitionIntentService() {
super("ActivityRecognitionIntentService");
}
protected void onHandleIntent(Intent intent) {
if (ActivityRecognitionResult.hasResult(intent)) {
//Extract the result from the Response
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
DetectedActivity detectedActivity = result.getMostProbableActivity();
//Get the Confidence and Name of Activity
int confidence = detectedActivity.getConfidence();
String mostProbableName = getActivityName(detectedActivity.getType());
//Fire the intent with activity name & confidence
Intent i = new Intent("ImActive");
i.putExtra("activity", mostProbableName);
i.putExtra("confidence", confidence);
Log.d(TAG, "Most Probable Name : " + mostProbableName);
Log.d(TAG, "Confidence : " + confidence);
//Send Broadcast to be listen in MainActivity
this.sendBroadcast(i);
} else {
Log.d(TAG, "Intent had no data returned");
}
}
//Get the activity name
private String getActivityName(int type) {
switch (type) {
case DetectedActivity.IN_VEHICLE:
return "In Vehicle";
case DetectedActivity.ON_BICYCLE:
return "On Bicycle";
case DetectedActivity.ON_FOOT:
return "On Foot";
case DetectedActivity.WALKING:
return "Walking";
case DetectedActivity.STILL:
return "Still";
case DetectedActivity.TILTING:
return "Tilting";
case DetectedActivity.RUNNING:
return "Running";
case DetectedActivity.UNKNOWN:
return "Unknown";
}
return "N/A";
}
}
MainActivity Class
public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener{
// LogCat
private static final String TAG = MainActivity.class.getSimpleName();
private Context mContext;
private GoogleApiClient mGApiClient;
private BroadcastReceiver receiver;
private TextView textView;
private TextView tv2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.msg);
textView.setMovementMethod(new ScrollingMovementMethod());
tv2 = (TextView) findViewById(R.id.text2);
//Set the context
mContext = this;
//Check Google Play Service Available
if (isPlayServiceAvailable()) {
mGApiClient = new GoogleApiClient.Builder(this)
.addApi(ActivityRecognition.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
//Connect to Google API
mGApiClient.connect();
} else {
Toast.makeText(mContext, "Google Play Service not Available", Toast.LENGTH_LONG).show();
}
//Broadcast receiver
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Add current time
Calendar rightNow = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("h:mm:ss a");
String strDate = sdf.format(rightNow.getTime());
;
String v = strDate + " " +
intent.getStringExtra("activity") + " " +
"Confidence : " + intent.getExtras().getInt("confidence") + "\n";
v = textView.getText() + v;
textView.setText(v);
}
};
//Filter the Intent and register broadcast receiver
IntentFilter filter = new IntentFilter();
filter.addAction("ImActive");
registerReceiver(receiver, filter);
//Check for Google play services available on device
}
private boolean isPlayServiceAvailable() {
return GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext) == ConnectionResult.SUCCESS;
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public void onConnected(Bundle bundle) {
Intent i = new Intent(this, ActivityRecognitionIntentService.class);
PendingIntent mActivityRecongPendingIntent = PendingIntent
.getService(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
Log.d(TAG, "connected to ActivityRecognition");
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGApiClient, 0, mActivityRecongPendingIntent);
//Update the TextView
textView.setText("Connected to Google Play Services \nWaiting for Active Recognition... \n");
}
#Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "Suspended to ActivityRecognition");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "Not connected to ActivityRecognition");
//Disconnect and detach the receiver
mGApiClient.disconnect();
unregisterReceiver(receiver);
}
}
MainActivity.java
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
public class MainActivity extends Activity {
IntentFilter filter;
BroadcastReceiver mReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
filter = new IntentFilter();
mReceiver = new MyReceiver();
filter.addAction("IN_VEHICLE"); //Name the action what ever you need to.
filter.addAction("OTHER_ACTION");
filter.addAction("YET_ANOTHER_ACTION)");
registerReceiver(mReceiver, filter); //Register the receiver you define with the actions you want.
}
class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if("IN_VEHICLE_RESPONSE".equals(intent.getAction())){
//Launch other activities here
Intent i = new Intent(getApplicationContext(), InVehicleActivity.class );
startActivity(i);
}else if("OTHER_ACTION_RESPONSE".equals(intent.getAction())){
//Launch desired activity
}else if("YET_ANOTHER_ACTION_RESPONSE".equals(intent.getAction())){
//Launch desired activity
}else{
//Handle unssuported actions
}
}
}
}
MyIntentService.java
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
public class MyIntentService extends IntentService {
Bundle extras;
public MyIntentService() {
super("MyIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
extras = intent.getExtras();
if("IN_VEHICLE".equals(intent.getAction())){
inVehicle(extras);
return;
}
if("OTHER_ACTION".equals(intent.getAction())){
//otheraction method
return;
}
if("YET_ANOTHER_ACTION".equals(intent.getAction())){
//yetanotheraction method
return;
}
}
private void inVehicle(Bundle extras) {
//do work
//do work
Intent intent = new Intent();
intent.setAction("IN_VEHICLE_RESPONSE");
//put all other desired stuff in intent
getApplicationContext().sendBroadcast(intent);
}
}
Don't forget to add your receiver to your manifest.
I would suggest that you start Activities from Activity not Service layer.