ورود

View Full Version : مشکل در استفاده از ویژگی درون پرداختی بازار



harani
دوشنبه 14 بهمن 1392, 18:10 عصر
با سلام خدمت دوستان آیا از بین شما کسی هست که در پروژش از ویژگی درون پرداختی که بازار در سایتش قرار داده است استفاده کرده باشد . اگر کسی هست لطفاً من رو راهنمایی کنه :

پروژه من دو تا اکتیوتی داره که در اولی دکمه ای وجود دارد به منظور launch کردن به صفحه ی پرداخت بازار .در صفحه ی دوم چنیدن آیتم وجود دارد که کاربر تعداد محدودی از آن را میتواند ببیند با خرید نسخه طلایی بازار تمام آیتم ها فعال میشود .

سوال من اینجاس که فرض کنید که کاربر برنامه را خریداری کرد، چطوری میتوانم بگم که وقتی از برنامه کلاً خارج شد و دوباره داخل برنامه شد تمامی آیتمهای صفحه ی دوم فعال باشد .

خواهشناً راهنمایی بفرمایید این موضوع برای من خیلی مهم است . اگه پروژه sample در خصوص این زمینه دارید آن را اتچ کنید چرا که پروژه خود بازار قابل اجرا شدن نیست .


با سپاس از تمامی دوستان

hamedjj
دوشنبه 14 بهمن 1392, 18:27 عصر
آموزش پرداخت درون برنامه ای اینجاست:

لینک (http://barnamenevis.org/showthread.php?429143-%D9%BE%D8%B1%D8%AF%D8%A7%D8%AE%D8%AA-%D8%AF%D8%B1%D9%88%D9%86-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D8%A7%DB%8C&highlight=%D9%BE%D8%B1%D8%AF%D8%A7%D8%AE%D8%AA+%D8 %AF%D8%B1%D9%88%D9%86+%D8%A8%D8%B1%D9%86%D8%A7%D9% 85%D9%87+%D8%A7%DB%8C)

برای اینکه با شروع برنامه بسته نشه از sharedprefences استفاده میشه

همه چیز هم در متد updateUi انجام میشه (آخر activity وجود داره)

harani
دوشنبه 14 بهمن 1392, 18:57 عصر
دست درد نکنه من کجا باید از share prefrence استفاده کنم میشه کد منو ببینید :



public class MainActivity extends Activity {
Button btnMusic, btnMenu;
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getA pplication().getApplicationContext());
Editor editor = preferences.edit();

// Debug tag, for logging
static final String TAG = "Music";

// SKUs for our products: the premium upgrade (non-consumable)
static final String SKU_PREMIUM = "Ertegha";

// Does the user have the premium upgrade?
boolean mIsPremium = false;

// (arbitrary) request code for the purchase flow
static final int RC_REQUEST = 1001;

Button btnPremium;

// The helper object
IabHelper mHelper;

IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
Log.d(TAG, "Query inventory finished.");
if (mHelper == null)
return;

if (result.isFailure()) {
Toast.makeText(MainActivity.this, getResources().getString(R.string.failure), Toast.LENGTH_LONG).show();
Log.d(TAG, "Failed to query inventory: " + result);
return;
} else {
Log.d(TAG, "Query inventory was successful.");
// does the user have the premium upgrade?
mIsPremium = inventory.hasPurchase(SKU_PREMIUM);

// update UI accordingly

Log.d(TAG, "User is "
+ (mIsPremium ? "PREMIUM" : "NOT PREMIUM"));
}

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

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
if (result.isFailure()) {
Toast.makeText(MainActivity.this, getResources().getString(R.string.failure), Toast.LENGTH_LONG).show();
Log.d(TAG, "Error purchasing: " + result);
return;
} else if (purchase.getSku().equals(SKU_PREMIUM)) {
// give user access to premium content and update the UI
editor.putBoolean("isPurchase", true);
editor.commit();
}
}
};

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + ","
+ data);

