Android gRPC request throwing UNAVAILABLE exception - android

I am attempting to send a request from an android application to my laptop. This is currently resulting in the following exception being thrown.
Status{code=UNAVAILABLE, description=null, cause=java.net.ConnectException: failed to connect to /192.168.1.35 (port 8445) from /:: (port 55176): connect failed: ETIMEDOUT (Connection timed out)
at libcore.io.IoBridge.connect(IoBridge.java:143)
at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:142)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
at java.net.Socket.connect(Socket.java:621)
at java.net.Socket.connect(Socket.java:570)
at java.net.Socket.<init>(Socket.java:450)
at java.net.Socket.<init>(Socket.java:250)
at javax.net.DefaultSocketFactory.createSocket(SocketFactory.java:285)
at io.grpc.okhttp.OkHttpClientTransport$3.run(OkHttpClientTransport.java:527)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: android.system.ErrnoException: connect failed: ETIMEDOUT (Connection timed out)
at libcore.io.Linux.connect(Native Method)
at libcore.io.ForwardingOs.connect(ForwardingOs.java:95)
at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:136)
at libcore.io.ForwardingOs.connect(ForwardingOs.java:95)
at libcore.io.IoBridge.connectErrno(IoBridge.java:157)
at libcore.io.IoBridge.connect(IoBridge.java:135)
... 15 more
}
I have confirmed that the IP and the port are correct. Below I have attached both the server proto file and the apps proto file, along with the execution from the app.
Server Proto file
syntax = "proto3";
option go_package = "bitbucket.org/bthreesoftware/restaurant-libs/proto/WaiterProto";
package WaiterProto;
service WaiterService {
rpc UserLogin(LoginRequest) returns (LoginResponse) {}
rpc GetMenuItems(MenuRequest) returns (MenuResponse) {}
}
message LoginRequest {
string username = 1;
string password = 2;
}
message LoginResponse {
Restaurant restaurant = 1;
User user = 2;
string jwt = 3;
}
message User {
int64 id = 1;
int64 restaurantId = 2;
string username = 3;
string firstName = 4;
string surname = 5;
string password = 6;
string lastLogin = 7;
}
message Restaurant {
int64 id = 1;
string name = 2;
string addressLineOne = 3;
string addressLineTwo = 4;
string postCode = 5;
string contactNumber = 6;
bool active = 7;
}
message MenuRequest {
int64 restaurantId = 1;
}
message MenuResponse {
int64 id = 1;
int64 restaurantId = 2;
string name = 3;
repeated MenuItem menuItems = 4;
}
message MenuItem {
int64 id = 1;
string name = 2;
string description = 3;
float price = 4;
}
Apps Proto file
syntax = "proto3";
option java_multiple_files = true;
option java_package = "uk.bthree.restaurant.WaiterProto";
option java_outer_classname = "WaiterProto";
option go_package = "bitbucket.org/bthreesoftware/restaurant-libs/proto/WaiterProto";
package WaiterProto;
service WaiterService {
rpc UserLogin(LoginRequest) returns (LoginResponse) {}
rpc GetMenuItems(MenuRequest) returns (MenuResponse) {}
}
message LoginRequest {
string username = 1;
string password = 2;
}
message LoginResponse {
Restaurant restaurant = 1;
User user = 2;
string jwt = 3;
}
message User {
int64 id = 1;
int64 restaurantId = 2;
string username = 3;
string firstName = 4;
string surname = 5;
string password = 6;
string lastLogin = 7;
}
message Restaurant {
int64 id = 1;
string name = 2;
string addressLineOne = 3;
string addressLineTwo = 4;
string postCode = 5;
string contactNumber = 6;
bool active = 7;
}
message MenuRequest {
int64 restaurantId = 1;
}
message MenuResponse {
int64 id = 1;
int64 restaurantId = 2;
string name = 3;
repeated MenuItem menuItems = 4;
}
message MenuItem {
int64 id = 1;
string name = 2;
string description = 3;
float price = 4;
}
App execution
fun runTask(vararg params: Void) {
executor.execute {
Log.i(TAG, "runTask: sending request")
try {
val channel: Channel = ManagedChannelBuilder.forAddress("192.168.1.35", 8445).usePlaintext().build()
val stub = WaiterServiceGrpc.newBlockingStub(channel)
val builder = LoginRequest.newBuilder()
builder.username = this.username
builder.password = this.password
val request = builder.build()
val response = stub.userLogin(request)
val mobileSession: MobileSession = mapResponse(response)
Log.i(TAG, "runTask: $mobileSession")
} catch (exception: Exception) {
Log.e(TAG, "runTask: ${exception.message}")
}
handler.post {
Log.i(TAG, "runTask: complete")
}
}
}
Android manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="uk.bthree.restaurant.waiter">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application android:allowBackup="true"
android:fullBackupContent="#xml/backup_rules"
tools:targetApi="31"
android:dataExtractionRules="#xml/data_extraction_rules"
android:label="#string/app_name"
android:icon="#mipmap/ic_bthree_logo"
android:roundIcon="#mipmap/ic_bthree_logo_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
<activity android:name=".LoginActivity"
android:exported="true"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
All help is appreciated. Thanks!
I have attempted to run this on different ports. I have also dropped all firewalls on my laptop to rule out that.
I am also using android 23 and above for the app.

