Showing posts with label How To. Show all posts
Showing posts with label How To. Show all posts

Wednesday, April 3, 2013

in-app billing doesn't work: "IAB Helper is not set up"


I tried to include in-app billing in my app and for the purpose of testing, based the whole procedure on the "TrivialDrive" example for version 3 of in-app billing (and implementing the unmodified versions of the IAB files as supplied in the "util" subdirectory of the demo), but it doesn't work for me - on LogCat, just before the app terminates with an error, it gives the message "In-app billing error: Illegal state for operation (launchPurchaseFlow): IAB Helper is not set up." (right after the startRegistered() function has been fired and given me the LOG message "Register button clicked; launching purchase flow for upgrade.")...


Any idea what goes wrong here?


Here are the relevant parts of my code:



package com.mytest;

(..)
import com.mytest.iab.IabHelper; // the originals from the demo example, unmodified
import com.mytest.iab.IabResult;
import com.mytest.iab.Inventory;
import com.mytest.iab.Purchase;

public class Result3 extends Activity implements OnClickListener {

private static final String TAG = "BillingService";

private Context mContext;

boolean mIsRegistered = false;

// this has already been set up for my app at the publisher's console
static final String IS_REGISTERED = "myregistered";

static final int RC_REQUEST = 10001;

// The helper object
IabHelper mHelper;

/** Call when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.result3);
mContext = this;

String base64EncodedPublicKey = "[my public key]"; // (from publisher's console for my app)

// Create the helper, passing it our context and the public key to verify signatures with
Log.d(TAG, "Creating IAB helper.");
mHelper = new IabHelper(this, base64EncodedPublicKey);

// enable debug logging (for a production application, you should set this to false).
mHelper.enableDebugLogging(true);

// Start setup. This is asynchronous and the specified listener
// will be called once setup completes.
Log.d(TAG, "Starting setup.");
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
Log.d(TAG, "Setup finished.");

if (!result.isSuccess()) {
complain("Problem setting up in-app billing: " + result);
return;
}

// Hooray, IAB is fully set up. Now, let's get an inventory of stuff we own.
Log.d(TAG, "Setup successful. Querying inventory.");
mHelper.queryInventoryAsync(mGotInventoryListener);
}
});

// Set the onClick listeners
findViewById(R.id.btnPurchase).setOnClickListener(this);
}

// Listener that's called when we finish querying the items we own
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
Log.d(TAG, "Query inventory finished.");
if (result.isFailure()) {
complain("Failed to query inventory: " + result);
return;
}

Log.d(TAG, "Query inventory was successful.");

// Do we have the premium upgrade?
mIsRegistered = inventory.hasPurchase(IS_REGISTERED);
Log.d(TAG, "User is " + (mIsRegistered ? "REGISTERED" : "NOT REGISTERED"));

setWaitScreen(false);
Log.d(TAG, "Initial inventory query finished; enabling main UI.");
}
};

// User clicked the "Register" button.
private void startRegistered() {
Log.d(TAG, "Register button clicked; launching purchase flow for upgrade.");
setWaitScreen(true);
mHelper.launchPurchaseFlow(this, IS_REGISTERED, RC_REQUEST, mPurchaseFinishedListener);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);

// Pass on the activity result to the helper for handling
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
// not handled, so handle it ourselves (here's where you'd
// perform any handling of activity results not related to in-app billing..
super.onActivityResult(requestCode, resultCode, data);
}
else {
Log.d(TAG, "onActivityResult handled by IABUtil.");
}
}

// Callback for when a purchase is finished
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);
if (result.isFailure()) {
// Oh noes!
complain("Error purchasing: " + result);
setWaitScreen(false);
return;
}

Log.d(TAG, "Purchase successful.");

if (purchase.getSku().equals(IS_REGISTERED)) {
Log.d(TAG, "User has registered..");
alert("Thank you.");
mIsRegistered = true;
setWaitScreen(false);
}
}
};

// We're being destroyed. It's important to dispose of the helper here!
@Override
public void onDestroy() {
// very important:
Log.d(TAG, "Destroying helper.");
if (mHelper != null) mHelper.dispose();
mHelper = null;
}

void complain(String message) {
Log.e(TAG, "**** Register Error: " + message);
alert("Error: " + message);
}

void setWaitScreen(boolean set) {
// just a dummy for now
}

void alert(String message) {
AlertDialog.Builder bld = new AlertDialog.Builder(this);
bld.setMessage(message);
bld.setNeutralButton("OK", null);
Log.d(TAG, "Showing alert dialog: " + message);
bld.create().show();
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnPurchase:
startRegistered();
break;
default:
break;
}
}


}


Here more lines from Logcat:



12-20 01:06:36.701: D/dalvikvm(299): GC_FOR_MALLOC freed 4262 objects / 308592 bytes in 84ms
12-20 01:06:36.701: D/webviewglue(299): nativeDestroy view: 0x2ea718
12-20 01:06:36.771: W/webcore(299): Can't get the viewWidth after the first layout
12-20 01:07:07.111: W/webcore(299): Can't get the viewWidth after the first layout
12-20 01:07:18.510: D/webviewglue(299): nativeDestroy view: 0x2dd458
12-20 01:07:18.510: D/dalvikvm(299): GC_FOR_MALLOC freed 6042 objects / 544504 bytes in 50ms
12-20 01:07:18.530: D/webviewglue(299): nativeDestroy view: 0x2ea8d0
12-20 01:07:18.660: D/BillingService(299): Creating IAB helper.
12-20 01:07:18.660: D/BillingService(299): Starting setup.
12-20 01:07:18.660: D/IabHelper(299): Starting in-app billing setup.
12-20 01:07:19.621: W/webcore(299): Can't get the viewWidth after the first layout
12-20 01:07:20.160: W/webcore(299): Can't get the viewWidth after the first layout
12-20 01:07:32.481: D/webviewglue(299): nativeDestroy view: 0x3f88e8
12-20 01:07:32.491: D/dalvikvm(299): GC_FOR_MALLOC freed 5798 objects / 513640 bytes in 50ms
12-20 01:07:32.511: D/BillingService(299): Register button clicked; launching purchase flow for upgrade.
12-20 01:07:32.511: E/IabHelper(299): In-app billing error: Illegal state for operation (launchPurchaseFlow): IAB helper is not set up.
12-20 01:07:32.521: D/AndroidRuntime(299): Shutting down VM
12-20 01:07:32.521: W/dalvikvm(299): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
12-20 01:07:32.541: E/AndroidRuntime(299): FATAL EXCEPTION: main
12-20 01:07:32.541: E/AndroidRuntime(299): java.lang.IllegalStateException: IAB helper is not set up. Can't perform operation: launchPurchaseFlow
12-20 01:07:32.541: E/AndroidRuntime(299): at com.test_ed.iab.IabHelper.checkSetupDone(IabHelper.java:673)
12-20 01:07:32.541: E/AndroidRuntime(299): at com.test_ed.iab.IabHelper.launchPurchaseFlow(IabHelper.java:315)
12-20 01:07:32.541: E/AndroidRuntime(299): at com.test_ed.iab.IabHelper.launchPurchaseFlow(IabHelper.java:294)
12-20 01:07:32.541: E/AndroidRuntime(299): at com.test_ed.Result3.startRegistered(Result3.java:157)
12-20 01:07:32.541: E/AndroidRuntime(299): at com.test_ed.Result3.onClick(Result3.java:248)
12-20 01:07:32.541: E/AndroidRuntime(299): at android.view.View.performClick(View.java:2408)
12-20 01:07:32.541: E/AndroidRuntime(299): at android.view.View$PerformClick.run(View.java:8816)
12-20 01:07:32.541: E/AndroidRuntime(299): at android.os.Handler.handleCallback(Handler.java:587)
12-20 01:07:32.541: E/AndroidRuntime(299): at android.os.Handler.dispatchMessage(Handler.java:92)
12-20 01:07:32.541: E/AndroidRuntime(299): at android.os.Looper.loop(Looper.java:123)
12-20 01:07:32.541: E/AndroidRuntime(299): at android.app.ActivityThread.main(ActivityThread.java:4627)
12-20 01:07:32.541: E/AndroidRuntime(299): at java.lang.reflect.Method.invokeNative(Native Method)
12-20 01:07:32.541: E/AndroidRuntime(299): at java.lang.reflect.Method.invoke(Method.java:521)
12-20 01:07:32.541: E/AndroidRuntime(299): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-20 01:07:32.541: E/AndroidRuntime(299): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-20 01:07:32.541: E/AndroidRuntime(299): at dalvik.system.NativeStart.main(Native Method)


.

forums.androidcentral.com

Adding Functionality to both Android's Activity (parent class) and FragmentActivity (child class) in best coding style (minimal duplication)


In Android Library, FragmentActivity extends Activity. I would like to add a few methods, and override some methods, of the original Activity.



import android.app.Activity

public class Activiti extends Activity {
public void myNewMethod() { ... }
}


Because of the original hierarchy, FragmentActivity extends Activity, myNewMethod() should also be present in my library's FragmentActiviti



import android.support.v4.app.FragmentActivity;

public abstract class FragmentActiviti extends FragmentActivity {
public void myNewMethod() { ... }
}


But this will lead to a duplication of code, which i do not want this happens. Is there a way to avoid this duplication?



Edit: Usage scenario


Activiti.java



public abstract class Activiti extends Activity {
private int current_orientation = Configuration.ORIENTATION_UNDEFINED; // ORIENTATION_UNDEFINED = 0

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
current_orientation = this.getResources().getConfiguration().orientation;
}
protected boolean isDevicePortrait() { return current_orientation == Configuration.ORIENTATION_PORTRAIT; }
}


FragmentActiviti.java



public abstract class FragmentActiviti extends FragmentActivity {
/* This onCreate() can be omitted. Just putting here explicitly. */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

protected void someUtilsForFragments() { /* not used yet */ }
}


