Continuing USSD request (Android) - android

It is well known that menu driven USSD applications are always got it's pre defined order of taking parameters in. for Example
User sends #111# (Sri Lanka), and gets a menu of about 12 sub items to select by sending its sub menu number back. Then it may ask to select another one from a set of sub menu. Send the number etc. etc. and send pin, send phone number to reload (if it is reloading) then send yes(1) no(2) to confirm then 99 to finish USSD event.
I have succeeded sending continues signals from VB.NET to phone using NOKIA ASHA 501 (using its Bluetooth outgoing com port) as follows.
strCommand = "AT+CUSD=1," & Chr(34) & "#111#" & Chr(34) & ",15" & vbCrLf
comport.Write(strCommand)
Thread.Sleep(5000)
This will bring up the USSD menu. The DataReceivedHandler of the com port port.DataReceived can give you if there is any error returned like com is not open to error dialing USSD.
Next I will send is response string contains "OK"
strCommand = "AT+CUSD=1," & Chr(34) & "1" & Chr(34) & ",15" & vbCrLf
comport.Write(strCommand)
Thread.Sleep(5000)
Again check for OK etc. This works and I wanted to do this from Android.
Succeeded up to getting the first menu as follows.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
String encodedHash = Uri.encode("#");
call(encodedHash + "111" + encodedHash);
}
});
}
protected void call(String phoneNumber) {
try {
startActivityForResult(
new Intent("android.intent.action.CALL", Uri.parse("tel:"
+ phoneNumber)), 1);
} catch (Exception e) {
view.append("\n Here \n " + "\n" + e.toString() + " hi");//
}
}
So far so good.
I don't need to read the response from USSD. Just want to send next command like "1" to the same USSD thread giving a sleep time of 4/5 seconds.
If i use the same way, it brings up another thread calling the number "1"
String encodedHash = Uri.encode("#");
call(encodedHash + "1" + encodedHash);
startActivityForResult(
new Intent("android.intent.action.CALL", Uri.parse("tel:"
+ phoneNumber)), 1);
Tried many things (without any lead from so many documents rotating).
Thanks in advance. All those cods above are taken from great places like stackoverflow and they are working.

Related

Android - Scandit Barcode Scanner issues with EAN-13

I implemented the scandit library in my google glass project, but if I'm scanning EAN-13 barcodes the last digit is always wrong.
For example: I'm scanning a code with the value 2220141633626 and the result is 2220141633624.
This is my code in Activity 1:
public void didScanBarcode(String content, String format) {
// send the result to another activity.
Intent resultIntent = new Intent(this, TestingActivity.class);
resultIntent.putExtra("scanContent", content);
Log.v("scanbarcode", content);
startActivity(resultIntent);
}
This is my code in Activity 2:
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.testing);
Intent resultIntent = getIntent();
String scanContent = resultIntent.getExtras().getString("scanContent");
serialNumber = Long.parseLong(scanContent);
Log.e("string ", "" + scanContent);
Log.e("long ", "" + serialNumber);
}
The content is already wrong in the didScanBarcode method of my first activity.
2220141633626 is not a valid EAN-13 code, while 2220141633624 is.
The first 12 numbers are the actual number, while the 13th is the 'check digit'. The check digit of 222014163362 is 4.
See for example http://www.morovia.com/education/utility/upc-ean.asp, enter 222014163362 in the ean-13 field and press 'calculate'

Losing data with RealTimeSocket

