How to connect paired bluetooth device on app startup in Android Studio? - java

Is there any way to automatically connect a specific device via Bluetooth LE on app startup?
I've been scrolling through stack overflow for the past few hours and have seen a number of similar questions, although majority are quite outdated and deal with reflections or other complex methods that I can't quite comprehend (these methods I've tried to implement, but not successfully, as I didn't really understand what was going on).
So far, I've managed to find the device by its friendly name, although I have no clue what to execute in that if statement. This is within my MainActivity:
protected void onCreate(Bundle savedInstanceState) {
...
if (bluetoothAdapter == null) {
Toast.makeText(getApplicationContext(),"Bluetooth not supported",Toast.LENGTH_SHORT).show();
} else {
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if(pairedDevices.size()>0){
for(BluetoothDevice device: pairedDevices){
if (deviceName.equals(device.getName())) {
//Device found!
//Now how do I pair it?
break;
}
...

Assuming you've successfully identified the BlueToothDevice, you now need to connect to the GATT(Generic Attribute Profile), which allows you to transfer data.
Use the BlueToothDevice.connectGatt method. Using the first overload, the method takes in a Context , a boolean (false = directly connect, true = connect when available), and a BlueToothGhattCallback. The callback receives info from the device.
BlueToothGatt blueToothGatt = device.connectGatt(this, false, blueToothGattCallback);
An example to implement the callback:
BluetoothGattCallback blueToothGattCallback =
new BluetoothGattCallback()
{
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if(newState == BlueToothProfile.STATE_CONNECTED){
/* do stuff */
}
}
}
More details on the callbacks here.

Ended up scrolling through the source code for this app, particularly the SerialSocket, SerialService and SerialListener files which completely solved my problem.

Related

Unity ads returns INVALID_ARGUMENT

I've integrated UnityAds on my Android app (that is not published yet).
I get app id and placement id from database on my server.
App id and placement id are correct, I've copied and pasted about 30 times for be sure of it.
So, when I try to get an ad in test mode, it give me the INVALID_ARGUMENT error.
Here an explaination of the error code by Unity, but as you can see it is a little generic.
I have an object that simply represents an ad service (like admob, FAN, inmobi etc)
In this case the object is called advert, and here it's how I show an ad with Unity:
protected void showUnity(){
UnityAds.initialize(this, advert.getApiKey(), true); //advert.getApiKey() returns the app id
UnityAds.addListener(new IUnityAdsListener() {
#Override
public void onUnityAdsReady(String s) {
Log.i(TAG, "onUnityAdsReady "+s);
if(s.equals(advert.getUnitId()) && !unityReady)
UnityAds.show(ActivityAd.this, advert.getUnitId()); //advert.getUnitId() returns the placement id
}
#Override
public void onUnityAdsStart(String s) {
Log.i(TAG, "onUnityAdsStart "+s);
unityReady = true;
}
#Override
public void onUnityAdsFinish(String s, UnityAds.FinishState finishState) {
if (finishState.compareTo(UnityAds.FinishState.COMPLETED) == 0) {
onAdReward(); //my callback for reward
} else if (finishState.compareTo(UnityAds.FinishState.SKIPPED) == 0) {
onAdClosed(); //my callback for ad close
} else if (finishState.compareTo(UnityAds.FinishState.ERROR) == 0) {
onAdError(finishState.toString()); //my callback for errors
}
}
#Override
public void onUnityAdsError(UnityAds.UnityAdsError unityAdsError, String s) {
onAdError(unityAdsError.toString()); //my callback for errors, here results INVALID_ARGUMENT error
}
});
}
Does anyone know what is wrong? Thanks in advance
If you check the callback closely the onUnityAdsError has 2 params, first provides the error code and the second param provides you information about what went wrong.
#Override
public void onUnityAdsError(UnityAds.UnityAdsError unityAdsError, String reason) {
onAdError(unityAdsError.toString()); //my callback for errors, here results INVALID_ARGUMENT error
}
So just check the reason and you should be able to find out what is going wrong in your integration.
Here are some methods which you can follow to solve this INVALID_ARGUMENT problem
1. Make sure you are implementing the right Initialization code in your app. There are 2 types of Initialization.
Only Unity ads Initialization
Mediation Initialization
and both methods have their own banner, interstitial, and rewarded ad code.
2. Make sure you enable test mode as Boolean. (i.e: private Boolean testMode = true;) (make sure to do false this before publish on store)
3. You can add your mobile phone as a test device to get test ads on your phone forcefully. for this, you have to first copy the Ad ID of your device. For that, go to your mobile settings > Google > Ads > This device's advertising ID. copy that ID and go to unity dashboard > Monetization > Testing > Add Test Device. Add your device Ads ID here with any name, and now you will be able to see test ads on the device.

Google Analyrics track user if connected to the Internet

I just started learning Google Analytics for Android (v4). I am trying to measure how many users use my application with WiFi turned on when an activity is created. I am not sure if I am doing this correctly but I added a custom dimension for "Users are Connected" and used this code:
builder.setCustomDimension(1, isNetworkConnected() ? "True" : "False");
tracker.send(builder.setNewSession().build());
I look at the Google Analytics webpage and cannot see any information about this custom dimension on the "Realtime" navigation. I can see that the user count increased but no information about whether users are connected or not.
Thanks in advance.
Android has to check with isNetworkConnected. If the condition provided, you can run your request in this. This will assume internet is available and connected.
Implement this way:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
if(isNetworkConnected(this)){
// start a service related to internet or
// put your tracker to send data
tracker.send(builder.setNewSession().build()); // or any other methot you use to track app
}
}
public static boolean isNetworkConnected(Context context) {
ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
return (cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isAvailable() && cm.getActiveNetworkInfo().isConnected());
}
}

readCharacteristic not returning data for custom attributes

When my code didn't work, I started with the project I found here and ran it against our custom bluetooth device on my moto-x. Against the general attributes with profiles, I get data back from the following code:
public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.readCharacteristic(characteristic);
}
which returns data asynchronously in:
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
This also works if i run this code against a heart rate monitor.
If I run it against one of our custom properties without a default profile, the data never comes back. Ever.
A google search included this: Cannot read characteristic. Android BLE but setting up notifications did not solve my problem.
Any advice?
I think the PROPERTY_READ, PROPERTY_WRITE isn't set to enabled in your custom properties.
Check for BluetoothGattCharacteristic PROPERTIES -I didn't realize that need to enable the PROPERTY_WRITE, PROPERTY_READ on the BLE hardware and that wasted a lot of time.
The part where to check the PROPERTY should be something like:
if ((characteristic.getProperties() &&
BluetoothGattCharacteristic.PROPERTY_READ)> 0) {
// toast or log here
}
These enable/disable the app or for that matter any app to connect to the bluetooth low energy device
Refer servicesListClickListner on this page