// Pass on the activity result to the helper for handling
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
} else {
Log.d(TAG, "onActivityResult handled by IABUtil.");
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//preferences = PreferenceManager.getDefaultSharedPreferences(this );
btnPremium = (Button) findViewById(R.id.btnPremium);
btnPremium.setTypeface(Typeface.createFromAsset(ge tAssets(), "fonts/BKOODKBD.TTF"));

String base64EncodedPublicKey = "MIHNMA0GCSqGSIb3DQEBAQUAA4G7ADCBtwKBrwCqHYQGGMF+qo KqA8WVy9gPjILn34MA+EKVWBEXAZflBdPvjQEnAMf+dHGqExMc 4vSvtPuBnbegkOfw8FTEiD+oOJ0hMtr/QLC3CvCex2kqVF0tqWW3l8IaI1DUu8nOYI/j648WO9bPlwIf2QB0Akkg5aAue8FMwavxqe29dNsziJwplkQwj 4MHMmKWXpKkNfdhCsMNWvQ3x+C6mfkv3Jkxq2SwMWoP2hu+/rReJ6cCAwEAAQ==";
// You can find it in your Bazaar console, in the Dealers section.
// It is recommended to add more security than just pasting it in your
// source code;
mHelper = new IabHelper(this, base64EncodedPublicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
Log.d(TAG, "Setup finished.");

if (!result.isSuccess()) {
// Oh noes, there was a problem.
Log.d(TAG, "Problem setting up In-app Billing: " + result);
}
// Hooray, IAB is fully set up!
mHelper.queryInventoryAsync(mGotInventoryListener) ;
}
});
Log.d(TAG, "Starting setup.");

btnMusic = (Button) findViewById(R.id.btnMusic);
btnMenu = (Button) findViewById(R.id.btnMenu);

SelectorForMainButton(btnMusic, R.drawable.music,
R.drawable.music_select);
SelectorForMainButton(btnMenu, R.drawable.kindly,
R.drawable.kindly_select);

btnMusic.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
startActivity(new Intent(MainActivity.this, Music.class));
}
});

btnMenu.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
startActivity(new Intent(MainActivity.this, MenuActivity.class));
}
});
}

void SelectorForMainButton(Button button, int BackImage, int SelectImage) {
StateListDrawable states = new StateListDrawable();
states.addState(new int[] { android.R.attr.state_pressed },
getResources().getDrawable(SelectImage));
states.addState(new int[] { android.R.attr.state_focused },
getResources().getDrawable(SelectImage));
states.addState(new int[] { android.R.attr.state_selected },
getResources().getDrawable(SelectImage));
states.addState(new int[] { android.R.attr.state_activated },
getResources().getDrawable(SelectImage));
states.addState(new int[] {}, getResources().getDrawable(BackImage));

button.setBackgroundDrawable(states);// FOR BUTTON
}

public void onClickPremium(View view) {
mHelper.launchPurchaseFlow(this, SKU_PREMIUM, RC_REQUEST,
mPurchaseFinishedListener, "payload-string");
}

@Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null)
mHelper.dispose();
mHelper = null;
}

}



1- اینکه آیا کد من برای این ویژگی کافی است یا ن

2- اینکه ببینید من کد prefrence که در oncreate و.. استفاده نکردم کرش کرده کجای برنامم باید shareprefrence و editor.put را صدا بزنم ؟ خواهشناً راهنمایی بفرمایید ممنون میشم .

hamedjj
دوشنبه 14 بهمن 1392, 19:20 عصر
توضیحات بازار را ول کن
برنامه trivialdrive یا برنامه خودم که در لینک بالا برات گذاشتم را ببین

https://github.com/congenialmobile/TrivialDrive/blob/master/src/com/example/android/trivialdrivesample/MainActivity.java

باید کدها را در اینجا قرار بدی که پس از پرداخت متد زیر فراخوانی میشه که در برنامه شما وجود نداره