Related

Getting Mac Address on Marshmallow In Xamarin

I've been trying several things to get the MAC on Android 6.0 with no success ):
I already have this permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
And this is my code:
public string GetMacAdress(Context context)
{
string mac = GetMacAddressLegacy(context);
if (mac == "02:00:00:00:00:00")
{
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface nif in interfaces)
{
if (!nif.Name.ToLower().Contains("wlan")) continue;
var physicalAddress = nif.GetPhysicalAddress();
byte[] macBytes = physicalAddress.GetAddressBytes();
if (macBytes == null) continue;
string macString = BitConverter.ToString(macBytes);
if (!string.IsNullOrWhiteSpace(macString)) mac = macString.Trim().ToUpper().Replace("-", ":");
}
}
return mac;
}
[Obsolete]
public string GetMacAddressLegacy(Context context)
{
string toReturn = "02:00:00:00:00:00";
if (DetectWifiNetwork())
{
isConected = true;
var telephonyMgr = (WifiManager)context.GetSystemService(Context.WifiService);
toReturn = telephonyMgr.ConnectionInfo.MacAddress;
if (!string.IsNullOrWhiteSpace(toReturn)) toReturn = toReturn.Trim().ToUpper();
}
else
{
isConected = false;
}
return toReturn;
}
But this line: byte[] macBytes = physicalAddress.GetAddressBytes(); returns an empty array.
Anyone could solve this?
Try to use this method
public static string getMacAddress()
{
string macAddress = string.Empty;
var all = Collections.List(Java.Net.NetworkInterface.NetworkInterfaces);
foreach (var interfaces in all)
{
if (!(interfaces as Java.Net.NetworkInterface).Name.Contains("wlan0")) continue;
var macBytes = (interfaces as
Java.Net.NetworkInterface).GetHardwareAddress();
if (macBytes == null) continue;
var sb = new System.Text.StringBuilder();
foreach (var b in macBytes)
{
string convertedByte = string.Empty;
convertedByte = (b & 0xFF).ToString("X2") + ":";
if(convertedByte.Length == 1)
{
convertedByte.Insert(0, "0");
}
sb.Append(convertedByte);
}
macAddress = sb.ToString().Remove(sb.Length - 1);
return macAddress;
}
return "02:00:00:00:00:00";
}
Try using this code:
public string GetMacAdress(Context context)
{
string mac = GetMacAddressLegacy(context);
if (mac == "02:00:00:00:00:00")
{
var interfaces = Java.Net.NetworkInterface.NetworkInterfaces;
foreach (var nif in interfaces)
{
if (!nif.Name.ToLower().Contains("wlan")) continue;
byte[] macBytes = nif.GetHardwareAddress();
string macString = BitConverter.ToString(macBytes);
if (!string.IsNullOrWhiteSpace(macString))
mac = macString.Trim().ToUpper().Replace("-", ":");
}
}
return mac;
}
Well using this is enough to make it work:
Permissions:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Code:
WifiManager wManager = (WifiManager)GetSystemService(Context.WifiService);
WifiInfo wInfo = wManager.ConnectionInfo;
button.Text = wInfo.MacAddress;
Are you testing on a real device or on a simulator?

