in app billing handler, and handlers/services/receivers - java

Here is my code, I have a few questions as I am completely new to this whole service receiver thing.
It works fine. I get to checkout,I purchase, google says I will receive my item soon.
My question is that after the application gets closed, or after the activity that contains the handler is closed, will my app still receive the notification, and the gems be updated?
Any pointers or clues to better help me understand this would be awesome =D
I checked and my service is still running in the background, so this is good :)
But it is taking forever to update, or to receive
does anyone know?
Button bPurchase = (Button) findViewById(R.id.bPurchase);
bPurchase.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox confirm = (CheckBox) findViewById(R.id.bConfirm);
if (!confirm.isChecked()) {
Toast msg = Toast.makeText(PurchaseActivity.this, "Please Check Confirmation box", Toast.LENGTH_SHORT);
msg.setGravity(Gravity.CENTER, msg.getXOffset() / 2, msg.getYOffset() / 2);
msg.show();
return;
}
if(BillingHelper.isBillingSupported()){
BillingHelper.requestPurchase(mContext, "android.test.purchased");
// android.test.purchased or android.test.canceled or android.test.refunded
} else {
Log.i("","Can't purchase on this device");
}
}
});
}
public Handler mTransactionHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
Log.i("", "Transaction complete");
Log.i("", "Transaction status: "+BillingHelper.latestPurchase.purchaseState);
Log.i("", "Item attempted purchase is: "+BillingHelper.latestPurchase.productId);
if(BillingHelper.latestPurchase.isPurchased()){
long g = GemUpgrades.getGems();
g = g + 1000;
GemUpgrades.setGems(g);
Toast msg1 = Toast.makeText(PurchaseActivity.this, "Received", Toast.LENGTH_SHORT);
msg1.setGravity(Gravity.CENTER, msg1.getXOffset() / 2, msg1.getYOffset() / 2);
msg1.show();
} else {
// Failure
}
};
};

SO I discovered that i was not receiving my calls because I forgot to set the Handler as the Handler. Also It seemed it updated outside the activity, and pretty quick too. But would it still update if the app has been closed before it gets its updat

Related

retry with varying intervals on each time

I am working on a ble-android communication app. I am getting TYPE_GATT_ERROR sometimes when I try to read values from ble device. So I like to retry the scan and reading values each time the TYPE_GATT_ERROR is seen. first time when it happens, I want to start the scan again after 30secs and if that time also if the code reaches TYPE_GATT_ERROR segment, It should start scan again after 1 min and third time if it reaches the error segment, It should rescan with time interval 2mins. How can I do that with the below code segment? The Elseif case with the TYPE_GATT_ERROR condition is where I want to implement the retry algorithm.
private final BroadcastReceiver bleServiceReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent){
String type = intent.getExtras().getString(
BleReceivedService.EXTRA_TYPE);
if (BleReceivedService.TYPE_GATT_CONNECTED.equals(type)){
Log.d(TAG, " MYTAG DashBoard onReceive TYPE_GATT_CONNECTED");
if (BleReceivedService.getGatt() != null){
BleReceivedService.getGatt().discoverServices();
Log.d(TAG, " Connect Device");
stopScan();
}
} else if (BleReceivedService.TYPE_GATT_DISCONNECTED.equals(type)){
Log.d(TAG, " MYTAG Disconnect Device");
Log.d(TAG, " MYTAG DashBoard onReceive TYPE_GATT_DISCONNECTED");
BleReceivedService.getInstance().disconnectDevice();
if(isScanning) {
Log.d("ScanCheck","Scanning after disconnection");
stopScan();
}
} else if (BleReceivedService.TYPE_GATT_ERROR.equals(type)) {
Log.d(TAG, " MYTAG DashBoard onReceive TYPE_GATT_ERROR");
//here i want to call startscan() method in the above described fashion
} else {
//do someting
}
}
};
Please help me with the code to achieve this.
Thanks in advance.

Show toast only if it's different from the existing toast

