Android GCM not working after Lollipop update on device - java

I implemented GCM for push notifications like stated in the Android Guide (https://developer.android.com/google/gcm/client.html) in one of my apps. The app and notifications are working fine on Kitkat and Lollipop.
But lastly I became some mails from users that upgraded their phones from to Lollipop. With that the notifications will not be displayed anymore. Only solution so far is to remove the app and reinstall it from the appstore.
Did someone face a similar problem and if so, did you find a solution to fix it?

This is a GCM ID issue. Try using Thread.sleep and retry for a number of times, till the GCM ID is recieved.
int noOfAttemptsAllowed = 5; // Number of Retries allowed
int noOfAttempts = 0; // Number of tries done
bool stopFetching = false; // Flag to denote if it has to be retried or not
String regId = "";
while (!stopFetching)
{
noOfAttempts ++;
GCMRegistrar.register(getApplicationContext(), "XXXX_SOME_KEY_XXXX");
try
{
// Leave some time here for the register to be
// registered before going to the next line
Thread.sleep(2000); // Set this timing based on trial.
} catch (InterruptedException e) {
e.printStackTrace();
}
try
{
// Get the registration ID
regId = GCMRegistrar.getRegistrationId(LoginActivity.this);
} catch (Exception e) {}
if (!regId.isEmpty() || noOfAttempts > noOfAttemptsAllowed)
{
// If registration ID obtained or No Of tries exceeded, stop fetching
stopFetching = true;
}
if (!regId.isEmpty())
{
// If registration ID Obtained, save to shared preferences
saveRegIDToSharedPreferences();
}
}
The Thread.sleep and noOfAttemptsAllowed can be played around with based on your design and other parameters. We had a sleep time of 7000 so that probability of getting registered at first attempt is higher. However, if it fails, the next attempt would consume another 7000ms. This might cause users to think your app is slow. So, play around intelligently with those two values.

Related

How to get button press event from camera

I've got a dental camera and iam try to get windows to press space when the camera button is pressed
I have the OEM software and driver installed, it works perfect, gets the feed and makes a snapshot when camera button is pressed. I need to use another software for the feed and the snapshot, the software gets the feed but doesn't react to camera button, it only reacts to space key press(part of the oem driver), so my way of solving this was getting the device by product id and listening the button press event and remapping it space press.
I am pretty much stuck at this point.
How can I listen on events coming from the device I've got?
public static Device findDCam(){
// Create the libusb context
Context context = new Context();
// Initialize the libusb context
int result = LibUsb.init(context);
if (result < 0)
{
throw new LibUsbException("Unable to initialize libusb", result);
}
// Read the USB device list
DeviceList list = new DeviceList();
result = LibUsb.getDeviceList(context, list);
if (result < 0)
{
throw new LibUsbException("Unable to get device list", result);
}
try
{
// Iterate over all devices and list them
for (Device device: list)
{
DeviceDescriptor descriptor = new DeviceDescriptor();
result = LibUsb.getDeviceDescriptor(device, descriptor);
if (result < 0)
{
throw new LibUsbException(
"Unable to read device descriptor", result);
}
if(descriptor.idProduct()== -3810){
System.out.println("D cam found");
return device;
}
}
}
finally
{
// Ensure the allocated device list is freed
LibUsb.freeDeviceList(list, true);
}
// Deinitialize the libusb context
LibUsb.exit(context);
return null;
}
I've also thought that maybe it's impossible using usb4java since as far as i understood, if i want to listen on the usb port i need to take control from the driver and then its pointless.
Maybe iam going all wrong and i should use the driver instead?
Or maybe there is an app that can read button presses from a specific device and remap it?
If the camera has a standard driver, this should work through this video capture SDK. To quick test it, run the demo executable included in the package, select the camera in the list, check the "webcam snapshot button" checkbox and start the camera. Then press the camera button to test the snapshot.

Can we open channel without AID and control the power of embedded SE?

We are now developing a payment card with NXP NQ220 (has embedded SE, called eSE) on Android N. The platform is MTK. Now, we can interact with eSE using OMA (using org.simalliance.openmobileapi.jar). It works as expected.
I was wondering if there is any ways to open channel in session without AID? Besides, is there any ways to control the power of eSE(power-on and power-off) and reset eSE in some situations?
My investigation as follows:
About open channel without AID, I have found following sentences in page 16 of Open Mobile API specification V3.
(h)Method: Channel openLogicalChannel(byte[] aid, Byte P2)
Open a logical channel with the SE, selecting the applet represented by the >given AID. If the AID is null, which means no applet is to be selected on >this channel, the default applet is used. It's up to the SE to choose which >logical channel will be used.
However, if we set aid to null in openLogicalChannel(byte[] aid), following exception will be shows. What happens about it? Is the default applet or eSE have problems?
01-30 01:06:39.941 V/SmartcardService( 2587): OpenLogicalChannel Exception: Access Control Enforcer: no APDU access allowed!
01-30 01:06:39.947 E/SeControlClient( 3239): Error occured:
01-30 01:06:39.947 E/SeControlClient( 3239): java.lang.SecurityException: Access Control Enforcer: no APDU access allowed!
01-30 01:06:39.947 E/SeControlClient( 3239): at org.simalliance.openmobileapi.SEService.checkForException(SEService.java:255)
01-30 01:06:39.947 E/SeControlClient( 3239): at org.simalliance.openmobileapi.Session.openLogicalChannel(Session.java:295)
It seems there is no method in OMA to reset eSE. But I found reset() method in INxpNfcAdapterExtras. However, when I use INxpNfcAdapterExtras.reset(), it always return false. Following codes is how we get INxpNfcAdapterExtras.
private INxpNfcAdapterExtras getNxpNfcAdapterExtras() {
if (mNfcAdapter != null) {
try {
INxpNfcAdapter nxpNfcAdapter =
mNfcAdapter.getService().getNxpNfcAdapterInterface();
return nxpNfcAdapter.getNxpNfcAdapterExtrasInterface();
} catch (Exception e) {
Log.e(LOGTAG, "Exception occured:", e);
}
} else {
Log.e(LOGTAG, "Please initialize NfcAdapter first.");
}
return null;
}
About control the power of eSE, is it related to the platform? Can you give me some suggestions? Thank you very much.
Dont known
To access SE functions your application must be execute with owner of android device.
You could check this in : https://github.com/NXPNFCLinux/android_nxp-nci/blob/1d95fe24334fa12c9d9eccd1141f8739972c4288/aosp/packages/apps/Nfc/src/com/android/nfc/NfcService.java
The reset method check permission before:
public boolean reset(String pkg) throws RemoteException {
NfcService.this.enforceNfceeAdminPerm(pkg);
Bundle result;
boolean stat = false;
try {
stat = _nfcEeReset();
result = writeNoException();
} catch (IOException e) {
result = writeEeException(EE_ERROR_IO, e.getMessage());
}
Log.d(TAG,"reset" + stat);
return stat;
}
The check permission method:
public void enforceNfceeAdminPerm(String pkg) {
if (pkg == null) {
throw new SecurityException("caller must pass a package name");
}
NfcPermissions.enforceUserPermissions(mContext);
if (!mNfceeAccessControl.check(Binder.getCallingUid(), pkg)) {
throw new SecurityException(NfceeAccessControl.NFCEE_ACCESS_PATH +
" denies NFCEE access to " + pkg);
}
if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
throw new SecurityException("only the owner is allowed to call SE APIs");
}
}
To execute your app with device owner, you could follow my anwser here:
Device Admin API, how to be a device owner?
I'm not sure about what you mean "control the power of eSE". If it's on/off eSE, then eSE is integrated with NFC chip so if you disable NFC in Android eSE will be power off.
I have found another way to solve this issue. It used NXP's own class NxpNfcAdapterExtrasService.
1.I still don't know why the exception happens when we open channel use the default Applet(without AID). But, with the method in NxpNfcAdapterExtrasService, we can establish connection with eSE.
2.About the second question. The codes is right but the way of how to use INxpNfcAdapterExtras.reset() is wrong. This method will return true only when you do something with eSE. Like transmit and execute APDU commands. So you can use this method when you want to disconnect the connection with eSE.
3.About the third question, I don't know whether the openUicc()/closeUicc() method can control the eSE power. But, it seems this two method works as expected.

