I have a real android device (Android 4.1.1). Which supports applications like Xender, ShareIt, Zapya etc which uses WiFi Direct to transfer files.
But when I run my application, it says P2P_UNSUPPORTED.
My manifest permissions are....
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
My MainActivity.java is like this..
intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
Receiver receiver=new Receiver();
registerReceiver(receiver,intentFilter);
WifiP2pManager manager=(WifiP2pManager)getSystemService(WIFI_P2P_SERVICE);
channel=manager.initialize(this, Looper.getMainLooper(),null);
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
// Code for when the discovery initiation is successful goes here.
// No services have actually been discovered yet, so this method
// can often be left blank. Code for peer discovery goes in the
// onReceive method, detailed below.
}
#Override
public void onFailure(int reasonCode) {
// Code for when the discovery initiation fails goes here.
// Alert the user that something went wrong.
switch (reasonCode){
case WifiP2pManager.BUSY:Log.e("code","BUSY");break;
case WifiP2pManager.ERROR:Log.e("code","ERROR");break;
case WifiP2pManager.P2P_UNSUPPORTED:Log.e("code","P2P_UNSUPPORTED");break;
}
}
});
In the Log,, I get.
code﹕ P2P_UNSUPPORTED
And my BraodcastReceiver is like this..
#Override
public void onReceive(Context context, Intent intent) {
//Log.e("intent",intent.getAction());
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
Log.e("raw state", ""+state);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
Log.e("state", "ON");
} else if(state == WifiP2pManager.WIFI_P2P_STATE_DISABLED) {
Log.e("state", "DISABLED "+ state);
}
}
And there i get the log as,,
raw state﹕ -1
NOTE : the variable state neither equals WifiP2pManager.WIFI_P2P_STATE_ENABLED nor WifiP2pManager.WIFI_P2P_STATE_DISABLED
It is possible that the applications that you have listed are able to use alternative transports other than Wi-Fi Direct. The P2P_UNSUPPORTED error implies that your device does not have the Wi-Fi Direct feature. You can try confirming this by executing the following: getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT). Alternatively, if your device has Wi-Fi Direct, you can access a Wi-Fi Direct settings activity from the Wi-Fi settings of your device.
Related
I'm new to the Android platform and I want to create an app that creates a wi-fi hotspot so my microcontroller (esp32-c3) can connect to it. Further, the app should only contain a webview and be able to automatically determinate the IP-adres of the microcontroller so there can be established a Websocket connection to receive sensor data.
After much frustration setting up the IDE, I finally managed to build a simple app and and run it on my phone. My problem is that I always get a failure with reason code 0 (WifiP2pManager.ERROR) after creating a group, which is according to the documentation an internal error. I've tested this on multiple phones (Android 12 and 13) with the same result.
What I noticed is that there are barley examples available covering this topic. Am i making a mistake and is it possible to find out the detailed error message instead of seeing just htis generic error code?
This whole platform is difficult and frustrating. Can someone help me out? It must definitely be possible to create this on my phone, because with the app PdaNet+ I'm able to create a wi-fi direct hotpot that works.
public class MainActivity extends AppCompatActivity implements WifiP2pManager.ChannelListener, WifiP2pManager.ActionListener {
private final IntentFilter intentFilter = new IntentFilter();
private TextView tv1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = this.findViewById(R.id.tv1);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
WifiP2pManager manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
WifiP2pManager.Channel channel = manager.initialize(this, getMainLooper(), this);
manager.createGroup(channel, this);
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
tv1.append("\n" + action);
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) {
tv1.append("\nWifi P2P is enabled");
} else {
tv1.append("\nWifi P2P is disabled");
}
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
tv1.append("\nCall WifiP2pManager.requestPeers() to get a list of current peers");
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
tv1.append("\nRespond to new connection or disconnections");
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
tv1.append("\nRespond to this device's wifi state changing");
}
}
};
registerReceiver(receiver, intentFilter);
}
#Override
public void onSuccess() {
tv1.append("\nGroup created successfully");
}
#Override
public void onFailure(int reason) {
tv1.append("\nFailed to create group (reason "+reason+")");
}
#Override
public void onChannelDisconnected() {
tv1.append("\nonChannelDisconnected");
}
}
Manifest:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
I finally solved the problem: it turned out the location permission was blocked. After giving access, the hotspot could get created.
I am building a Lost Device Finder app and want to be able to turn on GPS programmatically.
I am able to get Modify System Settings permission, but when I try to turn on GPS, Permission Denied exception is thrown.
The following is my Code:-
if (!Settings.System.canWrite(getBaseContext())) {
startActivityForResult(new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS).setData(Uri.parse(String.format("package:%s", getPackageName()))), request_code);
}
else{
turnGpsOn(getBaseContext());
}
private void turnGpsOn (Context context) {
String beforeEnable = Settings.Secure.getString(context.getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
String newSet = String.format ("%s,%s",
beforeEnable,
LocationManager.GPS_PROVIDER);
try {
Settings.Secure.putString (context.getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
newSet);
} catch(Exception e) {}
}
And I have defined permissions in Manifest like this,
<uses-permission android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"
tools:ignore="ProtectedPermissions" />
My device is not rooted but I think it can be done as the "PowerShade" app requires Modify System Settings Permission in order to do it.
What's the difference between Action CONNECTION_STATE_CHANGED and STATE_CHANGED in Android Bluetooth Receiver ?
else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED .equals(action)) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
BluetoothAdapter.STATE_DISCONNECTED);
if (state == BluetoothAdapter.STATE_CONNECTED) {
//nothing
} else {
}
} else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
if (state == BluetoothAdapter.STATE_OFF) {
}
}
According to the docs the difference is the following:
ACTION_CONNECTION_STATE_CHANGED
Intent used to broadcast the change in connection state of the local Bluetooth adapter to a profile of the remote device.
ACTION_STATE_CHANGED
The state of the local Bluetooth adapter has been changed. For example, Bluetooth has been turned on or off.
In other words one Intent is for changes in the connection state and the other one for state changes of the Bluetooth adapter itself.
EDIT:
To detect if a device moves in and out of range you need to use the following intents:
ACTION_ACL_CONNECTED: link to documentation
ACTION_ACL_DISCONNECTED: link to documentation
For both of those you need the normal BLUETOOTH permission and the BLUETOOTH_ADMIN permission:
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
The intent filter for your BroadcastReceiver would look something like this:
<intent-filter>
<action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
</intent-filter>
Here is the general documentation about BluetoothDevice.
I'm trying to have my app's service listen for Bluetooth connection and disconnection attempts, so I can dynamically check/support Bluetooth tethering network communication.
First I have two Samsung S4s (running CyanogenMod 10.2, which is Android 4.3.1 based) which I can pair just fine. If I set one device to Bluetooth tether, when the other connects, a new bt-pan network interface is created and DHCP is used to assign IPs. I confirmed this using iwconfig and ifconfig in shell.
I have the following perms in my app: (there's more, I'm just pointing out the BT perms I added)
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
Here's my Service's onCreate where I set my IntentFilters: (note I've got Toasts here, but I was working with Logging originally)
#Override
public void onCreate() {
super.onCreate();
...
this.mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
mLocalBroadcastManager.registerReceiver(mMessageReceiver, filter);
}
Here's my BroadcastReceiver implementation:
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(BluetoothDevice.ACTION_FOUND)) {
Toast.makeText(getApplicationContext(), "BT found", Toast.LENGTH_SHORT).show();
} else if(action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
Toast.makeText(getApplicationContext(), "BT Connected",
} else if(action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
Toast.makeText(getApplicationContext(), "BT Disconnected", Toast.LENGTH_SHORT).show();
} else
Toast.makeText(getApplicationContext(), "BT Disconnect requested", Toast.LENGTH_SHORT).show();
}
}
}
Now, when I turn Bluetooth off/on, connect/disconnect to a paired device, nothing fires. I've payed around with the devices from both ends. Nothing is broadcast.
Anyone have a suggestion? I really need to receive these bluetooth events. Please don't point to another post/site with the same perms and intent filters. Thanks.
I have a very similar code which works, the only major difference i found was this:
mLocalBroadcastManager.registerReceiver(mMessageReceiver, filter);
i beleive that registerReceiver should be called from the context you want to get intents to.
try calling the method from this. i.e remove the mLocalBroadcastManager like:
registerReceiver(mMessageReceiver, filter);
If you Register the Receiver on the Manifest instead of the Activity, you can receive broadcasts even if you do not have the app opened, you can do this:
<receiver android:name=".BluetoothReceiver" >
<intent-filter>
<action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
<action android:name="android.bluetooth.device.action.BOND_STATE_CHANGED" />
</intent-filter>
</receiver>
I want to receive notification when Mobile network connection is lost or received. Through following code, I can receive notification for Wi-Fi (Data) connection but not for Mobile (Voice) connection.
Manifest :
<uses-permission android:name="android.permission.ACCESS_NETWORK_ST ATE"/>
<application android:icon="#drawable/icon" android:label="#string/app_name">
<receiver android:name=".notifier">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE " />
</intent-filter>
</receiver>
</application>
Java :
public class notifier extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast toast = Toast.makeText(context, "Network Changed !!", Toast.LENGTH_LONG);
toast.show();
}
}
Please tell me, how can I receive notification for Mobile Network (Voice).
Pseudocode!!
PhoneStateListener myListener = new PhoneStateListener() {
#Override
public void onServiceStateChanged (ServiceState serviceState) {
// Handle different service states here.
}
};
((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE))
.listen(myListener, PhoneStateListener.LISTEN_SERVICE_STATE);
http://developer.android.com/reference/android/telephony/TelephonyManager.html#listen(android.telephony.PhoneStateListener, int)
Check the permission in the AndroidManifest.xml, first.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission>
And try this code below.
ConnectivityManager manager = (ConnectivityManager)appContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mobile = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if(mobile.isConnected()) {
//Do Sth.
}
If this is not work, check your phone's brand. If the phone's developer blocked some codes or not implement some code, it doesn't work. What is your phone?