public void updateUi() {
// update the car color to reflect premium status or lack thereof
((ImageView)findViewById(R.id.free_or_premium)).se tImageResource(mIsPremium ? R.drawable.premium : R.drawable.free);


// "Upgrade" button is only visible if the user is not premium
findViewById(R.id.upgrade_button).setVisibility(mI sPremium ? View.GONE : View.VISIBLE);


// "Get infinite gas" button is only visible if the user is not subscribed yet
findViewById(R.id.infinite_gas_button).setVisibili ty(mSubscribedToInfiniteGas ?
View.GONE : View.VISIBLE);


// update gas gauge to reflect tank status
if (mSubscribedToInfiniteGas) {
((ImageView)findViewById(R.id.gas_gauge)).setImage Resource(R.drawable.gas_inf);
}
else {
int index = mTank >= TANK_RES_IDS.length ? TANK_RES_IDS.length - 1 : mTank;
((ImageView)findViewById(R.id.gas_gauge)).setImage Resource(TANK_RES_IDS[index]);
}
}


اگر فقط قراره کاربر premium بشه برنامه من کافیه (البته دستور shareprefences یادت نره و اگر میخوای پس از هر بار ورود premium بودن کاربر را چک کنه if یادت نره)
اما اگر میخوای کالاهای مصرفی توش قرار بدی به trivialdrive رجوع کن

برای save کردن کاربر هم در برنامه trivialdrive از این متد استفاده شده
void saveData() {


/*
* WARNING: on a real application, we recommend you save data in a secure way to
* prevent tampering. For simplicity in this sample, we simply store the data using a
* SharedPreferences.
*/


SharedPreferences.Editor spe = getPreferences(MODE_PRIVATE).edit();
spe.putInt("tank", mTank);
spe.commit();
Log.d(TAG, "Saved data: tank = " + String.valueOf(mTank));
}


void loadData() {
SharedPreferences sp = getPreferences(MODE_PRIVATE);
mTank = sp.getInt("tank", 2);
Log.d(TAG, "Loaded data: tank = " + String.valueOf(mTank));
}


همچنین در دکمه ی ورود به پرداخت متد onclick در layout فراموش نشه که برنامه crash میشه

harani
دوشنبه 14 بهمن 1392, 19:26 عصر
دوست گرامی خواهشناً اگه ممکنه دردسترس بمانید که من سوالاتم را از شما بپرسم چون من حداکثر امشب یا نهایتاً فردا پروژمو تحویل بدم بره هیچی از این خاصیت دورن پرداختیم بلد نیستم.

harani
دوشنبه 14 بهمن 1392, 20:03 عصر
ارور میده ممکنه با ایمالاتور مشکل داشته باشه ؟


به این خط ارور میده
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {




import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Typeface;
import android.graphics.drawable.StateListDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.example.android.trivialdrivesample.util.IabHel per;
import com.example.android.trivialdrivesample.util.IabRes ult;
import com.example.android.trivialdrivesample.util.Invent ory;
import com.example.android.trivialdrivesample.util.Purcha se;

public class MainActivity extends Activity {
Button btnMusic, btnMenu;

// Debug tag, for logging
static final String TAG = "Music";

// SKUs for our products: the premium upgrade (non-consumable)
static final String SKU_PREMIUM = "Ertegha";

// Does the user have the premium upgrade?
boolean mIsPremium = false;

// (arbitrary) request code for the purchase flow
static final int RC_REQUEST = 10001;

Button btnPremium;

// The helper object
IabHelper mHelper;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadData();
// preferences = PreferenceManager.getDefaultSharedPreferences(this );
btnPremium = (Button) findViewById(R.id.btnPremium);
btnPremium.setTypeface(Typeface.createFromAsset(ge tAssets(),
"fonts/BKOODKBD.TTF"));

String base64EncodedPublicKey = "MIHNMA0GCSqGSIb3DQEBAQUAA4G7ADCBtwKBrwCqHYQGGMF+qo KqA8WVy9gPjILn34MA+EKVWBEXAZflBdPvjQEnAMf+dHGqExMc 4vSvtPuBnbegkOfw8FTEiD+oOJ0hMtr/QLC3CvCex2kqVF0tqWW3l8IaI1DUu8nOYI/j648WO9bPlwIf2QB0Akkg5aAue8FMwavxqe29dNsziJwplkQwj 4MHMmKWXpKkNfdhCsMNWvQ3x+C6mfkv3Jkxq2SwMWoP2hu+/rReJ6cCAwEAAQ==";
// You can find it in your Bazaar console, in the Dealers section.
// It is recommended to add more security than just pasting it in your
// source code;

// if (base64EncodedPublicKey.contains("PuBn")) {
// throw new RuntimeException(
// "Please put your app's public key in MainActivity.java. See README.");
// }
// if (getPackageName().startsWith("net.bornak")) {
// throw new RuntimeException(
// "Please change the sample's package name! See README.");
// }
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()) {
// Oh noes, there was a problem.
complain("Problem setting up in-app billing: " + result);
return;
}

// Have we been disposed of in the meantime? If so, quit.
if (mHelper == null)
return;

// 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) ;
}
});

