How to check Bluetooth tethering status programmatically in Android - java

Is there any way to find out bluetooth tethering is enabled or disabled programmatically in Android 2.3+(any version after 2.3+)?
I am not asking to enable/disable it, but only to know if it is enabled currently or not.

It turns out that BluetoothPan (Personal Area Networking) is the keyword for tethering. I pored over the API documentation and Android source code, but the brief examples in the comments were misleading. This poster provided an example but I had trouble with it initially:
Android BluetoothPAN to create TCP/IP network between Android device and Windows7 PC
I tried various other methods including checking the IP address of the BT device. However no Bluetooth network device exists, so there's no IP to check.
Detect USB tethering on android
Back to the BluetoothPan code... The example in the first thread was incomplete (no ServiceListener implementation). I tried a standard one but the isTetheringOn proxy call failed. The crucial piece is that the onServiceConnected() callback needs at least one line of code or the compiler optimizes it away. It also shouldn't disconnect the proxy like most other examples have. Here's the working code:
BluetoothAdapter mBluetoothAdapter = null;
Class<?> classBluetoothPan = null;
Constructor<?> BTPanCtor = null;
Object BTSrvInstance = null;
Class<?> noparams[] = {};
Method mIsBTTetheringOn;
#Override
public void onCreate() {
Context MyContext = getApplicationContext();
mBluetoothAdapter = getBTAdapter();
try {
classBluetoothPan = Class.forName("android.bluetooth.BluetoothPan");
mIsBTTetheringOn = classBluetoothPan.getDeclaredMethod("isTetheringOn", noparams);
BTPanCtor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
BTPanCtor.setAccessible(true);
BTSrvInstance = BTPanCtor.newInstance(MyContext, new BTPanServiceListener(MyContext));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private BluetoothAdapter getBTAdapter() {
if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1)
return BluetoothAdapter.getDefaultAdapter();
else {
BluetoothManager bm = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
return bm.getAdapter();
}
}
// Check whether Bluetooth tethering is enabled.
private boolean IsBluetoothTetherEnabled() {
try {
if(mBluetoothAdapter != null) {
return (Boolean) mIsBTTetheringOn.invoke(BTSrvInstance, (Object []) noparams);
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public class BTPanServiceListener implements BluetoothProfile.ServiceListener {
private final Context context;
public BTPanServiceListener(final Context context) {
this.context = context;
}
#Override
public void onServiceConnected(final int profile,
final BluetoothProfile proxy) {
//Some code must be here or the compiler will optimize away this callback.
Log.i("MyApp", "BTPan proxy connected");
}
#Override
public void onServiceDisconnected(final int profile) {
}
}

Related

How to create a Socket connection between Unity/C# Server and Android/Java Client?

I'm working on an academic project that consists in controlling a simulated environment created in Unity3D, from a conventional Android application. I already created the scenario in Unity and the mobile application is completely finished, my problem is in the connection. I chose to use sockets because of its simplicity. I managed to connect the application to a server written in C # through conventional Sockets, I know that information can be sent, but when I implemented it in Unity, everything failed, so I decided to use TCP Listener instead of Sockets in Unity / C # (the client Android still uses a conventional TCP connection through Sockets), and in effect, the application connects but there is no information transfer, because the Unity console throws an error that says: ObjectDisposedException: Can not access to disposed object.
Object name: 'System.Net.Sockets.TcpClient'.(The error is presented in line number 56: stream = client.tcp.GetStream ();) The main objective is to obtain the flow of information that would be represented in something like: "1: 0: 1: 0" and being able to make a Split to that string and according to that value change the state of a light bulb or other element, nevertheless I need the essential thing: to establish the connection flow. I'm not an expert in C # and much less using Unity, I really do not know much about design, but I wanted to do it to deliver an innovative work, I hope someone can guide me.
PD: C# Socket (No Unity yet) server working with Android Java client:
![1] https://imgur.com/a/HuNcDC3
//This is my Unity3D/C# Server:
public class SocketManager : MonoBehaviour
{
private List<ServerClient> connectedClients;
private List<ServerClient> disconectedClients;
private TcpListener server;
private string data;
private NetworkStream stream;
private StreamReader stremaReader;
private bool serverStarted;
public int socketPort = 7691;
private void Start()
{
connectedClients = new List<ServerClient>();
disconectedClients = new List<ServerClient>();
try
{
server = new TcpListener(IPAddress.Parse("192.168.1.64"), socketPort);
server.Start();
serverListening();
serverStarted = true;
Debug.Log("Server started. Port: " + socketPort.ToString());
}
catch (Exception ex)
{
Debug.Log("Server socket error: " + ex);
}
}
private void Update()
{
if (!serverStarted)
return;
foreach (ServerClient client in connectedClients)
{
if (IsConnected(client.tcp))
{
client.tcp.Close();
disconectedClients.Add(client);
continue;
}
else
{
stream = client.tcp.GetStream();
if (stream.DataAvailable)
{
this.stremaReader = new StreamReader(stream, true);
data = stremaReader.ReadLine();
if (data != null)
OnIcomingData(client, data);
}
}
}
}
private void OnIcomingData(ServerClient client, string data)
{
Debug.Log(client.clientName + ": " + data);
}
private bool IsConnected(TcpClient tcp)
{
try
{
if (tcp != null && tcp.Client != null && tcp.Client.Connected)
{
if (tcp.Client.Poll(0, SelectMode.SelectRead))
{
return !(tcp.Client.Receive(new byte[1], SocketFlags.Peek) == 0);
}
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
private void serverListening()
{
server.BeginAcceptTcpClient(AcceptTcpClient, server);
}
private void AcceptTcpClient(IAsyncResult asyncResult)
{
TcpListener tcplistener = (TcpListener)asyncResult.AsyncState;
connectedClients.Add(new ServerClient(tcplistener.EndAcceptTcpClient(asyncResult)));
serverListening();
}
}
public class ServerClient
{
public TcpClient tcp;
public string clientName;
public ServerClient(TcpClient tcp)
{
this.tcp = tcp;
this.clientName = "Android";
}
}
// This is my Android/Java Client:
public class SocketThread extends Thread {
private Socket adviser;
private DataOutputStream dataOut;
#Override
public void run() {
super.run();
Log.e("Status:", "Thread started");
try {
adviser = new Socket("192.168.1.64", 7691);
dataOut = new DataOutputStream(adviser.getOutputStream());
} catch (IOException ex) {
Logger.getLogger(SocketThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void sendCommand(String text) {
try {
dataOut.writeUTF(text);
Log.e("Sended Text: ", text);
} catch (IOException ex) {
Logger.getLogger(SocketThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
Here's a more detailed answer than my comment, for future reference.
The problem lies in the following if check if (IsConnected(client.tcp)).
Right now what is happening is that when the client is connected to the server (so the if returns true) you are Closing the connection using client.tcp.Close(); and adding the connection to your disconectedClients list (But you are not removing the client from your connectedClients list! Meaning the client is now in both lists). Then when the next iteration of the foreach loop foreach (ServerClient client in connectedClients) comes around the if (IsConnected(client.tcp)) will return false (the client is no longer connected to the server, since you called close() in the previous iteration.
You then try to call stream = client.tcp.GetStream(); on a stream that is already closed, resulting in an error telling you you cannot get the stream.
This should fix it:
if (IsConnected(client.tcp))
{
client.tcp.Close();
client.tcp.Dispose(); //Dispose of a stream to release it for GC
disconectedClients.Add(client);
connectedClients.Remove(client); //Note to also remove the disconnected client from the connectedClients list.
continue;
}
else
{ ...rest of logic }
Note that i added connectedClients.Remove(client); and client.tcp.Dispose(); to your logic closing the stream. If you don't do this it'll keep getting included in theforeachloop unnecessarily, and the programm will try to callclose()` on a connection that is already closed, resulting in more errors. Disposing of the stream will release it so the garbage collector can collect it, freeing up memory.

Android Firebase : Second Connected Database not allowing auth in rules

I've connected two Databases from the same firebase project like below.
//init the default db;
FirebaseApp.initializeApp(this);
//init the second db;
FirebaseOptions.Builder builder = new FirebaseOptions.Builder();
builder.setApplicationId("id"); //Same as default
builder.setApiKey("key"); //Same as default
builder.setDatabaseUrl("https://second-db.firebaseio.com");
try {
FirebaseApp.initializeApp(this, builder.build(), "second-db");
} catch (IllegalStateException e) {
e.printStackTrace();
}
Getting Reference.
public static DatabaseReference getSecondDbRef(String child) {
FirebaseApp app = FirebaseApp.getInstance("second-db");
return FirebaseDatabase.getInstance(app).getReference(child);
}
With the above, it works, but the rules in the second database don't seem to be getting auth. if I do.
{
"rules":{
"users":{
"$uid":{
".read":"auth.uid !== null",
// ".read":true // This works, so the issue is auth
}
}
}
}
The read fails, even though the user is authenticated, also, this problem isn't there with the default database. Is there anything I'm missing with the init?
Ok, because of highlights below, here's the code as it is on the app.
private static final String TEAMS_BD_ID = "second-db"
public void initFirebase() {
FirebaseApp.initializeApp(this);
FirebaseOptions.Builder builder = new FirebaseOptions.Builder();
builder.setApplicationId("appId"); // //Same as default
builder.setApiKey("key"); // //Same as default
builder.setDatabaseUrl("https://teams-db.firebaseio.com");//Second Db
try {
FirebaseApp.initializeApp(this, builder.build(), TEAMS_BD_ID);
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
public static FirebaseApp getTeamsApp() {
return FirebaseApp.getInstance(TEAMS_BD_ID);
}
public static String getTeamsUserUid() {
return FirebaseAuth.getInstance(getTeamsApp()).getCurrentUser().getUid();
}
public static DatabaseReference getTeamsRef(String child) {
return FirebaseDatabase.getInstance(getTeamsApp()).getReference(child);
}
public static DatabaseReference getTeamsRef() {
return FirebaseDatabase.getInstance(getTeamsApp()).getReference();
}
Then trying to read.
DatabaseReference r = getTeamsRef().child("users/" + getTeamsUserUid() + "/teams")
// getTeamsUserUid() This is null.
It is only a guess.
If you are using FirebaseAuth#getInstance() for getting auth instance, change it to FirebaseAuth#getInstance(FirebaseApp firebaseApp) with the second app instance.

Android set or reset SIM card PIN code programmatically

I have implemented below given to unlock my app (this code works for only systems apps so I have done my app as system app )
TelephonyManager manager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
int state = manager.getSimState();
if(state == TelephonyManager.SIM_STATE_PIN_REQUIRED || state == TelephonyManager.SIM_STATE_PUK_REQUIRED)
{
try {
#SuppressWarnings("rawtypes")
Class clazz = Class.forName(manager.getClass().getName());
Method m = clazz.getDeclaredMethod("getITelephony");
m.setAccessible(true);
ITelephony it = (ITelephony) m.invoke(manager);
if (it.supplyPin(simPin)) {
Toast.makeText(context,"SIM UnLocked",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context,"SIM UNLOCK FAILED",Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
//
e.printStackTrace();
}
}else{
Toast.makeText(context,"SIM is not Locked",Toast.LENGTH_LONG).show();
}
It works fine for me, but now I need to implement setting or resetting SIM PIN programmatically, let me know if it is possible or not. if possible than how can I implement that?
String ussdCode = "**04*"+oldPin+"*"+newPin+"*"+newPin+"#";
startActivity(new Intent("android.intent.action.CALL", Uri.parse("tel:" + ussdCode)));

JAVA - Converting android application into fragment styled application

My app has main.xml and MainActivity. I wanted to convert it to a tabbed styled app. By the help of this tutorial, I've successfully made a UI with a tabbed style.
Now I have to put the codes in my MainActivty(not tabbed style) to the fragments. i don't know how to do it. when i just put the codes to my ToolsFragment.java, it doesn't work.
Here are my codes:
//To get ip address using netcfg
private String ipnc()
{
int e = doNETCFG().indexOf("10.");
if (e == -1)
{
return "";
}
else
{
String ipnc1 = doNETCFG().substring(e, e + 15);
String ipnc2[] = ipnc1.split("/");
String ipnc3 = ipnc2[0];
return ipnc3;
}
}
//To generate netcfg from command line
public String doNETCFG()
{
String str = null;
try
{
Process localProcess = Runtime.getRuntime().exec("/system/bin/netcfg");
BufferedReader localBufferedReader = new BufferedReader(new InputStreamReader(localProcess.getInputStream()));
char[] arrayOfChar = new char[4096];
StringBuffer localStringBuffer = new StringBuffer();
while (true)
{
int i = localBufferedReader.read(arrayOfChar);
if (i <= 0)
{
localBufferedReader.close();
localProcess.waitFor();
str = localStringBuffer.toString();
break;
}
localStringBuffer.append(arrayOfChar, 0, i);
}
}
catch (IOException localIOException)
{
Log.e("TAG", localIOException.getStackTrace().toString());
}
catch (InterruptedException localInterruptedException)
{
Log.e("TAG", localInterruptedException.getStackTrace().toString());
}
return str;
}
//To enable/disable mobile data
private void setMobileDataEnabled(Context context, boolean enabled)
{
final ConnectivityManager conman;
conman =
(ConnectivityManager)context.getSystemService
(Context.CONNECTIVITY_SERVICE);
final Class conmanClass;
try
{
conmanClass =
Class.forName(conman.getClass
().getName());
final Field
iConnectivityManagerField =
conmanClass.getDeclaredField
("mService");
iConnectivityManagerField.
setAccessible(true);
final Object
iConnectivityManager =
iConnectivityManagerField.get
(conman);
final Class
iConnectivityManagerClass =
Class.forName
(iConnectivityManager.getClass
().getName());
final Method
setMobileDataEnabledMethod =
iConnectivityManagerClass.
getDeclaredMethod
("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.
setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
}
catch
(ClassNotFoundException e)
{
e.printStackTrace();
}
catch
(InvocationTargetException e)
{
e.printStackTrace();
}
catch
(NoSuchMethodException e)
{
e.printStackTrace();
}
catch
(IllegalAccessException e)
{
e.printStackTrace();
}
catch
(NoSuchFieldException e)
{
e.printStackTrace();
}
}
//To play success alert tone
public void playAlertTone()
{
new Thread()
{
public void run()
{
int i = 0;
while (true)
{
if (i >= 1)
return;
MediaPlayer localMediaPlayer = MediaPlayer.create(getApplicationContext(), 0x7f040000);
localMediaPlayer.start();
i++;
try
{
Thread.sleep(100 + localMediaPlayer.getDuration());
localMediaPlayer.release();
}
catch (InterruptedException localInterruptedException)
{
}
}
}
}
.start();
}
What should I do? Do I have to put this into another activity and call it in fragment? If that's the case, how?
Or convert it to a code executable in fragments and run it there? How can I do this?
I'm a newbie in android programming. Thanks!
when you convert an application to fragment based structure, you have to consider one thing that the context is same for all the fragments in an activity. You will get it by calling getActivity(). So save your context first and use it where ever you want the context.
From your question you are developing an application with tabs. So you may have to create fragments as many as the tabs. You can put your code for each tab in the corresponding fragment.
Now to communicate between the fragments the best way is to use callbacks in your parent activity.
A simple tutorial for implementing fragments can be found HERE
The communication between fragments is explained HERE
Fragments do most of the things activities do. The reason why they were introduced (one of the reasons at least) was so you can place the code in them instead of in the activities of your app. If you think this way, you will notice that you will only need a small number of activities.
I am not sure what you mean by "convert it to a code executable in fragments". You can place your code inside your fragments (use methods) and then simply call those methods.
If you are not sure how Fragments work, I would highly recommend reading the documentation.
I hope this gives you an idea of how to get your code to work in fragments.

Can't find resource for bundle 'ExceptionMessages_en_US', key in Android

I am new again to Java. Can't say I remember using a ResourceBundle. I am getting the exception Can't find resource for bundle 'ExceptionMessages_en_US', key.
Here is my ListResourceBundle class:
(I took the example straight from the JavaDoc and modified it with my own strings)
public class ExceptionMessages extends ListResourceBundle {
#Override
protected Object[][] getContents() {
return new Object[][] {
{"interfaceCount", "Device should have 1 interface."},
{"epCount", "Device should have 3 endpoints."},
{"noIntrIn", "Device does not have an interrupt input endpoint."},
{"noBulkIn", "Device does not have a bulk input endpoint."},
{"noBulkOut", "Device does not have a bulk output endpoint."},
{"openFailed", "A call to deviceOpen has failed."},
{"claimFailed", "A call to claimInterface has failed."},
{"startSessionFailed", "Start USB Session has failed."},
{"sessionNotStarted", "USB Session not started."},
{"bulkTxError", "Bulk endpoint transmit error."},
{"intrRxError", "Interrupt endpoint recieve error."},
};
}
}
I also tried naming the class ExceptionMessages_en_US with no luck
I get the resource bundle like this:
public void Test()
{
try
{
ResourceBundle rb = ResourceBundle.getBundle("ExceptionMessages");
}
catch (Exception e)
{
e.printStackTrace();
}
int i = 0;
i++;
}
I also tired:
public void Test()
{
try
{
ResourceBundle rb = ResourceBundle.getBundle("ExceptionMessages",new Locale("en", "US"));
}
catch (Exception e)
{
e.printStackTrace();
}
int i = 0;
i++;
}
But still get the exception.
What am I missing? I am sure it is something dumb.
I needed to add the full package containing ExceptionMessages.
Example:
ResourceBundle rb = ResourceBundle.getBundle("com.mycomp.ExceptionMessages");

Categories