So my goal is to only have a toast message shown to the user if there is no toast message showing or if the message showing is NOT the same as the message I want to send. If the message IS the same as the one being shown to the user, I don't want the message to go through (because that is pointless).
To work towards this goal, I found this post on how to only show a toast if none are being shown.
I have modified the code to fit both requirements.
private Toast toast;
public void showAToast (String st, boolean isLong){
try{
toast.getView().isShown();
String text = ((TextView)((LinearLayout)toast.getView()).getChildAt(0)).getText().toString();
if(!text.equalsIgnoreCase(st)){
//New message, show it after
if(isLong){
toast = Toast.makeText(getApplicationContext(), st, Toast.LENGTH_LONG);
} else {
toast = Toast.makeText(getApplicationContext(), st, Toast.LENGTH_SHORT);
}
toast.show();
}
} catch (Exception e) {
//New message
if(isLong){
toast = Toast.makeText(getApplicationContext(), st, Toast.LENGTH_LONG);
} else {
toast = Toast.makeText(getApplicationContext(), st, Toast.LENGTH_SHORT);
}
toast.show();
}
}
My issue is that any message will not go through if the last toast message was the same as the message that wants to go through.
Not sure exactly why this occurs, but I put some debugging messages in the method to figure out what the issue was.
The messages say that toast.getView().isShown() does not throw the exception (suppose to mean no toast is shown) if any toast message has been sent in the app's lifetime.
So my question is, how can I work around this? Surely there must be a way to achieve this desired functionality.
I saw this before in stackoverflow, but it's not nearly as clean as I would have liked. We implemented a dual toast approach, where it alternates between two toasts. First we define the toasts for the activity prior to the OnCreate:
Toast toast0;
Toast toast1;
private static boolean lastToast0 = true;
In the OnCreate:
toast0 = new Toast(getApplicationContext());
toast0.cancel();
toast1 = new Toast(getApplicationContext());
toast1.cancel();
//And finally, when I need to display the toast and cancel the prior toast at the same time I use something similar to:
if (lastToast0) {
toast0.cancel();
toast1.setDuration(Toast.LENGTH_LONG);
toast1.setText("new message");
toast1.show();
lastToast0 = false;
} else {
toast1.cancel();
toast0.setDuration(Toast.LENGTH_LONG);
toast0.setText("new message");
toast0.show();
lastToast0 = true;
}
// If you need to just cancel an existing toast (before it times out) use:
toast0.cancel();
toast1.cancel();
Quotation
You can use the same Toast instance to show message. If the message is same, the toast will no show twice time, otherwise the text will simple change to the latest one.
Toast mToast;
public void showToast(CharSequence message, int during){
if (mToast == null) {
mToast = Toast.makeText(getApplicationContext(), message, during);
} else {
mToast.setText(message);
}
mToast.show();
}
--↓---↓----↓---update--↓----↓---↓--↓
Sorry about that I miss your point above.
I read the source of Toast that we cannot get the view status since the view had been add to the WindownManager.So far, I cannot find out a method to point whether the Toast is shown.
But you can achieve your own Toast use Service,which likes a toast shown above the application. it may be easier.

Cant get ProgressDialog to show up in android

I cant get a progress dialog to show when I need it to. I have tried putting it in my asyncTask the ui class and the its own thread that runs on the ui and none have worked. Can anyone help me?
the method where the progressDialog method is called:
public void shareTest(View view){ //method called to jump to share activity if criteria matched
if(checkInputs()) { //call to check inputs
Share start = new Share();
boolean isConnected=start.connectToServer(); //connectToServer
Intent intent = new Intent(HomeScreen.this, Share.class); //create intent to move to share class from this activity
startProgressDialog();
if (isConnected) { //check to see if isconnected was succesful
if (Share.matchFound ){ //check to see if a match was found
progress.dismiss();
startActivity(intent); //if true jump to share activity
} else {
while (!Share.timedOut) { //While the time has not timedOut
if (Share.matchFound) { //if a share has been found
startActivity(intent); //start share activity
break; //if true then break
}
}
if (Share.timedOut) {
//send an notice that a match wasn't found
sendToast(getString(R.string.noShare)); //if not true then send Toast
}
}
}
else sendToast(getString(R.string.errServCon)); //if connection to server failed then send toast
}
}
this is the method:
void startProgressDialog() {
new Thread(new Runnable() {
#Override
public void run() { //creates a new runnable thread
// Issue command() on a separate thread
while (!Share.matchFound) { //while havent been asked to disconnect //if a new location has been recieved
activity.runOnUiThread(new Runnable() {
#Override
public void run() { //run on the ui thread act
progress.show(); //call the method that does the update
}
});
}
progress.dismiss();
}
}).start();
}
Declare a global variable like this:
ProgressDialog progress;
Wherever you want to show the progress, paste this code:
progress = ProgressDialog.show(this, "Please wait",
"Loading..", true);
When you are done, simply dismiss it:
progress.dismiss();

How to programmatically set a lock or pin for an app