E_fragtest_06.java



public class E_fragtest_06 extends FragmentActiviti {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.printf(isDevicePortrait()); // this NOT WORK for now
}
}



Edit 2: Try using Util class


i think using the Decorator Class would be the most nicest way to solve this problem (no duplication of code). But the Decorator Pattern is just a bit hard (or impossible) to apply on Android Activity scenario.


i try implementing @hazzik's approach, but i still experience some problems.


ActivityUtil.java



public abstract class ActivityUtil {
private int current_orientation = Configuration.ORIENTATION_UNDEFINED; // ORIENTATION_UNDEFINED = 0

public void onCreate(Activity activity, Bundle savedInstanceState) {
activity.onCreate(savedInstanceState);
current_orientation = activity.getResources().getConfiguration().orientation;
}
public boolean isDevicePortrait() { return current_orientation == Configuration.ORIENTATION_PORTRAIT; }
}


Activiti.java



public class Activiti extends Activity {
private ActivityUtil activityUtil;

@Override
public void onCreate(Bundle savedInstanceState) {
activityUtil.onCreate(this, savedInstanceState);
}
protected boolean isDevicePortrait() { return activityUtil.isDevicePortrait(); }
}


FragmentActiviti.java



public abstract class FragmentActiviti extends FragmentActivity {
private ActivityUtil activityUtil;

@Override
public void onCreate(Bundle savedInstanceState) {
activityUtil.onCreate(this, savedInstanceState);
}
protected boolean isDevicePortrait() { return activityUtil.isDevicePortrait(); }
}