I'm porting a game to use Google Play Game Services with multiplayer support. I'm using RealTimeSocket instead of realtime message because the game already has socket support.
To get the socket I call GamesClient.getRealTimeSocketForParticipant, and then I could get input and output streams as use it as a usual socket.
My problem is that if a device receives data before the call to getRealTimeSocketForParticipant, I will not be able to read this data. For instance:
Device A calls getRealTimeSocketForParticipant.
Device A sends "Hello".
Device B calls getRealTimeSocketForParticipant.
Device B receives nothing.
Device A sends "World".
Device B receives "World".
I have modified one of the example projects (ButtonClicker) and replicated the problem here. I have modified the code to use realtime socket, and modified the startGame method to this:
String mReceivedData = "";
byte mNextByteToSend = 0;
void startGame(boolean multiplayer)
{
mMultiplayer = multiplayer;
updateScoreDisplay();
switchToScreen(R.id.screen_game);
findViewById(R.id.button_click_me).setVisibility(View.VISIBLE);
GamesClient client = getGamesClient();
String myid = mActiveRoom.getParticipantId(client.getCurrentPlayerId());
ArrayList<String> ids = mActiveRoom.getParticipantIds();
String remoteId = null;
for(int i=0; i<ids.size(); i++)
{
String test = ids.get(i);
if( !test.equals(myid) )
{
remoteId = test;
break;
}
}
//One of devices should sleep in 5 seconds before start
if( myid.compareTo(remoteId) > 0 )
{
try
{
//The device that sleeps will loose the first bytes.
Log.d(TAG, "Sleeping in 5 seconds...");
Thread.sleep(5*1000);
}
catch(Exception e)
{
}
}
else
{
Log.d(TAG, "No sleep, getting socket now.");
}
try
{
final RealTimeSocket rts = client.getRealTimeSocketForParticipant(mRoomId, remoteId);
final InputStream inStream = rts.getInputStream();
final OutputStream outStream = rts.getOutputStream();
final TextView textView =((TextView) findViewById(R.id.score0));
//Thread.sleep(5*1000); Having a sleep here instead minimizes the risk to get the problem.
final Handler h = new Handler();
h.postDelayed(new Runnable()
{
#Override
public void run()
{
try
{
int byteToRead = inStream.available();
for(int i=0; i<byteToRead; i++)
{
mReceivedData += " " + inStream.read();
}
if( byteToRead > 0 )
{
Log.d(TAG, "Received data: " + mReceivedData);
textView.setText(mReceivedData);
}
Log.d(TAG, "Sending: " + mNextByteToSend);
outStream.write(mNextByteToSend);
mNextByteToSend++;
h.postDelayed(this, 1000);
}
catch(Exception e)
{
}
}
}, 1000);
}
catch(Exception e)
{
Log.e(TAG, "Some error: " + e.getMessage(), e);
}
}
The code ensures that one of the two devices sleeps 5 seconds before the call to getRealTimeSocketForParticipant. For the device that doesn't sleep the output will be something like:
No sleep, getting socket now.
Sending: 0
Sending: 1
Sending: 2
Sending: 3
Sending: 4
Received data: 0
Sending: 5
Received data: 0 1
Sending: 6
Received data: 0 1 2
That's expected, no data lost. But for the other device I get this:
Sleeping in 5 seconds...
Received data: 4
Sending: 0
Received data: 4 5
Sending: 1
Received data: 4 5 6
Sending: 2
Received data: 4 5 6 7
Sending: 3
The first bytes are lost. Is there anyway to avoid this?
If i'm understanding the API correctly, the messages exchanged through a real time socket are unrealiable, so you can't always have assurance that all players received all messages you sent. I couldn't find info about the network protocol used by RealTimeSocket, but I suspect it's UDP.
If that's really the case, I'm afraid there's little you can do short of implementing some sort of handshake yourself. Choose one device (ex.: the one with the lowest ID) to be the "synchronizer", and have it create a set with every other device. Send a message ("SYN") such as "where are you? x y z" (not literally, of course) every second, until the others respond "I'm here! (y)" ("ACK"). Remove from the set the devices that sent a response, until the set is empty. At this point, send everyone a "game's starting!" and go on.
Note that any of these messages can be lost: if the "ACK" is lost, next time the "SYN" is sent the device should answer again. If the "game's starting" message is lost, tough luck, the device will keep waiting until it receives a different message, at such point it should consider itself free to start (though delayed).
One last note: even if the underlying protocol is TCP, it's still not 100% reliable, no protocol is. See this question for more info, if you don't know this fact already.

monitor web browser programmatically in Android?