btnMusic = (Button) findViewById(R.id.btnMusic);
btnMenu = (Button) findViewById(R.id.btnMenu);

SelectorForMainButton(btnMusic, R.drawable.music,
R.drawable.music_select);
SelectorForMainButton(btnMenu, R.drawable.kindly,
R.drawable.kindly_select);

btnMusic.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
saveData();
startActivity(new Intent(MainActivity.this, Music.class));

}
});

btnMenu.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
startActivity(new Intent(MainActivity.this, MenuActivity.class));
}
});
}

void SelectorForMainButton(Button button, int BackImage, int SelectImage) {
StateListDrawable states = new StateListDrawable();
states.addState(new int[] { android.R.attr.state_pressed },
getResources().getDrawable(SelectImage));
states.addState(new int[] { android.R.attr.state_focused },
getResources().getDrawable(SelectImage));
states.addState(new int[] { android.R.attr.state_selected },
getResources().getDrawable(SelectImage));
states.addState(new int[] { android.R.attr.state_activated },
getResources().getDrawable(SelectImage));
states.addState(new int[] {}, getResources().getDrawable(BackImage));

button.setBackgroundDrawable(states);// FOR BUTTON
}

IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
Log.d(TAG, "Query inventory finished.");

// Have we been disposed of in the meantime? If so, quit.
if (mHelper == null)
return;

// Is it a failure?
if (result.isFailure()) {
complain("Failed to query inventory: " + result);
return;
}

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

/*
* Check for items we own. Notice that for each purchase, we check
* the developer payload to see if it's correct! See
* verifyDeveloperPayload().
*/

// Do we have the premium upgrade?
// Purchase premiumPurchase = inventory.getPurchase(SKU_PREMIUM);
// mIsPremium = (premiumPurchase != null &&
// verifyDeveloperPayload(premiumPurchase));
// Log.d(TAG, "User is " + (mIsPremium ? "PREMIUM" :
// "NOT PREMIUM"));
//
// // Do we have the infinite gas plan?
//
// // Check for gas delivery -- if we own gas, we should fill up the
// // tank immediately
//
// updateUi();
//
// Log.d(TAG,
// "Initial inventory query finished; enabling main UI.");
}
};

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

// 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.");
}
}

/** Verifies the developer payload of a purchase. */
boolean verifyDeveloperPayload(Purchase p) {
String payload = p.getDeveloperPayload();

/*
* TODO: verify that the developer payload of the purchase is correct.
* It will be the same one that you sent when initiating the purchase.
*
* WARNING: Locally generating a random string when starting a purchase
* and verifying it here might seem like a good approach, but this will
* fail in the case where the user purchases an item on one device and
* then uses your app on a different device, because on the other device
* you will not have access to the random string you originally
* generated.
*
* So a good developer payload has these characteristics:
*
* 1. If two different users purchase an item, the payload is different
* between them, so that one user's purchase can't be replayed to
* another user.
*
* 2. The payload must be such that you can verify it even when the app
* wasn't the one who initiated the purchase flow (so that items
* purchased by the user on one device work on other devices owned by
* the user).
*
* Using your own server to store and verify developer payloads across
* app installations is recommended.
*/

return true;
}