How to check permission is granted for a directory path and won't thorow EACCES error?

I have a photo editing android app that users can choose the output directory of the the result photos. Problem is Google made a change on sdcard write permission with the KITKAT version and devices with Android KITKAT version won't allow apps to write secondary sdcards. Now I need to check if the choosen directory by user has granted the permission and won't throw EACCES error. I am already checking canRead and canWrite but these won't help. Could you please tell me how can I check if the choosen directory won't throw EACCES. My only solution is trying to write a file in a try catch, however I am hoping there is better way to do it.
[update k3b 2016-09-19]
i tried this on my android-4.4 but without success
Uri uri = Uri.fromFile(file);
int permissionCode =
context.checkCallingOrSelfUriPermission(uri,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
if (permissionCode == PackageManager.PERMISSION_DENIED) {
// on my android-4.4 i always get PERMISSION_DENIED even
// if i can overwrite the file
return false;
}
try {
Process p = new ProcessBuilder("ls", "-l", "-s", dir.getCanonicalPath()).start();
String line;
ArrayList<String> lineOut = new ArrayList<>();
BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((line = error.readLine()) != null) {
Log.e(TAG, "ls error = "+line);
}
error.close();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
lineOut.add(line);
}
input.close();
String[] strings = lineOut.toArray(new String[]{});
List<FilesLS.FileEntry> fileEntries = FilesLS.processNewLines(strings);
for(FilesLS.FileEntry file : fileEntries){
Log.d(TAG, file.name +" = " + file.permissions);
}
} catch (IOException e) {
e.printStackTrace();
}
And some edits to this class
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class FilesLS {
/**
* Entry type: File
*/
public static final int TYPE_FILE = 0;
/**
* Entry type: Directory
*/
public static final int TYPE_DIRECTORY = 1;
/**
* Entry type: Directory Link
*/
public static final int TYPE_DIRECTORY_LINK = 2;
/**
* Entry type: Block
*/
public static final int TYPE_BLOCK = 3;
/**
* Entry type: Character
*/
public static final int TYPE_CHARACTER = 4;
/**
* Entry type: Link
*/
public static final int TYPE_LINK = 5;
/**
* Entry type: Socket
*/
public static final int TYPE_SOCKET = 6;
/**
* Entry type: FIFO
*/
public static final int TYPE_FIFO = 7;
/**
* Entry type: Other
*/
public static final int TYPE_OTHER = 8;
/**
* Device side file separator.
*/
public static final String FILE_SEPARATOR = "/"; //$NON-NLS-1$
/**
* Regexp pattern to parse the result from ls.
*/
private static Pattern sLsPattern = Pattern
.compile("^([bcdlsp-][-r][-w][-xsS][-r][-w][-xsS][-r][-w][-xstST])\\s+(\\S+)\\s+ (\\S+)\\s+(\\d{4}-\\d\\d-\\d\\d)\\s+(\\d\\d:\\d\\d)\\s+(.*)$"); //$NON-NLS-1$ \s+([\d\s,]*)
public static List<FileEntry> processNewLines(String[] lines) {
List<FileEntry> listOfFiles = new ArrayList<FileEntry>();
for (String line : lines) {
// no need to handle empty lines.
if (line.length() == 0) {
continue;
}
// run the line through the regexp
Matcher m = sLsPattern.matcher(line);
if (m.matches() == false) {
continue;
}
// get the name
String name = m.group(6);
// get the rest of the groups
String permissions = m.group(1);
String owner = m.group(2);
String group = m.group(3);
// String size = m.group(4);
String date = m.group(4);
String time = m.group(5);
String info = null;
// and the type
int objectType = TYPE_OTHER;
switch (permissions.charAt(0)) {
case '-':
objectType = TYPE_FILE;
break;
case 'b':
objectType = TYPE_BLOCK;
break;
case 'c':
objectType = TYPE_CHARACTER;
break;
case 'd':
objectType = TYPE_DIRECTORY;
break;
case 'l':
objectType = TYPE_LINK;
break;
case 's':
objectType = TYPE_SOCKET;
break;
case 'p':
objectType = TYPE_FIFO;
break;
}
// now check what we may be linking to
if (objectType == TYPE_LINK) {
String[] segments = name.split("\\s->\\s"); //$NON-NLS-1$
// we should have 2 segments
if (segments.length == 2) {
// update the entry name to not contain the link
name = segments[0];
// and the link name
info = segments[1];
// now get the path to the link
String[] pathSegments = info.split(FILE_SEPARATOR);
if (pathSegments.length == 1) {
// the link is to something in the same directory,
// unless the link is ..
if ("..".equals(pathSegments[0])) { //$NON-NLS-1$
// set the type and we're done.
objectType = TYPE_DIRECTORY_LINK;
} else {
// either we found the object already
// or we'll find it later.
}
}
}
// add an arrow in front to specify it's a link.
info = "-> " + info; //$NON-NLS-1$;
}
FileEntry entry = new FileEntry();
entry.permissions = permissions;
entry.name = name;
// entry.size = size;
entry.date = date;
entry.time = time;
entry.owner = owner;
entry.group = group;
if (objectType == TYPE_LINK) {
entry.info = info;
}
listOfFiles.add(entry);
}
return listOfFiles;
}
public final static class FileEntry {
String name;
String info;
String permissions;
String size;
String date;
String time;
String owner;
String group;
int type;
}
}
Add the permission(s) you need to the array:
private static final int REQUEST_CODE_PERMISSION = 2;
String[] mPermission = {
Manifest.permission.INTERNET,
Manifest.permission.CHANGE_WIFI_STATE,
Manifest.permission.CHANGE_NETWORK_STATE,
Manifest.permission.ACCESS_WIFI_STATE
};
Add this to onCreate or where you want it to be:
try {
if (
ActivityCompat.checkSelfPermission(this, mPermission[0])
!= MockPackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, mPermission[1])
!= MockPackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, mPermission[2])
!= MockPackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, mPermission[3])
!= MockPackageManager.PERMISSION_GRANTED
) {
Log.e("TAGTAG", "DENIED");
ActivityCompat.requestPermissions(
this, mPermission, REQUEST_CODE_PERMISSION
);
// 'Will execute recursively if any of the permissions was not granted.
} else {
Log.e("TAGTAG", "GRANTED");
}
} catch (Exception e) {
e.printStackTrace();
}
Don't forget to declare the permissions in AndroidManifest.xml.