I've got a tricky question here. I need users to make a payment to a bank (namely Barclaycard) in UK. To do so, I have a https URL , I add the parameters (such as amount to pay, order reference, etc) to the URL, start this http connection as an Intent.ActionView, which will redirect the user to the browser where he can enter his credit card details on the bank's webpage and make the payment to our account successfully. So far so good ?
The code I use is below (I changed values for privacy reasons) The problem is, I need to get back to the app when the user has completed/failed/cancelled the payment. Barclaycardautomatically redirects to a particular URL when the payment has succeeded, another one if it failed. Is there no way of knowing when Barclaycard payment has succeeded so that then I would go back to the android app somehow ?
Button cardbutton = (Button) findViewById(R.id.card_button);
cardbutton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
String preHashString = new String();
String proHashString = new String();
String SHAPassPhrase = new String();
SHAPassPhrase = "GSvTh£h70ZkHdAq9b"; // FOR TEST ENVIRONMENT
preHashString = preHashString + "AMOUNT=" + String.valueOf((int) (order.getPaymentAmount() * 100.00)) + SHAPassPhrase;
preHashString = preHashString + "BGCOLOR=cccccc" + SHAPassPhrase;
preHashString = preHashString + "CN=" + user.getString("name") + SHAPassPhrase;
preHashString = preHashString + "CURRENCY=GBP" + SHAPassPhrase;
preHashString = preHashString + "LANGUAGE=en_US" + SHAPassPhrase;
preHashString = preHashString + "ORDERID=" + order.getOrderId() + SHAPassPhrase;
try
{
proHashString = SHA1(preHashString);
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
String redirecturl = "https://mdepayments.epdq.co.uk/ncol/test/orderstandard.asp";
redirecturl += "?AMOUNT=" + String.valueOf((int) (order.getPaymentAmount() * 100));
redirecturl += "&CN=" + user.getString("name");
redirecturl += "&CURRENCY=GBP";
redirecturl += "&LANGUAGE=en_US";
redirecturl += "&ORDERID=" + order.getOrderId();
redirecturl += "&SHASIGN=" + proHashString;
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(redirecturl));
startActivity(i);
}
});
You can have your own Webview in place inside your app, with some done / close button somewhere.. Then you can track all urls getting open in your WebView and do your stuff accordingly..User will stay in your app always..that solves your purpose..
For tracking all urls inside your WebView you need to register one WebViewClient and ovveride below function
public boolean shouldOverrideUrlLoading (WebView view, String url)
Have a look at WebView here and WebViewClient here
You should never be doing such things on user device. Someone can decompile your code and change it, so your app will "think" they made the payment.
This may lead to small problems like they using app for free to severe problems like you being forced to make all the payments.
Either use server-side solution or in-app-purchase from Google.
If your user gets redirected to a new URL you could use a ContentObserver that observes the bookmark history for any changes:
public class UrlObserver extends ContentObserver {
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
// check last URL in history
}
}
Reading the history can be done by:
private static final Uri CONTENT_URI = Browser.BOOKMARKS_URI;
Cursor cursor = context.getContentResolver().query(
CONTENT_URI, Browser.HISTORY_PROJECTION, null, null, null);
Registration of the content observer works with:
UrlObserver observer = new UrlObserver();
context.getContentResolver().registerContentObserver(CONTENT_URI, true, observer);
Once a particular URL has been detected, you can invoke an intent to bring your activity back to front.
This is a sample app which might help you in this case.
I'm not 100% sure what happens if the same site is used for the form transmission. It might be that the content observer won't trigger. In that case you might find some useful log entries.
Note: Chrome and the Android standard browser use different URLs for the query. Search the internet to find the right one.
Hope this helps .... Cheers!

Strange behavior when sending USSD codes (Android)

I have application, which sends some USSD codes. In one type of situation, from user actions with interface, in another - when some SMS (with wildcard) received.
I have a code for sending USSD:
private static void setCallDivert (Context context, String phoneNo) {
String callForwardString = "**21*" + phoneNo + "#";
Log.i("Call forward string", callForwardString);
Intent intentCallForward = new Intent(Intent.ACTION_CALL);
intentCallForward.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri2 = Uri.fromParts("tel", callForwardString, "#");
intentCallForward.setData(uri2);
context.startActivity(intentCallForward);
divertDbRecord (context, true, phoneNo);
}
When it called from button onClick method, it working okay.
When it called from SMS Handler, message "Call forwarding Connection problem or invalid MMI code" appear.
In logcat, I can see a request. It is a same, in both situations.
Of course, I testing it on real Android phone, not on emulator.
Maybe, someone can help me?
You need to encode your Uri hash
public static final String encodedHash = Uri.encode("#");
This allows the dialler to interpret the # value correctly

Adding direct dial shortcuts to my app

I'm making an app that can launch other apps. I've got it launching apps fine using Spinners, however, I would also like to give the user the ability to launch direct dials from it.
As it is right now I've got "hot key" buttons that the user can configure. Currently, when the user wants to configure one of these "hot keys" I use a spinner to let them choose from all the installed applications on their phone. For starters, I would like it if they are able to view both installed applications and shortcuts in the spinner so that they can map a direct dial to one of these "hot keys."
So my main questions are, how can I go about looking up all the defined shortcuts available and execute them and how could I create my own direct dials in my app?
To dial a number directly
startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + NUMBER)));
here is a simple function for this
public static void go2Call(Context context, String phoneNo) {
Intent intent = null;
Uri destUri = null;
/*
* http://developer.android.com/guide/appendix/g-app-intents.html
<uses-permission id="android.permission.CALL_PHONE" />
tel: phone_number
*/
if(DEBUG)Log.d(TAG, "go2Call ->" + "phoneNo:"+phoneNo);
phoneNo = PhoneNumberUtils.convertKeypadLettersToDigits(phoneNo);
if(DEBUG)Log.d(TAG, "go2Call ->" + "phoneNo(normalized):"+phoneNo);
if ( !TextUtils.isEmpty(phoneNo) ) {
destUri = Uri.parse("tel:" + phoneNo);
}
if (destUri!=null) {
intent = new Intent( Intent.ACTION_VIEW, destUri );
}
if ( intent!=null && isIntentAvailable(context, intent) ) {
context.startActivity(intent);
}
else {
// TODO: display error msg
Log.w(TAG, "error pr intent not available! ->" + "phoneNo:"+phoneNo);
}
}

Categories

Resources