How to run a method when app is not active in Android

I want my app to do some tasks no matter if the app is currently active or at the background.
What I have done is:
private static void myCurrMethod() {
boolean checkIn = false;
if (1==1) {
checkIn = true;
}
// Sending message
Time now = new Time();
now.setToNow();
final String res = "Time is " + now.hour + ":" + now.minute + ":"
+ now.second + " stat " + checkIn;
new Thread(new Runnable() {
public void run() {
try {
Socket clientSocket = new Socket("xx.xx.xx.xx", 6790);
DataOutputStream outToServer = new DataOutputStream(
clientSocket.getOutputStream());
outToServer.writeBytes(res + '\n');
clientSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
// End of it
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
myCurrMethod();
}
}, (TIME_INTERVAL_WIFI_EN * MS_PER_MIN));
}
The socket part is to check how often is message being sent.
I have tried this when I am using another app. It works completely fine, if my phone is connected to my computer which has ADT installed. However the problem is, it does not work properly, or works for few times when my phone is not connected to my computer.
I found on the internet that there are ways to run, but they all seem like running things on the background while app is active. Also there are so many things on the internet some people suggest Services, some suggest AsyncTask, some others suggest a way like mine. I am confused, what is the best way to do this?
Note: I don't really discard this from my app. For instance if my app is not started at all, then it shouldn't work. If my app is removed from app list, then this shouldn't work. Basically what I want is the default behaviour that we could have in old Symbian apps.
Apps do not "close" - they might be killed to free resources when they are not active, but the "recents" list does not mean "active" (it can be on the list and be killed already, or not on the list and still be in an active task stack).
If you want to run things off the UI thread, then use another thread, AsyncTask, etc. They will live as long as your app does and continue to run even if another activity is on the screen.
If you need your process to survive your activity lifecycle or start when your app is not active (or continue running the process even if the activity is killed) then you need a service.
There are many references here on SO to help implement any solution. In your particular case, the connection to the computer - or a charger - may make a difference in how many active tasks Android allows to continue running, so your inactive activity is being killed faster when not connected. You likely need a service to "finish up" whatever processing is expected to occur while the app is inactive or in the background.

Odd InetAddress.isReachable() issue

My work is developing software for network capable cameras for retail enviroments. One of the peices of software my team is developing is a webserver that retrieves various reports generated in HTML by the camera itself (which has its own embedded webserver) and stored on the camera. Our software will then GET these reports from the camera and store it on a central webserver.
While we are fine plugging in the IPs of the cameras into our software, I am developing a simple Java class that will query the network and locate all cameras on the network.
The problem though is that while it runs just fine on my PC, and my coworker's PC, when we attempt to run it on the actual webserver PC that will host our software... it runs, but says every IP in the subnet is offline / unreachable EXCEPT for the gateway IP.
For example, if I run it from my PC or my coworkers PC when plugged into the closed LAN, I get the following active IPs found along with a flag telling me if its a camera or not.
(gateway is 192.168.0.1, subnet mask is 255.255.255.0, which means full range of 256 devices to be looked for)
IP:/192.168.0.1 Active:true Camera:false
IP:/192.168.0.100 Active:true Camera:true <- this is camera 1
IP:/192.168.0.101 Active:true Camera:true <- this is camera 2
IP:/192.168.0.103 Active:true Camera:false <- my PC
IP:/192.168.0.104 Active:true Camera:false <- this is our webserver
But for some reason, when running the same program from the webserver PC, using the same JRE, I only get the following found
IP:/192.168.0.1 Active:true Camera:false
Now my code, instead of enumerating through each IP in order on the main Thread, instead creates a seperate Thread for each IP to be checked and runs them concurrently (else it would take little over 21 minutes to enumerate through the entire IP range at a timeout of 5000ms / IP). The main Thread then re-runs these IP scan threads every 15 seconds over and over.
I have checked that all the threads are running to completion on all the PCs, no exceptions are being thrown. Even verified that none of the threads are getting stuck. Each Thread takes about 5001 to 5050ms from start to complete, and those Threads that have an active IP finish sooner (>5000ms), so I know that its correctly waiting the full 5000ms in the ipAddr.isReachable(5000) method.
Me and my coworker are stumped at this point while it seems to reach those active IPs fine when run on our PCs, yet getting no response from the webserver PC???
We have ruled out firewall issues, admin access issues, etc.. The only difference is that our webserver is Embedded Win XP, and our PCs are Windows 7.
This has us stumped. Any ideas why?
Below is the code that is running each IP Thread:
public void CheckIP() {
new Thread() {
#Override
public void run() {
try {
isActive = ipAddr.isReachable(5000);
if (isActive) {
if (!isCamera) {
isCamera = new IpHttpManager().GetResponse(ipAddr.toString());
}
} else {
isCamera = false;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
EDIT: Here is the code that builds each IP to check after determining the range based on gateway and subnet...
for(int i=subMin; i<=subMax; i++) {
byte[] ip = new byte[] {(byte)oct[0],(byte)oct[1],(byte)oct[2],(byte)i};
try {
scanners[subCount] = new IpScan(InetAddress.getByAddress(ip));
subCount++;
} catch (UnknownHostException e) {
e.printStackTrace();
}}
Thanks everyone, but I never did figure out or pinpoint why this oddity was happening. Everything I checked for was not the cause, so this question can be closed.
In any case, I ended up working around it completely. Instead of using InetAddress, I just went native and built my own ICMP ping class instead, via JNA, invoking Windows libraries IPHLPAPI.DLL and WSOCK32.DLL. Here is what I used...
public interface InetAddr extends StdCallLibrary {
InetAddr INSTANCE = (InetAddr)
Native.loadLibrary("wsock32.dll", InetAddr.class);
ULONG inet_addr(String cp); //in_addr creator. Creates the in_addr C struct used below
}
public interface IcmpEcho extends StdCallLibrary {
IcmpEcho INSTANCE = (IcmpEcho)
Native.loadLibrary("iphlpapi.dll", IcmpEcho.class);
int IcmpSendEcho(
HANDLE IcmpHandle, //Handle to the ICMP
ULONG DestinationAddress, //Destination address, in the form of an in_addr C Struct defaulted to ULONG
Pointer RequestData, //Pointer to the buffer where my Message to be sent is
short RequestSize, //size of the above buffer. sizeof(Message)
byte[] RequestOptions, //OPTIONAL!! Can set this to NULL
Pointer ReplyBuffer, //Pointer to the buffer where the replied echo is written to
int ReplySize, //size of the above buffer. Normally its set to the sizeof(ICMP_ECHO_REPLY), but arbitrarily set it to 256 bytes
int Timeout); //time, as int, for timeout
HANDLE IcmpCreateFile(); //win32 ICMP Handle creator
boolean IcmpCloseHandle(HANDLE IcmpHandle); //win32 ICMP Handle destroyer
}
And then using those to create the following method...
public void SendReply(String ipAddress) {
final IcmpEcho icmpecho = IcmpEcho.INSTANCE;
final InetAddr inetAddr = InetAddr.INSTANCE;
HANDLE icmpHandle = icmpecho.IcmpCreateFile();
byte[] message = new String("thisIsMyMessage!".toCharArray()).getBytes();
Memory messageData = new Memory(32); //In C/C++ this would be: void *messageData = (void*) malloc(message.length);
messageData.write(0, message, 0, message.length); //but ignored the length and set it to 32 bytes instead for now
Pointer requestData = messageData;
Pointer replyBuffer = new Memory(256);
replyBuffer.clear(256);
// HERE IS THE NATIVE CALL!!
reply = icmpecho.IcmpSendEcho(icmpHandle,
inetAddr.inet_addr(ipAddress),
requestData,
(short) 32,
null,
replyBuffer,
256,
timeout);
// NATIVE CALL DONE, CHECK REPLY!!
icmpecho.IcmpCloseHandle(icmpHandle);
}
public boolean IsReachable () {
return (reply > 0);
}
My guess is that your iteration logic to determine the different ip address is based upon different configuration hence your pc's fetches all addresses but your webserver doesn't.
Try adding debug in the logic where you build up the list of ip adresses to check.

SMSLib doesn't receive sms [java edition]

i am trying to use my mobile phone as GSM modem.i use SMSLib for sending and receiving SMS with this modem.
the problem is that when my phone(GSM modem) receive a sms i don't notify with SMSLib.but the code overall is good for example that notifies me when GSM modem receive a call.
my code has not any bug because i only use SMSLib example code for receiving message.
the SMSLib example code is :
public class TestSinaRec
{
public void doIt() throws Exception
{
// Define a list which will hold the read messages.
List<InboundMessage> msgList;
// Create the notification callback method for inbound & status report
// messages.
InboundNotification inboundNotification = new InboundNotification();
// Create the notification callback method for inbound voice calls.
CallNotification callNotification = new CallNotification();
//Create the notification callback method for gateway statuses.
GatewayStatusNotification statusNotification = new GatewayStatusNotification();
OrphanedMessageNotification orphanedMessageNotification = new OrphanedMessageNotification();
try
{
System.out.println("Example: Read messages from a serial gsm modem.");
System.out.println(Library.getLibraryDescription());
System.out.println("Version: " + Library.getLibraryVersion());
// Create the Gateway representing the serial GSM modem.
SerialModemGateway gateway = new SerialModemGateway("modem.com4", "COM4", 115200, "Nokia", " 6303i");
// Set the modem protocol to PDU (alternative is TEXT). PDU is the default, anyway...
gateway.setProtocol(Protocols.PDU);
// Do we want the Gateway to be used for Inbound messages?
gateway.setInbound(true);
// Do we want the Gateway to be used for Outbound messages?
gateway.setOutbound(true);
// Let SMSLib know which is the SIM PIN.
gateway.setSimPin("0444");
// Set up the notification methods.
Service.getInstance().setInboundMessageNotification(inboundNotification);
Service.getInstance().setCallNotification(callNotification);
Service.getInstance().setGatewayStatusNotification(statusNotification);
Service.getInstance().setOrphanedMessageNotification(orphanedMessageNotification);
// Add the Gateway to the Service object.
Service.getInstance().addGateway(gateway);
// Similarly, you may define as many Gateway objects, representing
// various GSM modems, add them in the Service object and control all of them.
// Start! (i.e. connect to all defined Gateways)
Service.getInstance().startService();
// Printout some general information about the modem.
System.out.println();
System.out.println("Modem Information:");
System.out.println(" Manufacturer: " + gateway.getManufacturer());
System.out.println(" Model: " + gateway.getModel());
System.out.println(" Serial No: " + gateway.getSerialNo());
System.out.println(" SIM IMSI: " + gateway.getImsi());
System.out.println(" Signal Level: " + gateway.getSignalLevel() + " dBm");
System.out.println(" Battery Level: " + gateway.getBatteryLevel() + "%");
System.out.println();
// In case you work with encrypted messages, its a good time to declare your keys.
// Create a new AES Key with a known key value.
// Register it in KeyManager in order to keep it active. SMSLib will then automatically
// encrypt / decrypt all messages send to / received from this number.
//Service.getInstance().getKeyManager().registerKey("+306948494037", new AESKey(new SecretKeySpec("0011223344556677".getBytes(), "AES")));
// Read Messages. The reading is done via the Service object and
// affects all Gateway objects defined. This can also be more directed to a specific
// Gateway - look the JavaDocs for information on the Service method calls.
msgList = new ArrayList<InboundMessage>();
Service.getInstance().readMessages(msgList, MessageClasses.ALL);
for (InboundMessage msg : msgList)
System.out.println(msg);
// Sleep now. Emulate real world situation and give a chance to the notifications
// methods to be called in the event of message or voice call reception.
System.out.println("Now Sleeping - Hit <enter> to stop service.");
System.in.read();
System.in.read();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
Service.getInstance().stopService();
}
}
public class InboundNotification implements IInboundMessageNotification
{
public void process(AGateway gateway, MessageTypes msgType, InboundMessage msg)
{
if (msgType == MessageTypes.INBOUND) System.out.println(">>> New Inbound message detected from Gateway: " + gateway.getGatewayId());
else if (msgType == MessageTypes.STATUSREPORT) System.out.println(">>> New Inbound Status Report message detected from Gateway: " + gateway.getGatewayId());
System.out.println(msg);
}
}
public class CallNotification implements ICallNotification
{
public void process(AGateway gateway, String callerId)
{
System.out.println(">>> New call detected from Gateway: " + gateway.getGatewayId() + " : " + callerId);
}
}
public class GatewayStatusNotification implements IGatewayStatusNotification
{
public void process(AGateway gateway, GatewayStatuses oldStatus, GatewayStatuses newStatus)
{
System.out.println(">>> Gateway Status change for " + gateway.getGatewayId() + ", OLD: " + oldStatus + " -> NEW: " + newStatus);
}
}
public class OrphanedMessageNotification implements IOrphanedMessageNotification
{
public boolean process(AGateway gateway, InboundMessage msg)
{
System.out.println(">>> Orphaned message part detected from " + gateway.getGatewayId());
System.out.println(msg);
// Since we are just testing, return FALSE and keep the orphaned message part.
return false;
}
}
public static void main(String args[])
{
TestSinaRec app = new TestSinaRec();
try
{
app.doIt();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
program output is for example :
Gateway Status change for modem.com4, OLD: STOPPED -> NEW: STARTING
Gateway Status change for modem.com4, OLD: STARTING -> NEW: STARTED
Modem Information: Manufacturer: Nokia Model: Nokia 6303i classic
Serial No: 355382041051833 SIM IMSI: ** MASKED ** Signal Level:
-57 dBm Battery Level: 91%
Now Sleeping - Hit to stop service.
New call detected from Gateway: modem.com4 : +989111007483
New call detected from Gateway: modem.com4 : +989111007483
when i searched for this issue i found this :
The correct operation of this method depends on the unsolicited modem
indications and on the correct operation of the CNMI command. If you
see that you are failing to receive messages using a callback method,
probably the modem indications have not been setup correctly.
so i changed my phone(my GSM modem) with Nokia 6303i rather than Nokia 5200 that i used first but the problem didn't solve.
so now i really don't know the problem will solve with choosing another phones ?! or i should search for a better and more reasonable solution.
thank you for any bit of help for solving this problem.
Well the only thing I can think of is that you're starting the Service and then sending the SMS to the modem. Because of this, this line won't be called: Service.getInstance().readMessages(msgList, MessageClasses.ALL);. However, you should still get the notification that a new message has arrived at the modem.
Try implementing the InboundNotification to fetch the messages when it senses any new messages on the modem. Do this by overriding the process() method.
However, it might also be due to the fact that you're actually pressing <Enter> too soon. As the comment say; you have to wait go give the notifications method a chance to be called.
Sometimes it's just something as silly as that. Let me know if any of it helped or if I completely misunderstood your problem. I'm working on a multi-modem gateway myself, so I'd be happy to help.
i had an issue with a GT-I9000 he received the inbound alert but couldn't fetch it the right sms object, i think this is a matter of the Storage Location,
i tried with another phone (Samsung GT-S5670 Android) of a friend of mine who had some messages stored on the SIM Card Memory, the smslibrary was notified and the ReadMessages Class logged all the messages.
so i think you need to find somehow to change storage location on the ReadMessages.java or find an compatible phone that can stores the sms to Sim Card instead of the phone memory.
hope this help.
The problem was with my phone.Smslib doesn't work in listening sms for a variety of phones(including smartphones,most of Nokia phones,etc.).I didn't check but probably this problem will be solved if you use a dedicated GSM modem(like huawei GSM modems)

Categories

Resources