So right now I am trying to develop an Android App for my young children. I want to set a pin or passwords on selected applications for a particular amount of time to prevent them from opening the app. For example, let's say that my daughter wants to play angry birds for some time on my phone while I am doing work. I will select my important apps like messaging, gmail, etc and put a pin or password on it for 30 minutes while she plays angry birds. After 30 minutes, I get my phone from my daughter and I can open the app without a pin because the time limit expired.
I have done a ton of research on this, but I haven't been able to find an implementation for my particular case.
How do android "app lock" applications work?
I know that app lock has a similar kind of structure of what I want to do. I just to place a time limit for the lock.
https://play.google.com/store/apps/details?id=com.domobile.applock&hl=en
I am staying away from killing activities/ applications with ActivityManager etc. I really just want a clean lock screen over a selected app for a particular amount of time.
I have a CountdownTimer to count down the timer for a time I set. How would I modify this code to block certain applications for a chosen amount of time if I had all the packagename?
start_timer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new AlertDialog.Builder( MainActivity.this )
.setMessage( "Are you sure you want to block the selected apps for the set amount of time?" )
.setPositiveButton( "Yeah man!", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Log.d( "AlertDialog", "Positive" );
hourint = Integer.valueOf(number_text.getText().toString());
minuteint = Integer.valueOf(minute_text.getText().toString());
secondint = Integer.valueOf(second_text.getText().toString());
Log.i("YourActivity", "Hours: " + hourint);
Log.i("YourActivity", "Minutes: " + minuteint);
Log.i("YourActivity", "Seconds: " + secondint);
totalTimeCountInMilliseconds = ((hourint*60*60) +(minuteint*60) + (secondint)) * 1000; // time count
timeBlinkInMilliseconds = 30*1000;
countDownTimer = new CountDownTimer(totalTimeCountInMilliseconds, 500) {
// 500 means, onTick function will be called at every 500 milliseconds
#Override
public void onTick(long leftTimeInMilliseconds) {
Context context = MainActivity.this;
long seconds = leftTimeInMilliseconds / 1000;
mSeekArc.setVisibility(View.INVISIBLE);
start_timer.setVisibility(View.INVISIBLE);
block_button1.setVisibility(View.INVISIBLE);
if ( leftTimeInMilliseconds < timeBlinkInMilliseconds ) {
// textViewShowTime.setTextAppearance(getApplicationContext(), R.style.blinkText);
// change the style of the textview .. giving a red alert style
if ( blink ) {
number_text.setVisibility(View.VISIBLE);
minute_text.setVisibility(View.VISIBLE);
second_text.setVisibility(View.VISIBLE);
// if blink is true, textview will be visible
} else {
number_text.setVisibility(View.INVISIBLE);
minute_text.setVisibility(View.INVISIBLE);
second_text.setVisibility(View.INVISIBLE);
}
blink = !blink; // toggle the value of blink
}
second_text.setText(String.format("%02d", seconds % 60));
minute_text.setText(String.format("%02d", (seconds / 60) % 60));
number_text.setText(String.format("%02d", seconds / 3600)); // format the textview to show the easily readable format
}
#Override
public void onFinish() {
// this function will be called when the timecount is finished
//textViewShowTime.setText("Time up!");
number_text.setVisibility(View.VISIBLE);
minute_text.setVisibility(View.VISIBLE);
second_text.setVisibility(View.VISIBLE);
mSeekArc.setVisibility(View.VISIBLE);
start_timer.setVisibility(View.VISIBLE);
block_button1.setVisibility(View.VISIBLE);
}
}.start();
}
})
.setNegativeButton("Nope!", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Log.d("AlertDialog", "Negative");
dialog.cancel();
}
})
.show();
EDITED: http://pastebin.com/MHGFw7PK
Logic
You have to make and start a service when you want to block apps,
And In Service you have to check packagenames of the apps, so that you can decide which app to run and which to show a pin/password activity
Now Code Example:
To Start a service, code like this,
startService(new Intent(this, SaveMyAppsService.class));
Now, Inside your service, check packages like this,
public class SaveMyAppsService extends android.app.Service
{
String CURRENT_PACKAGE_NAME = {your this app packagename};
String lastAppPN = "";
boolean noDelay = false;
public static SaveMyAppsService instance;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
scheduleMethod();
CURRENT_PACKAGE_NAME = getApplicationContext().getPackageName();
Log.e("Current PN", "" + CURRENT_PACKAGE_NAME);
instance = this;
return START_STICKY;
}
private void scheduleMethod() {
// TODO Auto-generated method stub
ScheduledExecutorService scheduler = Executors
.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
// This method will check for the Running apps after every 100ms
if(30 minutes spent){
stop();
}else{
checkRunningApps();
}
}
}, 0, 100, TimeUnit.MILLISECONDS);
}
public void checkRunningApps() {
ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> RunningTask = mActivityManager.getRunningTasks(1);
ActivityManager.RunningTaskInfo ar = RunningTask.get(0);
String activityOnTop = ar.topActivity.getPackageName();
Log.e("activity on TOp", "" + activityOnTop);
// Provide the packagename(s) of apps here, you want to show password activity
if (activityOnTop.contains("whatsapp") // you can make this check even better
|| activityOnTop.contains(CURRENT_PACKAGE_NAME)) {
// Show Password Activity
} else {
// DO nothing
}
}
public static void stop() {
if (instance != null) {
instance.stopSelf();
}
}
}
Edit: (Get Top Package Name for Lollipop)
A very good answer is here.
String lastAppPN = "";
public void checkRunningApps() {
ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
String activityOnTop;
if (Build.VERSION.SDK_INT > 20) {
activityOnTop = mActivityManager.getRunningAppProcesses().get(0).processName;
} else {
List<ActivityManager.RunningTaskInfo> RunningTask = mActivityManager.getRunningTasks(1);
ActivityManager.RunningTaskInfo ar = RunningTask.get(0);
activityOnTop = ar.topActivity.getPackageName();
}
//Log.e("activity on TOp", "" + activityOnTop);
// Provide the packagename(s) of apps here, you want to show password activity
if (activityOnTop.contains("whatsapp") // you can make this check even better
|| activityOnTop.contains(CURRENT_PACKAGE_NAME)) {
if (!(lastAppPN.equals(activityOnTop))) {
lastAppPN = activityOnTop;
Log.e("Whatsapp", "started");
}
} else {
if (lastAppPN.contains("whatsapp")) {
if (!(activityOnTop.equals(lastAppPN))) {
Log.e("Whatsapp", "stoped");
lastAppPN = "";
}
}
// DO nothing
}
}
I have created small demo project.
Hope this might be useful to someone
Link to project
You can use a DialogAlertView also:
Use shared preferences to keep the password in storage.
If the user enabled password for the app, then show the alert in home page
Ask for the password, confirm if it is equal to the saved password.
If yes, dismiss alert view and if wrong, show alert view again
Make sure alert view setCancellable() is false
You can have your own design and animations in the view
I think it is easy to do. Nobody can crack the password also. Suppose if somebody uninstalls (or clear data) the app then they have to login or register again (which is more secure).
Tip - you can save the password in the cloud or anywhere you want.