// 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 we were disposed of in the meantime, quit.
if (mHelper == null)
return;

if (result.isFailure()) {
complain("Error purchasing: " + result);
// setWaitScreen(false);
return;
}
if (!verifyDeveloperPayload(purchase)) {
complain("Error purchasing. Authenticity verification failed.");
// setWaitScreen(false);
return;
}

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

// if (purchase.getSku().equals(SKU_GAS)) {
// // bought 1/4 tank of gas. So consume it.
// Log.d(TAG, "Purchase is gas. Starting gas consumption.");
// mHelper.consumeAsync(purchase, mConsumeFinishedListener);
// }
// else
if (purchase.getSku().equals(SKU_PREMIUM)) {
// bought the premium upgrade!
Log.d(TAG, "Purchase is premium upgrade. Congratulating user.");
alert("Thank you for upgrading to premium!");
mIsPremium = true;
updateUi();
// setWaitScreen(false);
}
// else if (purchase.getSku().equals(SKU_INFINITE_GAS)) {
// // bought the infinite gas subscription
// Log.d(TAG, "Infinite gas subscription purchased.");
// alert("Thank you for subscribing to infinite gas!");
// mSubscribedToInfiniteGas = true;
// mTank = TANK_MAX;
// updateUi();
// setWaitScreen(false);
// }
}
};

IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase, IabResult result) {
Log.d(TAG, "Consumption finished. Purchase: " + purchase
+ ", result: " + result);

// if we were disposed of in the meantime, quit.
if (mHelper == null)
return;

// We know this is the "gas" sku because it's the only one we
// consume,
// so we don't check which sku was consumed. If you have more than
// one
// sku, you probably should check...
if (result.isSuccess()) {
// successfully consumed, so we apply the effects of the item in
// our
// game world's logic, which in our case means filling the gas
// tank a bit
Log.d(TAG, "Consumption successful. Provisioning.");
// mTank = mTank == TANK_MAX ? TANK_MAX : mTank + 1;
saveData();
// alert("You filled 1/4 tank. Your tank is now " +
// String.valueOf(mTank) + "/4 full!");
} else {
complain("Error while consuming: " + result);
}
updateUi();
// setWaitScreen(false);
Log.d(TAG, "End consumption flow.");
}
};

public void onClickPremium(View view) {
String payload = "";

mHelper.launchPurchaseFlow(this, SKU_PREMIUM, RC_REQUEST,
mPurchaseFinishedListener, payload);
}

@Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null)
mHelper.dispose();
mHelper = null;
}

public void updateUi() {

btnPremium.setVisibility(mIsPremium ? View.GONE : View.VISIBLE);
}

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

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();
}

void saveData() {

/*
* WARNING: on a real application, we recommend you save data in a
* secure way to prevent tampering. For simplicity in this sample, we
* simply store the data using a SharedPreferences.
*/

SharedPreferences.Editor spe = getPreferences(MODE_PRIVATE).edit();
spe.putBoolean("isPurchase", mIsPremium);
spe.commit();

}

void loadData() {
SharedPreferences sp = getPreferences(MODE_PRIVATE);
mIsPremium = sp.getBoolean("isPurchase", false);

}

}



مشکل من کجاست آخه ؟ که همش کرش میکنه .

hamedjj
دوشنبه 14 بهمن 1392, 20:19 عصر
بعد از پرداخت یا قبل از پرداخت

onclick را در layout فعال کردید؟

harani
دوشنبه 14 بهمن 1392, 20:24 عصر
بله من یک دکمه برای خرید درون پرداختی گذاشتم که اونم onclick شو گذاشتم . البته من سه تا اکتیوتی دارم که یکیش splash بعد میاد ت صفحه ای که کلیک موجود است ولی splash رو نشون میده بعد که صفحه ی بعد استارت میشه سر اون خطی که گفتم برنامه کرش میکنه . اصلاً صفحه بالا نمیاد که پرداخت چک بشه . من آیا باید apk ساخته شده را در بازار بذارم ؟ یا ن ؟ اگه باید بذارم نبایستی که انتشارش بدم ؟