In ActivityUtil.onCreate(), activity.onCreate(savedInstanceState); is causing this compile error:



The method onCreate(Bundle) from the type Activity is not visible.



If i change Activity to Activiti:



public abstract class ActivityUtil {
public void onCreate(Activiti activity, Bundle savedInstanceState) { ... }
...
}


It will lead to another compile error in FragmentActiviti.onCreate()'s activityUtil.onCreate():



The method onCreate(Activiti, Bundle) in the type ActivityUtil is not applicable for the arguments (FragmentActiviti, Bundle)



i understand why those errors occur. But i just don't know how to avoid them.



To thanks all the guys who have been contributing to this question, especially @flup for guiding me about the Decorator Pattern, @hazzik and @donramos for your extensive efforts, i m here posting



If you are also developing Android applications, i hope my codes could help you guys in some ways :-)


ActivityCore.java



package xxx.android;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;

public final class ActivityCore {
public interface ActivityCallbackInterface {
public void onCreateCallback(Bundle savedInstanceState);
public void onBeforeSaveInstanceState(Bundle outState);
public void onSaveInstanceStateCallback(Bundle outState);
}

private final Activity activity;
/**
* This current_orientation variable should be once set, never changed during the object life-cycle.
* But Activity.getResources() is not yet ready upon the object constructs.
* That's why THIS CLASS is wholly responsible to maintain THIS VARIABLE UNCHANGED.
*/
private int current_orientation = Configuration.ORIENTATION_UNDEFINED; // ORIENTATION_UNDEFINED = 0

public ActivityCore(Activity activity) { this.activity = activity; }

public void onCreate(Bundle savedInstanceState) {
((ActivityCallbackInterface) activity).onCreateCallback(savedInstanceState);
current_orientation = activity.getResources().getConfiguration().orientation;
}

public void onSaveInstanceState(Bundle outState) {
/**
* THIS is the best ever place i have found, to unload unwanted Fragments,
* thus prevent re-creating of un-needed Fragments in the next state of Activity.
* (state e.g. Portrait-to-Landscape, or Landscape-to-Portrait)
*
* The KEY is to do it BEFORE super.onSaveInstanceState()
* (my guess for this reason is, in super.onSaveInstanceState(),
* it saves the layout hierarchy, thus saved the Fragments into the Bundle also.
* Thus restored.
* Note that Fragments NOT IN LAYOUT, having ONLY TAGS, are also restored.)
*/
((ActivityCallbackInterface) activity).onBeforeSaveInstanceState(outState);
((ActivityCallbackInterface) activity).onSaveInstanceStateCallback(outState);
}

public int getCurrentOrientation() { return current_orientation; }

public boolean isDevicePortrait() { return current_orientation == Configuration.ORIENTATION_PORTRAIT; }
public boolean isDeviceLandscape() { return current_orientation == Configuration.ORIENTATION_LANDSCAPE; }
public boolean isNewDevicePortrait() { return activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; }
public boolean isNewDeviceLandscape() { return activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; }
public boolean isPortrait2Landscape() { return isDevicePortrait() && isNewDeviceLandscape(); }
public boolean isLandscape2Portrait() { return isDeviceLandscape() && isNewDevicePortrait(); }

public String describeCurrentOrientation() { return describeOrientation(current_orientation); }
public String getCurrentOrientationTag() { return getOrientationTag(current_orientation); }
public String describeNewOrientation() { return describeOrientation(activity.getResources().getConfiguration().orientation); }
public String getNewOrientationTag() { return getOrientationTag(activity.getResources().getConfiguration().orientation); }
private String describeOrientation(final int orientation) {
switch (orientation) {
case Configuration.ORIENTATION_UNDEFINED: return "ORIENTATION_UNDEFINED"; // 0
case Configuration.ORIENTATION_PORTRAIT: return "ORIENTATION_PORTRAIT"; // 1
case Configuration.ORIENTATION_LANDSCAPE: return "ORIENTATION_LANDSCAPE"; // 2
case Configuration.ORIENTATION_SQUARE: return "ORIENTATION_SQUARE"; // 3
default: return null;
}
}
@SuppressLint("DefaultLocale")
private String getOrientationTag(final int orientation) {
return String.format("[%d:%s]", orientation, describeOrientation(orientation).substring(12, 16).toLowerCase());
}
}