Creating Threads results in force close in android app

I am trying to create a thread to handle a login function that is executed when the login button is pushed, so that I can show a progressDialog.
btnLogin.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Check Login
ProgressDialog.show(Activity.this, "", "Loading...");
new Thread(new Runnable(){
public void run(){
try{
int duration;
Toast toast;
Context context;
String username = etUsername.getText().toString();
String password = etPassword.getText().toString();
JSONArray jsonArray=null;
password=ServerConnection.encryptPassword(password);
//Log.i("login hash",password);
jsonArray=ServerConnection.login(username, password);
if(jsonArray!=null) //login successful
{
context=getApplicationContext();
duration=Toast.LENGTH_SHORT;
toast=Toast.makeText(context, "Login Successful!", duration);
toast.show();//Shows the little pop up right at the bottom of the screen
Intent i = new Intent(getApplicationContext(), MapWithFriends.class);
startActivity(i);
}
else
{
context=getApplicationContext();
duration=Toast.LENGTH_SHORT;
toast=Toast.makeText(context, "Login Fail", duration);
toast.show();//Shows the little pop up right at the bottom of the screen
//lblResult.setText("Login failed. Username and/or password doesn't match.");
}
}catch(Exception e)
{
Log.e("tag", e.getMessage());
}
progressDialog.dismiss();
}
}).start();
}
});
However when the thread is created, it force closes. If I change back to no threads, it works fine.
Thanks
Edit:
LogCat of crash:
Can't create handler inside thread that has not called Looper.prepare()
FATAL EXCEPTION: Thread-10
java.lang.NullPointerException
.....
would you guys need more than this?
You shouldn't modify the UI from any thread except the main thread , as you do in: progressDialog.dismiss();
Consider using Handler or AsyncTask instead. And I would also recommend reading this article.
From a non-UI thread use something like
runOnUiThread(new Runnable() {
// Your UI modifications here
});
or
yourUIControl.post(new Runnable() {
// something like
yourUIControl.setText("new text");
});

Categories

Resources