Android: extracting wifi capabilities with contains

I'm trying to know the type security of the scanned networks, and i'm getting result like this :
[WPA-PSK-TKIP+CCMP][WPA2-PSK-TKIP+CCMP][ESS]
[WPA2-PSK-CCMP][WPS][ESS]
And i used this code :
// Constants used for different security types
public static final String WPA = "WPA";
public static final String WEP = "WEP";
public static final String WPA2 = "WPA2";
public static final String OPEN = "Open";
final String cap = results.get(position).capabilities;
final String[] securityModes = { WEP, WPA, WPA2 };
for (int i = securityModes.length - 1; i >= 0; i--) {
if (cap.toLowerCase().contains(securityModes[i].toLowerCase())) {
textView5.setText(securityModes[i] );
}
else
textView5.setText(OPEN );
}
But i'm just obtaining in textViex :OPEN or WEP , i don't get WPA or WPA2, what could be the problem ?
Try this function :
public String security(String cap){
if (cap.toLowerCase().contains(WEP.toLowerCase()))
{return WEP ;}
else if (cap.toLowerCase().contains(WPA2.toLowerCase()))
{return WPA2;}
else if (cap.toLowerCase().contains(WPA.toLowerCase()))
{return WPA;}
else
return OPEN;
}

Checking miracast compatible devices using android app