Activity.java



package xxx.android.app;

import xxx.android.ActivityCore;
import xxx.android.ActivityCore.ActivityCallbackInterface;
import android.os.Bundle;

public abstract class Activity extends android.app.Activity implements ActivityCallbackInterface {
private final ActivityCore activityCore;

public Activity() { super(); activityCore = new ActivityCore(this); }

@Override
protected void onCreate(Bundle savedInstanceState) { activityCore.onCreate(savedInstanceState); }
@Override public void onCreateCallback(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }

@Override
public void onBeforeSaveInstanceState(Bundle outState) {} // Optionally: let child class override
@Override
protected void onSaveInstanceState(Bundle outState) { activityCore.onSaveInstanceState(outState); }
@Override public void onSaveInstanceStateCallback(Bundle outState) { super.onSaveInstanceState(outState); }

public final int getCurrentOrientation() { return activityCore.getCurrentOrientation(); }

public final boolean isDevicePortrait() { return activityCore.isDevicePortrait(); }
public final boolean isDeviceLandscape() { return activityCore.isDeviceLandscape(); }
public final boolean isNewDevicePortrait() { return activityCore.isNewDevicePortrait(); }
public final boolean isNewDeviceLandscape() { return activityCore.isNewDeviceLandscape(); }
public final boolean isPortrait2Landscape() { return activityCore.isPortrait2Landscape(); }
public final boolean isLandscape2Portrait() { return activityCore.isLandscape2Portrait(); }

public final String describeCurrentOrientation() { return activityCore.describeCurrentOrientation(); }
public final String getCurrentOrientationTag() { return activityCore.getCurrentOrientationTag(); }
public final String describeNewOrientation() { return activityCore.describeNewOrientation(); }
public final String getNewOrientationTag() { return activityCore.getNewOrientationTag(); }
}


FragmentActivity.java



package xxx.android.support.v4.app;

import xxx.android.ActivityCore;
import xxx.android.ActivityCore.ActivityCallbackInterface;
import android.os.Bundle;