Connecting android device using WiFi Direct

I am developing an application which first discover the peers in range and then connect with all of them one by one my function look like this:
void connectTo(WifiP2pDevice device) {
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
config.groupOwnerIntent=15;
wifiP2pManager.connect(wifiDirectChannel, config, actionListener);
wifiP2pManager.createGroup(wifiDirectChannel, actionListener);
}
But I don't know the difference between the connect and createGroup function of Wifip2pManager class. What's the core difference between them, Please help!
I know I am late to answer but I am sure it would help others. There is no need to createGroup, you simply need to call connect method in this way:
void connectTo(WifiP2pDevice device) {
WifiP2pConfig wifiP2pConfig = new WifiP2pConfig();
wifiP2pConfig.deviceAddress = device.deviceAddress;
wifiP2pConfig.groupOwnerIntent = 0;
wifiP2pConfig.wps.setup = WpsInfo.PBC;
if (wifiP2pManager != null) {
wifiP2pManager.connect(mChannel, wifiP2pConfig,
new ActionListener() {
#Override
public void onSuccess() {
// WiFiDirectBroadcastReceiver will notify us.
// Ignore for now.
Utility.showToast(
WifiP2PConnectionActivity.this,
Constants.CONNECTED);
}
#Override
public void onFailure(int reason) {
Utility.showToast(
WifiP2PConnectionActivity.this,
getErrorMessage(reason));
}
});
}
It will get connected now.
wifiP2pConfig.groupOwnerIntent = 0; is set to zero so that you allow other device to become owner and your own device as client everytime. groupOwnerIntent prioritices our own device priority to be lesser of becoming groupOwner. Rest is upto you how you want your device to behave.

orientation change sound

Good morning,
We have developed an android app, and I have been charged with finding out how to remove the undesired behavior of a notification sound every time that the screen orientation changes. Obviously this behavior only exists on devices running OS version 3.2.3 or later.
I have read several posts that indicate that this can be turned off by unchecking USB Debugging in the Settings --> Developer options, however this option is not checked and none of the other apps that are on any of our Android devices make this notification sound upon orientation change.
The application does require there to be a notification when a "message is received" (the app connects to a webservice and gets new messages from the service every so often). So this would rule out any solution that disabled notifications.
Thus far, I have tried several potential solutions:
1) When a message is received, instantiate a new NotificationManager, and after the notification is sounded, destroy the NotificationManager.
if(MessageReceived == true) {
String ns = Context.NOTIFICATION_SERVICE;
messageNotifyManager = (NotificationManager) getSystemService(ns);
}
showNotification();
messageNotifyManager = null;
2) I realize that an orientation change is essentially the view being destroyed and re-created. I put set a flag in the initial onCreate method and checked to see if that flag had value before recreating the Notification Manager.
public static int Flag = 0;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(Flag == 0) {
String ns = Context.NOTIFICATION_SERVICE;
messageNotifyManager = (NotificationManager) getSystemService(ns);
Flag = 1;
}
}
3) In the application's main class, I created a public OrientationEventListener property and then set its value in the onCreate method, disabling it immediately. When that didn't disable the sound I tried disabling the property in every class that referenced the application's main class.
public OrientationEventListender listener;
#Override
public void onCreate() {
super.onCreate();
appContext = getApplicationContext();
GetPreferences();
//...
listener = new OrientationEventListener(appContext){
public void onOrientationChanged(int Orientation){
}
};
listener.disable();
}
Now, as you can probably tell, I am very new to Android development. I assume that this solution is something so simple that everyone knows, and that is why there are no answers anywhere handy on the web. But any help with this simple problem would be greatly appreciated. Thanks!
This issue was solved by modifying the AndroidManifest, adding the following tag to each activity: android:configChanges="orientation"

Categories

Resources