How can I search for Miracast compatible devices (may be using WiFi Direct) in android?
I just got to know that DisplayManager and Presentation class in Android 4.2 help in presentation & miracast. But is there any way I can check if the other device is Miracast compatible / search Miracast sink?
Thanks
Smitha
android framework source codes shows how to search miracast sink devices.
basically using WiFi Direct devices search API,
discoverPeers -> requestPeers -> isWifiDisplay & isPrimarySinkDeviceType
private static boolean isWifiDisplay(WifiP2pDevice device) {
return device.wfdInfo != null
&& device.wfdInfo.isWfdEnabled()
&& isPrimarySinkDeviceType(device.wfdInfo.getDeviceType());
}
private static boolean isPrimarySinkDeviceType(int deviceType) {
return deviceType == WifiP2pWfdInfo.PRIMARY_SINK
|| deviceType == WifiP2pWfdInfo.SOURCE_OR_PRIMARY_SINK;
}
https://github.com/kensuke/How-to-Miracast-on-AOSP/wiki/wfd_scan
WifiP2pWfdInfo defined four device types,
public static final int WFD_SOURCE = 0;
public static final int PRIMARY_SINK = 1;
public static final int SECONDARY_SINK = 2;
public static final int SOURCE_OR_PRIMARY_SINK = 3;
http s://android.googlesource.com/platform/frameworks/base/+/master/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
if you don't familiar with wifi direct, maybe my app is useful for using wifi direct api.
http s://github.com/kensuke/WiFiDirectTestApp
ADD: 2014/02/24 - parse toString output String for recognize Miracast devices Source or Sink
Wi-Fi Direct API requestPeers() callback to onPeersAvailable(), this method's parameter WifiP2pDeviceList has near by P2p devices that is a list of WifiP2pDevice instances, WifiP2pDevice has one device Wi-fi Direct information including Miracast information(wfd..) and device into can get uses WifiP2pDevice.toString() method.
Search "WFD DeviceInfo: XXX" String, XXX is a numerical value, masked "0x03" (see WifiP2pWfdInfo.java), after masked we get 0-3. That value defined SOURCE or SINK, see WifiP2pWfdInfo.java constants).
private static final int WFD_SOURCE = 0;
private static final int PRIMARY_SINK = 1;
private static final int SECONDARY_SINK = 2;
private static final int SOURCE_OR_PRIMARY_SINK = 3;
This very duty way can using on non rooted device, general app.
Sample of WifiP2pDevice.toString() returned value
"Device: ZTS1145
deviceAddress: 7a:e8:b6:f6:4d:74
primary type: 10-0050F204-5
secondary type: null
wps: 392
grpcapab: 0
devcapab: 33
status: 3
wfdInfo: WFD enabled: trueWFD DeviceInfo: 273
WFD CtrlPort: 7236
WFD MaxThroughput: 10"
// callback method of requestPeers();
public void onPeersAvailable(WifiP2pDeviceList peers) {
List<WifiP2pDevice> devs = new ArrayList<WifiP2pDevice>(peers.getDeviceList());
for (int i = 0; i < devs.size(); i++) {
WifiP2pDevice dev = devs.get(i);
boolean src = isWifiDisplaySource(dev);
boolean sink = isWifiDisplaySink(dev);
Log.d(TAG, dev.deviceName + " isSource[" + src + "] isSink[" + sink + "]");
}
}
private static final int WFD_DISABLED = -1;
private static final int WFD_SOURCE = 0;
private static final int PRIMARY_SINK = 1;
private static final int SECONDARY_SINK = 2;
private static final int SOURCE_OR_PRIMARY_SINK = 3;
private static final int DEVICE_TYPE = 0x3;
private int getWFDDeviceInfoFromString(String devStr) {
if (devStr == null) {
return WFD_DISABLED;
}
boolean wfd = false;
for (String line : devStr.split("\n")) {
// start self parsing...
// TODO: sprintf parse is more easy
// search "WFD enabled: [true|false]"
if (!line.matches(".*WFD enabled:.*")) {
continue;
}
String[] tokens = line.split(":");
int toks = tokens.length;
for (int i = 0; i < toks - 1; i++) {
if (!tokens[i].contains("WFD enabled")) {
continue;
}
String tok = tokens[i + 1].replaceAll("\\s", ""); // delete white space
if (tok.startsWith("true")) {
wfd = true;
break;
}
// why didn't use .equals() instead of .contains() and .startsWith() ? because
// 1) "wfdInfo: WFD enabled: trueWFD DeviceInfo: 273" // inputed string
// 2) "(wfdInfo):( WFD enabled):( trueWFD DeviceInfo):( 273)" // : splited string
// 3) "( trueWFD DeviceInfo)" => "trueWFD DeviceInfo" // white space deleted
}
}
if (!wfd) {
return WFD_DISABLED;
}
for (String line : devStr.split("\n")) {
// search "WFD DeviceInfo: \d+"
if (!line.matches(".*WFD DeviceInfo:.*")) {
continue;
}
String[] tokens = line.split(":");
int toks = tokens.length;
for (int i = 0; i < toks - 1; i++) {
if (!tokens[i].contains("WFD DeviceInfo")) {
continue;
}
String tok = tokens[i + 1].replaceAll("\\s", "");
int deviceInfo = Integer.parseInt(tok);
Log.d(TAG, "line[" + line + "] DeviceInfo[" + deviceInfo + "] masked[" + (deviceInfo & DEVICE_TYPE) + "]");
return deviceInfo;
}
}
return WFD_DISABLED;
}
private boolean isWifiDisplaySource(WifiP2pDevice dev) {
if (dev == null) {
return false;
}
int deviceInfo = getWFDDeviceInfoFromString(dev.toString());
if (deviceInfo == WFD_DISABLED) {
return false;
}
int deviceType = deviceInfo & DEVICE_TYPE; // masked
return deviceType == WFD_SOURCE || deviceType == SOURCE_OR_PRIMARY_SINK;
}
private boolean isWifiDisplaySink(WifiP2pDevice dev) {
if (dev == null) {
return false;
}
int deviceInfo = getWFDDeviceInfoFromString(dev.toString());
if (deviceInfo == WFD_DISABLED) {
return false;
}
int deviceType = deviceInfo & DEVICE_TYPE; // masked
return deviceType == PRIMARY_SINK || deviceType == SOURCE_OR_PRIMARY_SINK;
}