public abstract class FragmentActivity extends android.support.v4.app.FragmentActivity implements ActivityCallbackInterface {
private final ActivityCore activityCore;

public FragmentActivity() { super(); activityCore = new ActivityCore(this); }

@Override
protected void onCreate(Bundle savedInstanceState) { activityCore.onCreate(savedInstanceState); }
@Override public void onCreateCallback(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }

@Override
public void onBeforeSaveInstanceState(Bundle outState) {} // Optionally: let child class override
@Override
protected void onSaveInstanceState(Bundle outState) { activityCore.onSaveInstanceState(outState); }
@Override public void onSaveInstanceStateCallback(Bundle outState) { super.onSaveInstanceState(outState); }

public final int getCurrentOrientation() { return activityCore.getCurrentOrientation(); }

public final boolean isDevicePortrait() { return activityCore.isDevicePortrait(); }
public final boolean isDeviceLandscape() { return activityCore.isDeviceLandscape(); }
public final boolean isNewDevicePortrait() { return activityCore.isNewDevicePortrait(); }
public final boolean isNewDeviceLandscape() { return activityCore.isNewDeviceLandscape(); }
public final boolean isPortrait2Landscape() { return activityCore.isPortrait2Landscape(); }
public final boolean isLandscape2Portrait() { return activityCore.isLandscape2Portrait(); }

public final String describeCurrentOrientation() { return activityCore.describeCurrentOrientation(); }
public final String getCurrentOrientationTag() { return activityCore.getCurrentOrientationTag(); }
public final String describeNewOrientation() { return activityCore.describeNewOrientation(); }
public final String getNewOrientationTag() { return activityCore.getNewOrientationTag(); }
}


Lastly, i really have to thanks you guys are being so so so helpful and keep updating the solving progress with me! You all are the key persons who make stackoverflow a perfect site for programmers. Should you spot any problems in my codes, or any rooms for improvements, please do not hesitate to help me again :-)



It is because onBeforeSaveInstanceState() is implemented upon usage, all the three classes need to keep abstract. This leads to a duplication of the member variable current_orientation. If current_orientation could be put into class ActivityBase, or grouping it into somewhere else, it would be a lot nicer!


stupid me. i have fixed it :-)



.

forums.androidcentral.com

Unit testing Android application logic


Looking to write some tests for my application, I stumbled upon the Android testing pages. After a fairly long read, it quickly became apparent that the only thing that I could possibly get out of it is information about how to test the UI/Activities. What I really want is the way to test my logic with simply ant test, preferably without even involving the device. I should mention at this stage that I am not using Eclipse and it's quite saddening that 99% of the Java resources on Android assume people do so.


In any case, trying to get anything at all running, I played along with the tutorial as much as I could. It asks that a tests directory is made on the same level as src. Sure, even if every other of their pages implies that the test-project is a completely separate entity. While in the top level project directory, I ran android create test-project -m /path/to/my/project/ -n MyProjectTest -p tests. It's worth mentioning that they are very inconsistent with saying how they want things to be set up as seen on this question. Visiting the directory, I spot the default testing file. Here's where the issues begin.


To my understanding, testing is done as follows: build application, install; go to tests, build tests, install; run tests from the tests directory using ant test or start them directly using adb shell am instrument. This worked fine. I however have no desire to test the activity but just the logic (which doesn't access any Views/Activities).


Changing the default test to extend AndroidTestClass seemed to have work for a while. The tests were being ran but there were caveats: cleaning tests with ant clean also cleaned the project directory (../tests) so it took forever to build tests in a clean environment (which is necessary because ant debug seems terrible at detecting changes) but it worked and I was happy.


Few more tests later, I get java.lang.VerifyError on my only test class. Googling and Stacking around, it boiled down to either something wrong with external libs or something wrong with my class path. I'm not using any external .jars so it's probably my path.


In any case, here is my question: what is The Proper Way™ to unit test logic in Android applications with JUnit? I can't find any resources at all concerning this: all resources are either for testing the UI parts or for unit testing ordinary applications.


How can I unit test my logic only? This shouldn't even require a device to run on given that I don't need to use any parts of Android. Where do I place the tests? What do I need to change so that running ant test in my project directory will then run those?



.

forums.androidcentral.com

Not showing Main Activity after Splash screen


I under stand the thousand of people saying "don't use a splash," I get it, but the app is not that big, I just want to know what I am doing wrong I think it is something with my Manifest but after my splash shows and when its supposed to go to main page, I get error "Sorry! The Application Grifball (process com.grifball.info) has stopped unexpectedly. Please try again.


Here is my Manifest.




package="com.grifball.info"
android:versionCode="1"
android:versionName="1.0" >

android:minSdkVersion="8"
android:targetSdkVersion="8" />

android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >








android:name="MainActivity"
android:label="@string/app_name" >












Here is my Splash's Java



package com.grifball.info;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class Splash extends Activity{

@Override
protected void onCreate(Bundle startup) {
// TODO Auto-generated method stub
super.onCreate(startup);
setContentView(R.layout.splash);

Thread timer = new Thread(){

public void run(){

try{
sleep(5000);
}catch(InterruptedException e){
e.printStackTrace();
}finally{
Intent openMainActivity = new Intent("com.grifball.info.MAINACTIVITY");
startActivity(openMainActivity);
}
}

};
timer.start();
}

}


Here is the XML




android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/splashbg">





.

forums.androidcentral.com

How to add an index in json data?


I have following data structure:



Class UserModel {
Long pkid;
String name;
public UserModel() {
this.pkid = new Long(1001);
this.name = "ABC";
}
}


Now I have converted this into json:



UserModel usrObj = new UserModel();
Gson gson = new Gson();
String json = gson.toJson(userObj);


So my json string is now like:



{ "pkid": 1001,
"name": "ABC" }


But I need to create the json as



{"com.vlee.ejb.UserModel": [
{ "pkid": 1001,
"name": "ABC" } ] }


I am not sure how I can add the key "com.vlee.ejb.UserModel"



.

forums.androidcentral.com

Tuesday, April 2, 2013

Get Android AudioRecord startRecording time delay


I am using the AudioRecord class from https://github.com/nonameentername/soundtouch-android/blob/master/src/org/tecunhuman/ExtAudioRecorder.java but with it being slightly modified.


In the start() method, I start recording with the AudioRecord class. I also start a MediaPlayer to play a instrumental. To get these to sync at the server, I send the record delay (delay before AudioRecord actually starts recording and reads) and the instrumental delay (MediaPlayer delay from when start is called to it actually being played since there is latency).


My logic must be wrong because the timing is always off and I am unsure why. Any suggestions. Does audiorecording actually start when you call .startRecording or does it start after the first read? Any help would be greatly appreciated.


Note: I had to put the delay handler in there for some Jelly Bean devices because the AudioRecord listener was not being called.



public void start()
{
if (state == State.READY)
{
if (rUncompressed)
{
payloadSize = 0;
RecordReadDelayInSeconds = 0;
RecordDelayInSeconds = 0;

mPlayer = new MediaPlayer();

try {

mPlayer.setDataSource(mp3Path);

mPlayer.prepare();

} catch (IllegalArgumentException e) {e.printStackTrace();}
catch (SecurityException e) {e.printStackTrace();}
catch (IllegalStateException e) {e.printStackTrace();}
catch (IOException e) { e.printStackTrace();}

final long recordstarted = System.nanoTime() + 1500000000; //handler delay

audioRecorder.startRecording();

//Fix for recording issue with Samsung s3 Sprint phones.Doing a delayed first read
new Handler().postDelayed(new Runnable() {
@Override
public void run() {

long recordstopped = System.nanoTime();

long recordDelay = recordstopped - recordstarted;

double RecordDelayInSeconds = recordDelay / 1000000.0;

Log.i("StartRecording() Delay in seconds",
String.valueOf(RecordDelayInSeconds));

long recordreadstarted = System.nanoTime();

int bytesReceived = audioRecorder.read(buffer, 0, buffer.length);
Log.d(TAG,"Delayed first read: bytes recieved "+ bytesReceived);

long recordreadstopped = System.nanoTime();

long recordreadDelay = recordreadstopped - recordreadstarted;

RecordReadDelayInSeconds = recordreadDelay / 1000000.0;

Log.i("Record read() Delay in seconds",
String.valueOf(RecordReadDelayInSeconds));

long mediastarted = System.nanoTime();

mPlayer.start();

long mediastopped = System.nanoTime();

long beatDelay = mediastopped - mediastarted;

beatDelayInSeconds = 0;

beatDelayInSeconds = (beatDelay) / 1000000000.0;

Log.i("Beat Delay in seconds",
String.valueOf(beatDelayInSeconds));

}
}, 1500);
}


.

forums.androidcentral.com

Thursday, March 28, 2013

Upgraded to a new phone, now own a tablet, google accounts not syncing


Hi guys

Im going desperate here. Ive owned a samsung galaxy mini in the past and installed a couple of apps there, I then upgraded to a sony xperia p and what I noticed was the apps and settings that I had for my galaxy mini were carried over to my xperia p which of course is nothing but great.

But then when I got a google nexus 7 I noticed that when I linked that device to my google account the settings that it got were from my galaxy mini, including all the apps that Ive already uninstalled.

Which leads me to believe that somehow when I was using my xperia p my app information, app installations and phone settings were not synced to google's servers or something.

So how can I sync my xperia p to google's servers as so that when I link my tablet to my account all the installed apps and settings from my xperia p would get downloaded? not the ones from my galaxy mini

TL;DR: Owned 2 phones, now own a tablet, settings and installed apps of the 2nd phone did not sync to my google account, so when I logged into my google account from my tablet the settings and installed apps that it downloaded were from my (1st) old phone.



Read more...

forums.androidcentral.com

Motorola Razr MAXX connecting to Wifi


Model #: Motorola Razr Maxx
System Version: 98.72.16.XT912.Verizon.en.US
Android Version: 4.1.2

At work, we have a Actiontec Router. I have been able to connect to it for 5 months no problem.

Monday morning there was a verizon system update which I ran at home, and it connected to my Wifi at home again no problem.

Came to work, won't connect to the Wifi at work. I put in the password and it just says connecting and never connects.

I have read multiple forums and searched the internet for answers and nothing I do works.

The router has been reset, my phone has had multiple soft and hard reboots. While the router was off as well as not. I've forgotten the network multiple times. I know the password is right, if I put in the wrong password it doesn't even try to connect.

I really need to be able to connect to the wifi at work and I really really do not want to do a factory reset. PLEASE tell me there is another option.



Read more...

forums.androidcentral.com

ALL browsers crash constantly (except Chrome), Nexus 7


Hi all,

new user with an old(?) problem. I already wrote about it here, but I now realize that my problem is much larger than anticipated.

To put it short: Dolphin Browser started force closing randomly a few days ago. I couldn't get rid of the problem and tested pretty much every browser available for the Android platform. Opera, Firefox, Boat, xScope, Maxthon and so on, they ALL crash. I don't really like Google Chrome, due to its lack of options (no fullscreen etc.), so this is driving me nuts.

Here is what I did:

- uninstalled and reinstalled Dolphin
- rebooted the tablet
- deleted the app cache (also via "wipe cache partition")
- disabled Google Admob
- executed a full factory reset, installed Dolphin first, still crashing

The problem itself is and affects many OS versions, even more devices and every browser. The only workaround is to disable JavaScript, which of course renders many web pages unusable.

Coming from a Blackberry Playbook with its own fair share of browser related crahes, I'm now utterly frustrated with the situation. The first three weeks with my new Nexus 7 felt absolutely perfect, almost like honeymoon. Than BAM!, sh*t hits the fan.

Is there anything else I could try apart from whining and sharing my pain?



Read more...

forums.androidcentral.com

UCCW widgets


I've got 6 uccw 3x3 widgets on my home screen. They're not heavy ones, they're basically just for looks and each one has a small embedded image and one hotspot. I haven't seen any performance issues, and it's not showing up as an item in my battery settings screen. It's showing as using 12 MB in my running apps list.

Is it safe to say that the effect on my battery with these 6 widgets is negligible?

Sent from my Nexus 4 using Tapatalk 2



Read more...

forums.androidcentral.com

Wednesday, March 27, 2013

How do you remove the "Welcome to Google+" and "Looking for more?" messages in Google+?


I've been quite Google Plus for quite a while (though not very active with it).

On my Nexus 4 when I launch the Google Plus app and go to All Circles. It has this "Welcome to Google+" post with a couple suggestions of people I should add. Then below that is a post from my circle. Then bellow that is a "Looking for more?" post from Google suggesting yet even more people I should add.

My problem is, I already added quite a few people to my Circles. I'm set. I don't want to keep seeing this "Welcome to Google+" and "Looking for more?" posts in my Google feed. It's distracting and I have to scroll past this every time just to see what I really came to see.

Is there no way to turn this Google spam off somehow?

Another thing I don't like is how it sorts posts. I'm not really sure how it determines to sort these posts, I just know it's not chronologically. It's confusing and I have old posts showing up and new posts buried.

I want to like Google Plus. But I use Twitter mostly and have a hard time trying to embrace they weird way Google does things with this app on Android. Perhaps someone can provide me some tips or feedback on what I'm missing here?



Read more...

forums.androidcentral.com

Possible Ways for Samsung Galaxy S4 Data Recovery


Awesome! Samsung Galaxy S4 is Coming

As a Samsung Galaxy fan, I think you was so excited a few days ago, because a new awesome Galaxy phone met the public. Samsung Galaxy S4, the new flagship of Samsung smart phone which impressed people again by its amazing, awsome, excellent technology and design.

As the new flagship smartphone of Samsung in 2013, Samsung Galaxy S4 is equited by powerful hardware and software----the latest Android os ----Android 4.2.2 Jelly Bean, which improves the support for hardware significantly, and following high-tech hardware spec show the new flagship phone's power:
Bigger screen---- 5 inches with 1080p resolution,
Larger size battery---600mAh battery capacity,
more powerful processor ----.9GHz quad-core or 1.6GHz octa-core,
fantastic camera----rear-facing camera stuffed with more megapixels (13, to be exact).
Memory: 2GB RAM
Storage: 16GB, 32GB or 64 GB
Samsung Galaxy S4 raises a more taller bar for Samsung's competitors again, but also the new Galaxy has been left Apple behind by excellent screen and unique specialized software, such as Eye-tracking gestures, Air View and gestures,Dual Camera,etc.




Samsung Galaxy S4 Data Recovery is Potential

Thanks to the powerful functions and large storage of Samsung Galaxy S4, We may use S4 to take photos, listen music, watch videos, or store some important files to it, etc. Therefore,S4 is not only a smart mobile phone, but a multi-function portable digital device, which make our life more convennient.However,data loss is common in our daily life, although Samsung Galaxy serious are high quanlity. We can see so many trouble about Samsung Galaxy data recovery, such as recover photos from GalaxyS1, restor videos from GalaxyS2, how to recover deleted data from Samsung Galaxy S3, Can I retrieve text messages from Galaxy Note2? So, We can predict that is a common things as the phone is used by the people around the world.

Why We Can Recover Data from Samsung Galaxy S4
As you know, S4 is a Android device,which has a internal storage, hard drive and the external storage, such as SD card. And when you deleted files, the space where the deleted data save in is marked as blank and can be reused by new files, but the deleted file still exist unless new data overwrites it.Thus, it is possible to recover the data in the phone, and if you want to restore files from Samsung Galaxy S4, you should stop using the phone after data loss.

Possible Ways to recover data from Samsung Galaxy S4

Way one: you can recover any Anitannudorid devices data by Google account and backup app on phone or computer,such as Titanium and PC companion.
Way two: Howerver, There are not many people has a good sence in making a backup regularly .If we are so unlucky that lost data from Samsung Galaxy S4, we should ask help for recovery software.

It is recommended to have a try to download Card Data Recovery software ,and .

Step1. Download the Card Data Recovery from here: and install it on your computer
Step2. Connect Samsung Galaxy S4 to computer via USB cable or connect the SD card in the phone with card reader, and launch the Card Data Recovery application.
Step3. Click to choose "Removable media" that means your Samsung Galaxy S4 and Select the option “Photo Recovery”, “Video Recovery”,”Music Recovery” or all of them,then the program scan your lost data.
Step4. After scaning, you can preview the files and Choose the ones you want to get back and click “Recover”.
Step5. “Save” all your recovered data in the Android phone and you have completed to .
How about the performance of Samsung Galaxy S4? And Does Card Data Recovery work in Samsung Galaxy S4 Recovery? We will know in the coming month!

(You can leanr more about Samsung Galaxy data recovery here: )


Read more...

forums.androidcentral.com

Navigation autocomplete


Hi There,

I use Google Navigation daily in my work and have for years. Sometimes within the app, when I am typing in a new destination, the address will auto complete. Once this starts happening, it'll do it for the rest of the session. It is awesome as I type in 10 to 20 addresses a session and it usually nails it after I input the street # by the 2nd or 3rd letter of the street name!

My problem is this: it only does the auto complete thing sporadically and I have no idea what triggers it. I'd say 1 in 15 times it will start doing this. I'd like it to happen EVERY time. Any suggestions?

Thanks in advance...

BTW, using stock Droid Bionic, system is up to date, in Southern California...



Read more...

forums.androidcentral.com

Google Voice on T-Mobile? [General]

Google Voice on T-Mobile? So I recently switched from a GNex on Verizon to a Moto X DE on T-Mobile. I had always used Google Voice for my v...