NFC tag reading problem

This is my code to read the NFC tag. Why authentication is failing always? It is detecting the card but not reading the data. Could you please help me? Why if block is not executing? Where i'am wrong?
void resolveIntent(Intent intent)
{
String action = intent.getAction();
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action))
{
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
MifareClassic mfc = MifareClassic.get(tagFromIntent);
byte[] data;
try
{
mfc.connect();
boolean auth = false;
String cardData = "";
int sectorCount = mfc.getSectorCount();
int blockCount = 0;
int blockIndex = 0;
for(int j = 0; j < sectorCount; j++)
{
auth = mfc.authenticateSectorWithKeyA(j, MifareClassic.KEY_DEFAULT);
if(auth)
{
blockCount = mfc.getBlockCountInSector(j);
blockIndex = 0;
for(int i = 0; i < blockCount; i++)
{
blockIndex = mfc.sectorToBlock(j);
data = mfc.readBlock(blockIndex);
cardData = cardData + getHexString(data, data.length);
blockIndex++;
}
}
else
{
// Authentication failed - Handle it
showAlert(AUTH); //this alert message is executing always
}
}
Toast.makeText(getApplicationContext(), cardData, Toast.LENGTH_LONG).show();
}
catch (IOException e)
{
Log.e(TAG, e.getLocalizedMessage());
showAlert(NETWORK);
}
}//end of if
}// End of method
Since it is not a new tag, and has been written by another app, I would suspect that the authentication key has changed. You are using the default keys, but the other app may have changed them. The older Nokia phones do this all the time. In that case instead of using MifareClasic.KEY_DEFAULT, you will need to figure out what the new key is for keyA
Try to use MifareClassic.KEY_NFC_FORUM as the keyA.

Categories

Resources