From 5c059b15004bf9f523c34cc6be0d348fad7e686d Mon Sep 17 00:00:00 2001 From: AlessandroLazzari Date: Tue, 16 Sep 2014 21:12:57 +0200 Subject: [PATCH 01/12] from InApp v2 to InApp v3 --- AndroidManifest.xml | 2 +- build.gradle | 2 +- res/layout/donate_activity.xml | 13 +- res/values/strings.xml | 2 + .../vending/billing/IInAppBillingService.aidl | 144 +++ src/com/money/manager/ex/DonateActivity.java | 307 +++--- src/com/money/manager/ex/MainActivity.java | 15 +- .../money/manager/ex/inapp/util/Base64.java | 570 ++++++++++ .../ex/inapp/util/Base64DecoderException.java | 32 + .../manager/ex/inapp/util/IabException.java | 43 + .../manager/ex/inapp/util/IabHelper.java | 991 ++++++++++++++++++ .../manager/ex/inapp/util/IabResult.java | 45 + .../manager/ex/inapp/util/Inventory.java | 91 ++ .../money/manager/ex/inapp/util/Purchase.java | 63 ++ .../money/manager/ex/inapp/util/Security.java | 123 +++ .../manager/ex/inapp/util/SkuDetails.java | 58 + 16 files changed, 2342 insertions(+), 159 deletions(-) create mode 100644 src/com/android/vending/billing/IInAppBillingService.aidl create mode 100644 src/com/money/manager/ex/inapp/util/Base64.java create mode 100644 src/com/money/manager/ex/inapp/util/Base64DecoderException.java create mode 100644 src/com/money/manager/ex/inapp/util/IabException.java create mode 100644 src/com/money/manager/ex/inapp/util/IabHelper.java create mode 100644 src/com/money/manager/ex/inapp/util/IabResult.java create mode 100644 src/com/money/manager/ex/inapp/util/Inventory.java create mode 100644 src/com/money/manager/ex/inapp/util/Purchase.java create mode 100644 src/com/money/manager/ex/inapp/util/Security.java create mode 100644 src/com/money/manager/ex/inapp/util/SkuDetails.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 98a756b0dd..f6ef1d95a8 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -23,7 +23,7 @@ - + diff --git a/build.gradle b/build.gradle index 80788fb84a..cf058d1796 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ android { minSdkVersion 8 targetSdkVersion 19 versionCode 586 - versionName "1.4.14" + versionName "1.4.15" } sourceSets { diff --git a/res/layout/donate_activity.xml b/res/layout/donate_activity.xml index 1a2c2091d6..fecd90d60a 100644 --- a/res/layout/donate_activity.xml +++ b/res/layout/donate_activity.xml @@ -101,15 +101,22 @@ + android:text="@string/donate_in_app_button" + android:visibility="gone" /> + + diff --git a/res/values/strings.xml b/res/values/strings.xml index ac5f939d68..6085cb9316 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -471,4 +471,6 @@ Withdrawal From %1$s Deposit To %1$s MoneyManagerEx Website + + You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! \ No newline at end of file diff --git a/src/com/android/vending/billing/IInAppBillingService.aidl b/src/com/android/vending/billing/IInAppBillingService.aidl new file mode 100644 index 0000000000..2a492f7845 --- /dev/null +++ b/src/com/android/vending/billing/IInAppBillingService.aidl @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.vending.billing; + +import android.os.Bundle; + +/** + * InAppBillingService is the service that provides in-app billing version 3 and beyond. + * This service provides the following features: + * 1. Provides a new API to get details of in-app items published for the app including + * price, type, title and description. + * 2. The purchase flow is synchronous and purchase information is available immediately + * after it completes. + * 3. Purchase information of in-app purchases is maintained within the Google Play system + * till the purchase is consumed. + * 4. An API to consume a purchase of an inapp item. All purchases of one-time + * in-app items are consumable and thereafter can be purchased again. + * 5. An API to get current purchases of the user immediately. This will not contain any + * consumed purchases. + * + * All calls will give a response code with the following possible values + * RESULT_OK = 0 - success + * RESULT_USER_CANCELED = 1 - user pressed back or canceled a dialog + * RESULT_BILLING_UNAVAILABLE = 3 - this billing API version is not supported for the type requested + * RESULT_ITEM_UNAVAILABLE = 4 - requested SKU is not available for purchase + * RESULT_DEVELOPER_ERROR = 5 - invalid arguments provided to the API + * RESULT_ERROR = 6 - Fatal error during the API action + * RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned + * RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned + */ +interface IInAppBillingService { + /** + * Checks support for the requested billing API version, package and in-app type. + * Minimum API version supported by this interface is 3. + * @param apiVersion the billing version which the app is using + * @param packageName the package name of the calling app + * @param type type of the in-app item being purchased "inapp" for one-time purchases + * and "subs" for subscription. + * @return RESULT_OK(0) on success, corresponding result code on failures + */ + int isBillingSupported(int apiVersion, String packageName, String type); + + /** + * Provides details of a list of SKUs + * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle + * with a list JSON strings containing the productId, price, title and description. + * This API can be called with a maximum of 20 SKUs. + * @param apiVersion billing API version that the Third-party is using + * @param packageName the package name of the calling app + * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST" + * @return Bundle containing the following key-value pairs + * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on + * failure as listed above. + * "DETAILS_LIST" with a StringArrayList containing purchase information + * in JSON format similar to: + * '{ "productId" : "exampleSku", "type" : "inapp", "price" : "$5.00", + * "title : "Example Title", "description" : "This is an example description" }' + */ + Bundle getSkuDetails(int apiVersion, String packageName, String type, in Bundle skusBundle); + + /** + * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU, + * the type, a unique purchase token and an optional developer payload. + * @param apiVersion billing API version that the app is using + * @param packageName package name of the calling app + * @param sku the SKU of the in-app item as published in the developer console + * @param type the type of the in-app item ("inapp" for one-time purchases + * and "subs" for subscription). + * @param developerPayload optional argument to be sent back with the purchase information + * @return Bundle containing the following key-value pairs + * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on + * failure as listed above. + * "BUY_INTENT" - PendingIntent to start the purchase flow + * + * The Pending intent should be launched with startIntentSenderForResult. When purchase flow + * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. + * If the purchase is successful, the result data will contain the following key-value pairs + * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on + * failure as listed above. + * "INAPP_PURCHASE_DATA" - String in JSON format similar to + * '{"orderId":"12999763169054705758.1371079406387615", + * "packageName":"com.example.app", + * "productId":"exampleSku", + * "purchaseTime":1345678900000, + * "purchaseToken" : "122333444455555", + * "developerPayload":"example developer payload" }' + * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that + * was signed with the private key of the developer + * TODO: change this to app-specific keys. + */ + Bundle getBuyIntent(int apiVersion, String packageName, String sku, String type, + String developerPayload); + + /** + * Returns the current SKUs owned by the user of the type and package name specified along with + * purchase information and a signature of the data to be validated. + * This will return all SKUs that have been purchased in V3 and managed items purchased using + * V1 and V2 that have not been consumed. + * @param apiVersion billing API version that the app is using + * @param packageName package name of the calling app + * @param type the type of the in-app items being requested + * ("inapp" for one-time purchases and "subs" for subscription). + * @param continuationToken to be set as null for the first call, if the number of owned + * skus are too many, a continuationToken is returned in the response bundle. + * This method can be called again with the continuation token to get the next set of + * owned skus. + * @return Bundle containing the following key-value pairs + * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on + * failure as listed above. + * "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs + * "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information + * "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures + * of the purchase information + * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the + * next set of in-app purchases. Only set if the + * user has more owned skus than the current list. + */ + Bundle getPurchases(int apiVersion, String packageName, String type, String continuationToken); + + /** + * Consume the last purchase of the given SKU. This will result in this item being removed + * from all subsequent responses to getPurchases() and allow re-purchase of this item. + * @param apiVersion billing API version that the app is using + * @param packageName package name of the calling app + * @param purchaseToken token in the purchase information JSON that identifies the purchase + * to be consumed + * @return 0 if consumption succeeded. Appropriate error values for failures. + */ + int consumePurchase(int apiVersion, String packageName, String purchaseToken); +} diff --git a/src/com/money/manager/ex/DonateActivity.java b/src/com/money/manager/ex/DonateActivity.java index e13c7af05c..a4d9e497d8 100644 --- a/src/com/money/manager/ex/DonateActivity.java +++ b/src/com/money/manager/ex/DonateActivity.java @@ -1,155 +1,182 @@ package com.money.manager.ex; -import java.util.ArrayList; -import java.util.List; - -import net.robotmedia.billing.BillingController; -import net.robotmedia.billing.BillingRequest.ResponseCode; -import net.robotmedia.billing.helper.AbstractBillingObserver; -import net.robotmedia.billing.model.Transaction.PurchaseState; +import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.Spinner; +import android.widget.TextView; import android.widget.Toast; import com.actionbarsherlock.view.MenuItem; import com.money.manager.ex.core.Core; -import com.money.manager.ex.core.InAppBilling; import com.money.manager.ex.fragment.BaseFragmentActivity; +import com.money.manager.ex.inapp.util.IabHelper; +import com.money.manager.ex.inapp.util.IabResult; +import com.money.manager.ex.inapp.util.Inventory; +import com.money.manager.ex.inapp.util.Purchase; +import com.money.manager.ex.inapp.util.SkuDetails; -public class DonateActivity extends BaseFragmentActivity { - - private final String PURCHASED_SKU = "DonateActivity:Purchased_Sku"; - private String purchasedSku = ""; - // Helper In-app Billing - private AbstractBillingObserver billingObserver; - /** - * List of valid SKUs - */ - ArrayList skus = new ArrayList(); - - public void onPurchaseStateChanged(String itemId, PurchaseState state){ - if(state == PurchaseState.PURCHASED){ - Toast.makeText(this, R.string.donate_thank_you, Toast.LENGTH_LONG).show(); - Core core = new Core(this); - // update the info value - core.setInfoValue(Constants.INFOTABLE_SKU_ORDER_ID, itemId); - finish(); - } - } - - @Override - protected void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // Set up SKUs - if (BuildConfig.DEBUG) { - skus.add("android.test.purchased"); - skus.add("android.test.canceled"); - skus.add("android.test.refunded"); - skus.add("android.test.item_unavailable"); - } - // add SKU application - skus.add("android.money.manager.ex.donations.small"); - // Set up the UI - setContentView(R.layout.donate_activity); - final Spinner inAppSpinner = (Spinner) findViewById(R.id.spinnerDonateInApp); - final Button inAppButton = (Button) findViewById(R.id.buttonDonateInApp); - inAppButton.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(final View v) { - final int selectedInAppAmount = inAppSpinner.getSelectedItemPosition(); - purchasedSku = skus.get(selectedInAppAmount); - if (BuildConfig.DEBUG) Log.d(DonateActivity.this.getClass().getSimpleName(), "Clicked " + purchasedSku); - - BillingController.requestPurchase(DonateActivity.this, purchasedSku, true, null); - } - }); - // Disabilito il tasto fin che non è pronto - inAppButton.setEnabled(false); - // Start the In-App Billing process - BillingController.setConfiguration(InAppBilling.getConfiguaration()); - billingObserver = new AbstractBillingObserver(this) { - - public void onBillingChecked(boolean supported) { - DonateActivity.this.onBillingChecked(supported); - } - - public void onPurchaseStateChanged(String itemId, PurchaseState state) { - DonateActivity.this.onPurchaseStateChanged(itemId, state); - } - - public void onRequestPurchaseResponse(String itemId, ResponseCode response) { - DonateActivity.this.onRequestPurchaseResponse(itemId, response); - } - - @Override - public void onSubscriptionChecked(boolean supported) { } - - }; - BillingController.registerObserver(billingObserver); - BillingController.checkBillingSupported(getApplicationContext()); - // set enable return - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - protected void onDestroy() { - BillingController.unregisterObserver(billingObserver); - super.onDestroy(); - } - - public void onRequestPurchaseResponse(String itemId, ResponseCode response) {} - - public void onBillingChecked(boolean supported) { - if(supported){ - final List inAppName = new ArrayList(); - - for (int i = 0; i < skus.size(); i++) { - inAppName.add(skus.get(i)); - } - - Spinner inAppSpinner = (Spinner) findViewById(R.id.spinnerDonateInApp); - final ArrayAdapter adapter = new ArrayAdapter(this, R.layout.sherlock_spinner_item, inAppName); - // Specify the layout to use when the list of choices appears - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - // Apply the adapter to the spinner - inAppSpinner.setAdapter(adapter); - // enable button - final Button inAppButton = (Button) findViewById(R.id.buttonDonateInApp); - inAppButton.setEnabled(inAppName.size() > 0); - // hide spinner if release version - inAppSpinner.setVisibility(BuildConfig.DEBUG ? View.VISIBLE : View.GONE); - // if has 1 item set button text - /*if (!BuildConfig.DEBUG) { - if (inAppName.size() == 1) { - inAppButton.setText(inAppName.get(0)); - } - }*/ - } - } - - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - purchasedSku = savedInstanceState.containsKey(PURCHASED_SKU) ? savedInstanceState.getString(PURCHASED_SKU) : ""; - } - - @Override - protected void onSaveInstanceState(final Bundle outState) { - super.onSaveInstanceState(outState); - outState.putString(PURCHASED_SKU, purchasedSku); - } +import net.robotmedia.billing.helper.AbstractBillingObserver; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class DonateActivity extends BaseFragmentActivity { + + private final String PURCHASED_SKU = "DonateActivity:Purchased_Sku"; + private final String PURCHASED_TOKEN = "DonateActivity:Purchased_Token"; + + // List of valid SKUs + ArrayList skus = new ArrayList(); + ArrayList skusToBePublished = new ArrayList(); + // purchase + private String purchasedSku = ""; + private String purchasedToken = ""; + // Helper In-app Billing + private AbstractBillingObserver billingObserver; + private IabHelper mIabHelper; + private IabHelper.OnIabPurchaseFinishedListener mConsumeFinishedListener; + private IabHelper.QueryInventoryFinishedListener mQueryInventoryFinishedListener; + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // Set up SKUs + if (1==2 && BuildConfig.DEBUG) { + skus.add("android.test.purchased"); + skus.add("android.test.canceled"); + skus.add("android.test.refunded"); + skus.add("android.test.item_unavailable"); + // my items for test + skus.add("com.android.money.manager.ex.test.1"); + } + // add SKU application + skus.add("android.money.manager.ex.donations.small"); + // Set up the UI + setContentView(R.layout.donate_activity); + final Spinner inAppSpinner = (Spinner) findViewById(R.id.spinnerDonateInApp); + final Button inAppButton = (Button) findViewById(R.id.buttonDonateInApp); + inAppButton.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(final View v) { + final int selectedInAppAmount = inAppSpinner.getSelectedItemPosition(); + purchasedSku = skus.get(selectedInAppAmount); + if (BuildConfig.DEBUG) + Log.d(DonateActivity.this.getClass().getSimpleName(), "Clicked " + purchasedSku); + purchasedToken = UUID.randomUUID().toString(); + //BillingController.requestPurchase(DonateActivity.this, purchasedSku, true, null); + mIabHelper.launchPurchaseFlow(DonateActivity.this, purchasedSku, 1001, mConsumeFinishedListener, purchasedToken); + } + }); + // Disabilito il tasto fin che non è pronto + inAppButton.setEnabled(false); + // init IabHelper + mIabHelper = new IabHelper(this.getApplicationContext(), Core.getAppBase64()); + mIabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { + @Override + public void onIabSetupFinished(IabResult result) { + if (result.isSuccess()) { + mIabHelper.queryInventoryAsync(true, skus, mQueryInventoryFinishedListener); + } + } + }); + + mConsumeFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() { + @Override + public void onIabPurchaseFinished(IabResult result, Purchase info) { + if (result.isSuccess()) { + Toast.makeText(DonateActivity.this, R.string.donate_thank_you, Toast.LENGTH_LONG).show(); + // close activity + DonateActivity.this.finish(); + } + } + }; + mQueryInventoryFinishedListener = new IabHelper.QueryInventoryFinishedListener() { + @Override + public void onQueryInventoryFinished(IabResult result, Inventory inv) { + if (result.isSuccess()) { + for (String sku : skus) { + if (inv.hasDetails(sku)) { + SkuDetails skuDetails = inv.getSkuDetails(sku); + if (!inv.hasPurchase(sku)) { + skusToBePublished.add(skuDetails); + } + } + } + } + onStartupInApp(result.isSuccess()); + } + }; + // set enable return + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (!mIabHelper.handleActivityResult(requestCode, resultCode, data)) + super.onActivityResult(requestCode, resultCode, data); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + protected void onDestroy() { + //BillingController.unregisterObserver(billingObserver); + super.onDestroy(); + if (mIabHelper != null) + mIabHelper.dispose(); + mIabHelper = null; + } + + public void onStartupInApp(boolean supported) { + if (supported) { + final List inAppName = new ArrayList(); + + for (SkuDetails sku : skusToBePublished) { + inAppName.add(sku.getDescription() + " " + sku.getPrice()); + } + + Spinner inAppSpinner = (Spinner) findViewById(R.id.spinnerDonateInApp); + final ArrayAdapter adapter = new ArrayAdapter(this, R.layout.sherlock_spinner_item, inAppName); + // Specify the layout to use when the list of choices appears + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + // Apply the adapter to the spinner + inAppSpinner.setAdapter(adapter); + // visibility button + final Button inAppButton = (Button) findViewById(R.id.buttonDonateInApp); + inAppButton.setVisibility(inAppName.size() > 0 ? View.VISIBLE : View.GONE); + inAppButton.setEnabled(inAppName.size() > 0 ); + // text view + final TextView inAppAlready = (TextView) findViewById(R.id.textViewInAppAlreadyDonate); + inAppAlready.setVisibility(inAppName.size() <= 0 ? View.VISIBLE : View.GONE); + // hide spinner if release version + inAppSpinner.setVisibility(inAppName.size() > 1 ? View.VISIBLE : View.GONE); + } + } + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + purchasedSku = savedInstanceState.containsKey(PURCHASED_SKU) ? savedInstanceState.getString(PURCHASED_SKU) : ""; + purchasedToken = savedInstanceState.containsKey(PURCHASED_TOKEN) ? savedInstanceState.getString(PURCHASED_TOKEN) : ""; + } + + @Override + protected void onSaveInstanceState(final Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(PURCHASED_SKU, purchasedSku); + outState.putString(PURCHASED_TOKEN, purchasedToken); + } } diff --git a/src/com/money/manager/ex/MainActivity.java b/src/com/money/manager/ex/MainActivity.java index 7b067087e1..0ba74b9f20 100644 --- a/src/com/money/manager/ex/MainActivity.java +++ b/src/com/money/manager/ex/MainActivity.java @@ -496,13 +496,7 @@ protected void onCreate(Bundle savedInstanceState) { onCreateFragments(savedInstanceState); // show tips dialog showTipsDialog(savedInstanceState); - // show donate dialog - - if (TextUtils.isEmpty(core.getInfoValue(Constants.INFOTABLE_SKU_ORDER_ID))) - MoneyManagerApplication.showDonateDialog(this, false); - // show change log and path - // MoneyManagerApplication.showChangeLog(this, false, false); - // MoneyManagerApplication.showChangeLog(this, false); + // show change log and path; if (core.isToDisplayChangelog()) core.showChangelog(); @@ -660,13 +654,6 @@ public boolean onPrepareOptionsMenu(Menu menu) { itemDropbox.setVisible(mDropboxHelper != null && mDropboxHelper.isLinked()); } - // check if it has already made ​​a donation - MenuItem itemDonate = menu.findItem(R.id.menu_donate); - if (itemDonate != null) { - Core core = new Core(this); - itemDonate.setVisible(TextUtils.isEmpty(core.getInfoValue(Constants.INFOTABLE_SKU_ORDER_ID))); - } - return super.onPrepareOptionsMenu(menu); } diff --git a/src/com/money/manager/ex/inapp/util/Base64.java b/src/com/money/manager/ex/inapp/util/Base64.java new file mode 100644 index 0000000000..82d38be732 --- /dev/null +++ b/src/com/money/manager/ex/inapp/util/Base64.java @@ -0,0 +1,570 @@ +// Portions copyright 2002, Google, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.money.manager.ex.inapp.util; + +// This code was converted from code at http://iharder.sourceforge.net/base64/ +// Lots of extraneous features were removed. +/* The original code said: + *

+ * I am placing this code in the Public Domain. Do with it as you will. + * This software comes with no guarantees or warranties but with + * plenty of well-wishing instead! + * Please visit + * http://iharder.net/xmlizable + * periodically to check for updates or to contribute improvements. + *

+ * + * @author Robert Harder + * @author rharder@usa.net + * @version 1.3 + */ + +/** + * Base64 converter class. This code is not a complete MIME encoder; + * it simply converts binary data to base64 data and back. + * + *

Note {@link CharBase64} is a GWT-compatible implementation of this + * class. + */ +public class Base64 { + /** Specify encoding (value is {@code true}). */ + public final static boolean ENCODE = true; + + /** Specify decoding (value is {@code false}). */ + public final static boolean DECODE = false; + + /** The equals sign (=) as a byte. */ + private final static byte EQUALS_SIGN = (byte) '='; + + /** The new line character (\n) as a byte. */ + private final static byte NEW_LINE = (byte) '\n'; + + /** + * The 64 valid Base64 values. + */ + private final static byte[] ALPHABET = + {(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', + (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', + (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', + (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', + (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', + (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', + (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', + (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', + (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', + (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', + (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', + (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', + (byte) '9', (byte) '+', (byte) '/'}; + + /** + * The 64 valid web safe Base64 values. + */ + private final static byte[] WEBSAFE_ALPHABET = + {(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', + (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', + (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', + (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', + (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', + (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', + (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', + (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', + (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', + (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', + (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', + (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', + (byte) '9', (byte) '-', (byte) '_'}; + + /** + * Translates a Base64 value to either its 6-bit reconstruction value + * or a negative number indicating some other meaning. + **/ + private final static byte[] DECODABET = {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 + 62, // Plus sign at decimal 43 + -9, -9, -9, // Decimal 44 - 46 + 63, // Slash at decimal 47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' + -9, -9, -9, -9, -9, -9, // Decimal 91 - 96 + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' + -9, -9, -9, -9, -9 // Decimal 123 - 127 + /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ + }; + + /** The web safe decodabet */ + private final static byte[] WEBSAFE_DECODABET = + {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 44 + 62, // Dash '-' sign at decimal 45 + -9, -9, // Decimal 46-47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' + -9, -9, -9, -9, // Decimal 91-94 + 63, // Underscore '_' at decimal 95 + -9, // Decimal 96 + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' + -9, -9, -9, -9, -9 // Decimal 123 - 127 + /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ + }; + + // Indicates white space in encoding + private final static byte WHITE_SPACE_ENC = -5; + // Indicates equals sign in encoding + private final static byte EQUALS_SIGN_ENC = -1; + + /** Defeats instantiation. */ + private Base64() { + } + + /* ******** E N C O D I N G M E T H O D S ******** */ + + /** + * Encodes up to three bytes of the array source + * and writes the resulting four Base64 bytes to destination. + * The source and destination arrays can be manipulated + * anywhere along their length by specifying + * srcOffset and destOffset. + * This method does not check to make sure your arrays + * are large enough to accommodate srcOffset + 3 for + * the source array or destOffset + 4 for + * the destination array. + * The actual number of significant bytes in your array is + * given by numSigBytes. + * + * @param source the array to convert + * @param srcOffset the index where conversion begins + * @param numSigBytes the number of significant bytes in your array + * @param destination the array to hold the conversion + * @param destOffset the index where output will be put + * @param alphabet is the encoding alphabet + * @return the destination array + * @since 1.3 + */ + private static byte[] encode3to4(byte[] source, int srcOffset, + int numSigBytes, byte[] destination, int destOffset, byte[] alphabet) { + // 1 2 3 + // 01234567890123456789012345678901 Bit position + // --------000000001111111122222222 Array position from threeBytes + // --------| || || || | Six bit groups to index alphabet + // >>18 >>12 >> 6 >> 0 Right shift necessary + // 0x3f 0x3f 0x3f Additional AND + + // Create buffer with zero-padding if there are only one or two + // significant bytes passed in the array. + // We have to shift left 24 in order to flush out the 1's that appear + // when Java treats a value as negative that is cast from a byte to an int. + int inBuff = + (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0) + | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0) + | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0); + + switch (numSigBytes) { + case 3: + destination[destOffset] = alphabet[(inBuff >>> 18)]; + destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f]; + destination[destOffset + 3] = alphabet[(inBuff) & 0x3f]; + return destination; + case 2: + destination[destOffset] = alphabet[(inBuff >>> 18)]; + destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f]; + destination[destOffset + 3] = EQUALS_SIGN; + return destination; + case 1: + destination[destOffset] = alphabet[(inBuff >>> 18)]; + destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = EQUALS_SIGN; + destination[destOffset + 3] = EQUALS_SIGN; + return destination; + default: + return destination; + } // end switch + } // end encode3to4 + + /** + * Encodes a byte array into Base64 notation. + * Equivalent to calling + * {@code encodeBytes(source, 0, source.length)} + * + * @param source The data to convert + * @since 1.4 + */ + public static String encode(byte[] source) { + return encode(source, 0, source.length, ALPHABET, true); + } + + /** + * Encodes a byte array into web safe Base64 notation. + * + * @param source The data to convert + * @param doPadding is {@code true} to pad result with '=' chars + * if it does not fall on 3 byte boundaries + */ + public static String encodeWebSafe(byte[] source, boolean doPadding) { + return encode(source, 0, source.length, WEBSAFE_ALPHABET, doPadding); + } + + /** + * Encodes a byte array into Base64 notation. + * + * @param source the data to convert + * @param off offset in array where conversion should begin + * @param len length of data to convert + * @param alphabet the encoding alphabet + * @param doPadding is {@code true} to pad result with '=' chars + * if it does not fall on 3 byte boundaries + * @since 1.4 + */ + public static String encode(byte[] source, int off, int len, byte[] alphabet, + boolean doPadding) { + byte[] outBuff = encode(source, off, len, alphabet, Integer.MAX_VALUE); + int outLen = outBuff.length; + + // If doPadding is false, set length to truncate '=' + // padding characters + while (doPadding == false && outLen > 0) { + if (outBuff[outLen - 1] != '=') { + break; + } + outLen -= 1; + } + + return new String(outBuff, 0, outLen); + } + + /** + * Encodes a byte array into Base64 notation. + * + * @param source the data to convert + * @param off offset in array where conversion should begin + * @param len length of data to convert + * @param alphabet is the encoding alphabet + * @param maxLineLength maximum length of one line. + * @return the BASE64-encoded byte array + */ + public static byte[] encode(byte[] source, int off, int len, byte[] alphabet, + int maxLineLength) { + int lenDiv3 = (len + 2) / 3; // ceil(len / 3) + int len43 = lenDiv3 * 4; + byte[] outBuff = new byte[len43 // Main 4:3 + + (len43 / maxLineLength)]; // New lines + + int d = 0; + int e = 0; + int len2 = len - 2; + int lineLength = 0; + for (; d < len2; d += 3, e += 4) { + + // The following block of code is the same as + // encode3to4( source, d + off, 3, outBuff, e, alphabet ); + // but inlined for faster encoding (~20% improvement) + int inBuff = + ((source[d + off] << 24) >>> 8) + | ((source[d + 1 + off] << 24) >>> 16) + | ((source[d + 2 + off] << 24) >>> 24); + outBuff[e] = alphabet[(inBuff >>> 18)]; + outBuff[e + 1] = alphabet[(inBuff >>> 12) & 0x3f]; + outBuff[e + 2] = alphabet[(inBuff >>> 6) & 0x3f]; + outBuff[e + 3] = alphabet[(inBuff) & 0x3f]; + + lineLength += 4; + if (lineLength == maxLineLength) { + outBuff[e + 4] = NEW_LINE; + e++; + lineLength = 0; + } // end if: end of line + } // end for: each piece of array + + if (d < len) { + encode3to4(source, d + off, len - d, outBuff, e, alphabet); + + lineLength += 4; + if (lineLength == maxLineLength) { + // Add a last newline + outBuff[e + 4] = NEW_LINE; + e++; + } + e += 4; + } + + assert (e == outBuff.length); + return outBuff; + } + + + /* ******** D E C O D I N G M E T H O D S ******** */ + + + /** + * Decodes four bytes from array source + * and writes the resulting bytes (up to three of them) + * to destination. + * The source and destination arrays can be manipulated + * anywhere along their length by specifying + * srcOffset and destOffset. + * This method does not check to make sure your arrays + * are large enough to accommodate srcOffset + 4 for + * the source array or destOffset + 3 for + * the destination array. + * This method returns the actual number of bytes that + * were converted from the Base64 encoding. + * + * + * @param source the array to convert + * @param srcOffset the index where conversion begins + * @param destination the array to hold the conversion + * @param destOffset the index where output will be put + * @param decodabet the decodabet for decoding Base64 content + * @return the number of decoded bytes converted + * @since 1.3 + */ + private static int decode4to3(byte[] source, int srcOffset, + byte[] destination, int destOffset, byte[] decodabet) { + // Example: Dk== + if (source[srcOffset + 2] == EQUALS_SIGN) { + int outBuff = + ((decodabet[source[srcOffset]] << 24) >>> 6) + | ((decodabet[source[srcOffset + 1]] << 24) >>> 12); + + destination[destOffset] = (byte) (outBuff >>> 16); + return 1; + } else if (source[srcOffset + 3] == EQUALS_SIGN) { + // Example: DkL= + int outBuff = + ((decodabet[source[srcOffset]] << 24) >>> 6) + | ((decodabet[source[srcOffset + 1]] << 24) >>> 12) + | ((decodabet[source[srcOffset + 2]] << 24) >>> 18); + + destination[destOffset] = (byte) (outBuff >>> 16); + destination[destOffset + 1] = (byte) (outBuff >>> 8); + return 2; + } else { + // Example: DkLE + int outBuff = + ((decodabet[source[srcOffset]] << 24) >>> 6) + | ((decodabet[source[srcOffset + 1]] << 24) >>> 12) + | ((decodabet[source[srcOffset + 2]] << 24) >>> 18) + | ((decodabet[source[srcOffset + 3]] << 24) >>> 24); + + destination[destOffset] = (byte) (outBuff >> 16); + destination[destOffset + 1] = (byte) (outBuff >> 8); + destination[destOffset + 2] = (byte) (outBuff); + return 3; + } + } // end decodeToBytes + + + /** + * Decodes data from Base64 notation. + * + * @param s the string to decode (decoded in default encoding) + * @return the decoded data + * @since 1.4 + */ + public static byte[] decode(String s) throws Base64DecoderException { + byte[] bytes = s.getBytes(); + return decode(bytes, 0, bytes.length); + } + + /** + * Decodes data from web safe Base64 notation. + * Web safe encoding uses '-' instead of '+', '_' instead of '/' + * + * @param s the string to decode (decoded in default encoding) + * @return the decoded data + */ + public static byte[] decodeWebSafe(String s) throws Base64DecoderException { + byte[] bytes = s.getBytes(); + return decodeWebSafe(bytes, 0, bytes.length); + } + + /** + * Decodes Base64 content in byte array format and returns + * the decoded byte array. + * + * @param source The Base64 encoded data + * @return decoded data + * @since 1.3 + * @throws Base64DecoderException + */ + public static byte[] decode(byte[] source) throws Base64DecoderException { + return decode(source, 0, source.length); + } + + /** + * Decodes web safe Base64 content in byte array format and returns + * the decoded data. + * Web safe encoding uses '-' instead of '+', '_' instead of '/' + * + * @param source the string to decode (decoded in default encoding) + * @return the decoded data + */ + public static byte[] decodeWebSafe(byte[] source) + throws Base64DecoderException { + return decodeWebSafe(source, 0, source.length); + } + + /** + * Decodes Base64 content in byte array format and returns + * the decoded byte array. + * + * @param source the Base64 encoded data + * @param off the offset of where to begin decoding + * @param len the length of characters to decode + * @return decoded data + * @since 1.3 + * @throws Base64DecoderException + */ + public static byte[] decode(byte[] source, int off, int len) + throws Base64DecoderException { + return decode(source, off, len, DECODABET); + } + + /** + * Decodes web safe Base64 content in byte array format and returns + * the decoded byte array. + * Web safe encoding uses '-' instead of '+', '_' instead of '/' + * + * @param source the Base64 encoded data + * @param off the offset of where to begin decoding + * @param len the length of characters to decode + * @return decoded data + */ + public static byte[] decodeWebSafe(byte[] source, int off, int len) + throws Base64DecoderException { + return decode(source, off, len, WEBSAFE_DECODABET); + } + + /** + * Decodes Base64 content using the supplied decodabet and returns + * the decoded byte array. + * + * @param source the Base64 encoded data + * @param off the offset of where to begin decoding + * @param len the length of characters to decode + * @param decodabet the decodabet for decoding Base64 content + * @return decoded data + */ + public static byte[] decode(byte[] source, int off, int len, byte[] decodabet) + throws Base64DecoderException { + int len34 = len * 3 / 4; + byte[] outBuff = new byte[2 + len34]; // Upper limit on size of output + int outBuffPosn = 0; + + byte[] b4 = new byte[4]; + int b4Posn = 0; + int i = 0; + byte sbiCrop = 0; + byte sbiDecode = 0; + for (i = 0; i < len; i++) { + sbiCrop = (byte) (source[i + off] & 0x7f); // Only the low seven bits + sbiDecode = decodabet[sbiCrop]; + + if (sbiDecode >= WHITE_SPACE_ENC) { // White space Equals sign or better + if (sbiDecode >= EQUALS_SIGN_ENC) { + // An equals sign (for padding) must not occur at position 0 or 1 + // and must be the last byte[s] in the encoded value + if (sbiCrop == EQUALS_SIGN) { + int bytesLeft = len - i; + byte lastByte = (byte) (source[len - 1 + off] & 0x7f); + if (b4Posn == 0 || b4Posn == 1) { + throw new Base64DecoderException( + "invalid padding byte '=' at byte offset " + i); + } else if ((b4Posn == 3 && bytesLeft > 2) + || (b4Posn == 4 && bytesLeft > 1)) { + throw new Base64DecoderException( + "padding byte '=' falsely signals end of encoded value " + + "at offset " + i); + } else if (lastByte != EQUALS_SIGN && lastByte != NEW_LINE) { + throw new Base64DecoderException( + "encoded value has invalid trailing byte"); + } + break; + } + + b4[b4Posn++] = sbiCrop; + if (b4Posn == 4) { + outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet); + b4Posn = 0; + } + } + } else { + throw new Base64DecoderException("Bad Base64 input character at " + i + + ": " + source[i + off] + "(decimal)"); + } + } + + // Because web safe encoding allows non padding base64 encodes, we + // need to pad the rest of the b4 buffer with equal signs when + // b4Posn != 0. There can be at most 2 equal signs at the end of + // four characters, so the b4 buffer must have two or three + // characters. This also catches the case where the input is + // padded with EQUALS_SIGN + if (b4Posn != 0) { + if (b4Posn == 1) { + throw new Base64DecoderException("single trailing character at offset " + + (len - 1)); + } + b4[b4Posn++] = EQUALS_SIGN; + outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet); + } + + byte[] out = new byte[outBuffPosn]; + System.arraycopy(outBuff, 0, out, 0, outBuffPosn); + return out; + } +} diff --git a/src/com/money/manager/ex/inapp/util/Base64DecoderException.java b/src/com/money/manager/ex/inapp/util/Base64DecoderException.java new file mode 100644 index 0000000000..13780ccdc1 --- /dev/null +++ b/src/com/money/manager/ex/inapp/util/Base64DecoderException.java @@ -0,0 +1,32 @@ +// Copyright 2002, Google, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.money.manager.ex.inapp.util; + +/** + * Exception thrown when encountering an invalid Base64 input character. + * + * @author nelson + */ +public class Base64DecoderException extends Exception { + public Base64DecoderException() { + super(); + } + + public Base64DecoderException(String s) { + super(s); + } + + private static final long serialVersionUID = 1L; +} diff --git a/src/com/money/manager/ex/inapp/util/IabException.java b/src/com/money/manager/ex/inapp/util/IabException.java new file mode 100644 index 0000000000..38b5951305 --- /dev/null +++ b/src/com/money/manager/ex/inapp/util/IabException.java @@ -0,0 +1,43 @@ +/* Copyright (c) 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.money.manager.ex.inapp.util; + +/** + * Exception thrown when something went wrong with in-app billing. + * An IabException has an associated IabResult (an error). + * To get the IAB result that caused this exception to be thrown, + * call {@link #getResult()}. + */ +public class IabException extends Exception { + IabResult mResult; + + public IabException(IabResult r) { + this(r, null); + } + public IabException(int response, String message) { + this(new IabResult(response, message)); + } + public IabException(IabResult r, Exception cause) { + super(r.getMessage(), cause); + mResult = r; + } + public IabException(int response, String message, Exception cause) { + this(new IabResult(response, message), cause); + } + + /** Returns the IAB result (error) that this exception signals. */ + public IabResult getResult() { return mResult; } +} \ No newline at end of file diff --git a/src/com/money/manager/ex/inapp/util/IabHelper.java b/src/com/money/manager/ex/inapp/util/IabHelper.java new file mode 100644 index 0000000000..ae218c0544 --- /dev/null +++ b/src/com/money/manager/ex/inapp/util/IabHelper.java @@ -0,0 +1,991 @@ +/* Copyright (c) 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.money.manager.ex.inapp.util; + +import android.app.Activity; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentSender.SendIntentException; +import android.content.ServiceConnection; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.text.TextUtils; +import android.util.Log; + +import com.android.vending.billing.IInAppBillingService; + +import org.json.JSONException; + +import java.util.ArrayList; +import java.util.List; + + +/** + * Provides convenience methods for in-app billing. You can create one instance of this + * class for your application and use it to process in-app billing operations. + * It provides synchronous (blocking) and asynchronous (non-blocking) methods for + * many common in-app billing operations, as well as automatic signature + * verification. + * + * After instantiating, you must perform setup in order to start using the object. + * To perform setup, call the {@link #startSetup} method and provide a listener; + * that listener will be notified when setup is complete, after which (and not before) + * you may call other methods. + * + * After setup is complete, you will typically want to request an inventory of owned + * items and subscriptions. See {@link #queryInventory}, {@link #queryInventoryAsync} + * and related methods. + * + * When you are done with this object, don't forget to call {@link #dispose} + * to ensure proper cleanup. This object holds a binding to the in-app billing + * service, which will leak unless you dispose of it correctly. If you created + * the object on an Activity's onCreate method, then the recommended + * place to dispose of it is the Activity's onDestroy method. + * + * A note about threading: When using this object from a background thread, you may + * call the blocking versions of methods; when using from a UI thread, call + * only the asynchronous versions and handle the results via callbacks. + * Also, notice that you can only call one asynchronous operation at a time; + * attempting to start a second asynchronous operation while the first one + * has not yet completed will result in an exception being thrown. + * + * @author Bruno Oliveira (Google) + * + */ +public class IabHelper { + // Is debug logging enabled? + boolean mDebugLog = false; + String mDebugTag = "IabHelper"; + + // Is setup done? + boolean mSetupDone = false; + + // Has this object been disposed of? (If so, we should ignore callbacks, etc) + boolean mDisposed = false; + + // Are subscriptions supported? + boolean mSubscriptionsSupported = false; + + // Is an asynchronous operation in progress? + // (only one at a time can be in progress) + boolean mAsyncInProgress = false; + + // (for logging/debugging) + // if mAsyncInProgress == true, what asynchronous operation is in progress? + String mAsyncOperation = ""; + + // Context we were passed during initialization + Context mContext; + + // Connection to the service + IInAppBillingService mService; + ServiceConnection mServiceConn; + + // The request code used to launch purchase flow + int mRequestCode; + + // The item type of the current purchase flow + String mPurchasingItemType; + + // Public key for verifying signature, in base64 encoding + String mSignatureBase64 = null; + + // Billing response codes + public static final int BILLING_RESPONSE_RESULT_OK = 0; + public static final int BILLING_RESPONSE_RESULT_USER_CANCELED = 1; + public static final int BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE = 3; + public static final int BILLING_RESPONSE_RESULT_ITEM_UNAVAILABLE = 4; + public static final int BILLING_RESPONSE_RESULT_DEVELOPER_ERROR = 5; + public static final int BILLING_RESPONSE_RESULT_ERROR = 6; + public static final int BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED = 7; + public static final int BILLING_RESPONSE_RESULT_ITEM_NOT_OWNED = 8; + + // IAB Helper error codes + public static final int IABHELPER_ERROR_BASE = -1000; + public static final int IABHELPER_REMOTE_EXCEPTION = -1001; + public static final int IABHELPER_BAD_RESPONSE = -1002; + public static final int IABHELPER_VERIFICATION_FAILED = -1003; + public static final int IABHELPER_SEND_INTENT_FAILED = -1004; + public static final int IABHELPER_USER_CANCELLED = -1005; + public static final int IABHELPER_UNKNOWN_PURCHASE_RESPONSE = -1006; + public static final int IABHELPER_MISSING_TOKEN = -1007; + public static final int IABHELPER_UNKNOWN_ERROR = -1008; + public static final int IABHELPER_SUBSCRIPTIONS_NOT_AVAILABLE = -1009; + public static final int IABHELPER_INVALID_CONSUMPTION = -1010; + + // Keys for the responses from InAppBillingService + public static final String RESPONSE_CODE = "RESPONSE_CODE"; + public static final String RESPONSE_GET_SKU_DETAILS_LIST = "DETAILS_LIST"; + public static final String RESPONSE_BUY_INTENT = "BUY_INTENT"; + public static final String RESPONSE_INAPP_PURCHASE_DATA = "INAPP_PURCHASE_DATA"; + public static final String RESPONSE_INAPP_SIGNATURE = "INAPP_DATA_SIGNATURE"; + public static final String RESPONSE_INAPP_ITEM_LIST = "INAPP_PURCHASE_ITEM_LIST"; + public static final String RESPONSE_INAPP_PURCHASE_DATA_LIST = "INAPP_PURCHASE_DATA_LIST"; + public static final String RESPONSE_INAPP_SIGNATURE_LIST = "INAPP_DATA_SIGNATURE_LIST"; + public static final String INAPP_CONTINUATION_TOKEN = "INAPP_CONTINUATION_TOKEN"; + + // Item types + public static final String ITEM_TYPE_INAPP = "inapp"; + public static final String ITEM_TYPE_SUBS = "subs"; + + // some fields on the getSkuDetails response bundle + public static final String GET_SKU_DETAILS_ITEM_LIST = "ITEM_ID_LIST"; + public static final String GET_SKU_DETAILS_ITEM_TYPE_LIST = "ITEM_TYPE_LIST"; + + /** + * Creates an instance. After creation, it will not yet be ready to use. You must perform + * setup by calling {@link #startSetup} and wait for setup to complete. This constructor does not + * block and is safe to call from a UI thread. + * + * @param ctx Your application or Activity context. Needed to bind to the in-app billing service. + * @param base64PublicKey Your application's public key, encoded in base64. + * This is used for verification of purchase signatures. You can find your app's base64-encoded + * public key in your application's page on Google Play Developer Console. Note that this + * is NOT your "developer public key". + */ + public IabHelper(Context ctx, String base64PublicKey) { + mContext = ctx.getApplicationContext(); + mSignatureBase64 = base64PublicKey; + logDebug("IAB helper created."); + } + + /** + * Enables or disable debug logging through LogCat. + */ + public void enableDebugLogging(boolean enable, String tag) { + checkNotDisposed(); + mDebugLog = enable; + mDebugTag = tag; + } + + public void enableDebugLogging(boolean enable) { + checkNotDisposed(); + mDebugLog = enable; + } + + /** + * Callback for setup process. This listener's {@link #onIabSetupFinished} method is called + * when the setup process is complete. + */ + public interface OnIabSetupFinishedListener { + /** + * Called to notify that setup is complete. + * + * @param result The result of the setup process. + */ + public void onIabSetupFinished(IabResult result); + } + + /** + * Starts the setup process. This will start up the setup process asynchronously. + * You will be notified through the listener when the setup process is complete. + * This method is safe to call from a UI thread. + * + * @param listener The listener to notify when the setup process is complete. + */ + public void startSetup(final OnIabSetupFinishedListener listener) { + // If already set up, can't do it again. + checkNotDisposed(); + if (mSetupDone) throw new IllegalStateException("IAB helper is already set up."); + + // Connection to IAB service + logDebug("Starting in-app billing setup."); + mServiceConn = new ServiceConnection() { + @Override + public void onServiceDisconnected(ComponentName name) { + logDebug("Billing service disconnected."); + mService = null; + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + if (mDisposed) return; + logDebug("Billing service connected."); + mService = IInAppBillingService.Stub.asInterface(service); + String packageName = mContext.getPackageName(); + try { + logDebug("Checking for in-app billing 3 support."); + + // check for in-app billing v3 support + int response = mService.isBillingSupported(3, packageName, ITEM_TYPE_INAPP); + if (response != BILLING_RESPONSE_RESULT_OK) { + if (listener != null) listener.onIabSetupFinished(new IabResult(response, + "Error checking for billing v3 support.")); + + // if in-app purchases aren't supported, neither are subscriptions. + mSubscriptionsSupported = false; + return; + } + logDebug("In-app billing version 3 supported for " + packageName); + + // check for v3 subscriptions support + response = mService.isBillingSupported(3, packageName, ITEM_TYPE_SUBS); + if (response == BILLING_RESPONSE_RESULT_OK) { + logDebug("Subscriptions AVAILABLE."); + mSubscriptionsSupported = true; + } + else { + logDebug("Subscriptions NOT AVAILABLE. Response: " + response); + } + + mSetupDone = true; + } + catch (RemoteException e) { + if (listener != null) { + listener.onIabSetupFinished(new IabResult(IABHELPER_REMOTE_EXCEPTION, + "RemoteException while setting up in-app billing.")); + } + e.printStackTrace(); + return; + } + + if (listener != null) { + listener.onIabSetupFinished(new IabResult(BILLING_RESPONSE_RESULT_OK, "Setup successful.")); + } + } + }; + + Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND"); + serviceIntent.setPackage("com.android.vending"); + if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0).isEmpty()) { + // service available to handle that Intent + mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE); + } + else { + // no service available to handle that Intent + if (listener != null) { + listener.onIabSetupFinished( + new IabResult(BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE, + "Billing service unavailable on device.")); + } + } + } + + /** + * Dispose of object, releasing resources. It's very important to call this + * method when you are done with this object. It will release any resources + * used by it such as service connections. Naturally, once the object is + * disposed of, it can't be used again. + */ + public void dispose() { + logDebug("Disposing."); + mSetupDone = false; + if (mServiceConn != null) { + logDebug("Unbinding from service."); + if (mContext != null) mContext.unbindService(mServiceConn); + } + mDisposed = true; + mContext = null; + mServiceConn = null; + mService = null; + mPurchaseListener = null; + } + + private void checkNotDisposed() { + if (mDisposed) throw new IllegalStateException("IabHelper was disposed of, so it cannot be used."); + } + + /** Returns whether subscriptions are supported. */ + public boolean subscriptionsSupported() { + checkNotDisposed(); + return mSubscriptionsSupported; + } + + + /** + * Callback that notifies when a purchase is finished. + */ + public interface OnIabPurchaseFinishedListener { + /** + * Called to notify that an in-app purchase finished. If the purchase was successful, + * then the sku parameter specifies which item was purchased. If the purchase failed, + * the sku and extraData parameters may or may not be null, depending on how far the purchase + * process went. + * + * @param result The result of the purchase. + * @param info The purchase information (null if purchase failed) + */ + public void onIabPurchaseFinished(IabResult result, Purchase info); + } + + // The listener registered on launchPurchaseFlow, which we have to call back when + // the purchase finishes + OnIabPurchaseFinishedListener mPurchaseListener; + + public void launchPurchaseFlow(Activity act, String sku, int requestCode, OnIabPurchaseFinishedListener listener) { + launchPurchaseFlow(act, sku, requestCode, listener, ""); + } + + public void launchPurchaseFlow(Activity act, String sku, int requestCode, + OnIabPurchaseFinishedListener listener, String extraData) { + launchPurchaseFlow(act, sku, ITEM_TYPE_INAPP, requestCode, listener, extraData); + } + + public void launchSubscriptionPurchaseFlow(Activity act, String sku, int requestCode, + OnIabPurchaseFinishedListener listener) { + launchSubscriptionPurchaseFlow(act, sku, requestCode, listener, ""); + } + + public void launchSubscriptionPurchaseFlow(Activity act, String sku, int requestCode, + OnIabPurchaseFinishedListener listener, String extraData) { + launchPurchaseFlow(act, sku, ITEM_TYPE_SUBS, requestCode, listener, extraData); + } + + /** + * Initiate the UI flow for an in-app purchase. Call this method to initiate an in-app purchase, + * which will involve bringing up the Google Play screen. The calling activity will be paused while + * the user interacts with Google Play, and the result will be delivered via the activity's + * {@link android.app.Activity#onActivityResult} method, at which point you must call + * this object's {@link #handleActivityResult} method to continue the purchase flow. This method + * MUST be called from the UI thread of the Activity. + * + * @param act The calling activity. + * @param sku The sku of the item to purchase. + * @param itemType indicates if it's a product or a subscription (ITEM_TYPE_INAPP or ITEM_TYPE_SUBS) + * @param requestCode A request code (to differentiate from other responses -- + * as in {@link android.app.Activity#startActivityForResult}). + * @param listener The listener to notify when the purchase process finishes + * @param extraData Extra data (developer payload), which will be returned with the purchase data + * when the purchase completes. This extra data will be permanently bound to that purchase + * and will always be returned when the purchase is queried. + */ + public void launchPurchaseFlow(Activity act, String sku, String itemType, int requestCode, + OnIabPurchaseFinishedListener listener, String extraData) { + checkNotDisposed(); + checkSetupDone("launchPurchaseFlow"); + flagStartAsync("launchPurchaseFlow"); + IabResult result; + + if (itemType.equals(ITEM_TYPE_SUBS) && !mSubscriptionsSupported) { + IabResult r = new IabResult(IABHELPER_SUBSCRIPTIONS_NOT_AVAILABLE, + "Subscriptions are not available."); + flagEndAsync(); + if (listener != null) listener.onIabPurchaseFinished(r, null); + return; + } + + try { + logDebug("Constructing buy intent for " + sku + ", item type: " + itemType); + Bundle buyIntentBundle = mService.getBuyIntent(3, mContext.getPackageName(), sku, itemType, extraData); + int response = getResponseCodeFromBundle(buyIntentBundle); + if (response != BILLING_RESPONSE_RESULT_OK) { + logError("Unable to buy item, Error response: " + getResponseDesc(response)); + flagEndAsync(); + result = new IabResult(response, "Unable to buy item"); + if (listener != null) listener.onIabPurchaseFinished(result, null); + return; + } + + PendingIntent pendingIntent = buyIntentBundle.getParcelable(RESPONSE_BUY_INTENT); + logDebug("Launching buy intent for " + sku + ". Request code: " + requestCode); + mRequestCode = requestCode; + mPurchaseListener = listener; + mPurchasingItemType = itemType; + act.startIntentSenderForResult(pendingIntent.getIntentSender(), + requestCode, new Intent(), + Integer.valueOf(0), Integer.valueOf(0), + Integer.valueOf(0)); + } + catch (SendIntentException e) { + logError("SendIntentException while launching purchase flow for sku " + sku); + e.printStackTrace(); + flagEndAsync(); + + result = new IabResult(IABHELPER_SEND_INTENT_FAILED, "Failed to send intent."); + if (listener != null) listener.onIabPurchaseFinished(result, null); + } + catch (RemoteException e) { + logError("RemoteException while launching purchase flow for sku " + sku); + e.printStackTrace(); + flagEndAsync(); + + result = new IabResult(IABHELPER_REMOTE_EXCEPTION, "Remote exception while starting purchase flow"); + if (listener != null) listener.onIabPurchaseFinished(result, null); + } + } + + /** + * Handles an activity result that's part of the purchase flow in in-app billing. If you + * are calling {@link #launchPurchaseFlow}, then you must call this method from your + * Activity's {@link android.app.Activity@onActivityResult} method. This method + * MUST be called from the UI thread of the Activity. + * + * @param requestCode The requestCode as you received it. + * @param resultCode The resultCode as you received it. + * @param data The data (Intent) as you received it. + * @return Returns true if the result was related to a purchase flow and was handled; + * false if the result was not related to a purchase, in which case you should + * handle it normally. + */ + public boolean handleActivityResult(int requestCode, int resultCode, Intent data) { + IabResult result; + if (requestCode != mRequestCode) return false; + + checkNotDisposed(); + checkSetupDone("handleActivityResult"); + + // end of async purchase operation that started on launchPurchaseFlow + flagEndAsync(); + + if (data == null) { + logError("Null data in IAB activity result."); + result = new IabResult(IABHELPER_BAD_RESPONSE, "Null data in IAB result"); + if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null); + return true; + } + + int responseCode = getResponseCodeFromIntent(data); + String purchaseData = data.getStringExtra(RESPONSE_INAPP_PURCHASE_DATA); + String dataSignature = data.getStringExtra(RESPONSE_INAPP_SIGNATURE); + + if (resultCode == Activity.RESULT_OK && responseCode == BILLING_RESPONSE_RESULT_OK) { + logDebug("Successful resultcode from purchase activity."); + logDebug("Purchase data: " + purchaseData); + logDebug("Data signature: " + dataSignature); + logDebug("Extras: " + data.getExtras()); + logDebug("Expected item type: " + mPurchasingItemType); + + if (purchaseData == null || dataSignature == null) { + logError("BUG: either purchaseData or dataSignature is null."); + logDebug("Extras: " + data.getExtras().toString()); + result = new IabResult(IABHELPER_UNKNOWN_ERROR, "IAB returned null purchaseData or dataSignature"); + if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null); + return true; + } + + Purchase purchase = null; + try { + purchase = new Purchase(mPurchasingItemType, purchaseData, dataSignature); + String sku = purchase.getSku(); + + // Verify signature + if (!Security.verifyPurchase(mSignatureBase64, purchaseData, dataSignature)) { + logError("Purchase signature verification FAILED for sku " + sku); + result = new IabResult(IABHELPER_VERIFICATION_FAILED, "Signature verification failed for sku " + sku); + if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, purchase); + return true; + } + logDebug("Purchase signature successfully verified."); + } + catch (JSONException e) { + logError("Failed to parse purchase data."); + e.printStackTrace(); + result = new IabResult(IABHELPER_BAD_RESPONSE, "Failed to parse purchase data."); + if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null); + return true; + } + + if (mPurchaseListener != null) { + mPurchaseListener.onIabPurchaseFinished(new IabResult(BILLING_RESPONSE_RESULT_OK, "Success"), purchase); + } + } + else if (resultCode == Activity.RESULT_OK) { + // result code was OK, but in-app billing response was not OK. + logDebug("Result code was OK but in-app billing response was not OK: " + getResponseDesc(responseCode)); + if (mPurchaseListener != null) { + result = new IabResult(responseCode, "Problem purchashing item."); + mPurchaseListener.onIabPurchaseFinished(result, null); + } + } + else if (resultCode == Activity.RESULT_CANCELED) { + logDebug("Purchase canceled - Response: " + getResponseDesc(responseCode)); + result = new IabResult(IABHELPER_USER_CANCELLED, "User canceled."); + if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null); + } + else { + logError("Purchase failed. Result code: " + Integer.toString(resultCode) + + ". Response: " + getResponseDesc(responseCode)); + result = new IabResult(IABHELPER_UNKNOWN_PURCHASE_RESPONSE, "Unknown purchase response."); + if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null); + } + return true; + } + + public Inventory queryInventory(boolean querySkuDetails, List moreSkus) throws IabException { + return queryInventory(querySkuDetails, moreSkus, null); + } + + /** + * Queries the inventory. This will query all owned items from the server, as well as + * information on additional skus, if specified. This method may block or take long to execute. + * Do not call from a UI thread. For that, use the non-blocking version {@link #refreshInventoryAsync}. + * + * @param querySkuDetails if true, SKU details (price, description, etc) will be queried as well + * as purchase information. + * @param moreItemSkus additional PRODUCT skus to query information on, regardless of ownership. + * Ignored if null or if querySkuDetails is false. + * @param moreSubsSkus additional SUBSCRIPTIONS skus to query information on, regardless of ownership. + * Ignored if null or if querySkuDetails is false. + * @throws IabException if a problem occurs while refreshing the inventory. + */ + public Inventory queryInventory(boolean querySkuDetails, List moreItemSkus, + List moreSubsSkus) throws IabException { + checkNotDisposed(); + checkSetupDone("queryInventory"); + try { + Inventory inv = new Inventory(); + int r = queryPurchases(inv, ITEM_TYPE_INAPP); + if (r != BILLING_RESPONSE_RESULT_OK) { + throw new IabException(r, "Error refreshing inventory (querying owned items)."); + } + + if (querySkuDetails) { + r = querySkuDetails(ITEM_TYPE_INAPP, inv, moreItemSkus); + if (r != BILLING_RESPONSE_RESULT_OK) { + throw new IabException(r, "Error refreshing inventory (querying prices of items)."); + } + } + + // if subscriptions are supported, then also query for subscriptions + if (mSubscriptionsSupported) { + r = queryPurchases(inv, ITEM_TYPE_SUBS); + if (r != BILLING_RESPONSE_RESULT_OK) { + throw new IabException(r, "Error refreshing inventory (querying owned subscriptions)."); + } + + if (querySkuDetails) { + r = querySkuDetails(ITEM_TYPE_SUBS, inv, moreItemSkus); + if (r != BILLING_RESPONSE_RESULT_OK) { + throw new IabException(r, "Error refreshing inventory (querying prices of subscriptions)."); + } + } + } + + return inv; + } + catch (RemoteException e) { + throw new IabException(IABHELPER_REMOTE_EXCEPTION, "Remote exception while refreshing inventory.", e); + } + catch (JSONException e) { + throw new IabException(IABHELPER_BAD_RESPONSE, "Error parsing JSON response while refreshing inventory.", e); + } + } + + /** + * Listener that notifies when an inventory query operation completes. + */ + public interface QueryInventoryFinishedListener { + /** + * Called to notify that an inventory query operation completed. + * + * @param result The result of the operation. + * @param inv The inventory. + */ + public void onQueryInventoryFinished(IabResult result, Inventory inv); + } + + + /** + * Asynchronous wrapper for inventory query. This will perform an inventory + * query as described in {@link #queryInventory}, but will do so asynchronously + * and call back the specified listener upon completion. This method is safe to + * call from a UI thread. + * + * @param querySkuDetails as in {@link #queryInventory} + * @param moreSkus as in {@link #queryInventory} + * @param listener The listener to notify when the refresh operation completes. + */ + public void queryInventoryAsync(final boolean querySkuDetails, + final List moreSkus, + final QueryInventoryFinishedListener listener) { + final Handler handler = new Handler(); + checkNotDisposed(); + checkSetupDone("queryInventory"); + flagStartAsync("refresh inventory"); + (new Thread(new Runnable() { + public void run() { + IabResult result = new IabResult(BILLING_RESPONSE_RESULT_OK, "Inventory refresh successful."); + Inventory inv = null; + try { + inv = queryInventory(querySkuDetails, moreSkus); + } + catch (IabException ex) { + result = ex.getResult(); + } + + flagEndAsync(); + + final IabResult result_f = result; + final Inventory inv_f = inv; + if (!mDisposed && listener != null) { + handler.post(new Runnable() { + public void run() { + listener.onQueryInventoryFinished(result_f, inv_f); + } + }); + } + } + })).start(); + } + + public void queryInventoryAsync(QueryInventoryFinishedListener listener) { + queryInventoryAsync(true, null, listener); + } + + public void queryInventoryAsync(boolean querySkuDetails, QueryInventoryFinishedListener listener) { + queryInventoryAsync(querySkuDetails, null, listener); + } + + + /** + * Consumes a given in-app product. Consuming can only be done on an item + * that's owned, and as a result of consumption, the user will no longer own it. + * This method may block or take long to return. Do not call from the UI thread. + * For that, see {@link #consumeAsync}. + * + * @param itemInfo The PurchaseInfo that represents the item to consume. + * @throws IabException if there is a problem during consumption. + */ + void consume(Purchase itemInfo) throws IabException { + checkNotDisposed(); + checkSetupDone("consume"); + + if (!itemInfo.mItemType.equals(ITEM_TYPE_INAPP)) { + throw new IabException(IABHELPER_INVALID_CONSUMPTION, + "Items of type '" + itemInfo.mItemType + "' can't be consumed."); + } + + try { + String token = itemInfo.getToken(); + String sku = itemInfo.getSku(); + if (token == null || token.equals("")) { + logError("Can't consume "+ sku + ". No token."); + throw new IabException(IABHELPER_MISSING_TOKEN, "PurchaseInfo is missing token for sku: " + + sku + " " + itemInfo); + } + + logDebug("Consuming sku: " + sku + ", token: " + token); + int response = mService.consumePurchase(3, mContext.getPackageName(), token); + if (response == BILLING_RESPONSE_RESULT_OK) { + logDebug("Successfully consumed sku: " + sku); + } + else { + logDebug("Error consuming consuming sku " + sku + ". " + getResponseDesc(response)); + throw new IabException(response, "Error consuming sku " + sku); + } + } + catch (RemoteException e) { + throw new IabException(IABHELPER_REMOTE_EXCEPTION, "Remote exception while consuming. PurchaseInfo: " + itemInfo, e); + } + } + + /** + * Callback that notifies when a consumption operation finishes. + */ + public interface OnConsumeFinishedListener { + /** + * Called to notify that a consumption has finished. + * + * @param purchase The purchase that was (or was to be) consumed. + * @param result The result of the consumption operation. + */ + public void onConsumeFinished(Purchase purchase, IabResult result); + } + + /** + * Callback that notifies when a multi-item consumption operation finishes. + */ + public interface OnConsumeMultiFinishedListener { + /** + * Called to notify that a consumption of multiple items has finished. + * + * @param purchases The purchases that were (or were to be) consumed. + * @param results The results of each consumption operation, corresponding to each + * sku. + */ + public void onConsumeMultiFinished(List purchases, List results); + } + + /** + * Asynchronous wrapper to item consumption. Works like {@link #consume}, but + * performs the consumption in the background and notifies completion through + * the provided listener. This method is safe to call from a UI thread. + * + * @param purchase The purchase to be consumed. + * @param listener The listener to notify when the consumption operation finishes. + */ + public void consumeAsync(Purchase purchase, OnConsumeFinishedListener listener) { + checkNotDisposed(); + checkSetupDone("consume"); + List purchases = new ArrayList(); + purchases.add(purchase); + consumeAsyncInternal(purchases, listener, null); + } + + /** + * Same as {@link consumeAsync}, but for multiple items at once. + * @param purchases The list of PurchaseInfo objects representing the purchases to consume. + * @param listener The listener to notify when the consumption operation finishes. + */ + public void consumeAsync(List purchases, OnConsumeMultiFinishedListener listener) { + checkNotDisposed(); + checkSetupDone("consume"); + consumeAsyncInternal(purchases, null, listener); + } + + /** + * Returns a human-readable description for the given response code. + * + * @param code The response code + * @return A human-readable string explaining the result code. + * It also includes the result code numerically. + */ + public static String getResponseDesc(int code) { + String[] iab_msgs = ("0:OK/1:User Canceled/2:Unknown/" + + "3:Billing Unavailable/4:Item unavailable/" + + "5:Developer Error/6:Error/7:Item Already Owned/" + + "8:Item not owned").split("/"); + String[] iabhelper_msgs = ("0:OK/-1001:Remote exception during initialization/" + + "-1002:Bad response received/" + + "-1003:Purchase signature verification failed/" + + "-1004:Send intent failed/" + + "-1005:User cancelled/" + + "-1006:Unknown purchase response/" + + "-1007:Missing token/" + + "-1008:Unknown error/" + + "-1009:Subscriptions not available/" + + "-1010:Invalid consumption attempt").split("/"); + + if (code <= IABHELPER_ERROR_BASE) { + int index = IABHELPER_ERROR_BASE - code; + if (index >= 0 && index < iabhelper_msgs.length) return iabhelper_msgs[index]; + else return String.valueOf(code) + ":Unknown IAB Helper Error"; + } + else if (code < 0 || code >= iab_msgs.length) + return String.valueOf(code) + ":Unknown"; + else + return iab_msgs[code]; + } + + + // Checks that setup was done; if not, throws an exception. + void checkSetupDone(String operation) { + if (!mSetupDone) { + logError("Illegal state for operation (" + operation + "): IAB helper is not set up."); + throw new IllegalStateException("IAB helper is not set up. Can't perform operation: " + operation); + } + } + + // Workaround to bug where sometimes response codes come as Long instead of Integer + int getResponseCodeFromBundle(Bundle b) { + Object o = b.get(RESPONSE_CODE); + if (o == null) { + logDebug("Bundle with null response code, assuming OK (known issue)"); + return BILLING_RESPONSE_RESULT_OK; + } + else if (o instanceof Integer) return ((Integer)o).intValue(); + else if (o instanceof Long) return (int)((Long)o).longValue(); + else { + logError("Unexpected type for bundle response code."); + logError(o.getClass().getName()); + throw new RuntimeException("Unexpected type for bundle response code: " + o.getClass().getName()); + } + } + + // Workaround to bug where sometimes response codes come as Long instead of Integer + int getResponseCodeFromIntent(Intent i) { + Object o = i.getExtras().get(RESPONSE_CODE); + if (o == null) { + logError("Intent with no response code, assuming OK (known issue)"); + return BILLING_RESPONSE_RESULT_OK; + } + else if (o instanceof Integer) return ((Integer)o).intValue(); + else if (o instanceof Long) return (int)((Long)o).longValue(); + else { + logError("Unexpected type for intent response code."); + logError(o.getClass().getName()); + throw new RuntimeException("Unexpected type for intent response code: " + o.getClass().getName()); + } + } + + void flagStartAsync(String operation) { + if (mAsyncInProgress) throw new IllegalStateException("Can't start async operation (" + + operation + ") because another async operation(" + mAsyncOperation + ") is in progress."); + mAsyncOperation = operation; + mAsyncInProgress = true; + logDebug("Starting async operation: " + operation); + } + + void flagEndAsync() { + logDebug("Ending async operation: " + mAsyncOperation); + mAsyncOperation = ""; + mAsyncInProgress = false; + } + + + int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException { + // Query purchases + logDebug("Querying owned items, item type: " + itemType); + logDebug("Package name: " + mContext.getPackageName()); + boolean verificationFailed = false; + String continueToken = null; + + do { + logDebug("Calling getPurchases with continuation token: " + continueToken); + Bundle ownedItems = mService.getPurchases(3, mContext.getPackageName(), + itemType, continueToken); + + int response = getResponseCodeFromBundle(ownedItems); + logDebug("Owned items response: " + String.valueOf(response)); + if (response != BILLING_RESPONSE_RESULT_OK) { + logDebug("getPurchases() failed: " + getResponseDesc(response)); + return response; + } + if (!ownedItems.containsKey(RESPONSE_INAPP_ITEM_LIST) + || !ownedItems.containsKey(RESPONSE_INAPP_PURCHASE_DATA_LIST) + || !ownedItems.containsKey(RESPONSE_INAPP_SIGNATURE_LIST)) { + logError("Bundle returned from getPurchases() doesn't contain required fields."); + return IABHELPER_BAD_RESPONSE; + } + + ArrayList ownedSkus = ownedItems.getStringArrayList( + RESPONSE_INAPP_ITEM_LIST); + ArrayList purchaseDataList = ownedItems.getStringArrayList( + RESPONSE_INAPP_PURCHASE_DATA_LIST); + ArrayList signatureList = ownedItems.getStringArrayList( + RESPONSE_INAPP_SIGNATURE_LIST); + + for (int i = 0; i < purchaseDataList.size(); ++i) { + String purchaseData = purchaseDataList.get(i); + String signature = signatureList.get(i); + String sku = ownedSkus.get(i); + if (Security.verifyPurchase(mSignatureBase64, purchaseData, signature)) { + logDebug("Sku is owned: " + sku); + Purchase purchase = new Purchase(itemType, purchaseData, signature); + + if (TextUtils.isEmpty(purchase.getToken())) { + logWarn("BUG: empty/null token!"); + logDebug("Purchase data: " + purchaseData); + } + + // Record ownership and token + inv.addPurchase(purchase); + } + else { + logWarn("Purchase signature verification **FAILED**. Not adding item."); + logDebug(" Purchase data: " + purchaseData); + logDebug(" Signature: " + signature); + verificationFailed = true; + } + } + + continueToken = ownedItems.getString(INAPP_CONTINUATION_TOKEN); + logDebug("Continuation token: " + continueToken); + } while (!TextUtils.isEmpty(continueToken)); + + return verificationFailed ? IABHELPER_VERIFICATION_FAILED : BILLING_RESPONSE_RESULT_OK; + } + + int querySkuDetails(String itemType, Inventory inv, List moreSkus) + throws RemoteException, JSONException { + logDebug("Querying SKU details."); + ArrayList skuList = new ArrayList(); + skuList.addAll(inv.getAllOwnedSkus(itemType)); + if (moreSkus != null) { + for (String sku : moreSkus) { + if (!skuList.contains(sku)) { + skuList.add(sku); + } + } + } + + if (skuList.size() == 0) { + logDebug("queryPrices: nothing to do because there are no SKUs."); + return BILLING_RESPONSE_RESULT_OK; + } + + Bundle querySkus = new Bundle(); + querySkus.putStringArrayList(GET_SKU_DETAILS_ITEM_LIST, skuList); + Bundle skuDetails = mService.getSkuDetails(3, mContext.getPackageName(), + itemType, querySkus); + + if (!skuDetails.containsKey(RESPONSE_GET_SKU_DETAILS_LIST)) { + int response = getResponseCodeFromBundle(skuDetails); + if (response != BILLING_RESPONSE_RESULT_OK) { + logDebug("getSkuDetails() failed: " + getResponseDesc(response)); + return response; + } + else { + logError("getSkuDetails() returned a bundle with neither an error nor a detail list."); + return IABHELPER_BAD_RESPONSE; + } + } + + ArrayList responseList = skuDetails.getStringArrayList( + RESPONSE_GET_SKU_DETAILS_LIST); + + for (String thisResponse : responseList) { + SkuDetails d = new SkuDetails(itemType, thisResponse); + logDebug("Got sku details: " + d); + inv.addSkuDetails(d); + } + return BILLING_RESPONSE_RESULT_OK; + } + + + void consumeAsyncInternal(final List purchases, + final OnConsumeFinishedListener singleListener, + final OnConsumeMultiFinishedListener multiListener) { + final Handler handler = new Handler(); + flagStartAsync("consume"); + (new Thread(new Runnable() { + public void run() { + final List results = new ArrayList(); + for (Purchase purchase : purchases) { + try { + consume(purchase); + results.add(new IabResult(BILLING_RESPONSE_RESULT_OK, "Successful consume of sku " + purchase.getSku())); + } + catch (IabException ex) { + results.add(ex.getResult()); + } + } + + flagEndAsync(); + if (!mDisposed && singleListener != null) { + handler.post(new Runnable() { + public void run() { + singleListener.onConsumeFinished(purchases.get(0), results.get(0)); + } + }); + } + if (!mDisposed && multiListener != null) { + handler.post(new Runnable() { + public void run() { + multiListener.onConsumeMultiFinished(purchases, results); + } + }); + } + } + })).start(); + } + + void logDebug(String msg) { + if (mDebugLog) Log.d(mDebugTag, msg); + } + + void logError(String msg) { + Log.e(mDebugTag, "In-app billing error: " + msg); + } + + void logWarn(String msg) { + Log.w(mDebugTag, "In-app billing warning: " + msg); + } +} diff --git a/src/com/money/manager/ex/inapp/util/IabResult.java b/src/com/money/manager/ex/inapp/util/IabResult.java new file mode 100644 index 0000000000..8e7ddf00fc --- /dev/null +++ b/src/com/money/manager/ex/inapp/util/IabResult.java @@ -0,0 +1,45 @@ +/* Copyright (c) 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.money.manager.ex.inapp.util; + +/** + * Represents the result of an in-app billing operation. + * A result is composed of a response code (an integer) and possibly a + * message (String). You can get those by calling + * {@link #getResponse} and {@link #getMessage()}, respectively. You + * can also inquire whether a result is a success or a failure by + * calling {@link #isSuccess()} and {@link #isFailure()}. + */ +public class IabResult { + int mResponse; + String mMessage; + + public IabResult(int response, String message) { + mResponse = response; + if (message == null || message.trim().length() == 0) { + mMessage = IabHelper.getResponseDesc(response); + } + else { + mMessage = message + " (response: " + IabHelper.getResponseDesc(response) + ")"; + } + } + public int getResponse() { return mResponse; } + public String getMessage() { return mMessage; } + public boolean isSuccess() { return mResponse == IabHelper.BILLING_RESPONSE_RESULT_OK; } + public boolean isFailure() { return !isSuccess(); } + public String toString() { return "IabResult: " + getMessage(); } +} + diff --git a/src/com/money/manager/ex/inapp/util/Inventory.java b/src/com/money/manager/ex/inapp/util/Inventory.java new file mode 100644 index 0000000000..e0b6585987 --- /dev/null +++ b/src/com/money/manager/ex/inapp/util/Inventory.java @@ -0,0 +1,91 @@ +/* Copyright (c) 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.money.manager.ex.inapp.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Represents a block of information about in-app items. + * An Inventory is returned by such methods as {@link IabHelper#queryInventory}. + */ +public class Inventory { + Map mSkuMap = new HashMap(); + Map mPurchaseMap = new HashMap(); + + Inventory() { } + + /** Returns the listing details for an in-app product. */ + public SkuDetails getSkuDetails(String sku) { + return mSkuMap.get(sku); + } + + /** Returns purchase information for a given product, or null if there is no purchase. */ + public Purchase getPurchase(String sku) { + return mPurchaseMap.get(sku); + } + + /** Returns whether or not there exists a purchase of the given product. */ + public boolean hasPurchase(String sku) { + return mPurchaseMap.containsKey(sku); + } + + /** Return whether or not details about the given product are available. */ + public boolean hasDetails(String sku) { + return mSkuMap.containsKey(sku); + } + + /** + * Erase a purchase (locally) from the inventory, given its product ID. This just + * modifies the Inventory object locally and has no effect on the server! This is + * useful when you have an existing Inventory object which you know to be up to date, + * and you have just consumed an item successfully, which means that erasing its + * purchase data from the Inventory you already have is quicker than querying for + * a new Inventory. + */ + public void erasePurchase(String sku) { + if (mPurchaseMap.containsKey(sku)) mPurchaseMap.remove(sku); + } + + /** Returns a list of all owned product IDs. */ + List getAllOwnedSkus() { + return new ArrayList(mPurchaseMap.keySet()); + } + + /** Returns a list of all owned product IDs of a given type */ + List getAllOwnedSkus(String itemType) { + List result = new ArrayList(); + for (Purchase p : mPurchaseMap.values()) { + if (p.getItemType().equals(itemType)) result.add(p.getSku()); + } + return result; + } + + /** Returns a list of all purchases. */ + List getAllPurchases() { + return new ArrayList(mPurchaseMap.values()); + } + + void addSkuDetails(SkuDetails d) { + mSkuMap.put(d.getSku(), d); + } + + void addPurchase(Purchase p) { + mPurchaseMap.put(p.getSku(), p); + } +} diff --git a/src/com/money/manager/ex/inapp/util/Purchase.java b/src/com/money/manager/ex/inapp/util/Purchase.java new file mode 100644 index 0000000000..7f92930387 --- /dev/null +++ b/src/com/money/manager/ex/inapp/util/Purchase.java @@ -0,0 +1,63 @@ +/* Copyright (c) 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.money.manager.ex.inapp.util; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Represents an in-app billing purchase. + */ +public class Purchase { + String mItemType; // ITEM_TYPE_INAPP or ITEM_TYPE_SUBS + String mOrderId; + String mPackageName; + String mSku; + long mPurchaseTime; + int mPurchaseState; + String mDeveloperPayload; + String mToken; + String mOriginalJson; + String mSignature; + + public Purchase(String itemType, String jsonPurchaseInfo, String signature) throws JSONException { + mItemType = itemType; + mOriginalJson = jsonPurchaseInfo; + JSONObject o = new JSONObject(mOriginalJson); + mOrderId = o.optString("orderId"); + mPackageName = o.optString("packageName"); + mSku = o.optString("productId"); + mPurchaseTime = o.optLong("purchaseTime"); + mPurchaseState = o.optInt("purchaseState"); + mDeveloperPayload = o.optString("developerPayload"); + mToken = o.optString("token", o.optString("purchaseToken")); + mSignature = signature; + } + + public String getItemType() { return mItemType; } + public String getOrderId() { return mOrderId; } + public String getPackageName() { return mPackageName; } + public String getSku() { return mSku; } + public long getPurchaseTime() { return mPurchaseTime; } + public int getPurchaseState() { return mPurchaseState; } + public String getDeveloperPayload() { return mDeveloperPayload; } + public String getToken() { return mToken; } + public String getOriginalJson() { return mOriginalJson; } + public String getSignature() { return mSignature; } + + @Override + public String toString() { return "PurchaseInfo(type:" + mItemType + "):" + mOriginalJson; } +} diff --git a/src/com/money/manager/ex/inapp/util/Security.java b/src/com/money/manager/ex/inapp/util/Security.java new file mode 100644 index 0000000000..199eb0621c --- /dev/null +++ b/src/com/money/manager/ex/inapp/util/Security.java @@ -0,0 +1,123 @@ +/* Copyright (c) 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.money.manager.ex.inapp.util; + +import android.text.TextUtils; +import android.util.Log; + +import org.json.JSONException; +import org.json.JSONObject; + + +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +/** + * Security-related methods. For a secure implementation, all of this code + * should be implemented on a server that communicates with the + * application on the device. For the sake of simplicity and clarity of this + * example, this code is included here and is executed on the device. If you + * must verify the purchases on the phone, you should obfuscate this code to + * make it harder for an attacker to replace the code with stubs that treat all + * purchases as verified. + */ +public class Security { + private static final String TAG = "IABUtil/Security"; + + private static final String KEY_FACTORY_ALGORITHM = "RSA"; + private static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; + + /** + * Verifies that the data was signed with the given signature, and returns + * the verified purchase. The data is in JSON format and signed + * with a private key. The data also contains the {@link PurchaseState} + * and product ID of the purchase. + * @param base64PublicKey the base64-encoded public key to use for verifying. + * @param signedData the signed JSON string (signed, not encrypted) + * @param signature the signature for the data, signed with the private key + */ + public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) { + if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey) || + TextUtils.isEmpty(signature)) { + Log.e(TAG, "Purchase verification failed: missing data."); + return false; + } + + PublicKey key = Security.generatePublicKey(base64PublicKey); + return Security.verify(key, signedData, signature); + } + + /** + * Generates a PublicKey instance from a string containing the + * Base64-encoded public key. + * + * @param encodedPublicKey Base64-encoded public key + * @throws IllegalArgumentException if encodedPublicKey is invalid + */ + public static PublicKey generatePublicKey(String encodedPublicKey) { + try { + byte[] decodedKey = Base64.decode(encodedPublicKey); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM); + return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey)); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } catch (InvalidKeySpecException e) { + Log.e(TAG, "Invalid key specification."); + throw new IllegalArgumentException(e); + } catch (Base64DecoderException e) { + Log.e(TAG, "Base64 decoding failed."); + throw new IllegalArgumentException(e); + } + } + + /** + * Verifies that the signature from the server matches the computed + * signature on the data. Returns true if the data is correctly signed. + * + * @param publicKey public key associated with the developer account + * @param signedData signed data from server + * @param signature server signature + * @return true if the data and signature match + */ + public static boolean verify(PublicKey publicKey, String signedData, String signature) { + Signature sig; + try { + sig = Signature.getInstance(SIGNATURE_ALGORITHM); + sig.initVerify(publicKey); + sig.update(signedData.getBytes()); + if (!sig.verify(Base64.decode(signature))) { + Log.e(TAG, "Signature verification failed."); + return false; + } + return true; + } catch (NoSuchAlgorithmException e) { + Log.e(TAG, "NoSuchAlgorithmException."); + } catch (InvalidKeyException e) { + Log.e(TAG, "Invalid key specification."); + } catch (SignatureException e) { + Log.e(TAG, "Signature exception."); + } catch (Base64DecoderException e) { + Log.e(TAG, "Base64 decoding failed."); + } + return false; + } +} diff --git a/src/com/money/manager/ex/inapp/util/SkuDetails.java b/src/com/money/manager/ex/inapp/util/SkuDetails.java new file mode 100644 index 0000000000..715eb81c67 --- /dev/null +++ b/src/com/money/manager/ex/inapp/util/SkuDetails.java @@ -0,0 +1,58 @@ +/* Copyright (c) 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.money.manager.ex.inapp.util; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Represents an in-app product's listing details. + */ +public class SkuDetails { + String mItemType; + String mSku; + String mType; + String mPrice; + String mTitle; + String mDescription; + String mJson; + + public SkuDetails(String jsonSkuDetails) throws JSONException { + this(IabHelper.ITEM_TYPE_INAPP, jsonSkuDetails); + } + + public SkuDetails(String itemType, String jsonSkuDetails) throws JSONException { + mItemType = itemType; + mJson = jsonSkuDetails; + JSONObject o = new JSONObject(mJson); + mSku = o.optString("productId"); + mType = o.optString("type"); + mPrice = o.optString("price"); + mTitle = o.optString("title"); + mDescription = o.optString("description"); + } + + public String getSku() { return mSku; } + public String getType() { return mType; } + public String getPrice() { return mPrice; } + public String getTitle() { return mTitle; } + public String getDescription() { return mDescription; } + + @Override + public String toString() { + return "SkuDetails:" + mJson; + } +} From 230bd69150e55190979a45cb656d4809ad19ab64 Mon Sep 17 00:00:00 2001 From: AlessandroLazzari Date: Tue, 16 Sep 2014 22:15:21 +0200 Subject: [PATCH 02/12] remove module androidbillinglibrary --- AndroidManifest.xml | 12 +----------- build.gradle | 17 ++++++++--------- settings.gradle | 1 - src/com/money/manager/ex/DonateActivity.java | 3 --- src/com/money/manager/ex/MainActivity.java | 2 +- .../money/manager/ex/core/InAppBilling.java | 18 ------------------ 6 files changed, 10 insertions(+), 43 deletions(-) delete mode 100644 src/com/money/manager/ex/core/InAppBilling.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index f6ef1d95a8..d6cdbd52ca 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -105,16 +105,6 @@ android:exported="true"> - - - - - - - - - - - + diff --git a/build.gradle b/build.gradle index cf058d1796..08d245b9bd 100644 --- a/build.gradle +++ b/build.gradle @@ -18,24 +18,24 @@ apply plugin: 'android' dependencies { compile fileTree(dir: 'libs', include: '*.jar') - compile project(':androidbillinglibrary') + //compile project(':androidbillinglibrary') compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar' compile 'com.android.support:support-v4:20.0.0' compile 'com.github.gabrielemariotti.changeloglib:library:1.5.1' } android { + signingConfigs { + } compileSdkVersion 19 - buildToolsVersion "19.1.0" - + buildToolsVersion '19.1.0' defaultConfig { - applicationId "com.money.manager.ex" + applicationId 'com.money.manager.ex' minSdkVersion 8 targetSdkVersion 19 versionCode 586 - versionName "1.4.15" + versionName '1.4.15' } - sourceSets { main { manifest.srcFile 'AndroidManifest.xml' @@ -59,7 +59,6 @@ android { debug.setRoot('build-types/debug') release.setRoot('build-types/release') } - buildTypes { release { runProguard false @@ -71,17 +70,17 @@ android { } } } - lintOptions { // if true, stop the gradle build if errors are found abortOnError false } - packagingOptions { exclude 'META-INF/LICENSE.txt' exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' exclude 'META-INF/NOTICE.txt' } + productFlavors { + } } diff --git a/settings.gradle b/settings.gradle index 89f59ff958..e69de29bb2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +0,0 @@ -include ':androidbillinglibrary' diff --git a/src/com/money/manager/ex/DonateActivity.java b/src/com/money/manager/ex/DonateActivity.java index a4d9e497d8..b78b287f0d 100644 --- a/src/com/money/manager/ex/DonateActivity.java +++ b/src/com/money/manager/ex/DonateActivity.java @@ -19,8 +19,6 @@ import com.money.manager.ex.inapp.util.Purchase; import com.money.manager.ex.inapp.util.SkuDetails; -import net.robotmedia.billing.helper.AbstractBillingObserver; - import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -37,7 +35,6 @@ public class DonateActivity extends BaseFragmentActivity { private String purchasedSku = ""; private String purchasedToken = ""; // Helper In-app Billing - private AbstractBillingObserver billingObserver; private IabHelper mIabHelper; private IabHelper.OnIabPurchaseFinishedListener mConsumeFinishedListener; private IabHelper.QueryInventoryFinishedListener mQueryInventoryFinishedListener; diff --git a/src/com/money/manager/ex/MainActivity.java b/src/com/money/manager/ex/MainActivity.java index 0ba74b9f20..b1d99d32d9 100644 --- a/src/com/money/manager/ex/MainActivity.java +++ b/src/com/money/manager/ex/MainActivity.java @@ -817,7 +817,7 @@ public void createDrawerMenu() { private class CustomActionBarDrawerToggle extends ActionBarDrawerToggle { public CustomActionBarDrawerToggle(Activity mActivity, DrawerLayout mDrawerLayout) { - super(mActivity, mDrawerLayout, R.drawable.ic_navigation_drawer, R.string.app_name, R.string.app_name); + super(mActivity, mDrawerLayout, R.drawable.ic_navigation_drawer, R.string.application_name, R.string.application_name); } } diff --git a/src/com/money/manager/ex/core/InAppBilling.java b/src/com/money/manager/ex/core/InAppBilling.java deleted file mode 100644 index 8016adbae9..0000000000 --- a/src/com/money/manager/ex/core/InAppBilling.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.money.manager.ex.core; - -import net.robotmedia.billing.BillingController; - -public class InAppBilling { - - public static final BillingController.IConfiguration getConfiguaration(){ - return new BillingController.IConfiguration() { - public byte[] getObfuscationSalt() { - return new byte[]{11, 45, -96, -31, -66, 23, 52, 100, 99, -69, 25, -77, -17, 115, 25, 55, 95, -110, -48, -120}; - } - - public String getPublicKey() { - return Core.getAppBase64(); - } - }; - } -} From 102c67ea0995699d4d4ee7f4496ab25e06c99b9e Mon Sep 17 00:00:00 2001 From: AlessandroLazzari Date: Tue, 16 Sep 2014 22:29:16 +0200 Subject: [PATCH 03/12] remove directory of module androidbillinglibrary --- androidbillinglibrary/.classpath | 9 - androidbillinglibrary/.gitignore | 2 - androidbillinglibrary/.project | 33 - androidbillinglibrary/AndroidManifest.xml | 20 - androidbillinglibrary/build.gradle | 34 - androidbillinglibrary/proguard.cfg | 36 - androidbillinglibrary/project.properties | 15 - androidbillinglibrary/res/values/strings.xml | 4 - .../billing/IMarketBillingService.aidl | 24 - .../robotmedia/billing/BillingController.java | 746 ------------------ .../robotmedia/billing/BillingReceiver.java | 70 -- .../robotmedia/billing/BillingRequest.java | 325 -------- .../robotmedia/billing/BillingService.java | 289 ------- .../robotmedia/billing/IBillingObserver.java | 85 -- .../helper/AbstractBillingActivity.java | 160 ---- .../helper/AbstractBillingFragment.java | 147 ---- .../helper/AbstractBillingObserver.java | 67 -- .../robotmedia/billing/model/BillingDB.java | 110 --- .../robotmedia/billing/model/Transaction.java | 135 ---- .../billing/model/TransactionManager.java | 77 -- .../security/DefaultSignatureValidator.java | 106 --- .../billing/security/ISignatureValidator.java | 32 - .../billing/utils/AESObfuscator.java | 114 --- .../net/robotmedia/billing/utils/Base64.java | 570 ------------- .../billing/utils/Base64DecoderException.java | 32 - .../billing/utils/Compatibility.java | 75 -- .../billing/utils/Installation.java | 59 -- .../robotmedia/billing/utils/Security.java | 75 -- build.gradle | 1 - 29 files changed, 3452 deletions(-) delete mode 100644 androidbillinglibrary/.classpath delete mode 100644 androidbillinglibrary/.gitignore delete mode 100644 androidbillinglibrary/.project delete mode 100644 androidbillinglibrary/AndroidManifest.xml delete mode 100644 androidbillinglibrary/build.gradle delete mode 100644 androidbillinglibrary/proguard.cfg delete mode 100644 androidbillinglibrary/project.properties delete mode 100644 androidbillinglibrary/res/values/strings.xml delete mode 100644 androidbillinglibrary/src/com/android/vending/billing/IMarketBillingService.aidl delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/BillingController.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/BillingReceiver.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/BillingRequest.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/BillingService.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/IBillingObserver.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/helper/AbstractBillingActivity.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/helper/AbstractBillingFragment.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/helper/AbstractBillingObserver.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/model/BillingDB.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/model/Transaction.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/model/TransactionManager.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/security/DefaultSignatureValidator.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/security/ISignatureValidator.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/utils/AESObfuscator.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/utils/Base64.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/utils/Base64DecoderException.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/utils/Compatibility.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/utils/Installation.java delete mode 100644 androidbillinglibrary/src/net/robotmedia/billing/utils/Security.java diff --git a/androidbillinglibrary/.classpath b/androidbillinglibrary/.classpath deleted file mode 100644 index d57ec02513..0000000000 --- a/androidbillinglibrary/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/androidbillinglibrary/.gitignore b/androidbillinglibrary/.gitignore deleted file mode 100644 index 703f4e43d5..0000000000 --- a/androidbillinglibrary/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bin -gen \ No newline at end of file diff --git a/androidbillinglibrary/.project b/androidbillinglibrary/.project deleted file mode 100644 index 4418edd11e..0000000000 --- a/androidbillinglibrary/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - AndroidBillingLibrary - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/androidbillinglibrary/AndroidManifest.xml b/androidbillinglibrary/AndroidManifest.xml deleted file mode 100644 index 3d5f12b978..0000000000 --- a/androidbillinglibrary/AndroidManifest.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/androidbillinglibrary/build.gradle b/androidbillinglibrary/build.gradle deleted file mode 100644 index 593c04fa1c..0000000000 --- a/androidbillinglibrary/build.gradle +++ /dev/null @@ -1,34 +0,0 @@ -apply plugin: 'android-library' - -dependencies { - compile fileTree(dir: 'libs', include: '*.jar') -} - -android { - compileSdkVersion 19 - buildToolsVersion "20.0.0" - - sourceSets { - main { - manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = ['src'] - resources.srcDirs = ['src'] - aidl.srcDirs = ['src'] - renderscript.srcDirs = ['src'] - res.srcDirs = ['res'] - assets.srcDirs = ['assets'] - } - - // Move the tests to tests/java, tests/res, etc... - instrumentTest.setRoot('tests') - - // Move the build types to build-types/ - // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ... - // This moves them out of them default location under src//... which would - // conflict with src/ being used by the main source set. - // Adding new build types or product flavors should be accompanied - // by a similar customization. - debug.setRoot('build-types/debug') - release.setRoot('build-types/release') - } -} diff --git a/androidbillinglibrary/proguard.cfg b/androidbillinglibrary/proguard.cfg deleted file mode 100644 index 12dd0392c0..0000000000 --- a/androidbillinglibrary/proguard.cfg +++ /dev/null @@ -1,36 +0,0 @@ --optimizationpasses 5 --dontusemixedcaseclassnames --dontskipnonpubliclibraryclasses --dontpreverify --verbose --optimizations !code/simplification/arithmetic,!field/*,!class/merging/* - --keep public class * extends android.app.Activity --keep public class * extends android.app.Application --keep public class * extends android.app.Service --keep public class * extends android.content.BroadcastReceiver --keep public class * extends android.content.ContentProvider --keep public class * extends android.app.backup.BackupAgentHelper --keep public class * extends android.preference.Preference --keep public class com.android.vending.licensing.ILicensingService - --keepclasseswithmembernames class * { - native ; -} - --keepclasseswithmembernames class * { - public (android.content.Context, android.util.AttributeSet); -} - --keepclasseswithmembernames class * { - public (android.content.Context, android.util.AttributeSet, int); -} - --keepclassmembers enum * { - public static **[] values(); - public static ** valueOf(java.lang.String); -} - --keep class * implements android.os.Parcelable { - public static final android.os.Parcelable$Creator *; -} diff --git a/androidbillinglibrary/project.properties b/androidbillinglibrary/project.properties deleted file mode 100644 index 4a46b9d1c9..0000000000 --- a/androidbillinglibrary/project.properties +++ /dev/null @@ -1,15 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system edit -# "ant.properties", and override values to adapt the script to your -# project structure. -# -# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): -#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt - -android.library=true -# Project target. -target=android-17 diff --git a/androidbillinglibrary/res/values/strings.xml b/androidbillinglibrary/res/values/strings.xml deleted file mode 100644 index 75c75a39ec..0000000000 --- a/androidbillinglibrary/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - AndroidBillingLibraryTest - diff --git a/androidbillinglibrary/src/com/android/vending/billing/IMarketBillingService.aidl b/androidbillinglibrary/src/com/android/vending/billing/IMarketBillingService.aidl deleted file mode 100644 index 6884b41f6e..0000000000 --- a/androidbillinglibrary/src/com/android/vending/billing/IMarketBillingService.aidl +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.vending.billing; - -import android.os.Bundle; - -interface IMarketBillingService { - /** Given the arguments in bundle form, returns a bundle for results. */ - Bundle sendBillingRequest(in Bundle bundle); -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/BillingController.java b/androidbillinglibrary/src/net/robotmedia/billing/BillingController.java deleted file mode 100644 index 5b9d107fcc..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/BillingController.java +++ /dev/null @@ -1,746 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.robotmedia.billing; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import net.robotmedia.billing.model.Transaction; -import net.robotmedia.billing.model.TransactionManager; -import net.robotmedia.billing.security.DefaultSignatureValidator; -import net.robotmedia.billing.security.ISignatureValidator; -import net.robotmedia.billing.utils.Compatibility; -import net.robotmedia.billing.utils.Security; - -import android.app.Activity; -import android.app.PendingIntent; -import android.app.PendingIntent.CanceledException; -import android.content.Context; -import android.content.Intent; -import android.text.TextUtils; -import android.util.Log; - -public class BillingController { - - public static enum BillingStatus { - UNKNOWN, SUPPORTED, UNSUPPORTED - } - - /** - * Used to provide on-demand values to the billing controller. - */ - public interface IConfiguration { - - /** - * Returns a salt for the obfuscation of purchases in local memory. - * - * @return array of 20 random bytes. - */ - public byte[] getObfuscationSalt(); - - /** - * Returns the public key used to verify the signature of responses of - * the Market Billing service. - * - * @return Base64 encoded public key. - */ - public String getPublicKey(); - } - - private static BillingStatus billingStatus = BillingStatus.UNKNOWN; - private static BillingStatus subscriptionStatus = BillingStatus.UNKNOWN; - - private static Set automaticConfirmations = new HashSet(); - private static IConfiguration configuration = null; - private static boolean debug = false; - private static ISignatureValidator validator = null; - - private static final String JSON_NONCE = "nonce"; - private static final String JSON_ORDERS = "orders"; - private static HashMap> manualConfirmations = new HashMap>(); - - private static Set observers = new HashSet(); - - public static final String LOG_TAG = "Billing"; - - private static HashMap pendingRequests = new HashMap(); - - /** - * Adds the specified notification to the set of manual confirmations of the - * specified item. - * - * @param itemId - * id of the item. - * @param notificationId - * id of the notification. - */ - private static final void addManualConfirmation(String itemId, String notificationId) { - Set notifications = manualConfirmations.get(itemId); - if (notifications == null) { - notifications = new HashSet(); - manualConfirmations.put(itemId, notifications); - } - notifications.add(notificationId); - } - - /** - * Returns the in-app product billing support status, and checks it - * asynchronously if it is currently unknown. Observers will receive a - * {@link IBillingObserver#onBillingChecked(boolean)} notification in either - * case. - *

- * In-app product support does not imply subscription support. To check if - * subscriptions are supported, use - * {@link BillingController#checkSubscriptionSupported(Context)}. - *

- * - * @param context - * @return the current in-app product billing support status (unknown, - * supported or unsupported). If it is unsupported, subscriptions - * are also unsupported. - * @see IBillingObserver#onBillingChecked(boolean) - * @see BillingController#checkSubscriptionSupported(Context) - */ - public static BillingStatus checkBillingSupported(Context context) { - if (billingStatus == BillingStatus.UNKNOWN) { - BillingService.checkBillingSupported(context); - } else { - boolean supported = billingStatus == BillingStatus.SUPPORTED; - onBillingChecked(supported); - } - return billingStatus; - } - - /** - *

- * Returns the subscription billing support status, and checks it - * asynchronously if it is currently unknown. Observers will receive a - * {@link IBillingObserver#onSubscriptionChecked(boolean)} notification in - * either case. - *

- *

- * No support for subscriptions does not imply that in-app products are also - * unsupported. To check if in-app products are supported, use - * {@link BillingController#checkBillingSupported(Context)}. - *

- * - * @param context - * @return the current subscription billing status (unknown, supported or - * unsupported). If it is supported, in-app products are also - * supported. - * @see IBillingObserver#onSubscriptionChecked(boolean) - * @see BillingController#checkBillingSupported(Context) - */ - public static BillingStatus checkSubscriptionSupported(Context context) { - if (subscriptionStatus == BillingStatus.UNKNOWN) { - BillingService.checkSubscriptionSupported(context); - } else { - boolean supported = subscriptionStatus == BillingStatus.SUPPORTED; - onSubscriptionChecked(supported); - } - return subscriptionStatus; - } - - /** - * Requests to confirm all pending notifications for the specified item. - * - * @param context - * @param itemId - * id of the item whose purchase must be confirmed. - * @return true if pending notifications for this item were found, false - * otherwise. - */ - public static boolean confirmNotifications(Context context, String itemId) { - final Set notifications = manualConfirmations.get(itemId); - if (notifications != null) { - confirmNotifications(context, notifications.toArray(new String[] {})); - return true; - } else { - return false; - } - } - - /** - * Requests to confirm all specified notifications. - * - * @param context - * @param notifyIds - * array with the ids of all the notifications to confirm. - */ - private static void confirmNotifications(Context context, String[] notifyIds) { - BillingService.confirmNotifications(context, notifyIds); - } - - /** - * Returns the number of purchases for the specified item. Refunded and - * cancelled purchases are not subtracted. See - * {@link #countPurchasesNet(Context, String)} if they need to be. - * - * @param context - * @param itemId - * id of the item whose purchases will be counted. - * @return number of purchases for the specified item. - */ - public static int countPurchases(Context context, String itemId) { - final byte[] salt = getSalt(); - itemId = salt != null ? Security.obfuscate(context, salt, itemId) : itemId; - return TransactionManager.countPurchases(context, itemId); - } - - protected static void debug(String message) { - if (debug) { - Log.d(LOG_TAG, message); - } - } - - /** - * Requests purchase information for the specified notification. Immediately - * followed by a call to - * {@link #onPurchaseInformationResponse(long, boolean)} and later to - * {@link #onPurchaseStateChanged(Context, String, String)}, if the request - * is successful. - * - * @param context - * @param notifyId - * id of the notification whose purchase information is - * requested. - */ - private static void getPurchaseInformation(Context context, String notifyId) { - final long nonce = Security.generateNonce(); - BillingService.getPurchaseInformation(context, new String[] { notifyId }, nonce); - } - - /** - * Gets the salt from the configuration and logs a warning if it's null. - * - * @return salt. - */ - private static byte[] getSalt() { - byte[] salt = null; - if (configuration == null || ((salt = configuration.getObfuscationSalt()) == null)) { - Log.w(LOG_TAG, "Can't (un)obfuscate purchases without salt"); - } - return salt; - } - - /** - * Lists all transactions stored locally, including cancellations and - * refunds. - * - * @param context - * @return list of transactions. - */ - public static List getTransactions(Context context) { - List transactions = TransactionManager.getTransactions(context); - unobfuscate(context, transactions); - return transactions; - } - - /** - * Lists all transactions of the specified item, stored locally. - * - * @param context - * @param itemId - * id of the item whose transactions will be returned. - * @return list of transactions. - */ - public static List getTransactions(Context context, String itemId) { - final byte[] salt = getSalt(); - itemId = salt != null ? Security.obfuscate(context, salt, itemId) : itemId; - List transactions = TransactionManager.getTransactions(context, itemId); - unobfuscate(context, transactions); - return transactions; - } - - /** - * Returns true if the specified item has been registered as purchased in - * local memory, false otherwise. Also note that the item might have been - * purchased in another installation, but not yet registered in this one. - * - * @param context - * @param itemId - * item id. - * @return true if the specified item is purchased, false otherwise. - */ - public static boolean isPurchased(Context context, String itemId) { - final byte[] salt = getSalt(); - itemId = salt != null ? Security.obfuscate(context, salt, itemId) : itemId; - return TransactionManager.isPurchased(context, itemId); - } - - /** - * Notifies observers of the purchase state change of the specified item. - * - * @param itemId - * id of the item whose purchase state has changed. - * @param state - * new purchase state of the item. - */ - private static void notifyPurchaseStateChange(String itemId, Transaction.PurchaseState state) { - for (IBillingObserver o : observers) { - o.onPurchaseStateChanged(itemId, state); - } - } - - /** - * Obfuscates the specified purchase. Only the order id, product id and - * developer payload are obfuscated. - * - * @param context - * @param purchase - * purchase to be obfuscated. - * @see #unobfuscate(Context, Transaction) - */ - static void obfuscate(Context context, Transaction purchase) { - final byte[] salt = getSalt(); - if (salt == null) { - return; - } - purchase.orderId = Security.obfuscate(context, salt, purchase.orderId); - purchase.productId = Security.obfuscate(context, salt, purchase.productId); - purchase.developerPayload = Security.obfuscate(context, salt, purchase.developerPayload); - } - - /** - * Called after the response to a - * {@link net.robotmedia.billing.request.CheckBillingSupported} request is - * received. - * - * @param supported - */ - protected static void onBillingChecked(boolean supported) { - billingStatus = supported ? BillingStatus.SUPPORTED : BillingStatus.UNSUPPORTED; - if (billingStatus == BillingStatus.UNSUPPORTED) { // Save us the - // subscription - // check - subscriptionStatus = BillingStatus.UNSUPPORTED; - } - for (IBillingObserver o : observers) { - o.onBillingChecked(supported); - } - } - - /** - * Called when an IN_APP_NOTIFY message is received. - * - * @param context - * @param notifyId - * notification id. - */ - protected static void onNotify(Context context, String notifyId) { - debug("Notification " + notifyId + " available"); - - getPurchaseInformation(context, notifyId); - } - - /** - * Called after the response to a - * {@link net.robotmedia.billing.request.RequestPurchase} request is - * received. - * - * @param itemId - * id of the item whose purchase was requested. - * @param purchaseIntent - * intent to purchase the item. - */ - protected static void onPurchaseIntent(String itemId, PendingIntent purchaseIntent) { - for (IBillingObserver o : observers) { - o.onPurchaseIntent(itemId, purchaseIntent); - } - } - - /** - * Called after the response to a - * {@link net.robotmedia.billing.request.GetPurchaseInformation} request is - * received. Registers all transactions in local memory and confirms those - * who can be confirmed automatically. - * - * @param context - * @param signedData - * signed JSON data received from the Market Billing service. - * @param signature - * data signature. - */ - protected static void onPurchaseStateChanged(Context context, String signedData, String signature) { - debug("Purchase state changed"); - - if (TextUtils.isEmpty(signedData)) { - Log.w(LOG_TAG, "Signed data is empty"); - return; - } else { - debug(signedData); - } - - if (!debug) { - if (TextUtils.isEmpty(signature)) { - Log.w(LOG_TAG, "Empty signature requires debug mode"); - return; - } - final ISignatureValidator validator = BillingController.validator != null ? BillingController.validator - : new DefaultSignatureValidator(BillingController.configuration); - if (!validator.validate(signedData, signature)) { - Log.w(LOG_TAG, "Signature does not match data."); - return; - } - } - - List purchases; - try { - JSONObject jObject = new JSONObject(signedData); - if (!verifyNonce(jObject)) { - Log.w(LOG_TAG, "Invalid nonce"); - return; - } - purchases = parsePurchases(jObject); - } catch (JSONException e) { - Log.e(LOG_TAG, "JSON exception: ", e); - return; - } - - ArrayList confirmations = new ArrayList(); - for (Transaction p : purchases) { - if (p.notificationId != null && automaticConfirmations.contains(p.productId)) { - confirmations.add(p.notificationId); - } else { - // TODO: Discriminate between purchases, cancellations and - // refunds. - addManualConfirmation(p.productId, p.notificationId); - } - storeTransaction(context, p); - notifyPurchaseStateChange(p.productId, p.purchaseState); - } - if (!confirmations.isEmpty()) { - final String[] notifyIds = confirmations.toArray(new String[confirmations.size()]); - confirmNotifications(context, notifyIds); - } - } - - /** - * Called after a {@link net.robotmedia.billing.BillingRequest} is sent. - * - * @param requestId - * the id the request. - * @param request - * the billing request. - */ - protected static void onRequestSent(long requestId, BillingRequest request) { - debug("Request " + requestId + " of type " + request.getRequestType() + " sent"); - - if (request.isSuccess()) { - pendingRequests.put(requestId, request); - } else if (request.hasNonce()) { - Security.removeNonce(request.getNonce()); - } - } - - /** - * Called after a {@link net.robotmedia.billing.BillingRequest} is sent. - * - * @param context - * @param requestId - * the id of the request. - * @param responseCode - * the response code. - * @see net.robotmedia.billing.request.ResponseCode - */ - protected static void onResponseCode(Context context, long requestId, int responseCode) { - final BillingRequest.ResponseCode response = BillingRequest.ResponseCode.valueOf(responseCode); - debug("Request " + requestId + " received response " + response); - - final BillingRequest request = pendingRequests.get(requestId); - if (request != null) { - pendingRequests.remove(requestId); - request.onResponseCode(response); - } - } - - /** - * Called after the response to a - * {@link net.robotmedia.billing.request.CheckSubscriptionSupported} request - * is received. - * - * @param supported - */ - protected static void onSubscriptionChecked(boolean supported) { - subscriptionStatus = supported ? BillingStatus.SUPPORTED : BillingStatus.UNSUPPORTED; - if (subscriptionStatus == BillingStatus.SUPPORTED) { // Save us the - // billing check - billingStatus = BillingStatus.SUPPORTED; - } - for (IBillingObserver o : observers) { - o.onSubscriptionChecked(supported); - } - } - - protected static void onTransactionsRestored() { - for (IBillingObserver o : observers) { - o.onTransactionsRestored(); - } - } - - /** - * Parse all purchases from the JSON data received from the Market Billing - * service. - * - * @param data - * JSON data received from the Market Billing service. - * @return list of purchases. - * @throws JSONException - * if the data couldn't be properly parsed. - */ - private static List parsePurchases(JSONObject data) throws JSONException { - ArrayList purchases = new ArrayList(); - JSONArray orders = data.optJSONArray(JSON_ORDERS); - int numTransactions = 0; - if (orders != null) { - numTransactions = orders.length(); - } - for (int i = 0; i < numTransactions; i++) { - JSONObject jElement = orders.getJSONObject(i); - Transaction p = Transaction.parse(jElement); - purchases.add(p); - } - return purchases; - } - - /** - * Registers the specified billing observer. - * - * @param observer - * the billing observer to add. - * @return true if the observer wasn't previously registered, false - * otherwise. - * @see #unregisterObserver(IBillingObserver) - */ - public static boolean registerObserver(IBillingObserver observer) { - return observers.add(observer); - } - - /** - * Requests the purchase of the specified item. The transaction will not be - * confirmed automatically. - *

- * For subscriptions, use {@link #requestSubscription(Context, String)} - * instead. - *

- * - * @param context - * @param itemId - * id of the item to be purchased. - * @see #requestPurchase(Context, String, boolean) - */ - public static void requestPurchase(Context context, String itemId) { - requestPurchase(context, itemId, false, null); - } - - /** - *

- * Requests the purchase of the specified item with optional automatic - * confirmation. - *

- *

- * For subscriptions, use - * {@link #requestSubscription(Context, String, boolean, String)} instead. - *

- * - * @param context - * @param itemId - * id of the item to be purchased. - * @param confirm - * if true, the transaction will be confirmed automatically. If - * false, the transaction will have to be confirmed with a call - * to {@link #confirmNotifications(Context, String)}. - * @param developerPayload - * a developer-specified string that contains supplemental - * information about the order. - * @see IBillingObserver#onPurchaseIntent(String, PendingIntent) - */ - public static void requestPurchase(Context context, String itemId, boolean confirm, String developerPayload) { - if (confirm) { - automaticConfirmations.add(itemId); - } - BillingService.requestPurchase(context, itemId, developerPayload); - } - - /** - * Requests the purchase of the specified subscription item. The transaction - * will not be confirmed automatically. - * - * @param context - * @param itemId - * id of the item to be purchased. - * @see #requestSubscription(Context, String, boolean, String) - */ - public static void requestSubscription(Context context, String itemId) { - requestSubscription(context, itemId, false, null); - } - - /** - * Requests the purchase of the specified subscription item with optional - * automatic confirmation. - * - * @param context - * @param itemId - * id of the item to be purchased. - * @param confirm - * if true, the transaction will be confirmed automatically. If - * false, the transaction will have to be confirmed with a call - * to {@link #confirmNotifications(Context, String)}. - * @param developerPayload - * a developer-specified string that contains supplemental - * information about the order. - * @see IBillingObserver#onPurchaseIntent(String, PendingIntent) - */ - public static void requestSubscription(Context context, String itemId, boolean confirm, String developerPayload) { - if (confirm) { - automaticConfirmations.add(itemId); - } - BillingService.requestSubscription(context, itemId, developerPayload); - } - - /** - * Requests to restore all transactions. - * - * @param context - */ - public static void restoreTransactions(Context context) { - final long nonce = Security.generateNonce(); - BillingService.restoreTransations(context, nonce); - } - - /** - * Sets the configuration instance of the controller. - * - * @param config - * configuration instance. - */ - public static void setConfiguration(IConfiguration config) { - configuration = config; - } - - /** - * Sets debug mode. - * - * @param value - */ - public static final void setDebug(boolean value) { - debug = value; - } - - /** - * Sets a custom signature validator. If no custom signature validator is - * provided, - * {@link net.robotmedia.billing.signature.DefaultSignatureValidator} will - * be used. - * - * @param validator - * signature validator instance. - */ - public static void setSignatureValidator(ISignatureValidator validator) { - BillingController.validator = validator; - } - - /** - * Starts the specified purchase intent with the specified activity. - * - * @param activity - * @param purchaseIntent - * purchase intent. - * @param intent - */ - public static void startPurchaseIntent(Activity activity, PendingIntent purchaseIntent, Intent intent) { - if (Compatibility.isStartIntentSenderSupported()) { - // This is on Android 2.0 and beyond. The in-app buy page activity - // must be on the activity stack of the application. - Compatibility.startIntentSender(activity, purchaseIntent.getIntentSender(), intent); - } else { - // This is on Android version 1.6. The in-app buy page activity must - // be on its own separate activity stack instead of on the activity - // stack of the application. - try { - purchaseIntent.send(activity, 0 /* code */, intent); - } catch (CanceledException e) { - Log.e(LOG_TAG, "Error starting purchase intent", e); - } - } - } - - static void storeTransaction(Context context, Transaction t) { - final Transaction t2 = t.clone(); - obfuscate(context, t2); - TransactionManager.addTransaction(context, t2); - } - - static void unobfuscate(Context context, List transactions) { - for (Transaction p : transactions) { - unobfuscate(context, p); - } - } - - /** - * Unobfuscate the specified purchase. - * - * @param context - * @param purchase - * purchase to unobfuscate. - * @see #obfuscate(Context, Transaction) - */ - static void unobfuscate(Context context, Transaction purchase) { - final byte[] salt = getSalt(); - if (salt == null) { - return; - } - purchase.orderId = Security.unobfuscate(context, salt, purchase.orderId); - purchase.productId = Security.unobfuscate(context, salt, purchase.productId); - purchase.developerPayload = Security.unobfuscate(context, salt, purchase.developerPayload); - } - - /** - * Unregisters the specified billing observer. - * - * @param observer - * the billing observer to unregister. - * @return true if the billing observer was unregistered, false otherwise. - * @see #registerObserver(IBillingObserver) - */ - public static boolean unregisterObserver(IBillingObserver observer) { - return observers.remove(observer); - } - - private static boolean verifyNonce(JSONObject data) { - long nonce = data.optLong(JSON_NONCE); - if (Security.isNonceKnown(nonce)) { - Security.removeNonce(nonce); - return true; - } else { - return false; - } - } - - protected static void onRequestPurchaseResponse(String itemId, BillingRequest.ResponseCode response) { - for (IBillingObserver o : observers) { - o.onRequestPurchaseResponse(itemId, response); - } - } - -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/BillingReceiver.java b/androidbillinglibrary/src/net/robotmedia/billing/BillingReceiver.java deleted file mode 100644 index fd3abb3202..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/BillingReceiver.java +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package net.robotmedia.billing; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.util.Log; - -public class BillingReceiver extends BroadcastReceiver { - - static final String ACTION_NOTIFY = "com.android.vending.billing.IN_APP_NOTIFY"; - static final String ACTION_RESPONSE_CODE = - "com.android.vending.billing.RESPONSE_CODE"; - static final String ACTION_PURCHASE_STATE_CHANGED = - "com.android.vending.billing.PURCHASE_STATE_CHANGED"; - - static final String EXTRA_NOTIFICATION_ID = "notification_id"; - static final String EXTRA_INAPP_SIGNED_DATA = "inapp_signed_data"; - static final String EXTRA_INAPP_SIGNATURE = "inapp_signature"; - static final String EXTRA_REQUEST_ID = "request_id"; - static final String EXTRA_RESPONSE_CODE = "response_code"; - - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - BillingController.debug("Received " + action); - - if (ACTION_PURCHASE_STATE_CHANGED.equals(action)) { - purchaseStateChanged(context, intent); - } else if (ACTION_NOTIFY.equals(action)) { - notify(context, intent); - } else if (ACTION_RESPONSE_CODE.equals(action)) { - responseCode(context, intent); - } else { - Log.w(this.getClass().getSimpleName(), "Unexpected action: " + action); - } - } - - private void purchaseStateChanged(Context context, Intent intent) { - final String signedData = intent.getStringExtra(EXTRA_INAPP_SIGNED_DATA); - final String signature = intent.getStringExtra(EXTRA_INAPP_SIGNATURE); - BillingController.onPurchaseStateChanged(context, signedData, signature); - } - - private void notify(Context context, Intent intent) { - String notifyId = intent.getStringExtra(EXTRA_NOTIFICATION_ID); - BillingController.onNotify(context, notifyId); - } - - private void responseCode(Context context, Intent intent) { - final long requestId = intent.getLongExtra(EXTRA_REQUEST_ID, -1); - final int responseCode = intent.getIntExtra(EXTRA_RESPONSE_CODE, 0); - BillingController.onResponseCode(context, requestId, responseCode); - } - -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/BillingRequest.java b/androidbillinglibrary/src/net/robotmedia/billing/BillingRequest.java deleted file mode 100644 index 83625594a4..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/BillingRequest.java +++ /dev/null @@ -1,325 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package net.robotmedia.billing; - -import android.app.PendingIntent; -import android.os.Bundle; -import android.os.RemoteException; -import android.util.Log; - -import com.android.vending.billing.IMarketBillingService; - -public abstract class BillingRequest { - - public static class CheckBillingSupported extends BillingRequest { - - public CheckBillingSupported(String packageName, int startId) { - super(packageName, startId); - } - - @Override - public String getRequestType() { - return REQUEST_TYPE_CHECK_BILLING_SUPPORTED; - } - - @Override - protected void processOkResponse(Bundle response) { - final boolean supported = this.isSuccess(); - BillingController.onBillingChecked(supported); - } - - } - - public static class CheckSubscriptionSupported extends BillingRequest { - - public CheckSubscriptionSupported(String packageName, int startId) { - super(packageName, startId); - } - - @Override - protected int getAPIVersion() { - return 2; - }; - - @Override - public String getRequestType() { - return REQUEST_TYPE_CHECK_BILLING_SUPPORTED; - } - - @Override - protected void processOkResponse(Bundle response) { - final boolean supported = this.isSuccess(); - BillingController.onSubscriptionChecked(supported); - } - - @Override - protected void addParams(Bundle request) { - request.putString(KEY_ITEM_TYPE, ITEM_TYPE_SUBSCRIPTION); - } - - } - - public static class ConfirmNotifications extends BillingRequest { - - private String[] notifyIds; - - private static final String KEY_NOTIFY_IDS = "NOTIFY_IDS"; - - public ConfirmNotifications(String packageName, int startId, String[] notifyIds) { - super(packageName, startId); - this.notifyIds = notifyIds; - } - - @Override - protected void addParams(Bundle request) { - request.putStringArray(KEY_NOTIFY_IDS, notifyIds); - } - - @Override - public String getRequestType() { - return "CONFIRM_NOTIFICATIONS"; - } - - } - public static class GetPurchaseInformation extends BillingRequest { - - private String[] notifyIds; - - private static final String KEY_NOTIFY_IDS = "NOTIFY_IDS"; - - public GetPurchaseInformation(String packageName, int startId, String[] notifyIds) { - super(packageName,startId); - this.notifyIds = notifyIds; - } - - @Override - protected void addParams(Bundle request) { - request.putStringArray(KEY_NOTIFY_IDS, notifyIds); - } - - @Override - public String getRequestType() { - return "GET_PURCHASE_INFORMATION"; - } - - @Override public boolean hasNonce() { return true; } - - } - - public static class RequestPurchase extends BillingRequest { - - private String itemId; - private String developerPayload; - - private static final String KEY_ITEM_ID = "ITEM_ID"; - private static final String KEY_DEVELOPER_PAYLOAD = "DEVELOPER_PAYLOAD"; - private static final String KEY_PURCHASE_INTENT = "PURCHASE_INTENT"; - - public RequestPurchase(String packageName, int startId, String itemId, String developerPayload) { - super(packageName, startId); - this.itemId = itemId; - this.developerPayload = developerPayload; - } - - @Override - protected void addParams(Bundle request) { - request.putString(KEY_ITEM_ID, itemId); - if (developerPayload != null) { - request.putString(KEY_DEVELOPER_PAYLOAD, developerPayload); - } - } - - @Override - public String getRequestType() { - return "REQUEST_PURCHASE"; - } - - @Override - public void onResponseCode(ResponseCode response) { - super.onResponseCode(response); - BillingController.onRequestPurchaseResponse(itemId, response); - } - - @Override - protected void processOkResponse(Bundle response) { - final PendingIntent purchaseIntent = response.getParcelable(KEY_PURCHASE_INTENT); - BillingController.onPurchaseIntent(itemId, purchaseIntent); - } - - } - - public static class RequestSubscription extends RequestPurchase { - - public RequestSubscription(String packageName, int startId, String itemId, String developerPayload) { - super(packageName, startId, itemId, developerPayload); - } - - @Override - protected void addParams(Bundle request) { - super.addParams(request); - request.putString(KEY_ITEM_TYPE, ITEM_TYPE_SUBSCRIPTION); - } - - @Override - protected int getAPIVersion() { - return 2; - } - } - - public static enum ResponseCode { - RESULT_OK, // 0 - RESULT_USER_CANCELED, // 1 - RESULT_SERVICE_UNAVAILABLE, // 2 - RESULT_BILLING_UNAVAILABLE, // 3 - RESULT_ITEM_UNAVAILABLE, // 4 - RESULT_DEVELOPER_ERROR, // 5 - RESULT_ERROR; // 6 - - public static boolean isResponseOk(int response) { - return ResponseCode.RESULT_OK.ordinal() == response; - } - - // Converts from an ordinal value to the ResponseCode - public static ResponseCode valueOf(int index) { - ResponseCode[] values = ResponseCode.values(); - if (index < 0 || index >= values.length) { - return RESULT_ERROR; - } - return values[index]; - } - } - public static class RestoreTransactions extends BillingRequest { - - public RestoreTransactions(String packageName, int startId) { - super(packageName, startId); - } - - @Override - public String getRequestType() { - return "RESTORE_TRANSACTIONS"; - } - - @Override public boolean hasNonce() { return true; } - - @Override - public void onResponseCode(ResponseCode response) { - super.onResponseCode(response); - if (response == ResponseCode.RESULT_OK) { - BillingController.onTransactionsRestored(); - } - } - - } - - public static final String ITEM_TYPE_SUBSCRIPTION = "subs"; - private static final String KEY_API_VERSION = "API_VERSION"; - private static final String KEY_BILLING_REQUEST = "BILLING_REQUEST"; - private static final String KEY_ITEM_TYPE = "ITEM_TYPE"; - private static final String KEY_NONCE = "NONCE"; - private static final String KEY_PACKAGE_NAME = "PACKAGE_NAME"; - protected static final String KEY_REQUEST_ID = "REQUEST_ID"; - private static final String KEY_RESPONSE_CODE = "RESPONSE_CODE"; - private static final String REQUEST_TYPE_CHECK_BILLING_SUPPORTED = "CHECK_BILLING_SUPPORTED"; - - public static final long IGNORE_REQUEST_ID = -1; - private String packageName; - - private int startId; - private boolean success; - private long nonce; - public BillingRequest(String packageName,int startId) { - this.packageName = packageName; - this.startId=startId; - } - - protected void addParams(Bundle request) { - // Do nothing by default - } - - protected int getAPIVersion() { - return 1; - } - - public long getNonce() { - return nonce; - } - - public abstract String getRequestType(); - - public boolean hasNonce() { - return false; - } - - public boolean isSuccess() { - return success; - } - - protected Bundle makeRequestBundle() { - final Bundle request = new Bundle(); - request.putString(KEY_BILLING_REQUEST, getRequestType()); - request.putInt(KEY_API_VERSION, getAPIVersion()); - request.putString(KEY_PACKAGE_NAME, packageName); - if (hasNonce()) { - request.putLong(KEY_NONCE, nonce); - } - return request; - } - - public void onResponseCode(ResponseCode responde) { - // Do nothing by default - } - - protected void processOkResponse(Bundle response) { - // Do nothing by default - } - - public long run(IMarketBillingService mService) throws RemoteException { - final Bundle request = makeRequestBundle(); - addParams(request); - final Bundle response; - try { - response = mService.sendBillingRequest(request); - } catch (NullPointerException e) { - Log.e(this.getClass().getSimpleName(), "Known IAB bug. See: http://code.google.com/p/marketbilling/issues/detail?id=25", e); - return IGNORE_REQUEST_ID; - } - - if (validateResponse(response)) { - processOkResponse(response); - return response.getLong(KEY_REQUEST_ID, IGNORE_REQUEST_ID); - } else { - return IGNORE_REQUEST_ID; - } - } - - public void setNonce(long nonce) { - this.nonce = nonce; - } - - protected boolean validateResponse(Bundle response) { - final int responseCode = response.getInt(KEY_RESPONSE_CODE); - success = ResponseCode.isResponseOk(responseCode); - if (!success) { - Log.w(this.getClass().getSimpleName(), "Error with response code " + ResponseCode.valueOf(responseCode)); - } - return success; - } - - public int getStartId() { - return startId; - } - -} \ No newline at end of file diff --git a/androidbillinglibrary/src/net/robotmedia/billing/BillingService.java b/androidbillinglibrary/src/net/robotmedia/billing/BillingService.java deleted file mode 100644 index a37a1ae70b..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/BillingService.java +++ /dev/null @@ -1,289 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package net.robotmedia.billing; - -import java.util.LinkedList; - -import static net.robotmedia.billing.BillingRequest.*; - -import net.robotmedia.billing.utils.Compatibility; - -import com.android.vending.billing.IMarketBillingService; - -import android.app.Service; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.IBinder; -import android.os.RemoteException; -import android.util.Log; - -public class BillingService extends Service implements ServiceConnection { - - private static enum Action { - CHECK_BILLING_SUPPORTED, CHECK_SUBSCRIPTION_SUPPORTED, CONFIRM_NOTIFICATIONS, GET_PURCHASE_INFORMATION, REQUEST_PURCHASE, REQUEST_SUBSCRIPTION, RESTORE_TRANSACTIONS - } - - private static final String ACTION_MARKET_BILLING_SERVICE = "com.android.vending.billing.MarketBillingService.BIND"; - private static final String EXTRA_DEVELOPER_PAYLOAD = "DEVELOPER_PAYLOAD"; - private static final String EXTRA_ITEM_ID = "ITEM_ID"; - private static final String EXTRA_NONCE = "EXTRA_NONCE"; - private static final String EXTRA_NOTIFY_IDS = "NOTIFY_IDS"; - private static LinkedList mPendingRequests = new LinkedList(); - - private static IMarketBillingService mService; - - public static void checkBillingSupported(Context context) { - final Intent intent = createIntent(context, Action.CHECK_BILLING_SUPPORTED); - context.startService(intent); - } - - public static void checkSubscriptionSupported(Context context) { - final Intent intent = createIntent(context, Action.CHECK_SUBSCRIPTION_SUPPORTED); - context.startService(intent); - } - - public static void confirmNotifications(Context context, String[] notifyIds) { - final Intent intent = createIntent(context, Action.CONFIRM_NOTIFICATIONS); - intent.putExtra(EXTRA_NOTIFY_IDS, notifyIds); - context.startService(intent); - } - - private static Intent createIntent(Context context, Action action) { - final String actionString = getActionForIntent(context, action); - final Intent intent = new Intent(actionString); - intent.setClass(context, BillingService.class); - return intent; - } - - private static final String getActionForIntent(Context context, Action action) { - return context.getPackageName() + "." + action.toString(); - } - - public static void getPurchaseInformation(Context context, String[] notifyIds, long nonce) { - final Intent intent = createIntent(context, Action.GET_PURCHASE_INFORMATION); - intent.putExtra(EXTRA_NOTIFY_IDS, notifyIds); - intent.putExtra(EXTRA_NONCE, nonce); - context.startService(intent); - } - - public static void requestPurchase(Context context, String itemId, String developerPayload) { - final Intent intent = createIntent(context, Action.REQUEST_PURCHASE); - intent.putExtra(EXTRA_ITEM_ID, itemId); - intent.putExtra(EXTRA_DEVELOPER_PAYLOAD, developerPayload); - context.startService(intent); - } - - public static void requestSubscription(Context context, String itemId, String developerPayload) { - final Intent intent = createIntent(context, Action.REQUEST_SUBSCRIPTION); - intent.putExtra(EXTRA_ITEM_ID, itemId); - intent.putExtra(EXTRA_DEVELOPER_PAYLOAD, developerPayload); - context.startService(intent); - } - - public static void restoreTransations(Context context, long nonce) { - final Intent intent = createIntent(context, Action.RESTORE_TRANSACTIONS); - intent.setClass(context, BillingService.class); - intent.putExtra(EXTRA_NONCE, nonce); - context.startService(intent); - } - - private void bindMarketBillingService() { - try { - final boolean bindResult = bindService(new Intent(ACTION_MARKET_BILLING_SERVICE), this, Context.BIND_AUTO_CREATE); - if (!bindResult) { - Log.e(this.getClass().getSimpleName(), "Could not bind to MarketBillingService"); - } - } catch (SecurityException e) { - Log.e(this.getClass().getSimpleName(), "Could not bind to MarketBillingService", e); - } - } - - private void checkBillingSupported(int startId) { - final String packageName = getPackageName(); - final CheckBillingSupported request = new CheckBillingSupported(packageName, startId); - runRequestOrQueue(request); - } - - private void checkSubscriptionSupported(int startId) { - final String packageName = getPackageName(); - final CheckSubscriptionSupported request = new CheckSubscriptionSupported(packageName, startId); - runRequestOrQueue(request); - } - - private void confirmNotifications(Intent intent, int startId) { - final String packageName = getPackageName(); - final String[] notifyIds = intent.getStringArrayExtra(EXTRA_NOTIFY_IDS); - final ConfirmNotifications request = new ConfirmNotifications(packageName, startId, notifyIds); - runRequestOrQueue(request); - } - - private Action getActionFromIntent(Intent intent) { - final String actionString = intent.getAction(); - if (actionString == null) { - return null; - } - final String[] split = actionString.split("\\."); - if (split.length <= 0) { - return null; - } - return Action.valueOf(split[split.length - 1]); - } - - private void getPurchaseInformation(Intent intent, int startId) { - final String packageName = getPackageName(); - final long nonce = intent.getLongExtra(EXTRA_NONCE, 0); - final String[] notifyIds = intent.getStringArrayExtra(EXTRA_NOTIFY_IDS); - final GetPurchaseInformation request = new GetPurchaseInformation(packageName, startId, notifyIds); - request.setNonce(nonce); - runRequestOrQueue(request); - } - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - public void onServiceConnected(ComponentName name, IBinder service) { - mService = IMarketBillingService.Stub.asInterface(service); - runPendingRequests(); - } - - public void onServiceDisconnected(ComponentName name) { - mService = null; - } - - // This is the old onStart method that will be called on the pre-2.0 - // platform. On 2.0 or later we override onStartCommand() so this - // method will not be called. - @Override - public void onStart(Intent intent, int startId) { - handleCommand(intent, startId); - } - - // @Override // Avoid compile errors on pre-2.0 - public int onStartCommand(Intent intent, int flags, int startId) { - handleCommand(intent, startId); - return Compatibility.START_NOT_STICKY; - } - - private void handleCommand(Intent intent, int startId) { - final Action action = getActionFromIntent(intent); - if (action == null) { - return; - } - switch (action) { - case CHECK_BILLING_SUPPORTED: - checkBillingSupported(startId); - break; - case CHECK_SUBSCRIPTION_SUPPORTED: - checkSubscriptionSupported(startId); - break; - case REQUEST_PURCHASE: - requestPurchase(intent, startId); - break; - case REQUEST_SUBSCRIPTION: - requestSubscription(intent, startId); - break; - case GET_PURCHASE_INFORMATION: - getPurchaseInformation(intent, startId); - break; - case CONFIRM_NOTIFICATIONS: - confirmNotifications(intent, startId); - break; - case RESTORE_TRANSACTIONS: - restoreTransactions(intent, startId); - } - } - - private void requestPurchase(Intent intent, int startId) { - final String packageName = getPackageName(); - final String itemId = intent.getStringExtra(EXTRA_ITEM_ID); - final String developerPayload = intent.getStringExtra(EXTRA_DEVELOPER_PAYLOAD); - final RequestPurchase request = new RequestPurchase(packageName, startId, itemId, developerPayload); - runRequestOrQueue(request); - } - - private void requestSubscription(Intent intent, int startId) { - final String packageName = getPackageName(); - final String itemId = intent.getStringExtra(EXTRA_ITEM_ID); - final String developerPayload = intent.getStringExtra(EXTRA_DEVELOPER_PAYLOAD); - final RequestPurchase request = new RequestSubscription(packageName, startId, itemId, developerPayload); - runRequestOrQueue(request); - } - - private void restoreTransactions(Intent intent, int startId) { - final String packageName = getPackageName(); - final long nonce = intent.getLongExtra(EXTRA_NONCE, 0); - final RestoreTransactions request = new RestoreTransactions(packageName, startId); - request.setNonce(nonce); - runRequestOrQueue(request); - } - - private void runPendingRequests() { - BillingRequest request; - int maxStartId = -1; - while ((request = mPendingRequests.peek()) != null) { - if (mService != null) { - runRequest(request); - mPendingRequests.remove(); - if (maxStartId < request.getStartId()) { - maxStartId = request.getStartId(); - } - } else { - bindMarketBillingService(); - return; - } - } - if (maxStartId >= 0) { - stopSelf(maxStartId); - } - } - - private void runRequest(BillingRequest request) { - try { - final long requestId = request.run(mService); - BillingController.onRequestSent(requestId, request); - } catch (RemoteException e) { - Log.w(this.getClass().getSimpleName(), "Remote billing service crashed"); - // TODO: Retry? - } - } - - private void runRequestOrQueue(BillingRequest request) { - mPendingRequests.add(request); - if (mService == null) { - bindMarketBillingService(); - } else { - runPendingRequests(); - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - // Ensure we're not leaking Android Market billing service - if (mService != null) { - try { - unbindService(this); - } catch (IllegalArgumentException e) { - // This might happen if the service was disconnected - } - } - } - -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/IBillingObserver.java b/androidbillinglibrary/src/net/robotmedia/billing/IBillingObserver.java deleted file mode 100644 index 59f3ab460c..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/IBillingObserver.java +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.robotmedia.billing; - -import net.robotmedia.billing.BillingRequest.ResponseCode; -import net.robotmedia.billing.model.Transaction.PurchaseState; -import android.app.PendingIntent; - -public interface IBillingObserver { - - /** - * Called after checking if in-app product billing is supported or not. - * - * @param supported - * if true, in-app product billing is supported. If false, in-app - * product billing is not supported, and neither is subscription - * billing. - * @see BillingController#checkBillingSupported(android.content.Context) - */ - public void onBillingChecked(boolean supported); - - /** - * Called after checking if subscription billing is supported or not. - * - * @param supported - * if true, subscription billing is supported, and also is in-app - * product billing. Otherwise, subscription billing is not - * supported. - */ - public void onSubscriptionChecked(boolean supported); - - /** - * Called after requesting the purchase of the specified item. - * - * @param itemId - * id of the item whose purchase was requested. - * @param purchaseIntent - * a purchase pending intent for the specified item. - * @see BillingController#requestPurchase(android.content.Context, String, - * boolean) - */ - public void onPurchaseIntent(String itemId, PendingIntent purchaseIntent); - - /** - * Called when the specified item is purchased, cancelled or refunded. - * - * @param itemId - * id of the item whose purchase state has changed. - * @param state - * purchase state of the specified item. - */ - public void onPurchaseStateChanged(String itemId, PurchaseState state); - - /** - * Called with the response for the purchase request of the specified item. - * This is used for reporting various errors, or if the user backed out and - * didn't purchase the item. - * - * @param itemId - * id of the item whose purchase was requested - * @param response - * response of the purchase request - */ - public void onRequestPurchaseResponse(String itemId, ResponseCode response); - - /** - * Called when a restore transactions request has been successfully - * received by the server. - */ - public void onTransactionsRestored(); - -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/helper/AbstractBillingActivity.java b/androidbillinglibrary/src/net/robotmedia/billing/helper/AbstractBillingActivity.java deleted file mode 100644 index 4415c05a0b..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/helper/AbstractBillingActivity.java +++ /dev/null @@ -1,160 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.robotmedia.billing.helper; - -import net.robotmedia.billing.BillingController; -import net.robotmedia.billing.BillingController.BillingStatus; -import net.robotmedia.billing.BillingRequest.ResponseCode; -import net.robotmedia.billing.model.Transaction.PurchaseState; -import android.app.Activity; - -public abstract class AbstractBillingActivity extends Activity implements BillingController.IConfiguration { - - protected AbstractBillingObserver mBillingObserver; - - /** - *

- * Returns the in-app product billing support status, and checks it - * asynchronously if it is currently unknown. - * {@link AbstractBillingActivity#onBillingChecked(boolean)} will be called - * eventually with the result. - *

- *

- * In-app product support does not imply subscription support. To check if - * subscriptions are supported, use - * {@link AbstractBillingActivity#checkSubscriptionSupported()}. - *

- * - * @return the current in-app product billing support status (unknown, - * supported or unsupported). If it is unsupported, subscriptions - * are also unsupported. - * @see AbstractBillingActivity#onBillingChecked(boolean) - * @see AbstractBillingActivity#checkSubscriptionSupported() - */ - public BillingStatus checkBillingSupported() { - return BillingController.checkBillingSupported(this); - } - - /** - *

- * Returns the subscription billing support status, and checks it - * asynchronously if it is currently unknown. - * {@link AbstractBillingActivity#onSubscriptionChecked(boolean)} will be - * called eventually with the result. - *

- *

- * No support for subscriptions does not imply that in-app products are also - * unsupported. To check if subscriptions are supported, use - * {@link AbstractBillingActivity#checkSubscriptionSupported()}. - *

- * - * @return the current in-app product billing support status (unknown, - * supported or unsupported). If it is unsupported, subscriptions - * are also unsupported. - * @see AbstractBillingActivity#onBillingChecked(boolean) - * @see AbstractBillingActivity#checkSubscriptionSupported() - */ - public BillingStatus checkSubscriptionSupported() { - return BillingController.checkSubscriptionSupported(this); - } - - public abstract void onBillingChecked(boolean supported); - - public abstract void onSubscriptionChecked(boolean supported); - - @Override - protected void onCreate(android.os.Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mBillingObserver = new AbstractBillingObserver(this) { - - public void onBillingChecked(boolean supported) { - AbstractBillingActivity.this.onBillingChecked(supported); - } - - public void onSubscriptionChecked(boolean supported) { - AbstractBillingActivity.this.onSubscriptionChecked(supported); - } - - public void onPurchaseStateChanged(String itemId, PurchaseState state) { - AbstractBillingActivity.this.onPurchaseStateChanged(itemId, state); - } - - public void onRequestPurchaseResponse(String itemId, ResponseCode response) { - AbstractBillingActivity.this.onRequestPurchaseResponse(itemId, response); - } - }; - BillingController.registerObserver(mBillingObserver); - BillingController.setConfiguration(this); // This activity will provide - // the public key and salt - this.checkBillingSupported(); - if (!mBillingObserver.isTransactionsRestored()) { - BillingController.restoreTransactions(this); - } - } - - @Override - protected void onDestroy() { - super.onDestroy(); - BillingController.unregisterObserver(mBillingObserver); // Avoid - // receiving - // notifications after - // destroy - BillingController.setConfiguration(null); - } - - public abstract void onPurchaseStateChanged(String itemId, PurchaseState state);; - - public abstract void onRequestPurchaseResponse(String itemId, ResponseCode response); - - /** - * Requests the purchase of the specified item. The transaction will not be - * confirmed automatically; such confirmation could be handled in - * {@link AbstractBillingActivity#onPurchaseExecuted(String)}. If automatic - * confirmation is preferred use - * {@link BillingController#requestPurchase(android.content.Context, String, boolean)} - * instead. - * - * @param itemId - * id of the item to be purchased. - */ - public void requestPurchase(String itemId) { - BillingController.requestPurchase(this, itemId); - } - - /** - * Requests the purchase of the specified subscription item. The transaction - * will not be confirmed automatically; such confirmation could be handled - * in {@link AbstractBillingActivity#onPurchaseExecuted(String)}. If - * automatic confirmation is preferred use - * {@link BillingController#requestPurchase(android.content.Context, String, boolean)} - * instead. - * - * @param itemId - * id of the item to be purchased. - */ - public void requestSubscription(String itemId) { - BillingController.requestSubscription(this, itemId); - } - - /** - * Requests to restore all transactions. - */ - public void restoreTransactions() { - BillingController.restoreTransactions(this); - } - -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/helper/AbstractBillingFragment.java b/androidbillinglibrary/src/net/robotmedia/billing/helper/AbstractBillingFragment.java deleted file mode 100644 index 01644d2d17..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/helper/AbstractBillingFragment.java +++ /dev/null @@ -1,147 +0,0 @@ -package net.robotmedia.billing.helper; - -import net.robotmedia.billing.BillingController; -import net.robotmedia.billing.BillingController.BillingStatus; -import net.robotmedia.billing.BillingRequest.ResponseCode; -import net.robotmedia.billing.model.Transaction.PurchaseState; -import android.annotation.TargetApi; -import android.app.Fragment; - -@TargetApi(11) -public abstract class AbstractBillingFragment extends Fragment implements BillingController.IConfiguration { - - protected AbstractBillingObserver mBillingObserver; - - /** - *

- * Returns the in-app product billing support status, and checks it - * asynchronously if it is currently unknown. - * {@link AbstractBillingActivity#onBillingChecked(boolean)} will be called - * eventually with the result. - *

- *

- * In-app product support does not imply subscription support. To check if - * subscriptions are supported, use - * {@link AbstractBillingActivity#checkSubscriptionSupported()}. - *

- * - * @return the current in-app product billing support status (unknown, - * supported or unsupported). If it is unsupported, subscriptions - * are also unsupported. - * @see AbstractBillingActivity#onBillingChecked(boolean) - * @see AbstractBillingActivity#checkSubscriptionSupported() - */ - public BillingStatus checkBillingSupported() { - return BillingController.checkBillingSupported(getActivity()); - } - - /** - *

- * Returns the subscription billing support status, and checks it - * asynchronously if it is currently unknown. - * {@link AbstractBillingActivity#onSubscriptionChecked(boolean)} will be - * called eventually with the result. - *

- *

- * No support for subscriptions does not imply that in-app products are also - * unsupported. To check if subscriptions are supported, use - * {@link AbstractBillingActivity#checkSubscriptionSupported()}. - *

- * - * @return the current in-app product billing support status (unknown, - * supported or unsupported). If it is unsupported, subscriptions - * are also unsupported. - * @see AbstractBillingActivity#onBillingChecked(boolean) - * @see AbstractBillingActivity#checkSubscriptionSupported() - */ - public BillingStatus checkSubscriptionSupported() { - return BillingController.checkSubscriptionSupported(getActivity()); - } - - public abstract void onBillingChecked(boolean supported); - - public abstract void onSubscriptionChecked(boolean supported); - - @Override - public void onCreate(android.os.Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mBillingObserver = new AbstractBillingObserver(getActivity()) { - - public void onBillingChecked(boolean supported) { - AbstractBillingFragment.this.onBillingChecked(supported); - } - - public void onSubscriptionChecked(boolean supported) { - AbstractBillingFragment.this.onSubscriptionChecked(supported); - } - - public void onPurchaseStateChanged(String itemId, PurchaseState state) { - AbstractBillingFragment.this.onPurchaseStateChanged(itemId, state); - } - - public void onRequestPurchaseResponse(String itemId, ResponseCode response) { - AbstractBillingFragment.this.onRequestPurchaseResponse(itemId, response); - } - }; - BillingController.registerObserver(mBillingObserver); - BillingController.setConfiguration(this); // This fragment will provide - // the public key and salt - this.checkBillingSupported(); - if (!mBillingObserver.isTransactionsRestored()) { - BillingController.restoreTransactions(getActivity()); - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - BillingController.unregisterObserver(mBillingObserver); // Avoid - // receiving - // notifications - // after destroy - BillingController.setConfiguration(null); - } - - public abstract void onPurchaseStateChanged(String itemId, PurchaseState state);; - - public abstract void onRequestPurchaseResponse(String itemId, ResponseCode response); - - /** - * Requests the purchase of the specified item. The transaction will not be - * confirmed automatically; such confirmation could be handled in - * {@link AbstractBillingActivity#onPurchaseExecuted(String)}. If automatic - * confirmation is preferred use - * {@link BillingController#requestPurchase(android.content.Context, String, boolean)} - * instead. - * - * @param itemId - * id of the item to be purchased. - */ - public void requestPurchase(String itemId) { - BillingController.requestPurchase(getActivity(), itemId); - } - - /** - * Requests the purchase of the specified subscription item. The transaction - * will not be confirmed automatically; such confirmation could be handled - * in {@link AbstractBillingActivity#onPurchaseExecuted(String)}. If - * automatic confirmation is preferred use - * {@link BillingController#requestPurchase(android.content.Context, String, boolean)} - * instead. - * - * @param itemId - * id of the item to be purchased. - */ - public void requestSubscription(String itemId) { - BillingController.requestSubscription(getActivity(), itemId); - } - - /** - * Requests to restore all transactions. - */ - public void restoreTransactions() { - BillingController.restoreTransactions(getActivity()); - } - -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/helper/AbstractBillingObserver.java b/androidbillinglibrary/src/net/robotmedia/billing/helper/AbstractBillingObserver.java deleted file mode 100644 index f982d43832..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/helper/AbstractBillingObserver.java +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.robotmedia.billing.helper; - -import android.app.Activity; -import android.app.PendingIntent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.preference.PreferenceManager; -import net.robotmedia.billing.BillingController; -import net.robotmedia.billing.IBillingObserver; - -/** - * Abstract subclass of IBillingObserver that provides default implementations - * for {@link IBillingObserver#onPurchaseIntent(String, PendingIntent)} and - * {@link IBillingObserver#onTransactionsRestored()}. - * - */ -public abstract class AbstractBillingObserver implements IBillingObserver { - - protected static final String KEY_TRANSACTIONS_RESTORED = "net.robotmedia.billing.transactionsRestored"; - - protected Activity activity; - - public AbstractBillingObserver(Activity activity) { - this.activity = activity; - } - - public boolean isTransactionsRestored() { - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); - return preferences.getBoolean(KEY_TRANSACTIONS_RESTORED, false); - } - - /** - * Called after requesting the purchase of the specified item. The default - * implementation simply starts the pending intent. - * - * @param itemId - * id of the item whose purchase was requested. - * @param purchaseIntent - * a purchase pending intent for the specified item. - */ - public void onPurchaseIntent(String itemId, PendingIntent purchaseIntent) { - BillingController.startPurchaseIntent(activity, purchaseIntent, null); - } - - public void onTransactionsRestored() { - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); - final Editor editor = preferences.edit(); - editor.putBoolean(KEY_TRANSACTIONS_RESTORED, true); - editor.commit(); - } - -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/model/BillingDB.java b/androidbillinglibrary/src/net/robotmedia/billing/model/BillingDB.java deleted file mode 100644 index a56a80be62..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/model/BillingDB.java +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package net.robotmedia.billing.model; - -import net.robotmedia.billing.model.Transaction.PurchaseState; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; - -public class BillingDB { - static final String DATABASE_NAME = "billing.db"; - static final int DATABASE_VERSION = 1; - static final String TABLE_TRANSACTIONS = "purchases"; - - public static final String COLUMN__ID = "_id"; - public static final String COLUMN_STATE = "state"; - public static final String COLUMN_PRODUCT_ID = "productId"; - public static final String COLUMN_PURCHASE_TIME = "purchaseTime"; - public static final String COLUMN_DEVELOPER_PAYLOAD = "developerPayload"; - - private static final String[] TABLE_TRANSACTIONS_COLUMNS = { - COLUMN__ID, COLUMN_PRODUCT_ID, COLUMN_STATE, - COLUMN_PURCHASE_TIME, COLUMN_DEVELOPER_PAYLOAD - }; - - SQLiteDatabase mDb; - private DatabaseHelper mDatabaseHelper; - - public BillingDB(Context context) { - mDatabaseHelper = new DatabaseHelper(context); - mDb = mDatabaseHelper.getWritableDatabase(); - } - - public void close() { - mDatabaseHelper.close(); - } - - public void insert(Transaction transaction) { - ContentValues values = new ContentValues(); - values.put(COLUMN__ID, transaction.orderId); - values.put(COLUMN_PRODUCT_ID, transaction.productId); - values.put(COLUMN_STATE, transaction.purchaseState.ordinal()); - values.put(COLUMN_PURCHASE_TIME, transaction.purchaseTime); - values.put(COLUMN_DEVELOPER_PAYLOAD, transaction.developerPayload); - mDb.replace(TABLE_TRANSACTIONS, null /* nullColumnHack */, values); - } - - public Cursor queryTransactions() { - return mDb.query(TABLE_TRANSACTIONS, TABLE_TRANSACTIONS_COLUMNS, null, - null, null, null, null); - } - - public Cursor queryTransactions(String productId) { - return mDb.query(TABLE_TRANSACTIONS, TABLE_TRANSACTIONS_COLUMNS, COLUMN_PRODUCT_ID + " = ?", - new String[] {productId}, null, null, null); - } - - public Cursor queryTransactions(String productId, PurchaseState state) { - return mDb.query(TABLE_TRANSACTIONS, TABLE_TRANSACTIONS_COLUMNS, COLUMN_PRODUCT_ID + " = ? AND " + COLUMN_STATE + " = ?", - new String[] {productId, String.valueOf(state.ordinal())}, null, null, null); - } - - protected static final Transaction createTransaction(Cursor cursor) { - final Transaction purchase = new Transaction(); - purchase.orderId = cursor.getString(0); - purchase.productId = cursor.getString(1); - purchase.purchaseState = PurchaseState.valueOf(cursor.getInt(2)); - purchase.purchaseTime = cursor.getLong(3); - purchase.developerPayload = cursor.getString(4); - return purchase; - } - - private class DatabaseHelper extends SQLiteOpenHelper { - public DatabaseHelper(Context context) { - super(context, DATABASE_NAME, null, DATABASE_VERSION); - } - - @Override - public void onCreate(SQLiteDatabase db) { - createTransactionsTable(db); - } - - private void createTransactionsTable(SQLiteDatabase db) { - db.execSQL("CREATE TABLE " + TABLE_TRANSACTIONS + "(" + - COLUMN__ID + " TEXT PRIMARY KEY, " + - COLUMN_PRODUCT_ID + " INTEGER, " + - COLUMN_STATE + " TEXT, " + - COLUMN_PURCHASE_TIME + " TEXT, " + - COLUMN_DEVELOPER_PAYLOAD + " INTEGER)"); - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {} - } -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/model/Transaction.java b/androidbillinglibrary/src/net/robotmedia/billing/model/Transaction.java deleted file mode 100644 index b3b01e8fee..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/model/Transaction.java +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package net.robotmedia.billing.model; - -import org.json.JSONException; -import org.json.JSONObject; - -public class Transaction { - - public enum PurchaseState { - // Responses to requestPurchase or restoreTransactions. - PURCHASED, // 0: User was charged for the order. - CANCELLED, // 1: The charge failed on the server. - REFUNDED, // 2: User received a refund for the order. - EXPIRED; // 3: Sent at the end of a billing cycle to indicate that the - // subscription expired without renewal because of - // non-payment or user-cancellation. Your app does not need - // to grant continued access to the subscription content. - - // Converts from an ordinal value to the PurchaseState - public static PurchaseState valueOf(int index) { - PurchaseState[] values = PurchaseState.values(); - if (index < 0 || index >= values.length) { - return CANCELLED; - } - return values[index]; - } - } - static final String DEVELOPER_PAYLOAD = "developerPayload"; - static final String NOTIFICATION_ID = "notificationId"; - static final String ORDER_ID = "orderId"; - static final String PACKAGE_NAME = "packageName"; - static final String PRODUCT_ID = "productId"; - static final String PURCHASE_STATE = "purchaseState"; - - static final String PURCHASE_TIME = "purchaseTime"; - - public static Transaction parse(JSONObject json) throws JSONException { - final Transaction transaction = new Transaction(); - final int response = json.getInt(PURCHASE_STATE); - transaction.purchaseState = PurchaseState.valueOf(response); - transaction.productId = json.getString(PRODUCT_ID); - transaction.packageName = json.getString(PACKAGE_NAME); - transaction.purchaseTime = json.getLong(PURCHASE_TIME); - transaction.orderId = json.optString(ORDER_ID, null); - transaction.notificationId = json.optString(NOTIFICATION_ID, null); - transaction.developerPayload = json.optString(DEVELOPER_PAYLOAD, null); - return transaction; - } - - public String developerPayload; - public String notificationId; - public String orderId; - public String packageName; - public String productId; - public PurchaseState purchaseState; - public long purchaseTime; - - public Transaction() {} - - public Transaction(String orderId, String productId, String packageName, PurchaseState purchaseState, - String notificationId, long purchaseTime, String developerPayload) { - this.orderId = orderId; - this.productId = productId; - this.packageName = packageName; - this.purchaseState = purchaseState; - this.notificationId = notificationId; - this.purchaseTime = purchaseTime; - this.developerPayload = developerPayload; - } - - public Transaction clone() { - return new Transaction(orderId, productId, packageName, purchaseState, notificationId, purchaseTime, developerPayload); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Transaction other = (Transaction) obj; - if (developerPayload == null) { - if (other.developerPayload != null) - return false; - } else if (!developerPayload.equals(other.developerPayload)) - return false; - if (notificationId == null) { - if (other.notificationId != null) - return false; - } else if (!notificationId.equals(other.notificationId)) - return false; - if (orderId == null) { - if (other.orderId != null) - return false; - } else if (!orderId.equals(other.orderId)) - return false; - if (packageName == null) { - if (other.packageName != null) - return false; - } else if (!packageName.equals(other.packageName)) - return false; - if (productId == null) { - if (other.productId != null) - return false; - } else if (!productId.equals(other.productId)) - return false; - if (purchaseState != other.purchaseState) - return false; - if (purchaseTime != other.purchaseTime) - return false; - return true; - } - - @Override - public String toString() { - return String.valueOf(orderId); - } - -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/model/TransactionManager.java b/androidbillinglibrary/src/net/robotmedia/billing/model/TransactionManager.java deleted file mode 100644 index aa1ff0fa66..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/model/TransactionManager.java +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package net.robotmedia.billing.model; - -import java.util.ArrayList; -import java.util.List; - -import net.robotmedia.billing.model.Transaction.PurchaseState; -import android.content.Context; -import android.database.Cursor; - -public class TransactionManager { - - public synchronized static void addTransaction(Context context, Transaction transaction) { - BillingDB db = new BillingDB(context); - db.insert(transaction); - db.close(); - } - - public synchronized static boolean isPurchased(Context context, String itemId) { - return countPurchases(context, itemId) > 0; - } - - public synchronized static int countPurchases(Context context, String itemId) { - BillingDB db = new BillingDB(context); - final Cursor c = db.queryTransactions(itemId, PurchaseState.PURCHASED); - int count = 0; - if (c != null) { - count = c.getCount(); - c.close(); - } - db.close(); - return count; - } - - public synchronized static List getTransactions(Context context) { - BillingDB db = new BillingDB(context); - final Cursor c = db.queryTransactions(); - final List transactions = cursorToList(c); - db.close(); - return transactions; - } - - private static List cursorToList(final Cursor c) { - final List transactions = new ArrayList(); - if (c != null) { - while (c.moveToNext()) { - final Transaction purchase = BillingDB.createTransaction(c); - transactions.add(purchase); - } - c.close(); - } - return transactions; - } - - public synchronized static List getTransactions(Context context, String itemId) { - BillingDB db = new BillingDB(context); - final Cursor c = db.queryTransactions(itemId); - final List transactions = cursorToList(c); - db.close(); - return transactions; - } - -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/security/DefaultSignatureValidator.java b/androidbillinglibrary/src/net/robotmedia/billing/security/DefaultSignatureValidator.java deleted file mode 100644 index fb9e5db049..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/security/DefaultSignatureValidator.java +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.robotmedia.billing.security; - -import java.security.InvalidKeyException; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.Signature; -import java.security.SignatureException; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.X509EncodedKeySpec; - -import android.text.TextUtils; -import android.util.Log; -import net.robotmedia.billing.BillingController; -import net.robotmedia.billing.utils.Base64; -import net.robotmedia.billing.utils.Base64DecoderException; - -public class DefaultSignatureValidator implements ISignatureValidator { - - protected static final String KEY_FACTORY_ALGORITHM = "RSA"; - protected static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; - - /** - * Generates a PublicKey instance from a string containing the - * Base64-encoded public key. - * - * @param encodedPublicKey - * Base64-encoded public key - * @throws IllegalArgumentException - * if encodedPublicKey is invalid - */ - protected PublicKey generatePublicKey(String encodedPublicKey) { - try { - byte[] decodedKey = Base64.decode(encodedPublicKey); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM); - return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey)); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } catch (InvalidKeySpecException e) { - Log.e(BillingController.LOG_TAG, "Invalid key specification."); - throw new IllegalArgumentException(e); - } catch (Base64DecoderException e) { - Log.e(BillingController.LOG_TAG, "Base64 decoding failed."); - throw new IllegalArgumentException(e); - } - } - - private BillingController.IConfiguration configuration; - - public DefaultSignatureValidator(BillingController.IConfiguration configuration) { - this.configuration = configuration; - } - - protected boolean validate(PublicKey publicKey, String signedData, String signature) { - Signature sig; - try { - sig = Signature.getInstance(SIGNATURE_ALGORITHM); - sig.initVerify(publicKey); - sig.update(signedData.getBytes()); - if (!sig.verify(Base64.decode(signature))) { - Log.e(BillingController.LOG_TAG, "Signature verification failed."); - return false; - } - return true; - } catch (NoSuchAlgorithmException e) { - Log.e(BillingController.LOG_TAG, "NoSuchAlgorithmException"); - } catch (InvalidKeyException e) { - Log.e(BillingController.LOG_TAG, "Invalid key specification"); - } catch (SignatureException e) { - Log.e(BillingController.LOG_TAG, "Signature exception"); - } catch (Base64DecoderException e) { - Log.e(BillingController.LOG_TAG, "Base64 decoding failed"); - } - return false; - } - - public boolean validate(String signedData, String signature) { - final String publicKey; - if (configuration == null || TextUtils.isEmpty(publicKey = configuration.getPublicKey())) { - Log.w(BillingController.LOG_TAG, "Please set the public key or turn on debug mode"); - return false; - } - if (signedData == null) { - Log.e(BillingController.LOG_TAG, "Data is null"); - return false; - } - PublicKey key = generatePublicKey(publicKey); - return validate(key, signedData, signature); - } - -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/security/ISignatureValidator.java b/androidbillinglibrary/src/net/robotmedia/billing/security/ISignatureValidator.java deleted file mode 100644 index a329f05f22..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/security/ISignatureValidator.java +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.robotmedia.billing.security; - -public interface ISignatureValidator { - - /** - * Validates that the specified signature matches the computed signature on - * the specified signed data. Returns true if the data is correctly signed. - * - * @param signedData - * signed data - * @param signature - * signature - * @return true if the data and signature match, false otherwise. - */ - public boolean validate(String signedData, String signature); - -} \ No newline at end of file diff --git a/androidbillinglibrary/src/net/robotmedia/billing/utils/AESObfuscator.java b/androidbillinglibrary/src/net/robotmedia/billing/utils/AESObfuscator.java deleted file mode 100644 index 56c7d6dad2..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/utils/AESObfuscator.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.robotmedia.billing.utils; - -import java.io.UnsupportedEncodingException; -import java.security.GeneralSecurityException; -import java.security.spec.KeySpec; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.PBEKeySpec; -import javax.crypto.spec.SecretKeySpec; - -/** - * An obfuscator that uses AES to encrypt data. - */ -public class AESObfuscator { - private static final String UTF8 = "UTF-8"; - private static final String KEYGEN_ALGORITHM = "PBEWITHSHAAND256BITAES-CBC-BC"; - private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding"; - private static final byte[] IV = - { 16, 74, 71, -80, 32, 101, -47, 72, 117, -14, 0, -29, 70, 65, -12, 74 }; - private static final String header = "net.robotmedia.billing.utils.AESObfuscator-1|"; - - private Cipher mEncryptor; - private Cipher mDecryptor; - - public AESObfuscator(byte[] salt, String password) { - try { - SecretKeyFactory factory = SecretKeyFactory.getInstance(KEYGEN_ALGORITHM); - KeySpec keySpec = - new PBEKeySpec(password.toCharArray(), salt, 1024, 256); - SecretKey tmp = factory.generateSecret(keySpec); - SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); - mEncryptor = Cipher.getInstance(CIPHER_ALGORITHM); - mEncryptor.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(IV)); - mDecryptor = Cipher.getInstance(CIPHER_ALGORITHM); - mDecryptor.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(IV)); - } catch (GeneralSecurityException e) { - // This can't happen on a compatible Android device. - throw new RuntimeException("Invalid environment", e); - } - } - - public String obfuscate(String original) { - if (original == null) { - return null; - } - try { - // Header is appended as an integrity check - return Base64.encode(mEncryptor.doFinal((header + original).getBytes(UTF8))); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("Invalid environment", e); - } catch (GeneralSecurityException e) { - throw new RuntimeException("Invalid environment", e); - } - } - - public String unobfuscate(String obfuscated) throws ValidationException { - if (obfuscated == null) { - return null; - } - try { - String result = new String(mDecryptor.doFinal(Base64.decode(obfuscated)), UTF8); - // Check for presence of header. This serves as a final integrity check, for cases - // where the block size is correct during decryption. - int headerIndex = result.indexOf(header); - if (headerIndex != 0) { - throw new ValidationException("Header not found (invalid data or key)" + ":" + - obfuscated); - } - return result.substring(header.length(), result.length()); - } catch (Base64DecoderException e) { - throw new ValidationException(e.getMessage() + ":" + obfuscated); - } catch (IllegalBlockSizeException e) { - throw new ValidationException(e.getMessage() + ":" + obfuscated); - } catch (BadPaddingException e) { - throw new ValidationException(e.getMessage() + ":" + obfuscated); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("Invalid environment", e); - } - } - - public class ValidationException extends Exception { - public ValidationException() { - super(); - } - - public ValidationException(String s) { - super(s); - } - - private static final long serialVersionUID = 1L; - } - -} \ No newline at end of file diff --git a/androidbillinglibrary/src/net/robotmedia/billing/utils/Base64.java b/androidbillinglibrary/src/net/robotmedia/billing/utils/Base64.java deleted file mode 100644 index 7fa93cd702..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/utils/Base64.java +++ /dev/null @@ -1,570 +0,0 @@ -// Portions copyright 2002, Google, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package net.robotmedia.billing.utils; - -// This code was converted from code at http://iharder.sourceforge.net/base64/ -// Lots of extraneous features were removed. -/* The original code said: - *

- * I am placing this code in the Public Domain. Do with it as you will. - * This software comes with no guarantees or warranties but with - * plenty of well-wishing instead! - * Please visit - * http://iharder.net/xmlizable - * periodically to check for updates or to contribute improvements. - *

- * - * @author Robert Harder - * @author rharder@usa.net - * @version 1.3 - */ - -/** - * Base64 converter class. This code is not a complete MIME encoder; - * it simply converts binary data to base64 data and back. - * - *

Note {@link CharBase64} is a GWT-compatible implementation of this - * class. - */ -public class Base64 { - /** Specify encoding (value is {@code true}). */ - public final static boolean ENCODE = true; - - /** Specify decoding (value is {@code false}). */ - public final static boolean DECODE = false; - - /** The equals sign (=) as a byte. */ - private final static byte EQUALS_SIGN = (byte) '='; - - /** The new line character (\n) as a byte. */ - private final static byte NEW_LINE = (byte) '\n'; - - /** - * The 64 valid Base64 values. - */ - private final static byte[] ALPHABET = - {(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', - (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', - (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', - (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', - (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', - (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', - (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', - (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', - (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', - (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', - (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', - (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', - (byte) '9', (byte) '+', (byte) '/'}; - - /** - * The 64 valid web safe Base64 values. - */ - private final static byte[] WEBSAFE_ALPHABET = - {(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', - (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', - (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', - (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', - (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', - (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', - (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', - (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', - (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', - (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', - (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', - (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', - (byte) '9', (byte) '-', (byte) '_'}; - - /** - * Translates a Base64 value to either its 6-bit reconstruction value - * or a negative number indicating some other meaning. - **/ - private final static byte[] DECODABET = {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 - -5, -5, // Whitespace: Tab and Linefeed - -9, -9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 - -9, -9, -9, -9, -9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 - 62, // Plus sign at decimal 43 - -9, -9, -9, // Decimal 44 - 46 - 63, // Slash at decimal 47 - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine - -9, -9, -9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9, -9, -9, // Decimal 62 - 64 - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' - -9, -9, -9, -9, -9, -9, // Decimal 91 - 96 - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' - -9, -9, -9, -9, -9 // Decimal 123 - 127 - /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ - }; - - /** The web safe decodabet */ - private final static byte[] WEBSAFE_DECODABET = - {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 - -5, -5, // Whitespace: Tab and Linefeed - -9, -9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 - -9, -9, -9, -9, -9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 44 - 62, // Dash '-' sign at decimal 45 - -9, -9, // Decimal 46-47 - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine - -9, -9, -9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9, -9, -9, // Decimal 62 - 64 - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' - -9, -9, -9, -9, // Decimal 91-94 - 63, // Underscore '_' at decimal 95 - -9, // Decimal 96 - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' - -9, -9, -9, -9, -9 // Decimal 123 - 127 - /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ - }; - - // Indicates white space in encoding - private final static byte WHITE_SPACE_ENC = -5; - // Indicates equals sign in encoding - private final static byte EQUALS_SIGN_ENC = -1; - - /** Defeats instantiation. */ - private Base64() { - } - - /* ******** E N C O D I N G M E T H O D S ******** */ - - /** - * Encodes up to three bytes of the array source - * and writes the resulting four Base64 bytes to destination. - * The source and destination arrays can be manipulated - * anywhere along their length by specifying - * srcOffset and destOffset. - * This method does not check to make sure your arrays - * are large enough to accommodate srcOffset + 3 for - * the source array or destOffset + 4 for - * the destination array. - * The actual number of significant bytes in your array is - * given by numSigBytes. - * - * @param source the array to convert - * @param srcOffset the index where conversion begins - * @param numSigBytes the number of significant bytes in your array - * @param destination the array to hold the conversion - * @param destOffset the index where output will be put - * @param alphabet is the encoding alphabet - * @return the destination array - * @since 1.3 - */ - private static byte[] encode3to4(byte[] source, int srcOffset, - int numSigBytes, byte[] destination, int destOffset, byte[] alphabet) { - // 1 2 3 - // 01234567890123456789012345678901 Bit position - // --------000000001111111122222222 Array position from threeBytes - // --------| || || || | Six bit groups to index alphabet - // >>18 >>12 >> 6 >> 0 Right shift necessary - // 0x3f 0x3f 0x3f Additional AND - - // Create buffer with zero-padding if there are only one or two - // significant bytes passed in the array. - // We have to shift left 24 in order to flush out the 1's that appear - // when Java treats a value as negative that is cast from a byte to an int. - int inBuff = - (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0) - | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0) - | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0); - - switch (numSigBytes) { - case 3: - destination[destOffset] = alphabet[(inBuff >>> 18)]; - destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f]; - destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f]; - destination[destOffset + 3] = alphabet[(inBuff) & 0x3f]; - return destination; - case 2: - destination[destOffset] = alphabet[(inBuff >>> 18)]; - destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f]; - destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f]; - destination[destOffset + 3] = EQUALS_SIGN; - return destination; - case 1: - destination[destOffset] = alphabet[(inBuff >>> 18)]; - destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f]; - destination[destOffset + 2] = EQUALS_SIGN; - destination[destOffset + 3] = EQUALS_SIGN; - return destination; - default: - return destination; - } // end switch - } // end encode3to4 - - /** - * Encodes a byte array into Base64 notation. - * Equivalent to calling - * {@code encodeBytes(source, 0, source.length)} - * - * @param source The data to convert - * @since 1.4 - */ - public static String encode(byte[] source) { - return encode(source, 0, source.length, ALPHABET, true); - } - - /** - * Encodes a byte array into web safe Base64 notation. - * - * @param source The data to convert - * @param doPadding is {@code true} to pad result with '=' chars - * if it does not fall on 3 byte boundaries - */ - public static String encodeWebSafe(byte[] source, boolean doPadding) { - return encode(source, 0, source.length, WEBSAFE_ALPHABET, doPadding); - } - - /** - * Encodes a byte array into Base64 notation. - * - * @param source the data to convert - * @param off offset in array where conversion should begin - * @param len length of data to convert - * @param alphabet the encoding alphabet - * @param doPadding is {@code true} to pad result with '=' chars - * if it does not fall on 3 byte boundaries - * @since 1.4 - */ - public static String encode(byte[] source, int off, int len, byte[] alphabet, - boolean doPadding) { - byte[] outBuff = encode(source, off, len, alphabet, Integer.MAX_VALUE); - int outLen = outBuff.length; - - // If doPadding is false, set length to truncate '=' - // padding characters - while (doPadding == false && outLen > 0) { - if (outBuff[outLen - 1] != '=') { - break; - } - outLen -= 1; - } - - return new String(outBuff, 0, outLen); - } - - /** - * Encodes a byte array into Base64 notation. - * - * @param source the data to convert - * @param off offset in array where conversion should begin - * @param len length of data to convert - * @param alphabet is the encoding alphabet - * @param maxLineLength maximum length of one line. - * @return the BASE64-encoded byte array - */ - public static byte[] encode(byte[] source, int off, int len, byte[] alphabet, - int maxLineLength) { - int lenDiv3 = (len + 2) / 3; // ceil(len / 3) - int len43 = lenDiv3 * 4; - byte[] outBuff = new byte[len43 // Main 4:3 - + (len43 / maxLineLength)]; // New lines - - int d = 0; - int e = 0; - int len2 = len - 2; - int lineLength = 0; - for (; d < len2; d += 3, e += 4) { - - // The following block of code is the same as - // encode3to4( source, d + off, 3, outBuff, e, alphabet ); - // but inlined for faster encoding (~20% improvement) - int inBuff = - ((source[d + off] << 24) >>> 8) - | ((source[d + 1 + off] << 24) >>> 16) - | ((source[d + 2 + off] << 24) >>> 24); - outBuff[e] = alphabet[(inBuff >>> 18)]; - outBuff[e + 1] = alphabet[(inBuff >>> 12) & 0x3f]; - outBuff[e + 2] = alphabet[(inBuff >>> 6) & 0x3f]; - outBuff[e + 3] = alphabet[(inBuff) & 0x3f]; - - lineLength += 4; - if (lineLength == maxLineLength) { - outBuff[e + 4] = NEW_LINE; - e++; - lineLength = 0; - } // end if: end of line - } // end for: each piece of array - - if (d < len) { - encode3to4(source, d + off, len - d, outBuff, e, alphabet); - - lineLength += 4; - if (lineLength == maxLineLength) { - // Add a last newline - outBuff[e + 4] = NEW_LINE; - e++; - } - e += 4; - } - - assert (e == outBuff.length); - return outBuff; - } - - - /* ******** D E C O D I N G M E T H O D S ******** */ - - - /** - * Decodes four bytes from array source - * and writes the resulting bytes (up to three of them) - * to destination. - * The source and destination arrays can be manipulated - * anywhere along their length by specifying - * srcOffset and destOffset. - * This method does not check to make sure your arrays - * are large enough to accommodate srcOffset + 4 for - * the source array or destOffset + 3 for - * the destination array. - * This method returns the actual number of bytes that - * were converted from the Base64 encoding. - * - * - * @param source the array to convert - * @param srcOffset the index where conversion begins - * @param destination the array to hold the conversion - * @param destOffset the index where output will be put - * @param decodabet the decodabet for decoding Base64 content - * @return the number of decoded bytes converted - * @since 1.3 - */ - private static int decode4to3(byte[] source, int srcOffset, - byte[] destination, int destOffset, byte[] decodabet) { - // Example: Dk== - if (source[srcOffset + 2] == EQUALS_SIGN) { - int outBuff = - ((decodabet[source[srcOffset]] << 24) >>> 6) - | ((decodabet[source[srcOffset + 1]] << 24) >>> 12); - - destination[destOffset] = (byte) (outBuff >>> 16); - return 1; - } else if (source[srcOffset + 3] == EQUALS_SIGN) { - // Example: DkL= - int outBuff = - ((decodabet[source[srcOffset]] << 24) >>> 6) - | ((decodabet[source[srcOffset + 1]] << 24) >>> 12) - | ((decodabet[source[srcOffset + 2]] << 24) >>> 18); - - destination[destOffset] = (byte) (outBuff >>> 16); - destination[destOffset + 1] = (byte) (outBuff >>> 8); - return 2; - } else { - // Example: DkLE - int outBuff = - ((decodabet[source[srcOffset]] << 24) >>> 6) - | ((decodabet[source[srcOffset + 1]] << 24) >>> 12) - | ((decodabet[source[srcOffset + 2]] << 24) >>> 18) - | ((decodabet[source[srcOffset + 3]] << 24) >>> 24); - - destination[destOffset] = (byte) (outBuff >> 16); - destination[destOffset + 1] = (byte) (outBuff >> 8); - destination[destOffset + 2] = (byte) (outBuff); - return 3; - } - } // end decodeToBytes - - - /** - * Decodes data from Base64 notation. - * - * @param s the string to decode (decoded in default encoding) - * @return the decoded data - * @since 1.4 - */ - public static byte[] decode(String s) throws Base64DecoderException { - byte[] bytes = s.getBytes(); - return decode(bytes, 0, bytes.length); - } - - /** - * Decodes data from web safe Base64 notation. - * Web safe encoding uses '-' instead of '+', '_' instead of '/' - * - * @param s the string to decode (decoded in default encoding) - * @return the decoded data - */ - public static byte[] decodeWebSafe(String s) throws Base64DecoderException { - byte[] bytes = s.getBytes(); - return decodeWebSafe(bytes, 0, bytes.length); - } - - /** - * Decodes Base64 content in byte array format and returns - * the decoded byte array. - * - * @param source The Base64 encoded data - * @return decoded data - * @since 1.3 - * @throws Base64DecoderException - */ - public static byte[] decode(byte[] source) throws Base64DecoderException { - return decode(source, 0, source.length); - } - - /** - * Decodes web safe Base64 content in byte array format and returns - * the decoded data. - * Web safe encoding uses '-' instead of '+', '_' instead of '/' - * - * @param source the string to decode (decoded in default encoding) - * @return the decoded data - */ - public static byte[] decodeWebSafe(byte[] source) - throws Base64DecoderException { - return decodeWebSafe(source, 0, source.length); - } - - /** - * Decodes Base64 content in byte array format and returns - * the decoded byte array. - * - * @param source the Base64 encoded data - * @param off the offset of where to begin decoding - * @param len the length of characters to decode - * @return decoded data - * @since 1.3 - * @throws Base64DecoderException - */ - public static byte[] decode(byte[] source, int off, int len) - throws Base64DecoderException { - return decode(source, off, len, DECODABET); - } - - /** - * Decodes web safe Base64 content in byte array format and returns - * the decoded byte array. - * Web safe encoding uses '-' instead of '+', '_' instead of '/' - * - * @param source the Base64 encoded data - * @param off the offset of where to begin decoding - * @param len the length of characters to decode - * @return decoded data - */ - public static byte[] decodeWebSafe(byte[] source, int off, int len) - throws Base64DecoderException { - return decode(source, off, len, WEBSAFE_DECODABET); - } - - /** - * Decodes Base64 content using the supplied decodabet and returns - * the decoded byte array. - * - * @param source the Base64 encoded data - * @param off the offset of where to begin decoding - * @param len the length of characters to decode - * @param decodabet the decodabet for decoding Base64 content - * @return decoded data - */ - public static byte[] decode(byte[] source, int off, int len, byte[] decodabet) - throws Base64DecoderException { - int len34 = len * 3 / 4; - byte[] outBuff = new byte[2 + len34]; // Upper limit on size of output - int outBuffPosn = 0; - - byte[] b4 = new byte[4]; - int b4Posn = 0; - int i = 0; - byte sbiCrop = 0; - byte sbiDecode = 0; - for (i = 0; i < len; i++) { - sbiCrop = (byte) (source[i + off] & 0x7f); // Only the low seven bits - sbiDecode = decodabet[sbiCrop]; - - if (sbiDecode >= WHITE_SPACE_ENC) { // White space Equals sign or better - if (sbiDecode >= EQUALS_SIGN_ENC) { - // An equals sign (for padding) must not occur at position 0 or 1 - // and must be the last byte[s] in the encoded value - if (sbiCrop == EQUALS_SIGN) { - int bytesLeft = len - i; - byte lastByte = (byte) (source[len - 1 + off] & 0x7f); - if (b4Posn == 0 || b4Posn == 1) { - throw new Base64DecoderException( - "invalid padding byte '=' at byte offset " + i); - } else if ((b4Posn == 3 && bytesLeft > 2) - || (b4Posn == 4 && bytesLeft > 1)) { - throw new Base64DecoderException( - "padding byte '=' falsely signals end of encoded value " - + "at offset " + i); - } else if (lastByte != EQUALS_SIGN && lastByte != NEW_LINE) { - throw new Base64DecoderException( - "encoded value has invalid trailing byte"); - } - break; - } - - b4[b4Posn++] = sbiCrop; - if (b4Posn == 4) { - outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet); - b4Posn = 0; - } - } - } else { - throw new Base64DecoderException("Bad Base64 input character at " + i - + ": " + source[i + off] + "(decimal)"); - } - } - - // Because web safe encoding allows non padding base64 encodes, we - // need to pad the rest of the b4 buffer with equal signs when - // b4Posn != 0. There can be at most 2 equal signs at the end of - // four characters, so the b4 buffer must have two or three - // characters. This also catches the case where the input is - // padded with EQUALS_SIGN - if (b4Posn != 0) { - if (b4Posn == 1) { - throw new Base64DecoderException("single trailing character at offset " - + (len - 1)); - } - b4[b4Posn++] = EQUALS_SIGN; - outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet); - } - - byte[] out = new byte[outBuffPosn]; - System.arraycopy(outBuff, 0, out, 0, outBuffPosn); - return out; - } -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/utils/Base64DecoderException.java b/androidbillinglibrary/src/net/robotmedia/billing/utils/Base64DecoderException.java deleted file mode 100644 index 187f3f9455..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/utils/Base64DecoderException.java +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2002, Google, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package net.robotmedia.billing.utils; - -/** - * Exception thrown when encountering an invalid Base64 input character. - * - * @author nelson - */ -public class Base64DecoderException extends Exception { - public Base64DecoderException() { - super(); - } - - public Base64DecoderException(String s) { - super(s); - } - - private static final long serialVersionUID = 1L; -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/utils/Compatibility.java b/androidbillinglibrary/src/net/robotmedia/billing/utils/Compatibility.java deleted file mode 100644 index 9942636983..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/utils/Compatibility.java +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package net.robotmedia.billing.utils; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -import android.app.Activity; -import android.app.Service; -import android.content.Intent; -import android.content.IntentSender; -import android.util.Log; - -public class Compatibility { - private static Method startIntentSender; - public static int START_NOT_STICKY; - @SuppressWarnings("rawtypes") - private static final Class[] START_INTENT_SENDER_SIG = new Class[] { - IntentSender.class, Intent.class, int.class, int.class, int.class - }; - - static { - initCompatibility(); - }; - - private static void initCompatibility() { - try { - final Field field = Service.class.getField("START_NOT_STICKY"); - START_NOT_STICKY = field.getInt(null); - } catch (Exception e) { - START_NOT_STICKY = 2; - } - try { - startIntentSender = Activity.class.getMethod("startIntentSender", - START_INTENT_SENDER_SIG); - } catch (SecurityException e) { - startIntentSender = null; - } catch (NoSuchMethodException e) { - startIntentSender = null; - } - } - - public static void startIntentSender(Activity activity, IntentSender intentSender, Intent intent) { - if (startIntentSender != null) { - final Object[] args = new Object[5]; - args[0] = intentSender; - args[1] = intent; - args[2] = Integer.valueOf(0); - args[3] = Integer.valueOf(0); - args[4] = Integer.valueOf(0); - try { - startIntentSender.invoke(activity, args); - } catch (Exception e) { - Log.e(Compatibility.class.getSimpleName(), "startIntentSender", e); - } - } - } - - public static boolean isStartIntentSenderSupported() { - return startIntentSender != null; - } -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/utils/Installation.java b/androidbillinglibrary/src/net/robotmedia/billing/utils/Installation.java deleted file mode 100644 index bcd2ed41bf..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/utils/Installation.java +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package net.robotmedia.billing.utils; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.UUID; - -import android.content.Context; - -public class Installation { - private static final String INSTALLATION = "INSTALLATION"; - private static String sID = null; - - public synchronized static String id(Context context) { - if (sID == null) { - File installation = new File(context.getFilesDir(), INSTALLATION); - try { - if (!installation.exists()) { - writeInstallationFile(installation); - } - sID = readInstallationFile(installation); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - return sID; - } - - private static String readInstallationFile(File installation) throws IOException { - RandomAccessFile f = new RandomAccessFile(installation, "r"); - byte[] bytes = new byte[(int) f.length()]; - f.readFully(bytes); - f.close(); - return new String(bytes); - } - - private static void writeInstallationFile(File installation) throws IOException { - FileOutputStream out = new FileOutputStream(installation); - String id = UUID.randomUUID().toString(); - out.write(id.getBytes()); - out.close(); - } -} diff --git a/androidbillinglibrary/src/net/robotmedia/billing/utils/Security.java b/androidbillinglibrary/src/net/robotmedia/billing/utils/Security.java deleted file mode 100644 index 6ef248afe6..0000000000 --- a/androidbillinglibrary/src/net/robotmedia/billing/utils/Security.java +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright 2011 Robot Media SL (http://www.robotmedia.net) -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package net.robotmedia.billing.utils; - -import java.security.SecureRandom; -import java.util.HashSet; - -import net.robotmedia.billing.utils.AESObfuscator.ValidationException; - -import android.content.Context; -import android.provider.Settings; -import android.util.Log; - -public class Security { - - private static HashSet knownNonces = new HashSet(); - private static final SecureRandom RANDOM = new SecureRandom(); - private static final String TAG = Security.class.getSimpleName(); - - /** Generates a nonce (a random number used once). */ - public static long generateNonce() { - long nonce = RANDOM.nextLong(); - knownNonces.add(nonce); - return nonce; - } - - public static boolean isNonceKnown(long nonce) { - return knownNonces.contains(nonce); - } - - public static void removeNonce(long nonce) { - knownNonces.remove(nonce); - } - - public static String obfuscate(Context context, byte[] salt, String original) { - final AESObfuscator obfuscator = getObfuscator(context, salt); - return obfuscator.obfuscate(original); - } - - private static AESObfuscator _obfuscator = null; - - private static AESObfuscator getObfuscator(Context context, byte[] salt) { - if (_obfuscator == null) { - final String installationId = Installation.id(context); - final String deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); - final String password = installationId + deviceId + context.getPackageName(); - _obfuscator = new AESObfuscator(salt, password); - } - return _obfuscator; - } - - public static String unobfuscate(Context context, byte[] salt, String obfuscated) { - final AESObfuscator obfuscator = getObfuscator(context, salt); - try { - return obfuscator.unobfuscate(obfuscated); - } catch (ValidationException e) { - Log.w(TAG, "Invalid obfuscated data or key"); - } - return null; - } - -} diff --git a/build.gradle b/build.gradle index 08d245b9bd..0bb66b00c6 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,6 @@ apply plugin: 'android' dependencies { compile fileTree(dir: 'libs', include: '*.jar') - //compile project(':androidbillinglibrary') compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar' compile 'com.android.support:support-v4:20.0.0' compile 'com.github.gabrielemariotti.changeloglib:library:1.5.1' From 426f3539dbf8711caddbede3c80687defe49d0cf Mon Sep 17 00:00:00 2001 From: AlessandroLazzari Date: Tue, 16 Sep 2014 22:48:25 +0200 Subject: [PATCH 04/12] update changelog and credit's thirdparty --- res/raw/changelog.xml | 6 ++++++ res/raw/credits_thirdparty.html | 6 ------ res/values/strings.xml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/res/raw/changelog.xml b/res/raw/changelog.xml index e0d44202cc..51d3eb6098 100644 --- a/res/raw/changelog.xml +++ b/res/raw/changelog.xml @@ -1,5 +1,11 @@ + + Fixed issue that shows the messagebox of the donation, even if you've already donated + Migrate to Google In App Billing v3 + Remove libray Robotmedia + Fixed other minor bugs + Fixed issue that sometimes prevented by modifying the amounts in the dialog Updated translations diff --git a/res/raw/credits_thirdparty.html b/res/raw/credits_thirdparty.html index 5b4460a489..1431cafc10 100644 --- a/res/raw/credits_thirdparty.html +++ b/res/raw/credits_thirdparty.html @@ -62,12 +62,6 @@

3rd party libraries used within Money Manager Ex for Android

  • Web: achartengine.org
  • -
  • AndroidBillingLibrary - -
  • Changeloglib
    • Apache License 2.0
    • diff --git a/res/values/strings.xml b/res/values/strings.xml index 6085cb9316..de33e1c5f3 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5,7 +5,7 @@ Money Manager Ex © 2012 The Android Money Manager Ex Project A simple and easy-to-use application to manage personal finances, bank accounts, family budget, and so on. - Android Money Manager Ex Project uses ActionBarSherlock and RobotMediaBilling libraries + Android Money Manager Ex Project uses ActionBarSherlock library Open source licenses From 260bc951342584960fca41db45d051b8d1084999 Mon Sep 17 00:00:00 2001 From: AlessandroLazzari Date: Wed, 17 Sep 2014 22:01:03 +0200 Subject: [PATCH 05/12] fixed status in-app biling process --- res/layout/donate_activity.xml | 8 ++--- res/values/strings.xml | 4 ++- src/com/money/manager/ex/DonateActivity.java | 36 +++++++++++++------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/res/layout/donate_activity.xml b/res/layout/donate_activity.xml index fecd90d60a..f09d3d9953 100644 --- a/res/layout/donate_activity.xml +++ b/res/layout/donate_activity.xml @@ -111,12 +111,12 @@ android:visibility="gone" /> + android:text="@string/donate_in_app_retrieving_status" + android:gravity="center_horizontal" /> diff --git a/res/values/strings.xml b/res/values/strings.xml index de33e1c5f3..e08dbdf0b5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -472,5 +472,7 @@ Deposit To %1$s MoneyManagerEx Website - You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! + You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! + Retrieving status of your donations from Google Play. Please wait… + Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. \ No newline at end of file diff --git a/src/com/money/manager/ex/DonateActivity.java b/src/com/money/manager/ex/DonateActivity.java index b78b287f0d..ac9f76b3cc 100644 --- a/src/com/money/manager/ex/DonateActivity.java +++ b/src/com/money/manager/ex/DonateActivity.java @@ -2,6 +2,7 @@ import android.content.Intent; import android.os.Bundle; +import android.text.Html; import android.util.Log; import android.view.View; import android.widget.ArrayAdapter; @@ -24,6 +25,7 @@ import java.util.UUID; public class DonateActivity extends BaseFragmentActivity { + private static final String LOGCAT = DonateActivity.class.getSimpleName(); private final String PURCHASED_SKU = "DonateActivity:Purchased_Sku"; private final String PURCHASED_TOKEN = "DonateActivity:Purchased_Token"; @@ -72,16 +74,6 @@ public void onClick(final View v) { }); // Disabilito il tasto fin che non è pronto inAppButton.setEnabled(false); - // init IabHelper - mIabHelper = new IabHelper(this.getApplicationContext(), Core.getAppBase64()); - mIabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { - @Override - public void onIabSetupFinished(IabResult result) { - if (result.isSuccess()) { - mIabHelper.queryInventoryAsync(true, skus, mQueryInventoryFinishedListener); - } - } - }); mConsumeFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() { @Override @@ -109,6 +101,21 @@ public void onQueryInventoryFinished(IabResult result, Inventory inv) { onStartupInApp(result.isSuccess()); } }; + // init IabHelper + try { + mIabHelper = new IabHelper(this.getApplicationContext(), Core.getAppBase64()); + mIabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { + @Override + public void onIabSetupFinished(IabResult result) { + if (result.isSuccess()) { + mIabHelper.queryInventoryAsync(true, skus, mQueryInventoryFinishedListener); + } + } + }); + } catch (Exception e) { + Log.e(LOGCAT, "In-App Billing startup error"); + onStartupInApp(false); + } // set enable return getSupportActionBar().setDisplayHomeAsUpEnabled(true); } @@ -138,6 +145,7 @@ protected void onDestroy() { } public void onStartupInApp(boolean supported) { + final TextView inAppStatus = (TextView) findViewById(R.id.textViewInAppStatus); if (supported) { final List inAppName = new ArrayList(); @@ -155,11 +163,13 @@ public void onStartupInApp(boolean supported) { final Button inAppButton = (Button) findViewById(R.id.buttonDonateInApp); inAppButton.setVisibility(inAppName.size() > 0 ? View.VISIBLE : View.GONE); inAppButton.setEnabled(inAppName.size() > 0 ); - // text view - final TextView inAppAlready = (TextView) findViewById(R.id.textViewInAppAlreadyDonate); - inAppAlready.setVisibility(inAppName.size() <= 0 ? View.VISIBLE : View.GONE); + // status + inAppStatus.setText(inAppName.size() <= 0 ? Html.fromHtml("" + getString(R.string.donate_in_app_already_donate) + "") : null); // hide spinner if release version inAppSpinner.setVisibility(inAppName.size() > 1 ? View.VISIBLE : View.GONE); + } else { + inAppStatus.setText(R.string.donate_in_app_error); + inAppStatus.setTextColor(getResources().getColor(R.color.holo_red_dark)); } } From 466bc973c2345b54dd6bb6883a72ee03bf109bd2 Mon Sep 17 00:00:00 2001 From: AlessandroLazzari Date: Mon, 22 Sep 2014 20:47:01 +0200 Subject: [PATCH 06/12] fixed some strings --- res/layout/about_content.xml | 8 ++++---- res/values/privatestrings.xml | 1 + res/values/strings.xml | 7 +++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/res/layout/about_content.xml b/res/layout/about_content.xml index 8da6a89951..0d1d672690 100644 --- a/res/layout/about_content.xml +++ b/res/layout/about_content.xml @@ -8,15 +8,15 @@ diff --git a/res/values/privatestrings.xml b/res/values/privatestrings.xml index 02d0f1dd18..d38fffc2a7 100644 --- a/res/values/privatestrings.xml +++ b/res/values/privatestrings.xml @@ -1,4 +1,5 @@ user_size + © 2012-2014 Alessandro Lazzari \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index e08dbdf0b5..7f8d307ad3 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3,9 +3,8 @@ Money Manager Ex - © 2012 The Android Money Manager Ex Project A simple and easy-to-use application to manage personal finances, bank accounts, family budget, and so on. - Android Money Manager Ex Project uses ActionBarSherlock library + MoneyManagerEx for Android Project uses ActionBarSherlock library Open source licenses @@ -52,7 +51,7 @@ View open accounts If not selected will show all accounts View favourite accounts - + Version Build @@ -307,7 +306,7 @@ The data has been successfully exported to the file %1$s Export file %1$s failed - Android Money Manager Ex is provided free. If this application is to your liking, you can support the development team with a donation. + MoneyManagerEx for Android is provided free. If this application is to your liking, you can support the development team with a donation. Google Play In-App Billing Donate via Google Play In-App Billing. Select a donation amount From 997fb0f55c09c9deb047b692a2e5bb7ab8a255b4 Mon Sep 17 00:00:00 2001 From: AlessandroLazzari Date: Mon, 22 Sep 2014 20:52:07 +0200 Subject: [PATCH 07/12] update italian translations --- res/values-it/strings.xml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 40d17c55a3..52e37f4359 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -1,8 +1,9 @@ + Money Manager Ex Una applicazione semplice e facile da usare per gestire finanze personali, conti bancari, budget familiare, etc. - Android Money Manager Ex Project utilizza le librerie ActionBarSherlock e RobotMediaBilling + MoneyManagerEx for Android utilizza la libreria di ActionBarSherlock Licenze open source Inserimento di dati fallito Eliminazione di dati fallita @@ -122,6 +123,7 @@ Chiuso Nuovo/Modifica Valuta Tema dell\'applicazione + Holo Holo Light With Dark ActionBar Chiudere l\'applicazione Vuoi chiudere l\'applicazione? @@ -212,7 +214,8 @@ Esportazione dei dati. Attendere prego… I dati sono stati esportati con successo nel file %1$s Esportazione file %1$s fallita - Android Money Manager Ex viene fornito gratuitamente. Se questa applicazione è di vostro gradimento, potete sostenere il team di sviluppo con una donazione. + MoneyManagerEx for Android è fornito gratuitamente. Se questa applicazione è di vostro gradimento, è possibile supportare il team di sviluppo con una donazione. + Google Play In-App Billing Dona via Google Play In-App Billing. Seleziona l\'importo della donazione Donate @@ -226,6 +229,7 @@ La cartella Dropbox/Apps/Money Manager Ex Mobile è vuota. Se utilizzi già MoneyManagerEx copia il database in questa cartella dal vostro computer, e dopo effettua l\'aggiornamento. Selezionare un file da Dropbox Ultima modifica + Dropbox Il database è stato scaricato Per utilizzare il database scaricato, toccare Apri Database Toccare per selezionare il file da utilizzare da Dropbox @@ -234,6 +238,7 @@ Upload su Dropbox Tocca per caricare manualmente il file collegato alla cartella Dropbox Il database è stato caricato con successo + Dropbox - Money Manager Ex Come funziona Dropbox per Money Manager Ex\? Non visualizzare ancora Apri Database @@ -269,7 +274,7 @@ Operazioni Imminenti Quantità Dashboard - Il database è sincronizzato + Il database è aggiornato Ultimi 3 mesi Ultimi 6 mesi Categoria Vuota @@ -340,4 +345,7 @@ Prelievo da %1$s Deposito su %1$s MoneyManagerEx Website + Hai già sostenuto lo sviluppo di MoneyManagerEx for Android con la vostra donazione! \n\nGrazie mille dal team di sviluppo! + Recupero dello stato delle vostre donazioni da Google Play. Attendere prego… + Non è possibile utilizzare la fatturazione in-app. Verifica se è installata l\'ultima versione dell\'applicazione Play Store. From 8b276fc71d789f5e71d3722cc24a6fce87b21950 Mon Sep 17 00:00:00 2001 From: AlessandroLazzari Date: Fri, 10 Oct 2014 09:53:34 +0200 Subject: [PATCH 08/12] Fixed issue #5 --- res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 7f8d307ad3..a1d0711590 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -449,7 +449,7 @@ Search payee, categories, currencies, etc… by contents and not by starting characters Rate Application - Language Application + Application Language Czech English Spanish From 76bbb81ef6d14e3fc44bfa01ca9c5ee95aa84df2 Mon Sep 17 00:00:00 2001 From: AlessandroLazzari Date: Fri, 10 Oct 2014 10:02:48 +0200 Subject: [PATCH 09/12] Closed issue #4 --- .../manager/ex/MoneyManagerProvider.java | 14 ++--- .../manager/ex/database/ViewAllData.java | 60 ------------------- .../manager/ex/fragment/SearchFragment.java | 40 ++++++------- 3 files changed, 26 insertions(+), 88 deletions(-) delete mode 100644 src/com/money/manager/ex/database/ViewAllData.java diff --git a/src/com/money/manager/ex/MoneyManagerProvider.java b/src/com/money/manager/ex/MoneyManagerProvider.java index 725505e52f..8143c86b1e 100644 --- a/src/com/money/manager/ex/MoneyManagerProvider.java +++ b/src/com/money/manager/ex/MoneyManagerProvider.java @@ -17,11 +17,6 @@ ******************************************************************************/ package com.money.manager.ex; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; @@ -55,10 +50,14 @@ import com.money.manager.ex.database.TableSplitTransactions; import com.money.manager.ex.database.TableStock; import com.money.manager.ex.database.TableSubCategory; -import com.money.manager.ex.database.ViewAllData; import com.money.manager.ex.database.ViewMobileData; import com.money.manager.ex.dropbox.DropboxHelper; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * MoneyManagerProvider is the extension of the base class of Android * ContentProvider. Its purpose is to implement the read access and modify the @@ -98,8 +97,7 @@ public boolean onCreate() { new TableCheckingAccount(), new TableCurrencyFormats(), new TableInfoTable(), new TablePayee(), new TableSplitTransactions(), new TableStock(), - new TableSubCategory(), new ViewAllData(), - new QueryAccountBills(getContext()), new QueryCategorySubCategory(getContext()), + new TableSubCategory(), new QueryAccountBills(getContext()), new QueryCategorySubCategory(getContext()), new QueryAllData(getContext()), new QueryBillDeposits(getContext()), new QueryReportIncomeVsExpenses(getContext()), new ViewMobileData(), new SQLDataSet()}); diff --git a/src/com/money/manager/ex/database/ViewAllData.java b/src/com/money/manager/ex/database/ViewAllData.java deleted file mode 100644 index f3f89447ff..0000000000 --- a/src/com/money/manager/ex/database/ViewAllData.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2012 The Android Money Manager Ex Project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - ******************************************************************************/ -package com.money.manager.ex.database; - - -public class ViewAllData extends Dataset { - // FIELDS - public static final String ID = "ID"; - public static final String TransactionType = "TransactionType"; - public static final String Date = "Date"; - public static final String UserDate = "UserDate"; - public static final String Year = "Year"; - public static final String Month = "Month"; - public static final String Day = "Day"; - public static final String Category = "Category"; - public static final String Subcategory = "Subcategory"; - public static final String Amount = "Amount"; - public static final String BaseConvRate = "BaseConvRate"; - public static final String CURRENCYID = "CurrencyID"; - public static final String AccountName = "AccountName"; - public static final String ACCOUNTID = "AccountID"; - public static final String ToAccountName = "ToAccountName"; - public static final String ToAccountID = "ToAccountID"; - public static final String TOTRANSAMOUNT = "ToTransAmount"; - public static final String ToCurrencyID = "ToCurrencyID"; - public static final String Splitted = "Splitted"; - public static final String CategID = "CategID"; - public static final String SubcategID = "SubcategID"; - public static final String Payee = "Payee"; - public static final String PayeeID = "PayeeID"; - public static final String TransactionNumber = "TransactionNumber"; - public static final String Status = "Status"; - public static final String Notes = "Notes"; - public static final String currency = "currency"; - public static final String finyear = "finyear"; - // CONSTRUCTOR - public ViewAllData() { - super("alldata", DatasetType.VIEW, "alldata"); - } - - @Override - public String[] getAllColumns() { - return new String[] {"ID AS _id", ID, TransactionType, Date, UserDate, Year, Month, Day, Category, Subcategory, Amount, BaseConvRate, CURRENCYID, AccountName, ACCOUNTID, ToAccountName, ToAccountID, TOTRANSAMOUNT, ToCurrencyID, Splitted , CategID, SubcategID, Payee, PayeeID, TransactionNumber, Status, Notes, currency, finyear}; - } -} diff --git a/src/com/money/manager/ex/fragment/SearchFragment.java b/src/com/money/manager/ex/fragment/SearchFragment.java index b67c447177..4b07cb1042 100644 --- a/src/com/money/manager/ex/fragment/SearchFragment.java +++ b/src/com/money/manager/ex/fragment/SearchFragment.java @@ -17,13 +17,6 @@ ******************************************************************************/ package com.money.manager.ex.fragment; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.List; - import android.app.Activity; import android.app.DatePickerDialog; import android.content.Context; @@ -61,9 +54,16 @@ import com.money.manager.ex.database.MoneyManagerOpenHelper; import com.money.manager.ex.database.QueryAllData; import com.money.manager.ex.database.TableAccountList; -import com.money.manager.ex.database.ViewAllData; +import com.money.manager.ex.database.ViewMobileData; import com.money.manager.ex.fragment.InputAmountDialog.InputAmountDialogListener; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + public class SearchFragment extends SherlockFragment implements InputAmountDialogListener { // LOGCAT private static final String LOGCAT = SearchFragment.class.getSimpleName(); @@ -340,51 +340,51 @@ public void executeSearch() { ArrayList whereClause = new ArrayList(); //account if (spinAccount.getSelectedItemPosition() != AdapterView.INVALID_POSITION && mAccountIdList.get(spinAccount.getSelectedItemPosition()) != -1) { - whereClause.add(ViewAllData.ACCOUNTID + "=" + mAccountIdList.get(spinAccount.getSelectedItemPosition())); + whereClause.add(ViewMobileData.ACCOUNTID + "=" + mAccountIdList.get(spinAccount.getSelectedItemPosition())); } //checkbox if (cbxDeposit.isChecked() || cbxTransfer.isChecked() || cbxWithdrawal.isChecked()) { - whereClause.add(ViewAllData.TransactionType + " IN (" + (cbxDeposit.isChecked() ? "'Deposit'" : "''") + "," + (cbxTransfer.isChecked() ? "'Transfer'" : "''") + whereClause.add(ViewMobileData.TransactionType + " IN (" + (cbxDeposit.isChecked() ? "'Deposit'" : "''") + "," + (cbxTransfer.isChecked() ? "'Transfer'" : "''") + "," + (cbxWithdrawal.isChecked() ? "'Withdrawal'" : "''") + ")"); } //status if (spinStatus.getSelectedItemPosition() > 0) { - whereClause.add(ViewAllData.Status + "='" + mStatusValues.get(spinStatus.getSelectedItemPosition()) + "'"); + whereClause.add(ViewMobileData.Status + "='" + mStatusValues.get(spinStatus.getSelectedItemPosition()) + "'"); } //from date if (!TextUtils.isEmpty(txtFromDate.getText())) { - whereClause.add(ViewAllData.Date + ">='" + mApplication.getSQLiteStringDate(mApplication.getDateFromString(String.valueOf(txtFromDate.getText()))) + "'"); + whereClause.add(ViewMobileData.Date + ">='" + mApplication.getSQLiteStringDate(mApplication.getDateFromString(String.valueOf(txtFromDate.getText()))) + "'"); } //to date if (!TextUtils.isEmpty(txtToDate.getText())) { - whereClause.add(ViewAllData.Date + "<='" + mApplication.getSQLiteStringDate(mApplication.getDateFromString(String.valueOf(txtToDate.getText()))) + "'"); + whereClause.add(ViewMobileData.Date + "<='" + mApplication.getSQLiteStringDate(mApplication.getDateFromString(String.valueOf(txtToDate.getText()))) + "'"); } //payee if (txtSelectPayee.getTag() != null) { - whereClause.add(ViewAllData.PayeeID + "=" + String.valueOf(txtSelectPayee.getTag())); + whereClause.add(ViewMobileData.PayeeID + "=" + String.valueOf(txtSelectPayee.getTag())); } //categories if (txtSelectCategory.getTag() != null) { CategorySub categorySub = (CategorySub)txtSelectCategory.getTag(); - whereClause.add(ViewAllData.CategID + "=" + categorySub.categId); + whereClause.add(ViewMobileData.CategID + "=" + categorySub.categId); if (categorySub.subCategId != -1) - whereClause.add(ViewAllData.SubcategID + "=" + categorySub.subCategId); + whereClause.add(ViewMobileData.SubcategID + "=" + categorySub.subCategId); } //from amount if (txtFromAmount.getTag() != null) { - whereClause.add(ViewAllData.Amount + ">=" + String.valueOf(txtFromAmount.getTag())); + whereClause.add(ViewMobileData.Amount + ">=" + String.valueOf(txtFromAmount.getTag())); } //to amount if (txtToAmount.getTag() != null) { - whereClause.add(ViewAllData.Amount + "<=" + String.valueOf(txtToAmount.getTag())); + whereClause.add(ViewMobileData.Amount + "<=" + String.valueOf(txtToAmount.getTag())); } //transaction number if (!TextUtils.isEmpty(edtTransNumber.getText())) { - whereClause.add(ViewAllData.TransactionNumber + " LIKE '" + edtTransNumber.getText() + "'"); + whereClause.add(ViewMobileData.TransactionNumber + " LIKE '" + edtTransNumber.getText() + "'"); } //note if (!TextUtils.isEmpty(edtNotes.getText())) { - whereClause.add(ViewAllData.Notes + " LIKE '" + edtNotes.getText() + "'"); + whereClause.add(ViewMobileData.Notes + " LIKE '" + edtNotes.getText() + "'"); } //create a fragment search AllDataFragment fragment; From e24a2a3e1048d3e77f1854ea911b0bd0c8bb4257 Mon Sep 17 00:00:00 2001 From: AlessandroLazzari Date: Fri, 10 Oct 2014 10:21:14 +0200 Subject: [PATCH 10/12] restore database settings --- res/values/strings.xml | 8 ++++---- res/xml/prefrences.xml | 8 ++++---- .../ex/preferences/PreferencesActivity.java | 14 +++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index a1d0711590..6c97e613e2 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -45,7 +45,7 @@ General - Display + Look & Feel Base currency View open accounts @@ -55,7 +55,7 @@ Version Build - + Database path Account @@ -292,7 +292,7 @@ Financial Year: Start Month - + Export database The database has been moved: %1$s Copy database on external storage failed You\'re using the database saved in: %1$s @@ -350,7 +350,7 @@ Shows the balance for each transaction Shows the balance for each transaction. The display of balance could make the application slower Open database - + Database--> Tips Application Font Select the font you want to give the application diff --git a/res/xml/prefrences.xml b/res/xml/prefrences.xml index 962ff194b8..5a0d2721e9 100644 --- a/res/xml/prefrences.xml +++ b/res/xml/prefrences.xml @@ -112,17 +112,17 @@ android:key="@string/pref_disable_passcode" android:title="@string/preferences_disable_passcode" /> - - --> + diff --git a/src/com/money/manager/ex/preferences/PreferencesActivity.java b/src/com/money/manager/ex/preferences/PreferencesActivity.java index fa85e2b2ce..11c7ef72f6 100644 --- a/src/com/money/manager/ex/preferences/PreferencesActivity.java +++ b/src/com/money/manager/ex/preferences/PreferencesActivity.java @@ -17,9 +17,6 @@ ******************************************************************************/ package com.money.manager.ex.preferences; -import java.io.File; -import java.util.List; - import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; @@ -61,7 +58,6 @@ import com.money.manager.ex.core.Core; import com.money.manager.ex.core.CurrencyUtils; import com.money.manager.ex.core.Passcode; -import com.money.manager.ex.database.MoneyManagerOpenHelper; import com.money.manager.ex.database.TableCurrencyFormats; import com.money.manager.ex.dropbox.DropboxBrowserActivity; import com.money.manager.ex.dropbox.DropboxHelper; @@ -70,6 +66,9 @@ import com.money.manager.ex.fragment.TipsDialogFragment; import com.money.manager.ex.view.RobotoView; +import java.io.File; +import java.util.List; + @SuppressWarnings("deprecation") public class PreferencesActivity extends SherlockPreferenceActivity { private static final String LOGCAT = PreferencesActivity.class.getSimpleName(); @@ -249,7 +248,7 @@ public void onCreate(Bundle savedInstanceState) { onCreateScreenPreferenceDisplay(); // database preference - //onCreateScreenPreferenceDatabase(); + onCreateScreenPreferenceDatabase(); // dropbox preference screen mDropboxHelper = DropboxHelper.getInstance(getApplicationContext()); @@ -609,17 +608,18 @@ public boolean onPreferenceClick(Preference preference) { return false; } }); + pMoveDatabase.setEnabled(MoneyManagerApplication.getDatabasePath(this.getApplicationContext()).startsWith("/data/")); } final PreferenceScreen pDatabasePath = (PreferenceScreen) findPreference(PreferencesConstant.PREF_DATABASE_PATH); pDatabasePath.setSummary(MoneyManagerApplication.getDatabasePath(this.getApplicationContext())); //sqlite version - PreferenceScreen pSQLiteVersion = (PreferenceScreen)findPreference(PreferencesConstant.PREF_SQLITE_VERSION); + /*PreferenceScreen pSQLiteVersion = (PreferenceScreen)findPreference(PreferencesConstant.PREF_SQLITE_VERSION); if (pSQLiteVersion != null) { MoneyManagerOpenHelper helper = new MoneyManagerOpenHelper(this); String sqliteVersion = helper.getSQLiteVersion(); if (sqliteVersion != null) pSQLiteVersion.setSummary(sqliteVersion); helper.close(); - } + }*/ } public void onCreateScreenPreferenceDropbox() { From 30c630a99956991939f762049845346953570d37 Mon Sep 17 00:00:00 2001 From: AlessandroLazzari Date: Wed, 15 Oct 2014 14:01:49 +0200 Subject: [PATCH 11/12] Add check to notification repeating transactions overdue --- res/values-cs/strings.xml | 694 ++++++++--------- res/values-es/strings.xml | 231 +++--- res/values-fr/strings.xml | 644 ++++++++-------- res/values-he/strings.xml | 694 ++++++++--------- res/values-hu/strings.xml | 694 ++++++++--------- res/values-it/strings.xml | 702 +++++++++--------- res/values-pl/strings.xml | 694 ++++++++--------- res/values-pt/strings.xml | 694 ++++++++--------- res/values-ru/strings.xml | 694 ++++++++--------- res/values-vi/strings.xml | 635 +++++++++------- res/values-zh-rTW/strings.xml | 695 ++++++++--------- res/values/prefids.xml | 29 +- res/values/strings.xml | 11 +- res/xml/prefrences.xml | 37 +- .../ex/core/MoneyManagerBootReceiver.java | 70 +- .../ex/preferences/PreferencesConstant.java | 5 +- 16 files changed, 3698 insertions(+), 3525 deletions(-) diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 59fdcce8a3..e8add6496a 100755 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -1,343 +1,355 @@ - - + - Jednoduchá a snadno použitelná aplikace pro správu osobních financí, bankovních účtů, rodinného rozpočtu a tak dále. - Projenkt Money Manager Ex pro Android používá knihovny ActionBarSherlock a RobotMediaBilling - Open source licence - Vkládání dat se nezdařilo - Mazání dat se nezdařilo - Aktualizace dat se nezdařila - Ukončit - Správa - Připojit na Dropboxu - Odpojit od Dropboxu - Synchronizuji soubor. Počkejte prosím… - Stahuji soubor z Dropboxu. Počkejte prosím… - Nahrávám souboru na Dropbox. Počkejte prosím… - Soubor Dropbox - Obecné - Displej - Základní měna - Zobrazit otevřené účty - Pokud není vybráno pak zobrazit všechny účty - Zobrazit oblíbené účty - Verze - Build - Účet - Seznam účtů - Nenalezeny žádné účty - Zůstatek na účtu - Ověřené bilance - Odstranit účet - Název účtu - Typ účtu - Číslo účtu - Účet veden v - Stav účtu - Oblíbený účet - Vyberte měnu - Běžný - Investiční - Vkladový - Chyba při vkládání účtu - Chyba při aktualizaci účtu - Je vyžadována měna - Je vyžadován počáteční zůstatek účtu - Je vyžadován název účtu - Je vyžadován typ účtu - Je vyžadován stav účtu - Jméno příjemce - Upravit příjemce - Odstranit příjemce - Příjemce - Vybrat příjemce - Nenalezen žádný příjemce - Od - Aktualizace příjemce se nezdařila - Kategorie - Podkategorie - Nenalezena žádná kategorie - Vyberte kategorii - Přidejte kategorii - Přidat podkategorii - Upravit kategorii - Odstranit kategorii - Název měny - Symbol měny - Odstranit měnu - Název jednotky - Název setiny jednotky - Symbol před - Symbol za - Desetinný oddělovač - Skupinový oddělovač - Míra - Kurz pro převod - Je vyžadován název měny - Částka - Celková částka - Vklad - Stav - Ověřeno - Neplatné - Sledovat - Duplikovat - Žádný - Převod - Typ transakce - Stav - Výběr - Vložení transakce se nezdařilo - Aktualizace transakce selhala - Odstranit transakci - Nová transakce - Je vyžadován příjemce - Je vyžadován cílový účet - Je vyžadována kategorie - Je vyžadována celková částka - O programu - Přidat - Jste si jisti, že chcete odstranit? - Datum - Odstranit - Stáhnout - Upravit - Logo - Nová/úprava transakce - Aktualizovat - Hledat - Nastavení - Celkem - Synchronizovat - Otevřít - Uživatel - Nahrát - Uživatelské jméno - Komu - Webová stránka - Kontakt - Informace o přístupu - Počáteční zůstatek - Poznámky - Zavřený - Nová/úprava měny - Téma aplikace - Holo světlé s tmavou lištou - Ukončit aplikaci - Chcete zavřít aplikaci? - Nenalezena aplikace vhodná pro výběr souboru - Upozornění - Vybraný příjemce nemůže být odstraněn, protože je na něj odkazováno - Zvolený účet nelze odstranit, protože na něj existuje odkaz - Zvolenou měnu nelze odstranit, protože na ni existuje odkaz - Zvolenou kategorii nelze odstranit, protože na ni existuje odkaz - Všechny transakce - Posledních 7 dní - Poslední 2 týdny - Aktuální měsíc - Aktuální rok - Zobrazit transakce - Přehled změn - Číslo transakce - Money Manager Ex - Souhrnný zůstatek - Money Manager Ex - Zůstatky na účtech - Money Manager Ex přidat transakci - Žádný trvalý příkaz - Žádný(á) - Týden - 2 týdny - Měsíc - 2 měsíce - Čtvrtletí - Půl roku - Rok - 4 měsíce - 4 týdny - Denně - Na (x) dní - Na (x) měsíců - Každých (x) dní - Každých (x) měsíců - Neaktivní - dny po splatnosti! - dnů zbývá - Nový/úprava trvalého příkazu - Další výskyt - Periodicita - Počet opakování - Je vyžadován další výskyt - Aktivní - Zadejte další výskyt - Přeskočit další výskyt - Existují propadlé trvalé příkazy - Dotkněte se pro kontrolu splatnosti transakce - %1$d opakované transakce po splatnosti - Zašlete svůj názor - Informace - Zabezpečení - Aktivace hesla - Zadejte heslo - Znovu zadejte své nové heslo - Hesla si neodpovídají - Upravit přístupový kód - Deaktiovovat přístupový kód - Zadejte své předchozí heslo - heslo není aktualizováno - Pro vyhledávání můžete použít zástupný znak % - Příjmy a výdaje: aktuální měsíc - Příjmy - Výdaje - Rozdíl - Žádná data k zobrazení - Měsíc - Rok - Sestavy - Příjmy a výdaje - Celkem - Celkem - Předchozí měsíc - Posledních 30 dnů - Předchozí rok - Počet nalezených transakcí: %1$d - Formát data - Fiskální rok: První den - Fiskální rok: První měsíc - Databáze byla přesunuta: %1$s - Kopírování databáze na externí úložiště selhalo - Používáte databázi uloženou na: %1$s - Rozdělit transakci - Rozdělit - Je vyžadováno alespoň jedno rozdělení transakce - Exportovat data do souboru CSV - Exportuji data. Čekejte prosím… - Data byla úspěšně uložena do souboru %1$s - Export souboru %1$s selhal - Money Manager Ex pro Android je poskytován zdarma. Je-li tato aplikace podle vašich představ, můžete podpořit vývojový tým příspěvkem. - Přispět přes Google Play In-App Billing. - Vyberte částku příspěvku - Přispět - Děkujeme vám za váš příspěvek! - Přispět - Ne, děkuji - Přispět! - Vzestupně - Sestupně - Řazení měsíců - Složka Dropbox/Apps/Money Manager Ex Mobile je prázdná. Pokud již používáte MoneyManagerEx, pak zkopírujte databázi do této složky na vašem počítači a poté proveďte aktualizaci. - Vyberte soubor z Dropboxu - Naposledy změněno - Databáze byla stažena - Pro použití stažené databáze se dotkněte Otevřít databázi - Dotkněte se pro výběr souboru z Dropboxu k použití - Stáhnout z Dropbox - Dotkněte se pro ruční stažení propojeného souboru ze složky Dropboxu - Nahrát na Dropbox - Dotkněte se pro ruční vložení propojeného souboru do složky Dropboxu - Databáze byla úspěšně odeslána - Jak funguje Dropbox pro Money Manager Ex\? - Příště nezobrazovat - Otevřít databázi - Interval synchronizace - Jak často synchronizovat? - Od verze 1.2.0 Money Manager Ex pro Android se změnila správa synchronizace s Dropboxem. Uživatelé, kteří již využívají synchronizaci s Dropboxem, musí zopakovat konfiguraci. \nKonfigurace synchronizace s Dropboxem a výběr databáze se nachází v nastavení. \nOd verze 1.2.0 Money Manager Ex pro Android může automaticky synchronizovat databázi s Dropboxem - Po změně okamžitě odeslat databázi - Tato možnost umožňuje automaticky odeslat databázi ihned po změně - Zobrazí zůstatek pro každou transakci - Zobrazí zůstatek pro každou transakci. Zobrazení zůstatku může zpomalit aplikaci - Otevřít databázi - Tipy - Písmo aplikace - Vyberte písmo, které má používat aplikace - Velikost písma aplikace - Vyberte velikost písma, kterou má používat aplikace - Mikro - Malé - Výchozí - Střední - Velké - Stahuji z Dropboxu. Čekejte prosím… - Ukládám na Dropbox. Čekejte prosím… - Peníze odchozí - Peníze příchozí - Zobrazit přehled v Money Manager Ex pro Android - Zobrazit Shrnutí každého účtu v Money Manager Ex pro Android - Nastavit kontrolu zpožděných trvalých příkazú - Uveďte čas kdy by měla aplikace zkontrolovat, zda jsou zpožděné opakující transakce (výchozí 08:00) - Poděkování - Největší výběry: Posledních 30 dní - Největší příjemci: Posledních 30 dní - Očekávané transakce - Množství - Přehled - Databáze je synchronizována - Poslední 3 měsíce - Posledních 6 měsíců - Prázdná kategorie - Bez příjemce - Nápověda - Odstranit trvalý příkaz - Poslední - Účty - Na účet - Z účtu - Výchozí stav - Výchozí příjemce - Upravit transakci - Jste si jisti, že chcete odstranit vybranou transakci? - Jste si jisti, že chcete odstranit %d vybraných transakcí? - Kategorie - Měny - Příjemci - Trvalé příkazy - Holo světlé - Nový účet - Načíst měny - Načítají se měny. Počkejte prosím… - Částka větší nebo rovna - Částka menší nebo rovna - Výsledek hledání - Nový trvalý příkaz - Úprava trvalého příkazu - Každých 5 minut - Každých 15 minut - Každých 30 minut - Každou hodinu - Každé 2 hodiny - Každých 6 hodin - Každých 12 hodin - Nikdy - Cesta k databázi neexistuje - Databázi nelze otevřít pro zápis - Chcete importovat měnu? - Časový rámec - Zobrazit graf - Přidat transakci - Vítejte v MoneyManagerEx - V MoneyManagerEx patří všechny transakce k účtům.\n\nPro snazší používání, začněte vytvořením seznamu finančních institucí, ve kterých máte své účty.\n\nDotkněte se pro zahájení zadávání účtů. - Pokud již používáte aplikaci MoneyManagerEx na Windows, Max OS nebo Linux, můžete použít vzájemnou synchronizaci databází pomocí Dropbox - Nastavit Dropbox - Hledání v textu podle obsahu a nikoli počátečních písmen - Hledání příjemců, kategorií, měn, apod… podle obsahu a nikoli počátečních písmen - Hodnocení aplikace - Jazyk aplikace - Čeština - English - Španělština - Francouzština - Hebrejština - Italština - Portugalština - Brazilská portugalština - Ruština - Vietnamština - Zjednodušená čínština - Tradiční čínština - Aktualizuji směnné kurzy měn. Čekejte prosím… - Aktualizuji směnný kurz:\n%1$s - Všechny směnné kurzy měn byly úspěšně aktualizovány - Aktualizovat směnná kurzy - Chcete aktualizovat směnný kurz? - Výběr z %1$s - Vkad do %1$s - Web MoneyManagerEx + Money Manager Ex + Jednoduchá a snadno použitelná aplikace pro správu osobních financí, bankovních účtů, rodinného rozpočtu a tak dále. + MoneyManagerEx for Android Project uses ActionBarSherlock library + Open source licence + Vkládání dat se nezdařilo + Mazání dat se nezdařilo + Aktualizace dat se nezdařila + Ukončit + Správa + Připojit na Dropboxu + Odpojit od Dropboxu + Synchronizuji soubor. Počkejte prosím… + Stahuji soubor z Dropboxu. Počkejte prosím… + Nahrávám souboru na Dropbox. Počkejte prosím… + Soubor Dropbox + Obecné + Look & Feel + Základní měna + Zobrazit otevřené účty + Pokud není vybráno pak zobrazit všechny účty + Zobrazit oblíbené účty + Verze + Build + Database path + Účet + Seznam účtů + Nenalezeny žádné účty + Zůstatek na účtu + Ověřené bilance + Odstranit účet + Název účtu + Typ účtu + Číslo účtu + Účet veden v + Stav účtu + Oblíbený účet + Vyberte měnu + Běžný + Investiční + Vkladový + Chyba při vkládání účtu + Chyba při aktualizaci účtu + Je vyžadována měna + Je vyžadován počáteční zůstatek účtu + Je vyžadován název účtu + Je vyžadován typ účtu + Je vyžadován stav účtu + Jméno příjemce + Upravit příjemce + Odstranit příjemce + Příjemce + Vybrat příjemce + Nenalezen žádný příjemce + Od + Aktualizace příjemce se nezdařila + Kategorie + Podkategorie + Nenalezena žádná kategorie + Vyberte kategorii + Přidejte kategorii + Přidat podkategorii + Upravit kategorii + Odstranit kategorii + Název měny + Symbol měny + Odstranit měnu + Název jednotky + Název setiny jednotky + Symbol před + Symbol za + Desetinný oddělovač + Skupinový oddělovač + Míra + Kurz pro převod + Je vyžadován název měny + Částka + Celková částka + Vklad + Stav + Ověřeno + Neplatné + Sledovat + Duplikovat + Žádný + Převod + Typ transakce + Stav + Výběr + Vložení transakce se nezdařilo + Aktualizace transakce selhala + Odstranit transakci + Nová transakce + Je vyžadován příjemce + Je vyžadován cílový účet + Je vyžadována kategorie + Je vyžadována celková částka + O programu + Přidat + Jste si jisti, že chcete odstranit? + Datum + Odstranit + Stáhnout + Upravit + Logo + Nová/úprava transakce + Aktualizovat + Hledat + Nastavení + Celkem + Synchronizovat + Otevřít + Uživatel + Nahrát + Uživatelské jméno + Komu + Webová stránka + Kontakt + Informace o přístupu + Počáteční zůstatek + Poznámky + Zavřený + Nová/úprava měny + Theme + Holo + Holo světlé s tmavou lištou + Ukončit aplikaci + Chcete zavřít aplikaci? + Nenalezena aplikace vhodná pro výběr souboru + Upozornění + Vybraný příjemce nemůže být odstraněn, protože je na něj odkazováno + Zvolený účet nelze odstranit, protože na něj existuje odkaz + Zvolenou měnu nelze odstranit, protože na ni existuje odkaz + Zvolenou kategorii nelze odstranit, protože na ni existuje odkaz + Všechny transakce + Posledních 7 dní + Poslední 2 týdny + Aktuální měsíc + Aktuální rok + Zobrazit transakce + Přehled změn + Číslo transakce + Money Manager Ex - Souhrnný zůstatek + Money Manager Ex - Zůstatky na účtech + Money Manager Ex přidat transakci + Žádný trvalý příkaz + Žádný(á) + Týden + 2 týdny + Měsíc + 2 měsíce + Čtvrtletí + Půl roku + Rok + 4 měsíce + 4 týdny + Denně + Na (x) dní + Na (x) měsíců + Každých (x) dní + Každých (x) měsíců + Neaktivní + dny po splatnosti! + dnů zbývá + Nový/úprava trvalého příkazu + Další výskyt + Periodicita + Počet opakování + Je vyžadován další výskyt + Aktivní + Zadejte další výskyt + Přeskočit další výskyt + Existují propadlé trvalé příkazy + Dotkněte se pro kontrolu splatnosti transakce + %1$d opakované transakce po splatnosti + Zašlete svůj názor + Informace + Zabezpečení + Aktivace hesla + Zadejte heslo + Znovu zadejte své nové heslo + Hesla si neodpovídají + Upravit přístupový kód + Deaktiovovat přístupový kód + Zadejte své předchozí heslo + heslo není aktualizováno + Pro vyhledávání můžete použít zástupný znak % + Příjmy a výdaje: aktuální měsíc + Příjmy + Výdaje + Rozdíl + Žádná data k zobrazení + Měsíc + Rok + Sestavy + Příjmy a výdaje + Celkem + Celkem + Předchozí měsíc + Posledních 30 dnů + Předchozí rok + Počet nalezených transakcí: %1$d + Formát data + Fiskální rok: První den + Fiskální rok: První měsíc + Export database + Databáze byla přesunuta: %1$s + Kopírování databáze na externí úložiště selhalo + Používáte databázi uloženou na: %1$s + Rozdělit transakci + Rozdělit + Je vyžadováno alespoň jedno rozdělení transakce + Exportovat data do souboru CSV + Exportuji data. Čekejte prosím… + Data byla úspěšně uložena do souboru %1$s + Export souboru %1$s selhal + MoneyManagerEx for Android is provided free. If this application is to your liking, you can support the development team with a donation. + Google Play In-App Billing + Přispět přes Google Play In-App Billing. + Vyberte částku příspěvku + Přispět + Děkujeme vám za váš příspěvek! + Přispět + Ne, děkuji + Přispět! + Vzestupně + Sestupně + Řazení měsíců + Složka Dropbox/Apps/Money Manager Ex Mobile je prázdná. Pokud již používáte MoneyManagerEx, pak zkopírujte databázi do této složky na vašem počítači a poté proveďte aktualizaci. + Vyberte soubor z Dropboxu + Naposledy změněno + Dropbox + Databáze byla stažena + Pro použití stažené databáze se dotkněte Otevřít databázi + Dotkněte se pro výběr souboru z Dropboxu k použití + Stáhnout z Dropbox + Dotkněte se pro ruční stažení propojeného souboru ze složky Dropboxu + Nahrát na Dropbox + Dotkněte se pro ruční vložení propojeného souboru do složky Dropboxu + Databáze byla úspěšně odeslána + Dropbox - Money Manager Ex + Jak funguje Dropbox pro Money Manager Ex\? + Příště nezobrazovat + Otevřít databázi + Interval synchronizace + Jak často synchronizovat? + Od verze 1.2.0 Money Manager Ex pro Android se změnila správa synchronizace s Dropboxem. Uživatelé, kteří již využívají synchronizaci s Dropboxem, musí zopakovat konfiguraci. \nKonfigurace synchronizace s Dropboxem a výběr databáze se nachází v nastavení. \nOd verze 1.2.0 Money Manager Ex pro Android může automaticky synchronizovat databázi s Dropboxem + Po změně okamžitě odeslat databázi + Tato možnost umožňuje automaticky odeslat databázi ihned po změně + Zobrazí zůstatek pro každou transakci + Zobrazí zůstatek pro každou transakci. Zobrazení zůstatku může zpomalit aplikaci + Otevřít databázi + Database--> + Tipy + Písmo aplikace + Vyberte písmo, které má používat aplikace + Velikost písma aplikace + Vyberte velikost písma, kterou má používat aplikace + Mikro + Malé + Výchozí + Střední + Velké + Stahuji z Dropboxu. Čekejte prosím… + Ukládám na Dropbox. Čekejte prosím… + Peníze odchozí + Peníze příchozí + Zobrazit přehled v Money Manager Ex pro Android + Zobrazit Shrnutí každého účtu v Money Manager Ex pro Android + Check time + What time would you check if there are repeating transactions overdue? (default 08:00) + Poděkování + Největší výběry: Posledních 30 dní + Největší příjemci: Posledních 30 dní + Očekávané transakce + Množství + Přehled + The database is up to date + Poslední 3 měsíce + Posledních 6 měsíců + Prázdná kategorie + Bez příjemce + Nápověda + Odstranit trvalý příkaz + Poslední + Účty + Na účet + Z účtu + Výchozí stav + Výchozí příjemce + Upravit transakci + Jste si jisti, že chcete odstranit vybranou transakci? + Jste si jisti, že chcete odstranit %d vybraných transakcí? + Kategorie + Měny + Příjemci + Trvalé příkazy + Holo světlé + Nový účet + Načíst měny + Načítají se měny. Počkejte prosím… + Částka větší nebo rovna + Částka menší nebo rovna + Výsledek hledání + Nový trvalý příkaz + Úprava trvalého příkazu + Každých 5 minut + Každých 15 minut + Každých 30 minut + Každou hodinu + Každé 2 hodiny + Každých 6 hodin + Každých 12 hodin + Nikdy + Cesta k databázi neexistuje + Databázi nelze otevřít pro zápis + Chcete importovat měnu? + Časový rámec + Zobrazit graf + Přidat transakci + Vítejte v MoneyManagerEx + V MoneyManagerEx patří všechny transakce k účtům.\n\nPro snazší používání, začněte vytvořením seznamu finančních institucí, ve kterých máte své účty.\n\nDotkněte se pro zahájení zadávání účtů. + Pokud již používáte aplikaci MoneyManagerEx na Windows, Max OS nebo Linux, můžete použít vzájemnou synchronizaci databází pomocí Dropbox + Nastavit Dropbox + Hledání v textu podle obsahu a nikoli počátečních písmen + Hledání příjemců, kategorií, měn, apod… podle obsahu a nikoli počátečních písmen + Hodnocení aplikace + Application Language + Čeština + English + Španělština + Francouzština + Hebrejština + Italština + Portugalština + Brazilská portugalština + Ruština + Vietnamština + Zjednodušená čínština + Tradiční čínština + Aktualizuji směnné kurzy měn. Čekejte prosím… + Aktualizuji směnný kurz:\n%1$s + Všechny směnné kurzy měn byly úspěšně aktualizovány + Aktualizovat směnná kurzy + Chcete aktualizovat směnný kurz? + Výběr z %1$s + Vkad do %1$s + Web MoneyManagerEx + You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! + Retrieving status of your donations from Google Play. Please wait… + Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. + Notification Repeating Transaction overdue + Show notification for repeating transaction overdue diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index a1d9c2a688..ca10eec524 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -1,58 +1,34 @@ - - + Money Manager Ex - © 2012 The Android Money Manager Ex Project Una aplicación simple y fácil de utilizar para organizar las finanzas personales, las cuentas bancarias, el presupuesto familiar, etc. - El proyecto Android Money Manager Ex utiliza las librerias ActionBarSherlock y ViewPagerIndicator + MoneyManagerEx for Android Project uses ActionBarSherlock library Licencias de fuente abierta - La inserción de datos ha fallado - El borrado de datos ha fallado - La actualización de datos ha fallado - Menú + Inserting data failed + Deleting data failed + Updating data failed Salir - Importación/exportación - Sincronizar - Importar desde tarjeta de memoria - Exportar a tarjeta de memoria Organizar - Sincronizar con Dropbox - Herramientas - Utilizar base de datos externa - Carpeta vacía - Nivel superior - Importar/exportar - Importación/exportación base de datos en curso - La importación/exportación ha terminado correctamente - La importación/exportación ha fallado Conectar con Dropbox Desconectar desde Dropbox - Lista de archivos en curso… - Sincronización con Dropbox en curso… - Descargando los archivos desde Dropbox… - Cargando los archivos a Dropbox… - Usuario Dropbox - Archivo enlazado con Dropbox - Método de sincronización con Dropbox + Sincronización del archivo. Espera… + Descargando archivo desde Dropbox. Espera… + Cargando archivo en Dropbox. Espera… + File Dropbox Generales - Visualización + Look & Feel Divisa base - Cuentas visualizables Visualizar cuentas abiertas Si no se selecciona visualizar todas las cuentas Visualizar cuentas favoritas - Android Money Manager Ex Versión Compilación - Opciones de Dropbox - Ruta de la base de datos + Database path Cuenta Lista de las cuentas Ningúna cuenta encontrada Balance - Balance reconciliado - Balance: %s balance reconciliado: %s - Seleccionar la cuenta de abono + Reconciled Balance Borrar la cuenta Nombre de la cuenta Tipo de cuenta @@ -66,32 +42,29 @@ Cuenta depósito a plazo Error al insertar la cuenta Error al actualizar la cuenta - Atención: la divisa de la cuenta no está seleccionada - Atención: por favor introducir el balance inicial - Atención: por favor introducir el nombre de la cuenta - Atención: por favor introducir el tipo de cuenta - Atención: por favor introducir el estado de la cuenta - Nombre beneficiario - Modificar nombre beneficiario + Se requiere la divisa + Se requiere el balance inicial de la cuenta + Se requiere el nombre de la cuenta + Se requiere el tipo de cuenta + Se requiere el estado de la cuenta + Nombre del beneficiario + Edit Payee Borrar beneficiario Beneficiario Seleccionar beneficiario - Seleccionar desde Ningún beneficiario encontrado Desde - La actualización del beneficiario ha fallado + Updating payee failed Categoría Subcategoría Ningúna categoría encontrada Seleccionar categoría Agregar categoría - Agregar subcategoría - Nombre categoría - Modificar nombre categoría + Añadir Subcategoría + Editar Categoría Borrar categoría - Divisa - Nombre divisa - Símbolo divisa + Nombre de la divisa + símbolo de la divisa Borrar divisa Nombre de la unidad Nombre de los céntimos @@ -101,7 +74,7 @@ Separador de millares Escala Conversión a tasa base - El nombre de la divisa es necesario + Currency name is required Importe Importe total Depósito @@ -115,81 +88,63 @@ Tipo de transacción Estado Retiro - Error al insertar la transacción - Error al actualizar la transacción + Inserting transaction failed + Updating transaction failed Borrar transacción Nueva transacción - Atención: el beneficiario no está seleccionado - Atención: la cuenta de destino no está seleccionada - Atención: la categoría no está seleccionada - Atención: por favor introducir el importe total de la transacción + Payee is required + To Account is required + Category is required + Total amount is required Acerca de - Abortar Añadir - Todos - Confirmar la eliminación? + Are you sure you want to delete? Fecha Borrar Descargar Modificar - Favoritos - Inicio - Enlace Logo - Nuevo Nueva/modificar transacción Actualizar - Reporta un problema Buscar - Seleccionar Opciones Resumen - Sincronización Sincronizar - La sincronización ha terminado correctamente Abierto Usuario - Desconnectar Cargar Nombre del usuario - Por favor informenos de cualquier error o problema A Sitio Web Contacto Información de acceso Balance inicial Notas - Nueva/modificar cuenta Cerrado Nueva/modificar divisa - Ruta - Tema de la aplicación + Theme Holo Holo Claro con Barra Oscura Cerrar la aplicación Cerrar la aplicación? Sin actividad para manejar archivos Pick Atención - El beneficiario seleccionado no puede ser eliminado porque está referenciado - La cuenta seleccionada no puede ser eliminada porque está referenciada - La divisa seleccionada no puede ser eliminada porque está referenciada - La categoría seleccionada no puede ser eliminada porque está referenciada + El beneficiario seleccionado no puede ser eliminado porque referenciado + La cuenta seleccionada no puede ser eliminada porque referenciada + La divisa seleccionada no puede ser eliminada porque referenciada + La categoría seleccionada no puede ser eliminada porque referenciada Todas las transacciones Última semana Últimas 2 semanas Mes en curso Año en curso Visualizar las transacciones - Tipo de Hogar - Clásico - Avance Cambios Número de transacción Resumen de Money Manager Ex Todas las cuentas de Money Manager Ex Agregar transacción en Money Manager Ex Transacción Periódica Vacía - Transacción Periódica Ningúno Semanal Quincenal @@ -212,26 +167,23 @@ Siguiente Ocurrencia Frecuencia Ocurrencias Repetidas - Atención: la fecha del próximo vencimiento no está seleccionada + Next occurrence is required Se Activa - Frecuencia: días Efectuar Siguiente Ocurrencia Omitir Siguiente Ocurrencia Hay Transacciónes Periódicas vencidas - Haga clic para verificar la transacción atrasada + Touch to check the transaction overdue %1$d transacción periódica vencida Enviar comentarios - Envíenos sus comentarios Información Seguridad - Activar Código Acceso + Activate Passcode Escribe tu passcode - Vuelve a escribir tu nuevo código seguridad - Los códigos de seguridad no son iguales + Re-enter your new passcode + Passcode do not match Modificar Passcode Desactivar Código de seguridad Escribe tu código anterior - El Código se ha actualizado El Código no se ha actualizado Para búsquedas puedes utilizar el carácter comodín % Ingresos vs Gastos: Mes Actual @@ -244,30 +196,26 @@ Reporte Ingresos Vs Gastos Total - Opción Tiempo Total - Mes Pasado + Mes anterior Últimos 30 Días - Año Pasado - Resultado + Año anterior Número de transacciónes encontradas: %1$d Formato de la fecha Ejercicio: Día Inicial Ejercicio: Mes Inicial - Fecha de estreno - Transferir Base de Datos a Dispositivos de Almacenamiento Externo + Export database La base de datos ha sido transferida: %1$s La copia de la base de datos a dispositivos de almacenamiento externo ha fallado Estás utilizando la base de datos guardada en: %1$s Transacción dividida - Categoría dividida Dividido - Atención: por favor, introduzcan al menos una transacción dividida - Exportar a archivo CSV - Exportación de datos en curso … - La Exportación del archivo %1$s ha terminado correctamente + At least one of split transaction is required + Export data to CSV file + Exporting data. Please wait… + The data has been successfully exported to the file %1$s La Exportación del archivo %1$s ha fallado - Android Money Manager Ex es gratuito. Si esta aplicación es de tu agrado, puedes ayudar al equipo de desarrollo con una donación. + MoneyManagerEx for Android is provided free. If this application is to your liking, you can support the development team with a donation. Google Play In-App Billing Donar a través Google Play In-App Billing. Selecciona una cantidad para la donación @@ -276,38 +224,34 @@ Donas No, gracias Donas! - Versión de SQLite - Ordenar Ascendente Descendente - Mes de ordenamiento + Sorting Months La carpeta en Dropbox/Apps/Money Manager Ex Mobile está vacía. Si ya utilizas MoneyManagerEx copia tu base de datos a esta carpeta en tu ordenador, y después actualiza. - Selecciona el Archivo en Dropbox + Select a file from Dropbox Última fecha de modificación - Selecciona el Archivo Remoto en Dropbox Dropbox - La base de datos descargada desde Dropbox está lista para ser utilizada - Haz clic para ir la base de datos descargada - Haz clic para seleccionar el archivo que desea enlazar con Dropbox - Descargando la base de datos desde Dropbox - Haz clic aquí para descargar manualmente el archivo enlazado con la carpeta de Dropbox - Cargando la base de datos en Dropbox - Haz clic aquí para cargar manualmente el archivo enlazado con la carpeta de Dropbox - El cargamento de la base de datos a Dropbox ha terminado correctamente + Your database has been downloaded + To use the database downloaded, touch Open Database + Touch to select the file to use from Dropbox + Descargar desde Dropbox + Touch to manually download the linked file from Dropbox folder + Cargar en Dropbox + Touch to manually upload the linked file to Dropbox folder + Su base de datos ha sido cargada con éxito Dropbox - Money Manager Ex - Cómo funciona Dropbox para Money Manager Ex\? + ¿Cómo funciona Dropbox para Money Manager Ex\? No mostrar de nuevo Abrir la Base de Datos Intervalo de Sincronización - Indica el intervalo de sincronización con Dropbox en minutos. Póngalo en 0 minutos para ninguna sincronización automática - Nueva versión de Dropbox + How often should synchronize? Desde la version 1.2.0 de Money Manager Ex for Android ha cambiado la gestión de la sincronización con Dropbox. Para los usuarios que ya están utilizando la sincronización con Dropbox, hay que hacer de nuevo la configuración. La configuración de la sincronización con Dropbox y la selección de la base de datos, se encuentran en la configuración.\nDesde la version 1.2.0 Money Manager Ex for Android puede sincronizar automáticamente la base de datos con Dropbox Cargar la base de datos inmediatamente después de cualquier cambio Esta opción permite de cargar automáticamente cuando se cambia la base de datos Muestra el balance para cada transacción Muestra el balance para cada transacción. Mostrar el balance podría hacer más lenta la aplicación Abrir la Base de Datos - Base de Datos + Database--> Consejos Fuente de la Aplicación Selecciona el tipo de letra que quieres para la aplicación @@ -318,33 +262,27 @@ Por defecto Medio Grande - La descarga desde Dropbox está comenzando. Espere por favor… - La carga a Dropbox está comenzando. Espere por favor… - ¿Dónde va el dinero? + Descargando desde Dropbox. Espera… + Uploading to Dropbox. Please wait…¿Dónde va el dinero? ¿De dónde viene el dinero? Muestra el Resumen de Money Manager Ex para Android Ver el Resumen de cada cuenta de Money Manager Ex para Android - Compruebe horarios de transacciones repetidas vencidas - Indicar qué hora del día, debe comprobar si hay repetición de transacciones atrasadas (por defecto 8:00) + Check time + What time would you check if there are repeating transactions overdue? (default 08:00) Créditos - Agradecimiento especial a librerías de terceros utilizadas Retiros superiores: Últimos 30 días Principales beneficiarios: Últimos 30 días - Estadísticas de transacción Próximas transacciones Cantidad Panel de Control - La base de datos está sincronizada - Descargar una nueva versión de la base de datos desde Dropbox. En %1$d segundos, se actualizarán los datos + The database is up to date Últimos 3 meses Últimos 3 meses Categoría Vacía Beneficiario Vacío Ayuda Eliminar Transacción Periódica - Total Cuenta Bancaria - Plazo de Cuenta Total Última Cuentas A Cuenta @@ -352,21 +290,16 @@ Estado por defecto Beneficiario por defecto Editar Transacción - ¿Confirmar la eliminación de la transacción seleccionada? - Confirma la eliminación de las %d transacciones seleccionadas? + ¿Seguro que quieres borrar la transacción seleccionada? + ¿Seguro que quieres borrar las %d transacciones seleccionadas? Categorías Monedas Beneficiarios Transacción Periódica Holo Claro Nueva cuenta - Editar cuenta - Nueva moneda - Editar moneda - Importar todas las monedas del mundo - Importando moneda ... - Desde la fecha - En la fecha + Import Currencies + Importing currencies. Please wait… Cantidad mayor o igual Cantidad menor o igual Resultado de la búsqueda @@ -393,24 +326,30 @@ Buscando textos que contengas y no textos que comiencen con Buscar beneficiarios, categorías, divisas, etc... por contenido y no por los caracteres iniciales Valorar Aplicación - Lenguaje de la Aplicación + Application Language Checo Inglés Español Francés Hebreo Italiano - Portugés - Brasileño + Portugués + Portugués de Brasil Ruso Vietnamita Chino Simplificado Chino Tradicional - Comenzar Actualizando el valor de las Monedas - Actualizar el Tipo de Cambio:\n%1$s - La Actualización del tipo de Cambio se completó satisfactoriamente + Updating the exchange rates of currencies. Please wait… + Updating the exchange rate:\n%1$s + Se han actualizado todos los tipos de cambio de divisas con éxito Actualizar Cambio de Moneda - ¿Quieres actualizar el tipo de cambio de todas las monedas? + Do you want to update exchange rate? Retirar desde %1$s Depositar en %1$s + Sitio web de MoneyManagerEx + You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! + Retrieving status of your donations from Google Play. Please wait… + Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. + Notification Repeating Transaction overdue + Show notification for repeating transaction overdue diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 4ace0c0b91..e0d63ae68a 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -1,293 +1,355 @@ - - + - Une application simple et facile à utiliser pour gérer ses finances personnelles, comptes bancaires, budget familial… - License open source - L\'insertion de la base de données a échoué - Suppression des données échouée - Mise à jour des données échouée - Quitter - Gérer - Associer à Dropbox - Dissocier de Dropbox - Synchronisation du fichier en cours. Patientez s\'il vous plaît... - Téléchargement du fichier depuis Dropbox. Patientez s\'il vous plaît... - Téléchargement du fichier vers Dropbox. Patientez s\'il vous plaît... - Fichier Dropbox - Général - Affichage - Monnaie de référence - Voir les comptes ouverts - Si pas selectionné, tous les comptes seront affichés - Voir les comptes préférés - Version - Compilation - Compte - Liste des comptes - Pas de compte trouvé - Balance du compte - Balance réconciliée - Supprimer le compte - Nom du Compte - Type de compte - Numéro du compte - Tenue par - État du compte - Compte favori - Choisir la devise - Chèque/Epargne - Titres - Terme - Erreur d\'insertion du compte - Erreur de mise à jour du compte - La devise est obligatoire - Le solde initial du compte est obligatoire - Le nom du compte est obligatoire - Le type de compte est obligatoire - État de compte est requis - Nom du bénéficiaire - Modifier le bénéficiaire - Supprimer le bénéficiaire - Bénéficiaire - Selectionner le bénéficiaire - Pas de bénéficiaire trouvé - A partir de - Mise à jour du bénéficiaire a échouée - Catégorie - Sous-catégorie - Pas de catégorie trouvée - Selectionner une catégorie - Ajouter une catégorie - Ajouter une sous-catégorie - Modifier la catégorie - Supprimer la catégorie - Nom de la devise - Symbole de la devise - Supprimer la devise - Nom de l\'unité - Nom des centimes - Symbole du préfixe - Symbole du suffixe - Caractère des décimales - Caractère de groupement - Echelle - Taux de conversion de base - Nom de la monnaie est obligatoire - Montant - Montant total - Crédit - Etat - Rapproché - Nul - A suivre - Duplicata - Stable - Virement - Type d\'opération - Etat - Débit - Insertion de la transaction a échoué - Mise à jour de la transaction a échouée - Suppression de l\'opération - Nouvelle opération - Bénéficiaire est obligatoire - Vers Compte est obligatoire - Catégorie est obligatoire - Montant total est requis - A propos de - Ajouter - Êtes-vous sûr de vouloir supprimer ? - Date - Supprimer - Télécharger - Modifier - Logo - Créer/Modifier une opération - Rafraéchir - Rechercher - Paramétres - Résumé - Synchroniser - Ouvert - Utilisateur - Téléchager vers - Nom de l\'utilisateur - De - Site web - Contact - Information d\'accés - Solde initial - Notes - Clôturé - Créer/Editer une devise - Théme de l\'application - Holo Light avec barre de menu sombre. - Fermer l\'application - Voulez-vous fermer l\'application? - Aucune activité trouvée pour gérer le fichier choisi - Attention - Des 7 derniers jours - Des 2 dernieres semaines - Du mois en cours - De l\'année en cours - Voir opérations - Des modification - Money Manager Ex Résumé - Money Manager Ex Tous les comptes - Money Manager Ex Ajouter une transaction - Opération périodique vide - Aucun - Hebdomadaire - Bi-hebdomadaire - Mensuel - Bi-mensuel - Trimestriel - Semestriel - Annuel - Quatre mois - 4 Semaines - Quotidien - Dans (x) jours - Dans (x) mois - Tous les (x) jours - Tous les (x) mois - Inactif - jours de retard ! - jours restants - Nouvelle/Modifier opération périodique - Occurrence suivante - Répétitions - Occurrence - active - Entrez l\'Occurrence suivante - Ignorer l\'occurence suivante - Il y a des opérations périodiques expirées - %1$d répéter la transaction en retard. - Envoyer un commentaire - Info - Sécurité - Entrez votre code d\'accès - Modifier le code d\'accès - Désactiver le code d\'accès - Saisissez votre code d\'accès précédent - code d\'accès non mis à jour - Vous pouvez utiliser le caractère générique % dans vos recherches - Revenus vs dépenses : Mois en cours - Revenu - Dépenses - Différence - Aucune donnée à afficher - Mois - Année - Rapports - Revenus Vs dépenses - Total - Tous le temps - 30 derniers jours - Nombre de transactions trouvé : %1$d - Format de date - Exercice : Date de début - Exercice : Début mois - La base de données a été déplacée : %1$s - La copie de la base de données sur le stockage externe a échouée - Vous utilisez la base de données enregistrée dans : %1$s - Opération ventilée - Fractionner - L\'exportation du fichier %1$s a échoué - Android Money Manager Ex est fourni gratuitement. Si cette application vous plait, vous pouvez soutenir l\'équipe de développement avec un don. - Faire un don via Google Play In-App Billing. - Sélectionnez le montant du don - Donner - Merci pour votre don ! - Donner - Non merci - Donner! - croissant - décroissant - Dernière modification - Ne plus afficher - Ouvrir la base de données - Intervalle de synchronisation - Depuis la version 1.2.0, Money Manager Ex pour Android a changé la gestion de la synchronisation avec Dropbox. Pour les utilisateurs qui utilisent déjà la synchro avec Dropbox, vous devez refaire la configuration. \nLa synchronisation avec Dropbox et la sélection de la base de données, se trouve dans les réglages. \nDepuis la version 1.2.0, Money Manager Ex pour Android peut synchroniser automatiquement la base de données avec Dropbox - Télécharger immédiate de base de données à chaque changement - Cette option permet de télécharger automatiquement dès que vous modifiez la base de données - Affiche le solde pour chaque transaction - Affiche le solde pour chaque transaction. L\'affichage du solde pourrait rendre l\'application plus lente - Ouvrir la base de données - Astuces - Polices de l\'application - Sélectionnez la police d\'affichage - Taille de police d\'affichage - Sélectionnez la taille de la police d\'affichage - Micro - Petit - Par défaut - Moyenne - Grande - Où va l\'argent - D\'où vient l\'argent - Affiche le résumé de Money Manager Ex pour Android - Afficher le résumé de chaque compte Money Manager Ex pour Android - Planifier le controle des opérations périodiques en retard - Indiquer à quelle heure du jour, l\'application doit vérifier s\'il y a des opérations périodiques en retard (08:00 par défaut) - Crédits - Principaux retraits : 30 derniers jours - Principaux bénéficiaires : 30 derniers jours - Transactions à venir - Quantité - Tableau de bord - La base de données est synchronisée - 3 derniers mois - 6 derniers mois - Catégorie vide - Bénéficiaire vide - Aide - Supprimer l\'opération périodique - Dernière - Comptes - Vers le compte - Du compte - Statut par défaut - Bénéficiaire par défaut - Éditer l\'opération - Catégories - Devises - Bénéficiaires - Opérations périodiques - Holo Light - Nouveau compte - Montant supérieur ou égal - Montant inférieur ou égal - Résultat de votre recherche - Nouvelle opération périodique - Editer l\'opération périodique - Toutes les 5 minutes - Toutes les 15 minutes - Toutes les 30 minutes - Toutes les heures - Toutes les 2 heures - Toutes les 6 heures - Toutes les 12 heures - Jamais - Le chemin de la base de données n\'existe pas - La base de données ne peut pas être ouvert en écriture - Vous voulez importer des devises ? - Délai - Afficher le graphique - Ajouter une transaction - Bienvenue sur MoneyManagerEx - Si vous utilisez déjà MoneyManagerEx sur Windows, Linux ou Mac reliez cette application avec Dropbox pour synchroniser votre base de données - Configuration de Dropbox - Rechercher dans le contenu du texte et non pas en de début de mot - Vietnamien - Chinois simplifié - Chinois traditionnel - Mise à jour des taux de change des devises. Veuillez patienter... - Mise à jour du taux de change:\n%1$s - Tous les taux de change des monnaies ont été mis à jour avec succès - Mise à jour des taux de change - Vous voulez mettre à jour les taux de change ? - Retrait de %1$s - Dépôt de %1$s - Site Web MoneyManagerEx + Money Manager Ex + Une application simple et facile à utiliser pour gérer ses finances personnelles, comptes bancaires, budget familial… + MoneyManagerEx for Android Project uses ActionBarSherlock library + License open source + L\'insertion de la base de données a échoué + Suppression des données échouée + Mise à jour des données échouée + Quitter + Gérer + Associer à Dropbox + Dissocier de Dropbox + Synchronisation du fichier en cours. Patientez s\'il vous plaît... + Téléchargement du fichier depuis Dropbox. Patientez s\'il vous plaît... + Téléchargement du fichier vers Dropbox. Patientez s\'il vous plaît... + Fichier Dropbox + Général + Look & Feel + Monnaie de référence + Voir les comptes ouverts + Si pas selectionné, tous les comptes seront affichés + Voir les comptes préférés + Version + Compilation + Database path + Compte + Liste des comptes + Pas de compte trouvé + Balance du compte + Balance réconciliée + Supprimer le compte + Nom du Compte + Type de compte + Numéro du compte + Tenue par + État du compte + Compte favori + Choisir la devise + Chèque/Epargne + Titres + Terme + Erreur d\'insertion du compte + Erreur de mise à jour du compte + La devise est obligatoire + Le solde initial du compte est obligatoire + Le nom du compte est obligatoire + Le type de compte est obligatoire + État de compte est requis + Nom du bénéficiaire + Modifier le bénéficiaire + Supprimer le bénéficiaire + Bénéficiaire + Selectionner le bénéficiaire + Pas de bénéficiaire trouvé + A partir de + Mise à jour du bénéficiaire a échouée + Catégorie + Sous-catégorie + Pas de catégorie trouvée + Selectionner une catégorie + Ajouter une catégorie + Ajouter une sous-catégorie + Modifier la catégorie + Supprimer la catégorie + Nom de la devise + Symbole de la devise + Supprimer la devise + Nom de l\'unité + Nom des centimes + Symbole du préfixe + Symbole du suffixe + Caractère des décimales + Caractère de groupement + Echelle + Taux de conversion de base + Nom de la monnaie est obligatoire + Montant + Montant total + Crédit + Etat + Rapproché + Nul + A suivre + Duplicata + Stable + Virement + Type d\'opération + Etat + Débit + Insertion de la transaction a échoué + Mise à jour de la transaction a échouée + Suppression de l\'opération + Nouvelle opération + Bénéficiaire est obligatoire + Vers Compte est obligatoire + Catégorie est obligatoire + Montant total est requis + A propos de + Ajouter + Êtes-vous sûr de vouloir supprimer ? + Date + Supprimer + Télécharger + Modifier + Logo + Créer/Modifier une opération + Rafraéchir + Rechercher + Paramétres + Résumé + Synchroniser + Ouvert + Utilisateur + Téléchager vers + Nom de l\'utilisateur + De + Site web + Contact + Information d\'accés + Solde initial + Notes + Clôturé + Créer/Editer une devise + Theme + Holo + Holo Light avec barre de menu sombre. + Fermer l\'application + Voulez-vous fermer l\'application? + Aucune activité trouvée pour gérer le fichier choisi + Attention + The payee selected can not be deleted because it is referenced + The account selected can not be deleted because it is referenced + The currency selected can not be deleted because it is referenced + The category selected can not be deleted because it is referenced + All transactions + Des 7 derniers jours + Des 2 dernieres semaines + Du mois en cours + De l\'année en cours + Voir opérations + Des modification + Transaction number + Money Manager Ex Résumé + Money Manager Ex Tous les comptes + Money Manager Ex Ajouter une transaction + Opération périodique vide + Aucun + Hebdomadaire + Bi-hebdomadaire + Mensuel + Bi-mensuel + Trimestriel + Semestriel + Annuel + Quatre mois + 4 Semaines + Quotidien + Dans (x) jours + Dans (x) mois + Tous les (x) jours + Tous les (x) mois + Inactif + jours de retard ! + jours restants + Nouvelle/Modifier opération périodique + Occurrence suivante + Répétitions + Occurrence + Next occurrence is required + active + Entrez l\'Occurrence suivante + Ignorer l\'occurence suivante + Il y a des opérations périodiques expirées + Touch to check the transaction overdue + %1$d répéter la transaction en retard. + Envoyer un commentaire + Info + Sécurité + Activate Passcode + Entrez votre code d\'accès + Re-enter your new passcode + Passcode do not match + Modifier le code d\'accès + Désactiver le code d\'accès + Saisissez votre code d\'accès précédent + code d\'accès non mis à jour + Vous pouvez utiliser le caractère générique % dans vos recherches + Revenus vs dépenses : Mois en cours + Revenu + Dépenses + Différence + Aucune donnée à afficher + Mois + Année + Rapports + Revenus Vs dépenses + Total + Tous le temps + Previous Month + 30 derniers jours + Previous Year + Nombre de transactions trouvé : %1$d + Format de date + Exercice : Date de début + Exercice : Début mois + Export database + La base de données a été déplacée : %1$s + La copie de la base de données sur le stockage externe a échouée + Vous utilisez la base de données enregistrée dans : %1$s + Opération ventilée + Fractionner + At least one of split transaction is required + Export data to CSV file + Exporting data. Please wait… + The data has been successfully exported to the file %1$s + L\'exportation du fichier %1$s a échoué + MoneyManagerEx for Android is provided free. If this application is to your liking, you can support the development team with a donation. + Google Play In-App Billing + Faire un don via Google Play In-App Billing. + Sélectionnez le montant du don + Donner + Merci pour votre don ! + Donner + Non merci + Donner! + croissant + décroissant + Sorting Months + The folder in Dropbox/Apps/Money Manager Ex Mobile is empty. If you already use MoneyManagerEx copy your database to this folder in your computer, and after you do the refresh. + Select a file from Dropbox + Dernière modification + Dropbox + Your database has been downloaded + To use the database downloaded, touch Open Database + Touch to select the file to use from Dropbox + Download from Dropbox + Touch to manually download the linked file from Dropbox folder + Upload to Dropbox + Touch to manually upload the linked file to Dropbox folder + Your database has been successfully uploaded + Dropbox - Money Manager Ex + How does Dropbox work for Money Manager Ex\? + Ne plus afficher + Ouvrir la base de données + Intervalle de synchronisation + How often should synchronize? + Depuis la version 1.2.0, Money Manager Ex pour Android a changé la gestion de la synchronisation avec Dropbox. Pour les utilisateurs qui utilisent déjà la synchro avec Dropbox, vous devez refaire la configuration. \nLa synchronisation avec Dropbox et la sélection de la base de données, se trouve dans les réglages. \nDepuis la version 1.2.0, Money Manager Ex pour Android peut synchroniser automatiquement la base de données avec Dropbox + Télécharger immédiate de base de données à chaque changement + Cette option permet de télécharger automatiquement dès que vous modifiez la base de données + Affiche le solde pour chaque transaction + Affiche le solde pour chaque transaction. L\'affichage du solde pourrait rendre l\'application plus lente + Ouvrir la base de données + Database--> + Astuces + Polices de l\'application + Sélectionnez la police d\'affichage + Taille de police d\'affichage + Sélectionnez la taille de la police d\'affichage + Micro + Petit + Par défaut + Moyenne + Grande + Downloading from Dropbox. Please wait… + Uploading to Dropbox. Please wait… + Où va l\'argent + D\'où vient l\'argent + Affiche le résumé de Money Manager Ex pour Android + Afficher le résumé de chaque compte Money Manager Ex pour Android + Check time + What time would you check if there are repeating transactions overdue? (default 08:00) + Crédits + Principaux retraits : 30 derniers jours + Principaux bénéficiaires : 30 derniers jours + Transactions à venir + Quantité + Tableau de bord + The database is up to date + 3 derniers mois + 6 derniers mois + Catégorie vide + Bénéficiaire vide + Aide + Supprimer l\'opération périodique + Dernière + Comptes + Vers le compte + Du compte + Statut par défaut + Bénéficiaire par défaut + Éditer l\'opération + Are you sure you want delete the selected transaction? + Are you sure you want delete the %d selected transactions? + Catégories + Devises + Bénéficiaires + Opérations périodiques + Holo Light + Nouveau compte + Import Currencies + Importing currencies. Please wait… + Montant supérieur ou égal + Montant inférieur ou égal + Résultat de votre recherche + Nouvelle opération périodique + Editer l\'opération périodique + Toutes les 5 minutes + Toutes les 15 minutes + Toutes les 30 minutes + Toutes les heures + Toutes les 2 heures + Toutes les 6 heures + Toutes les 12 heures + Jamais + Le chemin de la base de données n\'existe pas + La base de données ne peut pas être ouvert en écriture + Vous voulez importer des devises ? + Délai + Afficher le graphique + Ajouter une transaction + Bienvenue sur MoneyManagerEx + MoneyManagerEx models all transactions as belonging to accounts.\n\nTo help you get started, begin by making a list of all financial institutions where you hold an account.\n\nTouch to begin enter your accounts. + Si vous utilisez déjà MoneyManagerEx sur Windows, Linux ou Mac reliez cette application avec Dropbox pour synchroniser votre base de données + Configuration de Dropbox + Rechercher dans le contenu du texte et non pas en de début de mot + Search payee, categories, currencies, etc… by contents and not by starting characters + Rate Application + Application Language + Czech + English + Spanish + French + Hebrew + Italian + Portuguese + Portuguese, Brazilian + Russian + Vietnamien + Chinois simplifié + Chinois traditionnel + Mise à jour des taux de change des devises. Veuillez patienter... + Mise à jour du taux de change:\n%1$s + Tous les taux de change des monnaies ont été mis à jour avec succès + Mise à jour des taux de change + Vous voulez mettre à jour les taux de change ? + Retrait de %1$s + Dépôt de %1$s + Site Web MoneyManagerEx + You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! + Retrieving status of your donations from Google Play. Please wait… + Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. + Notification Repeating Transaction overdue + Show notification for repeating transaction overdue diff --git a/res/values-he/strings.xml b/res/values-he/strings.xml index 0bf596754b..0cde7c5a83 100644 --- a/res/values-he/strings.xml +++ b/res/values-he/strings.xml @@ -1,343 +1,355 @@ - - + - יישום לניהול כספים אישי, פשוט וקל לשימוש, לניהול חשבונות בנק, תקציב משפחה, וכן הלאה. - פרויקטdroid Money Manager משתמש בספריות ActionBarSherlock ו- RobotMediaBilling - רשיונות קוד פתוח - הוספת נתונים נכשלה - מחיקת נתונים נכשלה - עדכון נתונים נכשל - צא - נהל - קישור ל Dropbox - התנתק מ- Dropbox - מסנכרן קובץ. המתן בבקשה... - מוריד קובץ Dropbox. המתן בבקשה... - מעלה קובץ ל Dropbox. המתן בבקשה... - קובץ Dropbox - כללי - הצג - מטבע בסיס - הצג חשבונות פעילים - אם לא נבחר, כל החשבונות יוצגו - הצג חשבונות מועדפים - גירסה - גרסת משנה - חשבון - רשימת חשבונות - לא נמצאו חשבונות - יתרת חשבון - יתרה מותאמת - מחק חשבון - שם חשבון - סוג חשבון - מספר חשבון - מנוהל ב - מצב חשבון - חשבון מועדף - בחר מטבע - עובר ושב - השקעה - טווח ארוך - שגיאה בהוספת חשבון - שגיאה בעת עדכון חשבון - נדרש מטבע - נדרשת יתרת פתיחה לחשבון - נדרש שם החשבון - נדרש סוג חשבון - נדרש מצב חשבון - שם מוטב - ערוך מוטב - מחק מוטב - מוטב - בחר מוטב - מוטב לא נמצא - מ - עדכון מוטב נכשל - קטגוריה - קטגוריית משנה - לא נמצאה קטגוריה - בחר קטגוריה - הוסף קטגוריה - הוסף קטגוריית משנה - ערוך קטגוריה - מחק קטגוריה - שם מטבע - סמל מטבע - מחק מטבע - שם יחידה - שם הסנט (מאית המטבע) - סמל קידומת - סמל סיומת - סימן עשרוני - סימן \'אלפים\' - סולם - המרה - נדרש שם מטבע - סכום - סך הכל - הפקדה - סטטוס - מותאם - מבוטל - מעקב - שכפל - אף אחד - העברה - סוג תנועה - מצב - משיכה - הוספת תנועה נכשלה - עדכון תנועה נכשל - מחק תנועה - תנועה חדשה - נדרש מוטב - נדרש חשבון יעד - נדרשת קטגוריה - נדרש סכום כולל - אודות - הוסף - האם אתה בטוח שברצונך למחוק? - תאריך - מחק - הורד - ערוך - לוגו - חדשה/עריכת תנועה - רענן - חפש - הגדרות - סיכום - סינכרון - פתח - משתמש - העלה - שם משתמש - ל - אתר אינטרנט - צור קשר - פרטי גישה - יתרת פתיחה - הערות - סגור - חדש/עריכת מטבע - ערכת נושא יישום - אור הולוגרפי עם סרגל-פעולה כהה - סגור יישום - האם לסגור את היישום? - לא נמצאה פעולה לביצוע עם הקובץ שנבחר - תשומת לב - לא ניתן למחוק את המוטב שנבחר מאחר וקימות כבר תנועות - לא ניתן למחוק את החשבון שנבחר מאחר וקימות כבר תנועות - לא ניתן למחוק המטבע שנבחר מאחר וקימות כבר תנועות - לא ניתן למחוק את הקטגוריה שנבחרה מאחר וקימות כבר תנועות - כל התנועות - 7 הימים האחרונים - בשבועיים האחרונים - החודש הנוכחי - שנה נוכחית - הצג תנועה - יומן שינוים - מספר תנועה - סיכום Money Manager Ex - כל חשבונות Money Manager Ex - הוסיף תנועת Money Manager Ex - תנועה חוזרת ריקה - ללא - שבועי - דו שבועי - חודשי - דו-חודשי - רבעוני - חצי שנתי - שנתי - ארבעה חודשים - ארבעה שבועות - יומי - ב (x) ימים - ב (x) חודשים - כל (x) ימים - כל (x) חודשים - לא פעיל - ימים בפיגור! - ימים שנותרו - חדש/עריכת תנועות חוזרת - המופע הבא - מופעים - מספר מופעים - נדרש המופע הבא - משפעל - הזן את המופע הבא - דלג על מופע הבא - קימות תנועת חוזרות שמועד פרעונן חלף - גע על מנת לבדוק תנועה שמועד פרעונה חלף - %1$d תנועות חוזרות חלף זמנם - שלח משוב - מידע - אבטחה - הפעל קוד גישה - הזן סיסמא - הזן מחדש את קוד הגישה החדש - קודי הגישה אינם תואמים - עריכת קוד גישה - נטרל קוד הגישה - הזן את הסיסמא הקודמת - הסיסמא לא עודכנה - לחיפוש ניתן להשתמש בתו הכללי % - הכנסה מול הוצאות: החודש הנוכחי - הכנסה - הוצאות - הפרש - אין נתונים להצגה - חודש - השנה - דוחות - הכנסה לעומת הוצאות - סך הכל - בכל הזמנים - החודש הקודם - 30 הימים האחרונים - שנה קודמת - מספר תנועות שנמצאו: %1$d - תבנית התאריך - שנת הכספים: מתחילה ביום - שנת הכספים: מתחילה בחודש - מסד הנתונים הועבר: %1$s - העתקת מסד הנתונים לאחסון חיצוני נכשלה - אתה משתמש במסד נתונים שנשמר ב: %1$s - פצל תנועה - פצל - נדרש להזין לפחות תנועת פיצול אחת - ייצא נתונים לקובץ CSV - מייצוא נתונים. המתן בבקשה... - הנתונים יוצאה בהצלחה את הקובץ %1$s - ייצוא קובץ %1$s נכשל - Money Manager Ex לאנדרואיד מסופקת ללא תשלום. אם יישום מוצא חן בעינך, אתה יכול לתמוך בצוות הפיתוח בתרומה. - לתרומה באמצעות חיוב ביישום מובנה של Google Play. - בחר סכום תרומה - תרום - תודה על תרומתך! - תרום - לא, תודה - תרום! - סדר עולה - סדר יורד - מיון חודשים - התיקיה ב\"Dropbox/Apps/Money Manager Ex\" ריקה. אם אתה כבר משתמש MoneyManagerEx העתק את מסד הנתונים שלך לתיקיה זו במחשב שלך, לאחר מכן בצע רענון. - בחר קובץ מ- Dropbox - עודכן לאחרונה - מסד הנתונים הורד - על מנת להשתמש במסד הנתונים שהורד, גע ב \'פתח מסד נתונים\' - גע על מנת לבחור את הקובץ מ Dropbox - מוריד מ Dropbox - געעל מנת להוריד באופן ידני את הקובץ המקושר מתיקית Dropbox - העלה ל- Dropbox - גע על מנת להעלות באופן ידני את הקובץ המקושר לתיקית Dropbox - העלאת בהצלחה את מסד הנתונים שלך - כיצד פועלת Dropbox עם Money Manager Ex\? - אל תציג שוב - פתח מסד נתונים - מחזור סינכרון - באיזו תכיפות לסנכרן? - מגירסה 1.2.0 Money Manager Ex עבור אנדרואיד ניהול סינכרון עם Dropbox השתנה. עבור משתמשים שכבר משתמשים בסינכרון עם Dropbox, נדרש להגדיר מחדש את התצורה. \nThe הגדרת תצורת הסינכרון עם Dropbox, בחירת מסד הנתונים, ממוקם בהגדרות. \n מגירסה 1.2.0 Money Manager Ex עבור אנדרואיד יכול לסנכרן באופן אוטומטי את מסד הנתונים עם Dropbox - עדכון מיידי של מסד הנתונים עם השינוי - אפשרות זו מאפשרת להעלות באופן אוטומטי עם כל שינוי במסד הנתונים - מציג יתרה לכל תנועה - מציג את יתרה לכל תנועה. הצגת יתרות עשויה להאט את היישום - מסד נתונים פתוחה - עצות - גופן יישום - בחר את הגופן בו תרצה להשתמש ביישום - גודל גופן יישום - בחר את גודל הגופן בו תרצה להשתמש ביישום - מיקרו - קטן - ברירת מחדל - בינוני - גדול - מוריד מ- Dropbox. המתן בבקשה... - מעלה ל Dropbox. המתן בבקשה... - לאן הכסף הולך - מהיכן הכסף מגיע - מציג סיכום של Money Manager Ex עבור אנדרואיד - הצג יתרה לכל חשבון Money Manager Ex עבור אנדרואיד - תזמן מועד לבדיקת תנועות חוזרות שמועד היעד שלהן חלף - ציין את השעה שעל היישום לבדוק האם קיימות תנועות חוזרות שתאריך היעד שלהן חלף (ברירת המחדל 08:00) - קרדיטים - משיכות מובילות: 30 הימים האחרונים - מקבלי העליון: 30 הימים האחרונים - התנועות הקרבות - כמות - לוח בקרה - מסד הנתונים מסונכרן - 3 חודשים אחרונים - 6 חודשים אחרונים - קטגוריה ריקה - מוטב ריק - עזרה - מחק תנועה חוזרת - אחרון - חשבונות - לחשבון - מחשבון - סטאטוס ברירת המחדל - מוטב ברירת מחדל - ערוך תנועה - האם אתה בטוח שברצונך למחוק את התנועה שנבחרה? - האם אתה בטוח שברצונך למחוק את %d התנועות שנבחרו? - קטגוריות - מטבעות - מוטב - תנועות חוזרות - אור ההולוגרפי - חשבון חדש - ייבוא סוגי מטבע - מייבוא סוגי מטבע. המתן …בבקשה... - סכום גדול או שווה - סכום קטן או שווה - תוצאת החיפוש - תנועה חוזרת חדשה - ערוך תנועה חוזרת - כל 5 דקות - כל 15 דקות - כל 30 דקות - כל שעה - כל שעתיים - כל 6 שעות - כל 12 שעות - אף פעם - נתיב מסד הנתונים לא קיים - לא ניתן לפתוח את מסד הנתונים לכתיבה - האם לייבא מטבע? - מסגרת הזמן - הצג תרשים - הוסף תנועה - ברוכים הבאים ל MoneyManagerEx - MoneyManagerEx ממדל כל התנועות כשייכות לחשבות .\n\n על מנת לסייער לך להתחיל בעבודה, התחל על-ידי הכנת רשימה של כל במוסדות בפיננסיים בהם אתה מחזיק חשבון .\n\n גע על מנת להזין את החשבונות שלך. - אם אתה כבר משתמש MoneyManagerEx על, חלונות, לינוקס או Mac, קשור יישום זה עם Dropbox, על מנת לסנכרן את הנתונים שלך - קביעת תצורה של Dropbox - חיפוש לפי תוכן הטקסט ולא לפי האות בה מתחיל הטקסט - חפש מוטבים, קטגוריות, מטבעות, וכו \'... לפי תוכן ולא לפי תחיליות - האות בה מתחיל הטקסט - דרג את היישום - שפת היישום - צ\'כית - אנגלית - ספרדית - צרפתית - עברית - איטלקית - פורטוגזית - פורטוגזית, ברזילאית - רוסית - ויאטנמית - סינית פשוטה - סינית מסורתית - מעדכון שערי חליפין למטבעות. המתן בבקשה... - מעדכן שער חליפין :\n%1$s - כל שערי החליפין של המטבעות עודכנו בהצלחה - עדכן שער חליפין - האם ברצונך לעדכן את שער החליפין? - משיכה מ %1$s - הפקדה ל %1$s - אתר MoneyManagerEx + Money Manager Ex + יישום לניהול כספים אישי, פשוט וקל לשימוש, לניהול חשבונות בנק, תקציב משפחה, וכן הלאה. + MoneyManagerEx for Android Project uses ActionBarSherlock library + רשיונות קוד פתוח + הוספת נתונים נכשלה + מחיקת נתונים נכשלה + עדכון נתונים נכשל + צא + נהל + קישור ל Dropbox + התנתק מ- Dropbox + מסנכרן קובץ. המתן בבקשה... + מוריד קובץ Dropbox. המתן בבקשה... + מעלה קובץ ל Dropbox. המתן בבקשה... + קובץ Dropbox + כללי + Look & Feel + מטבע בסיס + הצג חשבונות פעילים + אם לא נבחר, כל החשבונות יוצגו + הצג חשבונות מועדפים + גירסה + גרסת משנה + Database path + חשבון + רשימת חשבונות + לא נמצאו חשבונות + יתרת חשבון + יתרה מותאמת + מחק חשבון + שם חשבון + סוג חשבון + מספר חשבון + מנוהל ב + מצב חשבון + חשבון מועדף + בחר מטבע + עובר ושב + השקעה + טווח ארוך + שגיאה בהוספת חשבון + שגיאה בעת עדכון חשבון + נדרש מטבע + נדרשת יתרת פתיחה לחשבון + נדרש שם החשבון + נדרש סוג חשבון + נדרש מצב חשבון + שם מוטב + ערוך מוטב + מחק מוטב + מוטב + בחר מוטב + מוטב לא נמצא + מ + עדכון מוטב נכשל + קטגוריה + קטגוריית משנה + לא נמצאה קטגוריה + בחר קטגוריה + הוסף קטגוריה + הוסף קטגוריית משנה + ערוך קטגוריה + מחק קטגוריה + שם מטבע + סמל מטבע + מחק מטבע + שם יחידה + שם הסנט (מאית המטבע) + סמל קידומת + סמל סיומת + סימן עשרוני + סימן \'אלפים\' + סולם + המרה + נדרש שם מטבע + סכום + סך הכל + הפקדה + סטטוס + מותאם + מבוטל + מעקב + שכפל + אף אחד + העברה + סוג תנועה + מצב + משיכה + הוספת תנועה נכשלה + עדכון תנועה נכשל + מחק תנועה + תנועה חדשה + נדרש מוטב + נדרש חשבון יעד + נדרשת קטגוריה + נדרש סכום כולל + אודות + הוסף + האם אתה בטוח שברצונך למחוק? + תאריך + מחק + הורד + ערוך + לוגו + חדשה/עריכת תנועה + רענן + חפש + הגדרות + סיכום + סינכרון + פתח + משתמש + העלה + שם משתמש + ל + אתר אינטרנט + צור קשר + פרטי גישה + יתרת פתיחה + הערות + סגור + חדש/עריכת מטבע + Theme + Holo + אור הולוגרפי עם סרגל-פעולה כהה + סגור יישום + האם לסגור את היישום? + לא נמצאה פעולה לביצוע עם הקובץ שנבחר + תשומת לב + לא ניתן למחוק את המוטב שנבחר מאחר וקימות כבר תנועות + לא ניתן למחוק את החשבון שנבחר מאחר וקימות כבר תנועות + לא ניתן למחוק המטבע שנבחר מאחר וקימות כבר תנועות + לא ניתן למחוק את הקטגוריה שנבחרה מאחר וקימות כבר תנועות + כל התנועות + 7 הימים האחרונים + בשבועיים האחרונים + החודש הנוכחי + שנה נוכחית + הצג תנועה + יומן שינוים + מספר תנועה + סיכום Money Manager Ex + כל חשבונות Money Manager Ex + הוסיף תנועת Money Manager Ex + תנועה חוזרת ריקה + ללא + שבועי + דו שבועי + חודשי + דו-חודשי + רבעוני + חצי שנתי + שנתי + ארבעה חודשים + ארבעה שבועות + יומי + ב (x) ימים + ב (x) חודשים + כל (x) ימים + כל (x) חודשים + לא פעיל + ימים בפיגור! + ימים שנותרו + חדש/עריכת תנועות חוזרת + המופע הבא + מופעים + מספר מופעים + נדרש המופע הבא + משפעל + הזן את המופע הבא + דלג על מופע הבא + קימות תנועת חוזרות שמועד פרעונן חלף + גע על מנת לבדוק תנועה שמועד פרעונה חלף + %1$d תנועות חוזרות חלף זמנם + שלח משוב + מידע + אבטחה + הפעל קוד גישה + הזן סיסמא + הזן מחדש את קוד הגישה החדש + קודי הגישה אינם תואמים + עריכת קוד גישה + נטרל קוד הגישה + הזן את הסיסמא הקודמת + הסיסמא לא עודכנה + לחיפוש ניתן להשתמש בתו הכללי % + הכנסה מול הוצאות: החודש הנוכחי + הכנסה + הוצאות + הפרש + אין נתונים להצגה + חודש + השנה + דוחות + הכנסה לעומת הוצאות + סך הכל + בכל הזמנים + החודש הקודם + 30 הימים האחרונים + שנה קודמת + מספר תנועות שנמצאו: %1$d + תבנית התאריך + שנת הכספים: מתחילה ביום + שנת הכספים: מתחילה בחודש + Export database + מסד הנתונים הועבר: %1$s + העתקת מסד הנתונים לאחסון חיצוני נכשלה + אתה משתמש במסד נתונים שנשמר ב: %1$s + פצל תנועה + פצל + נדרש להזין לפחות תנועת פיצול אחת + ייצא נתונים לקובץ CSV + מייצוא נתונים. המתן בבקשה... + הנתונים יוצאה בהצלחה את הקובץ %1$s + ייצוא קובץ %1$s נכשל + MoneyManagerEx for Android is provided free. If this application is to your liking, you can support the development team with a donation. + Google Play In-App Billing + לתרומה באמצעות חיוב ביישום מובנה של Google Play. + בחר סכום תרומה + תרום + תודה על תרומתך! + תרום + לא, תודה + תרום! + סדר עולה + סדר יורד + מיון חודשים + התיקיה ב\"Dropbox/Apps/Money Manager Ex\" ריקה. אם אתה כבר משתמש MoneyManagerEx העתק את מסד הנתונים שלך לתיקיה זו במחשב שלך, לאחר מכן בצע רענון. + בחר קובץ מ- Dropbox + עודכן לאחרונה + Dropbox + מסד הנתונים הורד + על מנת להשתמש במסד הנתונים שהורד, גע ב \'פתח מסד נתונים\' + גע על מנת לבחור את הקובץ מ Dropbox + מוריד מ Dropbox + געעל מנת להוריד באופן ידני את הקובץ המקושר מתיקית Dropbox + העלה ל- Dropbox + גע על מנת להעלות באופן ידני את הקובץ המקושר לתיקית Dropbox + העלאת בהצלחה את מסד הנתונים שלך + Dropbox - Money Manager Ex + כיצד פועלת Dropbox עם Money Manager Ex\? + אל תציג שוב + פתח מסד נתונים + מחזור סינכרון + באיזו תכיפות לסנכרן? + מגירסה 1.2.0 Money Manager Ex עבור אנדרואיד ניהול סינכרון עם Dropbox השתנה. עבור משתמשים שכבר משתמשים בסינכרון עם Dropbox, נדרש להגדיר מחדש את התצורה. \nThe הגדרת תצורת הסינכרון עם Dropbox, בחירת מסד הנתונים, ממוקם בהגדרות. \n מגירסה 1.2.0 Money Manager Ex עבור אנדרואיד יכול לסנכרן באופן אוטומטי את מסד הנתונים עם Dropbox + עדכון מיידי של מסד הנתונים עם השינוי + אפשרות זו מאפשרת להעלות באופן אוטומטי עם כל שינוי במסד הנתונים + מציג יתרה לכל תנועה + מציג את יתרה לכל תנועה. הצגת יתרות עשויה להאט את היישום + מסד נתונים פתוחה + Database--> + עצות + גופן יישום + בחר את הגופן בו תרצה להשתמש ביישום + גודל גופן יישום + בחר את גודל הגופן בו תרצה להשתמש ביישום + מיקרו + קטן + ברירת מחדל + בינוני + גדול + מוריד מ- Dropbox. המתן בבקשה... + מעלה ל Dropbox. המתן בבקשה... + לאן הכסף הולך + מהיכן הכסף מגיע + מציג סיכום של Money Manager Ex עבור אנדרואיד + הצג יתרה לכל חשבון Money Manager Ex עבור אנדרואיד + Check time + What time would you check if there are repeating transactions overdue? (default 08:00) + קרדיטים + משיכות מובילות: 30 הימים האחרונים + מקבלי העליון: 30 הימים האחרונים + התנועות הקרבות + כמות + לוח בקרה + The database is up to date + 3 חודשים אחרונים + 6 חודשים אחרונים + קטגוריה ריקה + מוטב ריק + עזרה + מחק תנועה חוזרת + אחרון + חשבונות + לחשבון + מחשבון + סטאטוס ברירת המחדל + מוטב ברירת מחדל + ערוך תנועה + האם אתה בטוח שברצונך למחוק את התנועה שנבחרה? + האם אתה בטוח שברצונך למחוק את %d התנועות שנבחרו? + קטגוריות + מטבעות + מוטב + תנועות חוזרות + אור ההולוגרפי + חשבון חדש + ייבוא סוגי מטבע + מייבוא סוגי מטבע. המתן …בבקשה... + סכום גדול או שווה + סכום קטן או שווה + תוצאת החיפוש + תנועה חוזרת חדשה + ערוך תנועה חוזרת + כל 5 דקות + כל 15 דקות + כל 30 דקות + כל שעה + כל שעתיים + כל 6 שעות + כל 12 שעות + אף פעם + נתיב מסד הנתונים לא קיים + לא ניתן לפתוח את מסד הנתונים לכתיבה + האם לייבא מטבע? + מסגרת הזמן + הצג תרשים + הוסף תנועה + ברוכים הבאים ל MoneyManagerEx + MoneyManagerEx ממדל כל התנועות כשייכות לחשבות .\n\n על מנת לסייער לך להתחיל בעבודה, התחל על-ידי הכנת רשימה של כל במוסדות בפיננסיים בהם אתה מחזיק חשבון .\n\n גע על מנת להזין את החשבונות שלך. + אם אתה כבר משתמש MoneyManagerEx על, חלונות, לינוקס או Mac, קשור יישום זה עם Dropbox, על מנת לסנכרן את הנתונים שלך + קביעת תצורה של Dropbox + חיפוש לפי תוכן הטקסט ולא לפי האות בה מתחיל הטקסט + חפש מוטבים, קטגוריות, מטבעות, וכו \'... לפי תוכן ולא לפי תחיליות - האות בה מתחיל הטקסט + דרג את היישום + Application Language + צ\'כית + אנגלית + ספרדית + צרפתית + עברית + איטלקית + פורטוגזית + פורטוגזית, ברזילאית + רוסית + ויאטנמית + סינית פשוטה + סינית מסורתית + מעדכון שערי חליפין למטבעות. המתן בבקשה... + מעדכן שער חליפין :\n%1$s + כל שערי החליפין של המטבעות עודכנו בהצלחה + עדכן שער חליפין + האם ברצונך לעדכן את שער החליפין? + משיכה מ %1$s + הפקדה ל %1$s + אתר MoneyManagerEx + You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! + Retrieving status of your donations from Google Play. Please wait… + Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. + Notification Repeating Transaction overdue + Show notification for repeating transaction overdue diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 0cabf61a29..7f1260834f 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -1,343 +1,355 @@ - - + - Egy egyszerű és könnyen használható alkalmazás, amely segít, hogy kézben tartsa pénzügyeit, kezelje a bankszámláit és a családi költségvetést. - Az Android Money Manager Ex Project az ActionBarSherlock és a RobotMediaBilling libraries használatával készült - Nyílt forráskódú licenc - Adatok felvitele nem sikerült - Adatok törlése nem sikerült - Adatok frissítése nem sikerült - Kilépés - Kezelés - Csatlakozás a Dropbox-hoz - Dropbox leválasztása - Állomány szinkronizálása. Kérem várjon… - Állomány letöltése Dropbox-ból. Kérem várjon… - Állomány feltöltés Dropbox-ba. Kérem várjon… - Dropbox állomány - Általános - Megjelenés - Alapértelmezett pénznem - Nyitott számlák megjelenítése - Ha nincs bejelölve, akkor minden számlát megjelenít - Kedvenc számlák megjelenítése - Verzió - Build - Számla - Számla lista - Nincsenek számlák - Számla egyenleg - Egyeztetett egyenleg - Számla törlése - Számla neve - Számla típusa - Számla száma - Számlakezelő bank - Számla státusza - Kedvenc számla - Válasszon pénznemet - Folyószámla - Befektetési - Időszaki - Számla felviteli hiba - Számla frissítési hiba - Pénznem megadása kötelező - Kezdő egyenleg megadása kötelező - Számla név megadása kötelező - Számla típusának megadása kötelező - Számla státuszának megadása kötelező - Partner neve - Partner szerkesztése - Partner törlése - Partner - Válasszon partnert - Nincsenek partnerek - Dátumtól - Partner frissítése nem sikerült - Kategória - Alkategória - Nincsenek kategóriák - Válasszon kategóriát - Új kategória - Új alkategória - Kategória szerkesztése - Kategória törlése - Pénznem neve - Pénznem szimbóluma - Pénznem törlése - Egység neve - Váltópénz - Előtag jele - Utótag jele - Tizedes jel - Csoport jel - Skála - Átváltás - Pénznem nevének megadása kötelező - Összeg - Teljes összeg - Bevétel - Státusz - Visszaigazolt - Hiányos - Követés - Ismétlődő - Nincs - Átvezetés - Tranzakció típusa - Státusz - Kiadás - Tranzakció felvitele nem sikerült - Tranzakció frissítése nem sikerült - Tranzakció törlése - Új tranzakció - Partner megadása kötelező - Célszámla megadása kötelező - Kategória megadása kötelező - Teljes összeg megadása kötelező - Rólunk - Hozzáad - Biztosan törölni szeretné? - Dátum - Törlés - Letöltés - Szerkesztés - Logo - Új tranzakció/Szerkesztés - Frissít - Keresés - Beállítások - Összesen - Szinkronizálás - Nyitott - Felhasználó - Feltöltés - Felhasználó név - Dátumig - Honlap - Kapcsolat - Hozzáférési információk - Kezdő egyenleg - Jegyzetek - Zárt - Új pénznem/szerkesztés - Téma beállítása - Holo light sötét műveleti sávval - Kilépés - Bezárja az alkalmazást? - Nem található tevékenység, hogy kezelje az Intent Pick File-t - Figyelem - A kiválasztott partner nem törölhető, mert van rá hivatkozás - A kiválasztott számla nem törölhető, mert van rá hivatkozás - A kiválasztott pénznem nem törölhető, mert van rá hivatkozás - A kiválasztott kategória nem törölhető, mert van rá hivatkozás - Minden tranzakció - Elmúlt 7 nap - Elmúlt 2 hét - Aktuális hónap - Aktuális év - Tranzakciók megjelenítése - Újdonságok - Tranzakció száma - Money Manager Ex Összesen - Money Manager Ex minden számla - Money Manager Ex Új tranzakció - Üres ismétlődő tranzakció - Soha - Hetente - Kéthetente - Havonta - Kéthavonta - Negyedévente - Félévente - Évente - Négy havonta - Négy hetente - Naponta - (x) naponta - (x) havonta - Minden (x). napon - Minden (x). hónapban - Inaktív - napja lejárt! - hátralévő nap - Új ismétlődő tranzakció/Szerkesztés - Következő előfordulás - Ismétlődik - Gyakoriság - Következő előfordulás megadása kötelező - Aktiválás - Következő előfordulás felvitele - Következő előfordulás kihagyása - Vannak lejárt ismétlődő tranzakciók - Érintse meg az esedékesség ellenőrzéséhez - %1$d ismétlődő tranzakció lejárt - Visszajelzés küldése - Információ - Biztonság - Jelszó bekapcsolása - Adja meg a jelszót - Adja meg újra az új jelszót - A megadott jelszavak nem egyeznek - Jelszó szerkesztése - Jelszó kikapcsolása - Adja meg az előző jelszót - Jelszó nem frissült - Kereséskor használhatja a % helyettesítő karaktert - Bevételek-Kiadások: Aktuális hónap - Bevételek - Kiadások - Különbség - Nincs megjelenítendő adat - Hónap - Év - Jelentések - Bevételek - Kiadások - Összesen - Mind - Előző hónap - Utolsó 30 nap - Előző év - Talált tranzakciók: %1$d - Dátum formátum - Pénzügyi év: Kezdő nap - Pénzügyi év: Kezdő hónap - Az adatbázis másolása megtörtént: %1$s - Az adatbázis másolása sikertelen - Ün ezt az adatbázist használja: %1$s - Tranzakció megosztása - Megosztás - Legalább egy megosztott tranzakció megadása kötelező - Adatok exportálása CSV állományba - Adatok exportálása. Kérem várjon… - Az adatok exportálása sikeresen megtörtént a %1$s állományba - Export állomány %1$s nem sikerült - Az Android Money Manager Ex program használata ingyenes. Ha tetszik az alkalmazás, adománnyal támogathatod a fejlesztést. - Adomány Google Play-en keresztül alkalmazáson belüli fizetéssel. - Válaszd ki az adomány értékét - Adomány - Köszönjük a támogatását! - Adomány - Nem, köszönöm - Adományozzon! - Növekvő - Csökkenő - Hónapok rendezése - A Dropbox/Apps/Money Manager Ex Mobile mappa üres. Ha már használja a MoneyManagerEx programot, másolja az adatbázisát ebbe a mappába, majd nyomja meg a frissítés gombot. - Válasszon egy Dropbox állományt - Utoljára módosítva - Az adatbázis letöltése megtörtént - A letöltött adatbázis használatához válassza az Adatbázis megnyitása menüt - Válassza ki a használni kívánt állományt a Dropbox-ból - Letöltés Dropbox-ból - Érintse meg a csatolt Dropbox állomány kézi letöltéséhez - Feltöltés Dropbox-ba - Érintse meg a csatolt Dropbox állomány kézi feltöltéséhez - Az adatbázis feltöltése sikeresen megtörtént - Hogyan működik a Dropbox a Money Manager Ex programban\? - Ne mutassa többet - Adatbázis megnyitása - Szinkronizálási időköz - Milyen gyakran kell szinkronizálni? - Az 1.2.0 verziótól kezdve megváltozott a Money Manager Ex for Android alkalmazás Dropbox szinkronizáció kezelése. Azon felhasználóknak, akik már használták ezt a funkciót, újra el kell végezni a konfigurálást.\nA Dropbox szinkronizáció konfigurálása és az adatbázis kiválasztása a Beállítások menüben található.\nAz 1.2.0 verziótól kezdve a program képes az automatikus Dropbox szinkronizációra - Adatbázis változás azonnali feltöltése - Ez a beállítás lehetővé teszi az automatikus feltöltést, amint változik az adatbázis - Tranzakciónkénti egyenleg - Mutatja az egyenleget tranzakciónként is. Ez a megjelenítés lassíthatja a program működését - Adatbázis megnyitása - Tippek - Alkalmazás betűtípusa - Válasszon betűtípust az alkalmazásban - Alkalmazás betűmérete - Válasszon betűméretet az alkalmazásban - Apró - Kicsi - Alapértelmezett - Közepes - Nagy - Letöltés a Dropbox-ból. Kérem várjon… - Feltöltés a Dropbox-ba. Kérem várjon… - Kiadások - Bevételek - Money Manager Ex for Android összegzés megjelenítése - Minden számla összegzésének megjelenítése - Lejárt ismétlődő tranzakciók ellenőrzése - Állítsa be, hogy a nap melyik időszakában ellenőrizze a program, vannak-e lejárt ismétlődő tranzakciók (alapértelmezett időpont 08:00) - Készítők - Legnagyobb kiadások: Elmúlt 30 nap - Top partnerek: Elmúlt 30 nap - Közelgő tranzakciók - Mennyiség - Vezérlőpult - Az adatbázis szinkronizálva - Utolsó 3 hónap - Utolsó 6 hónap - Üres kategória - Üres partner - Segítség - Ismétlődő tranzakció törlése - Utolsó - Számlák - Számlára - Számláról - Alapértelmezett státusz - Alapértelmezett partner - Tranzakció szerkesztése - Biztosan törölni szeretné a kiválasztott tranzakciót? - Biztosan törölni szeretné a kiválasztott %d tranzakciót? - Kategóriák - Pénznemek - Partnerek - Ismétlődő tranzakciók - Holo világos - Új számla - Pénznemek importálása - Pénznemek importálása. Kérem várjon… - Nagyobb, vagy egyenlő - Kisebb, vagy egyenlő - A keresés eredménye - Új ismétlődő tranzakció - Ismétlődő tranzakció szerkesztése - 5 percenként - 15 percenként - 30 percenként - Óránként - 2 óránként - 6 óránként - 12 óránként - Soha - Adatbázis elérési út nem létezik - Az adatbázis nem nyitható meg szerkesztésre - Szeretné importálni a pénznemeket? - Idő keret - Diagram mutatása - Új tranzakció - Köszöntjük a MoneyManagerEx programban! - A MoneyManagerEx alkalmazásban minden tranzakció egy számlához tartozik.\n\nHogy elősegítse a kezdeti lépéseket, készítsen egy listát minden pénzintézetről, ahol a számláit kezeli.\n\nÉrintse meg , hogy elkezdhesse felvinni a számláit. - Ha már használja a MoneyManagerEx programot Windows, Linux, vagy Mac operációs rendszeren, kapcsolja össze ezt az alkalmazást a Dropbox fiókjával, hogy szinkronizálhassa az adatbázisát - Dropbox konfigurálás - Keresés a szöveg tartalmában - Partner, kategória, pénznem, stb… keresése tartalom, és nem kezdő karakter alapján is - Alkalmazás értékelése - Alkalmazás nyelve - Cseh - Angol - Spanyol - Francia - Héber - Olasz - Portugál - Portugál, Brazil - Orosz - Vietnámi - Egyszerű kínai - Hagyományos kínai - Pénznemek árfolyamának frissítése. Kérem várjon… - Árfolyam frissítés:\n%1$s - Minden pénznem árfolyamának frissítése sikeresen megtörtént - Árfolyam frissítés - Szeretné frissíteni az árfolyamokat? - Kiadás innen %1$s - Betét ide %1$s - MoneyManagerEx honlap + Money Manager Ex + Egy egyszerű és könnyen használható alkalmazás, amely segít, hogy kézben tartsa pénzügyeit, kezelje a bankszámláit és a családi költségvetést. + A Money Manager Ex for Android az ActionBarSherlock library használatával készült + Nyílt forráskódú licenc + Adatok felvitele nem sikerült + Adatok törlése nem sikerült + Adatok frissítése nem sikerült + Kilépés + Kezelés + Csatlakozás a Dropbox-hoz + Dropbox leválasztása + Állomány szinkronizálása. Kérem várjon… + Állomány letöltése Dropbox-ból. Kérem várjon… + Állomány feltöltés Dropbox-ba. Kérem várjon… + Dropbox állomány + Általános + Look & Feel + Alapértelmezett pénznem + Nyitott számlák megjelenítése + Ha nincs bejelölve, akkor minden számlát megjelenít + Kedvenc számlák megjelenítése + Verzió + Build + Database path + Számla + Számla lista + Nincsenek számlák + Számla egyenleg + Egyeztetett egyenleg + Számla törlése + Számla neve + Számla típusa + Számla száma + Számlakezelő bank + Számla státusza + Kedvenc számla + Válasszon pénznemet + Folyószámla + Befektetési + Időszaki + Számla felviteli hiba + Számla frissítési hiba + Pénznem megadása kötelező + Kezdő egyenleg megadása kötelező + Számla név megadása kötelező + Számla típusának megadása kötelező + Számla státuszának megadása kötelező + Partner neve + Partner szerkesztése + Partner törlése + Partner + Válasszon partnert + Nincsenek partnerek + Dátumtól + Partner frissítése nem sikerült + Kategória + Alkategória + Nincsenek kategóriák + Válasszon kategóriát + Új kategória + Új alkategória + Kategória szerkesztése + Kategória törlése + Pénznem neve + Pénznem szimbóluma + Pénznem törlése + Egység neve + Váltópénz + Előtag jele + Utótag jele + Tizedes jel + Csoport jel + Skála + Átváltás + Pénznem nevének megadása kötelező + Összeg + Teljes összeg + Bevétel + Státusz + Visszaigazolt + Hiányos + Követés + Ismétlődő + Nincs + Átvezetés + Tranzakció típusa + Státusz + Kiadás + Tranzakció felvitele nem sikerült + Tranzakció frissítése nem sikerült + Tranzakció törlése + Új tranzakció + Partner megadása kötelező + Célszámla megadása kötelező + Kategória megadása kötelező + Teljes összeg megadása kötelező + Rólunk + Hozzáad + Biztosan törölni szeretné? + Dátum + Törlés + Letöltés + Szerkesztés + Logo + Új tranzakció/Szerkesztés + Frissít + Keresés + Beállítások + Összesen + Szinkronizálás + Nyitott + Felhasználó + Feltöltés + Felhasználó név + Dátumig + Honlap + Kapcsolat + Hozzáférési információk + Kezdő egyenleg + Jegyzetek + Zárt + Új pénznem/szerkesztés + Theme + Holo + Holo light sötét műveleti sávval + Kilépés + Bezárja az alkalmazást? + Nem található tevékenység, hogy kezelje az Intent Pick File-t + Figyelem + A kiválasztott partner nem törölhető, mert van rá hivatkozás + A kiválasztott számla nem törölhető, mert van rá hivatkozás + A kiválasztott pénznem nem törölhető, mert van rá hivatkozás + A kiválasztott kategória nem törölhető, mert van rá hivatkozás + Minden tranzakció + Elmúlt 7 nap + Elmúlt 2 hét + Aktuális hónap + Aktuális év + Tranzakciók megjelenítése + Újdonságok + Tranzakció száma + Money Manager Ex Összesen + Money Manager Ex minden számla + Money Manager Ex Új tranzakció + Üres ismétlődő tranzakció + Soha + Hetente + Kéthetente + Havonta + Kéthavonta + Negyedévente + Félévente + Évente + Négy havonta + Négy hetente + Naponta + (x) naponta + (x) havonta + Minden (x). napon + Minden (x). hónapban + Inaktív + napja lejárt! + hátralévő nap + Új ismétlődő tranzakció/Szerkesztés + Következő előfordulás + Ismétlődik + Gyakoriság + Következő előfordulás megadása kötelező + Aktiválás + Következő előfordulás felvitele + Következő előfordulás kihagyása + Vannak lejárt ismétlődő tranzakciók + Érintse meg az esedékesség ellenőrzéséhez + %1$d ismétlődő tranzakció lejárt + Visszajelzés küldése + Információ + Biztonság + Jelszó bekapcsolása + Adja meg a jelszót + Adja meg újra az új jelszót + A megadott jelszavak nem egyeznek + Jelszó szerkesztése + Jelszó kikapcsolása + Adja meg az előző jelszót + Jelszó nem frissült + Kereséskor használhatja a % helyettesítő karaktert + Bevételek-Kiadások: Aktuális hónap + Bevételek + Kiadások + Különbség + Nincs megjelenítendő adat + Hónap + Év + Jelentések + Bevételek - Kiadások + Összesen + Mind + Előző hónap + Utolsó 30 nap + Előző év + Talált tranzakciók: %1$d + Dátum formátum + Pénzügyi év: Kezdő nap + Pénzügyi év: Kezdő hónap + Export database + Az adatbázis másolása megtörtént: %1$s + Az adatbázis másolása sikertelen + Ün ezt az adatbázist használja: %1$s + Tranzakció megosztása + Megosztás + Legalább egy megosztott tranzakció megadása kötelező + Adatok exportálása CSV állományba + Adatok exportálása. Kérem várjon… + Az adatok exportálása sikeresen megtörtént a %1$s állományba + Export állomány %1$s nem sikerült + A Money Manager Ex for Android használata ingyenes. Ha tetszik az alkalmazás, adománnyal támogathatja a fejlesztő csapatot. + Google Play In-App Billing + Adomány Google Play-en keresztül alkalmazáson belüli fizetéssel. + Válaszd ki az adomány értékét + Adomány + Köszönjük a támogatását! + Adomány + Nem, köszönöm + Adományozzon! + Növekvő + Csökkenő + Hónapok rendezése + A Dropbox/Apps/Money Manager Ex Mobile mappa üres. Ha már használja a MoneyManagerEx programot, másolja az adatbázisát ebbe a mappába, majd nyomja meg a frissítés gombot. + Válasszon egy Dropbox állományt + Utoljára módosítva + Dropbox + Az adatbázis letöltése megtörtént + A letöltött adatbázis használatához válassza az Adatbázis megnyitása menüt + Válassza ki a használni kívánt állományt a Dropbox-ból + Letöltés Dropbox-ból + Érintse meg a csatolt Dropbox állomány kézi letöltéséhez + Feltöltés Dropbox-ba + Érintse meg a csatolt Dropbox állomány kézi feltöltéséhez + Az adatbázis feltöltése sikeresen megtörtént + Dropbox - Money Manager Ex + Hogyan működik a Dropbox a Money Manager Ex programban\? + Ne mutassa többet + Adatbázis megnyitása + Szinkronizálási időköz + Milyen gyakran kell szinkronizálni? + Az 1.2.0 verziótól kezdve megváltozott a Money Manager Ex for Android alkalmazás Dropbox szinkronizáció kezelése. Azon felhasználóknak, akik már használták ezt a funkciót, újra el kell végezni a konfigurálást.\nA Dropbox szinkronizáció konfigurálása és az adatbázis kiválasztása a Beállítások menüben található.\nAz 1.2.0 verziótól kezdve a program képes az automatikus Dropbox szinkronizációra + Adatbázis változás azonnali feltöltése + Ez a beállítás lehetővé teszi az automatikus feltöltést, amint változik az adatbázis + Tranzakciónkénti egyenleg + Mutatja az egyenleget tranzakciónként is. Ez a megjelenítés lassíthatja a program működését + Adatbázis megnyitása + Database--> + Tippek + Alkalmazás betűtípusa + Válasszon betűtípust az alkalmazásban + Alkalmazás betűmérete + Válasszon betűméretet az alkalmazásban + Apró + Kicsi + Alapértelmezett + Közepes + Nagy + Letöltés a Dropbox-ból. Kérem várjon… + Feltöltés a Dropbox-ba. Kérem várjon… + Kiadások + Bevételek + Money Manager Ex for Android összegzés megjelenítése + Minden számla összegzésének megjelenítése + Check time + What time would you check if there are repeating transactions overdue? (default 08:00) + Készítők + Legnagyobb kiadások: Elmúlt 30 nap + Top partnerek: Elmúlt 30 nap + Közelgő tranzakciók + Mennyiség + Vezérlőpult + Az adatbázis naprakész + Utolsó 3 hónap + Utolsó 6 hónap + Üres kategória + Üres partner + Segítség + Ismétlődő tranzakció törlése + Utolsó + Számlák + Számlára + Számláról + Alapértelmezett státusz + Alapértelmezett partner + Tranzakció szerkesztése + Biztosan törölni szeretné a kiválasztott tranzakciót? + Biztosan törölni szeretné a kiválasztott %d tranzakciót? + Kategóriák + Pénznemek + Partnerek + Ismétlődő tranzakciók + Holo világos + Új számla + Pénznemek importálása + Pénznemek importálása. Kérem várjon… + Nagyobb, vagy egyenlő + Kisebb, vagy egyenlő + A keresés eredménye + Új ismétlődő tranzakció + Ismétlődő tranzakció szerkesztése + 5 percenként + 15 percenként + 30 percenként + Óránként + 2 óránként + 6 óránként + 12 óránként + Soha + Adatbázis elérési út nem létezik + Az adatbázis nem nyitható meg szerkesztésre + Szeretné importálni a pénznemeket? + Idő keret + Diagram mutatása + Új tranzakció + Köszöntjük a MoneyManagerEx programban! + A MoneyManagerEx alkalmazásban minden tranzakció egy számlához tartozik.\n\nHogy elősegítse a kezdeti lépéseket, készítsen egy listát minden pénzintézetről, ahol a számláit kezeli.\n\nÉrintse meg , hogy elkezdhesse felvinni a számláit. + Ha már használja a MoneyManagerEx programot Windows, Linux, vagy Mac operációs rendszeren, kapcsolja össze ezt az alkalmazást a Dropbox fiókjával, hogy szinkronizálhassa az adatbázisát + Dropbox konfigurálás + Keresés a szöveg tartalmában + Partner, kategória, pénznem, stb… keresése tartalom, és nem kezdő karakter alapján is + Alkalmazás értékelése + Application Language + Cseh + Angol + Spanyol + Francia + Héber + Olasz + Portugál + Portugál, Brazil + Orosz + Vietnámi + Egyszerű kínai + Hagyományos kínai + Pénznemek árfolyamának frissítése. Kérem várjon… + Árfolyam frissítés:\n%1$s + Minden pénznem árfolyamának frissítése sikeresen megtörtént + Árfolyam frissítés + Szeretné frissíteni az árfolyamokat? + Kiadás innen %1$s + Betét ide %1$s + MoneyManagerEx honlap + Ön már támogatta a Money Manager Ex for Android program fejlesztését adományával!\n\nKöszönjük a fejlesztő csapat nevében! + Támogatási állapotának lekérése a Google Play szerveréről. Kérem, várjon… + Nem tudjuk használni az alkalmazáson belüli számlázást. Ellenőrizze, hogy a Play Áruház legfrissebb verziója van-e telepítve az eszközére. + Notification Repeating Transaction overdue + Show notification for repeating transaction overdue diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 52e37f4359..21add04f9c 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -1,351 +1,355 @@ - - + - Money Manager Ex - Una applicazione semplice e facile da usare per gestire finanze personali, conti bancari, budget familiare, etc. - MoneyManagerEx for Android utilizza la libreria di ActionBarSherlock - Licenze open source - Inserimento di dati fallito - Eliminazione di dati fallita - Aggiornamento dei dati fallito - Esci - Gestisci - Collega con Dropbox - Scollega da Dropbox - Sincronizzazione file. Attendere prego… - Download file da Dropbox. Attendere prego… - Upload file su Dropbox. Attendere prego… - File Dropbox - Generale - Visualizzazione - Valuta base - Visualizza conti aperti - Se non selezionato visualizza tutti i conti - Visualizza conti preferiti - Versione - Build - Conto - Elenco dei Conti - Nessun Conto Trovato - Saldo - Saldo Riconciliato - Elimina Conto - Nome account - Tipo di account - Numero conto - Tenuto presso - Stato conto - Conto preferito - Seleziona valuta - Conto Corrente - Conto di Investimento - Conto Deposito a Termine - Errore nell\'inserimento del conto - Errore nell\'aggiornamento del conto - Valuta è richiesta - Saldo iniziale è richiesto - Nome dell\'account è necessario - Tipo di conto è richiesto - Lo stato dell\'account è necessario - Nome beneficiario - Modifica il beneficiario - Elimina Beneficiario - Beneficiario - Seleziona Beneficiario - Nessun Beneficiario Trovato - Da - Aggiornamento beneficiario fallito - Categoria - Sottocategoria - Nessuna Categoria Trovata - Seleziona Categoria - Aggiungi Categoria - Aggiungi Sottocategoria - Modifica categoria - Elimina Categoria - Nome valuta - Simbolo della valuta - Elimina Valuta - Nome dell\'unità - Nome centesimi - Simbolo prefisso - Simbolo suffisso - Separatore decimale - Separatore migliaia - Scala - Tasso Base di Conversione - Nome della valuta è richiesto - Importo - Importo totale - Deposito - Stato - Riconciliata - Nulla - Da Monitorare - Duplicata - Nessuno - Trasferimento - Tipo Transazione - Stato - Prelievo - Inserimento di transazione non riuscito - Aggiornamento transazione non riuscito - Elimina Transazione - Nuova transazione - Beneficiario è richiesto - Account di destino è richiesto - Categoria è richiesta - Importo totale è richiesto - About - Aggiungi - Sei sicuro di che voler eliminare? - Data - Cancella - Scarica - Modifica - Logo - Nuova/Modifica Transazione - Aggiorna - Ricerca - Impostazioni - Riepilogo - Sincronizza - Aperto - Utente - Carica - Nome Utente - Da - Sito Web - Contatto - Informazioni di accesso - Saldo iniziale - Note - Chiuso - Nuovo/Modifica Valuta - Tema dell\'applicazione - Holo - Holo Light With Dark ActionBar - Chiudere l\'applicazione - Vuoi chiudere l\'applicazione? - Nessuna attività trovato per gestire l\'intent \"PICK_FILE\" - Attenzione - Il beneficiario selezionato non può essere cancellato perché referenziato - Il conto selezionato non può essere cancellato perché referenziato - La valuta selezionata non può essere cancellata perché referenziata - La categoria selezionata non può essere cancellata perché referenziata - Tutte le transazioni - Ultima settimana - Ultime 2 settimane - Mese corrente - Anno corrente - Visualizzazione Transazioni - Modifiche di Versione - Numero transazione - Money Manager Ex Saldo - Money Manager Ex Conti Correnti - Money Manager Ex Nuova Transazione - Nessuna Operazione Ricorrente - Nessuna - Settimanale - Quindicinale - Mensile - Bimestrale - Trimestrale - Semestrale - Annuale - Quattro Mesi - Quattro Settimane - Quotidiane - In (x) Giorni - In (x) Mesi - Ogni (x) Giorni - Ogni (x) Mese - Inattivo - giorni scaduti! - giorni rimanenti - Nuovo/Modifica Operazione Ricorrente - Prossima Scadenza - Cadenza - Numero di Operazione - Prossima ricorrenza è richiesta - Attiva - Inserire Scadenza Successiva - Ignora Successiva Scadenza - Ci sono delle operazioni ricorrenti scadute - Toccare per controllare la transazione scadute - %1$d operazioni ricorrenti scadute - Invia commenti - Info - Sicurezza - Attivare il passcode - Inserisci il tuo passcode - Reinserisci il nuovo passcode - Passcode non corrispondono - Modifica Passcode - Disattiva Passcode - Inserisci il tuo precedente passcode - passcode non aggiornato - Per le ricerche si può utilizzare il carattere jolly % - Entrate / Uscite: Mese Corrente - Entrate - Uscite - Differenze - Nessun dato da visualizzare - Mese - Anno - Resoconti - Entrate Vs Uscite - Totale - Dall\'inizio - Mese precedente - Ultimi 30 Giorni - Anno precedente - Numero di transazioni trovate: %1$d - Formato data - Anno Finanziario: Giorno Inizio - Anno Finanziario: Mese Inizio - Il database è stato spostati: %1$s - Copia del database su scheda di memoria fallita - Stai utilizzando il database salvato in: %1$s - Transazioni Suddivise - Suddividi - È richiesta almeno una delle transazione suddivisa - Esportare dati in un file CSV - Esportazione dei dati. Attendere prego… - I dati sono stati esportati con successo nel file %1$s - Esportazione file %1$s fallita - MoneyManagerEx for Android è fornito gratuitamente. Se questa applicazione è di vostro gradimento, è possibile supportare il team di sviluppo con una donazione. - Google Play In-App Billing - Dona via Google Play In-App Billing. - Seleziona l\'importo della donazione - Donate - Grazie per la vostra donazione! - Donate - No, grazie - Donate! - Crescente - Decrescente - Ordinamento per mese - La cartella Dropbox/Apps/Money Manager Ex Mobile è vuota. Se utilizzi già MoneyManagerEx copia il database in questa cartella dal vostro computer, e dopo effettua l\'aggiornamento. - Selezionare un file da Dropbox - Ultima modifica - Dropbox - Il database è stato scaricato - Per utilizzare il database scaricato, toccare Apri Database - Toccare per selezionare il file da utilizzare da Dropbox - Download da Dropbox - Tocca per scaricare manualmente il file collegato dalla cartella Dropbox - Upload su Dropbox - Tocca per caricare manualmente il file collegato alla cartella Dropbox - Il database è stato caricato con successo - Dropbox - Money Manager Ex - Come funziona Dropbox per Money Manager Ex\? - Non visualizzare ancora - Apri Database - Intervallo di Sincronizzazione - Quanto spesso devi sincronizzare? - Dalla versione 1.2.0 di Money Manager Ex for Android è cambiata la gestione della sincronizzazione con Dropbox. Per gli utenti che stanno già utilizzando la sincronizzazione con Dropbox, è necessario rifare la configurazione.\nLa configurazione della sincronizzazione con Dropbox e la selezione del database, si trova nelle impostazioni.\nDalla versione 1.2.0 di Money Manager Ex for Android, l\'applicazione è in grado di sincronizzare automaticamente il database con Dropbox. - Upload database immediatamente dopo una modifica - Questa opzione consente di caricare (upload) automaticamente su Dropbox non appena si modifica il database - Visualizza il saldo per ogni transazasione - Visualizza il saldo per ogni transazasione. La visualizzazione del bilancio per transazione potrebbe rendere l\'applicazione più lenta - Apri Database - Suggerimenti - Font Applicazione - Seleziona il font che vuoi dare all\'applicazione - Dimensione Font Applicazione - Seleziona la dimensione del font che vuoi dare all\'applicazione - Micro - Piccolo - Default - Medio - Grande - Download da Dropbox. Attendere prego… - Caricamento su Dropbox. Attendere prego… - Dove va il denaro - Da dove arriva il denaro - Visualizza il saldo di Money Manager Ex for Android - Visualizza il saldo per ogni conto di Money Manager Ex for Android - Pianifica il Controllo delle Operazioni Ricorrenti scadute - Indicare l\'orario del giorno nel quale l\'applicazione controlla se ci sono operazioni ricorrenti scadute (default 08:00) - Ringraziamenti - Top Prelievi: Ultimi 30 giorni - Top Beneficiari: Ultimi 30 giorni - Operazioni Imminenti - Quantità - Dashboard - Il database è aggiornato - Ultimi 3 mesi - Ultimi 6 mesi - Categoria Vuota - Beneficiario Vuoto - Guida - Elimina Operazioni Ricorrenti - Ultimo - Conti - Al Conto - Dal Conto - Stato di Default - Beneficiario di Default - Modifica Transazione - Sei sicuro di che volere eliminare la transazione selezionata? - Sei sicuro di che volere cancellare le %d transazioni selezionate? - Categorie - Valute - Beneficiari - Operazioni Ricorrenti - Holo Light - Nuovo Conto - Importazione Valute - L\'importazione valute. Attendere prego… - Importo maggiore o uguale - Importo minore o uguale - Risultato della tua ricerca - Nuova operazione ricorrente - Modifica Operazione Ricorrente - Ogni 5 minuti - Ogni 15 minuti - Ogni 30 minuti - Ogni ora - Ogni 2 ore - Ogni 6 ore - Ogni 12 ore - Mai - Percorso del database non esiste - Il database non può essere aperto in scrittura - Vuoi importare tutte le valute? - Intervallo di tempo - Visualizza Grafico - Aggiungi Transazione - Benevenuti in MoneyManagerEx! - MoneyManagerEx tratta tutte le transazioni assegnandole a dei conti.\n\nPer aiutarti nella fase iniziale, comincia con l\'annotare l\'elenco di tutti gli istituti finanziari presso i quali intrattieni un conto.\n\nTocca per iniziare a inserire i vostri conti. - Se utilizzi già MoneyManagerEx su Windows, Linux o Mac collegate questa applicazione con Dropbox per sincronizzare il database - Configura Dropbox - Ricerca testo per contenuto e non per l\'inizio del testo - Ricerca beneficiario, categorie, valute, etc… per contenuto e non per l\'inizio del testo - Valuta l\'applicazione - Lingua dell\'Applicazione - Ceco - Inglese - Spagnolo - Francese - Ebraico - Italiano - Portoghese - Portoghese, Brasiliano - Russo - Vietnamita - Cinese Semplificato - Cinese Tradizionale - Aggiornarmento tassi di cambio delle valute. Attendere prego… - Aggiornamento tasso di cambio:\n%1$s - Tutti i tassi di cambio delle valute sono stati aggiornati con successo - Aggiornamento tasso di cambio - Si desidera aggiornare il tasso di cambio? - Prelievo da %1$s - Deposito su %1$s - MoneyManagerEx Website - Hai già sostenuto lo sviluppo di MoneyManagerEx for Android con la vostra donazione! \n\nGrazie mille dal team di sviluppo! - Recupero dello stato delle vostre donazioni da Google Play. Attendere prego… - Non è possibile utilizzare la fatturazione in-app. Verifica se è installata l\'ultima versione dell\'applicazione Play Store. + Money Manager Ex + Una applicazione semplice e facile da usare per gestire finanze personali, conti bancari, budget familiare, etc. + MoneyManagerEx for Android utilizza la libreria di ActionBarSherlock + Licenze open source + Inserimento di dati fallito + Eliminazione di dati fallita + Aggiornamento dei dati fallito + Esci + Gestisci + Collega con Dropbox + Scollega da Dropbox + Sincronizzazione file. Attendere prego… + Download file da Dropbox. Attendere prego… + Upload file su Dropbox. Attendere prego… + File Dropbox + Generale + Look & Feel + Valuta base + Visualizza conti aperti + Se non selezionato visualizza tutti i conti + Visualizza conti preferiti + Versione + Build + Percorso del database + Conto + Elenco dei Conti + Nessun Conto Trovato + Saldo + Saldo Riconciliato + Elimina Conto + Nome account + Tipo di account + Numero conto + Tenuto presso + Stato conto + Conto preferito + Seleziona valuta + Conto Corrente + Conto di Investimento + Conto Deposito a Termine + Errore nell\'inserimento del conto + Errore nell\'aggiornamento del conto + Valuta è richiesta + Saldo iniziale è richiesto + Nome dell\'account è necessario + Tipo di conto è richiesto + Lo stato dell\'account è necessario + Nome beneficiario + Modifica il beneficiario + Elimina Beneficiario + Beneficiario + Seleziona Beneficiario + Nessun Beneficiario Trovato + Da + Aggiornamento beneficiario fallito + Categoria + Sottocategoria + Nessuna Categoria Trovata + Seleziona Categoria + Aggiungi Categoria + Aggiungi Sottocategoria + Modifica categoria + Elimina Categoria + Nome valuta + Simbolo della valuta + Elimina Valuta + Nome dell\'unità + Nome centesimi + Simbolo prefisso + Simbolo suffisso + Separatore decimale + Separatore migliaia + Scala + Tasso Base di Conversione + Nome della valuta è richiesto + Importo + Importo totale + Deposito + Stato + Riconciliata + Nulla + Da Monitorare + Duplicata + Nessuno + Trasferimento + Tipo Transazione + Stato + Prelievo + Inserimento di transazione non riuscito + Aggiornamento transazione non riuscito + Elimina Transazione + Nuova transazione + Beneficiario è richiesto + Account di destino è richiesto + Categoria è richiesta + Importo totale è richiesto + About + Aggiungi + Sei sicuro di che voler eliminare? + Data + Cancella + Scarica + Modifica + Logo + Nuova/Modifica Transazione + Aggiorna + Ricerca + Impostazioni + Riepilogo + Sincronizza + Aperto + Utente + Carica + Nome Utente + Da + Sito Web + Contatto + Informazioni di accesso + Saldo iniziale + Note + Chiuso + Nuovo/Modifica Valuta + Tema + Holo + Holo Light With Dark ActionBar + Chiudere l\'applicazione + Vuoi chiudere l\'applicazione? + Nessuna attività trovato per gestire l\'intent \"PICK_FILE\" + Attenzione + Il beneficiario selezionato non può essere cancellato perché referenziato + Il conto selezionato non può essere cancellato perché referenziato + La valuta selezionata non può essere cancellata perché referenziata + La categoria selezionata non può essere cancellata perché referenziata + Tutte le transazioni + Ultima settimana + Ultime 2 settimane + Mese corrente + Anno corrente + Visualizzazione Transazioni + Modifiche di Versione + Numero transazione + Money Manager Ex Saldo + Money Manager Ex Conti Correnti + Money Manager Ex Nuova Transazione + Nessuna Operazione Ricorrente + Nessuna + Settimanale + Quindicinale + Mensile + Bimestrale + Trimestrale + Semestrale + Annuale + Quattro Mesi + Quattro Settimane + Quotidiane + In (x) Giorni + In (x) Mesi + Ogni (x) Giorni + Ogni (x) Mese + Inattivo + giorni scaduti! + giorni rimanenti + Nuovo/Modifica Operazione Ricorrente + Prossima Scadenza + Cadenza + Numero di Operazione + Prossima ricorrenza è richiesta + Attiva + Inserire Scadenza Successiva + Ignora Successiva Scadenza + Ci sono delle operazioni ricorrenti scadute + Toccare per controllare la transazione scadute + %1$d operazioni ricorrenti scadute + Invia commenti + Info + Sicurezza + Attivare il passcode + Inserisci il tuo passcode + Reinserisci il nuovo passcode + Passcode non corrispondono + Modifica Passcode + Disattiva Passcode + Inserisci il tuo precedente passcode + passcode non aggiornato + Per le ricerche si può utilizzare il carattere jolly % + Entrate / Uscite: Mese Corrente + Entrate + Uscite + Differenze + Nessun dato da visualizzare + Mese + Anno + Resoconti + Entrate Vs Uscite + Totale + Dall\'inizio + Mese precedente + Ultimi 30 Giorni + Anno precedente + Numero di transazioni trovate: %1$d + Formato data + Anno Finanziario: Giorno Inizio + Anno Finanziario: Mese Inizio + Esportazione del database + Il database è stato spostati: %1$s + Copia del database su scheda di memoria fallita + Stai utilizzando il database salvato in: %1$s + Transazioni Suddivise + Suddividi + È richiesta almeno una delle transazione suddivisa + Esportare dati in un file CSV + Esportazione dei dati. Attendere prego… + I dati sono stati esportati con successo nel file %1$s + Esportazione file %1$s fallita + MoneyManagerEx for Android è fornito gratuitamente. Se questa applicazione è di vostro gradimento, è possibile supportare il team di sviluppo con una donazione. + Google Play In-App Billing + Dona via Google Play In-App Billing. + Seleziona l\'importo della donazione + Donate + Grazie per la vostra donazione! + Donate + No, grazie + Donate! + Crescente + Decrescente + Ordinamento per mese + La cartella Dropbox/Apps/Money Manager Ex Mobile è vuota. Se utilizzi già MoneyManagerEx copia il database in questa cartella dal vostro computer, e dopo effettua l\'aggiornamento. + Selezionare un file da Dropbox + Ultima modifica + Dropbox + Il database è stato scaricato + Per utilizzare il database scaricato, toccare Apri Database + Toccare per selezionare il file da utilizzare da Dropbox + Download da Dropbox + Tocca per scaricare manualmente il file collegato dalla cartella Dropbox + Upload su Dropbox + Tocca per caricare manualmente il file collegato alla cartella Dropbox + Il database è stato caricato con successo + Dropbox - Money Manager Ex + Come funziona Dropbox per Money Manager Ex\? + Non visualizzare ancora + Apri Database + Intervallo di Sincronizzazione + Quanto spesso devi sincronizzare? + Dalla versione 1.2.0 di Money Manager Ex for Android è cambiata la gestione della sincronizzazione con Dropbox. Per gli utenti che stanno già utilizzando la sincronizzazione con Dropbox, è necessario rifare la configurazione.\nLa configurazione della sincronizzazione con Dropbox e la selezione del database, si trova nelle impostazioni.\nDalla versione 1.2.0 di Money Manager Ex for Android, l\'applicazione è in grado di sincronizzare automaticamente il database con Dropbox. + Upload database immediatamente dopo una modifica + Questa opzione consente di caricare (upload) automaticamente su Dropbox non appena si modifica il database + Visualizza il saldo per ogni transazasione + Visualizza il saldo per ogni transazasione. La visualizzazione del bilancio per transazione potrebbe rendere l\'applicazione più lenta + Apri Database + Database--> + Suggerimenti + Font Applicazione + Seleziona il font che vuoi dare all\'applicazione + Dimensione Font Applicazione + Seleziona la dimensione del font che vuoi dare all\'applicazione + Micro + Piccolo + Default + Medio + Grande + Download da Dropbox. Attendere prego… + Caricamento su Dropbox. Attendere prego… + Dove va il denaro + Da dove arriva il denaro + Visualizza il saldo di Money Manager Ex for Android + Visualizza il saldo per ogni conto di Money Manager Ex for Android + Orario di Controllo + A che ora vuoi controllare se ci sono le transazioni ripetute in ritardo? (impostazione predefinita 08.00) + Ringraziamenti + Top Prelievi: Ultimi 30 giorni + Top Beneficiari: Ultimi 30 giorni + Operazioni Imminenti + Quantità + Dashboard + Il database è aggiornato + Ultimi 3 mesi + Ultimi 6 mesi + Categoria Vuota + Beneficiario Vuoto + Guida + Elimina Operazioni Ricorrenti + Ultimo + Conti + Al Conto + Dal Conto + Stato di Default + Beneficiario di Default + Modifica Transazione + Sei sicuro di che volere eliminare la transazione selezionata? + Sei sicuro di che volere cancellare le %d transazioni selezionate? + Categorie + Valute + Beneficiari + Operazioni Ricorrenti + Holo Light + Nuovo Conto + Importazione Valute + L\'importazione valute. Attendere prego… + Importo maggiore o uguale + Importo minore o uguale + Risultato della tua ricerca + Nuova operazione ricorrente + Modifica Operazione Ricorrente + Ogni 5 minuti + Ogni 15 minuti + Ogni 30 minuti + Ogni ora + Ogni 2 ore + Ogni 6 ore + Ogni 12 ore + Mai + Percorso del database non esiste + Il database non può essere aperto in scrittura + Vuoi importare tutte le valute? + Intervallo di tempo + Visualizza Grafico + Aggiungi Transazione + Benevenuti in MoneyManagerEx! + MoneyManagerEx tratta tutte le transazioni assegnandole a dei conti.\n\nPer aiutarti nella fase iniziale, comincia con l\'annotare l\'elenco di tutti gli istituti finanziari presso i quali intrattieni un conto.\n\nTocca per iniziare a inserire i vostri conti. + Se utilizzi già MoneyManagerEx su Windows, Linux o Mac collegate questa applicazione con Dropbox per sincronizzare il database + Configura Dropbox + Ricerca testo per contenuto e non per l\'inizio del testo + Ricerca beneficiario, categorie, valute, etc… per contenuto e non per l\'inizio del testo + Valuta l\'applicazione + Lingua dell\'applicazione + Ceco + Inglese + Spagnolo + Francese + Ebraico + Italiano + Portoghese + Portoghese, Brasiliano + Russo + Vietnamita + Cinese Semplificato + Cinese Tradizionale + Aggiornarmento tassi di cambio delle valute. Attendere prego… + Aggiornamento tasso di cambio:\n%1$s + Tutti i tassi di cambio delle valute sono stati aggiornati con successo + Aggiornamento tasso di cambio + Si desidera aggiornare il tasso di cambio? + Prelievo da %1$s + Deposito su %1$s + MoneyManagerEx Website + Hai già sostenuto lo sviluppo di MoneyManagerEx for Android con la vostra donazione! \n\nGrazie mille dal team di sviluppo! + Recupero dello stato delle vostre donazioni da Google Play. Attendere prego… + Non è possibile utilizzare la fatturazione in-app. Verifica se è installata l\'ultima versione dell\'applicazione Play Store. + Notifica Operazioni Riccorenti scadute + Visualizza notifica per le operazioni riccorenti scadute diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index f06a6d7177..ebfb48bf05 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -1,343 +1,355 @@ - - + - Prosta i łatwa w użyciu aplikacja do zarządzania osobistymi wydatkami, kontami bankowymi, rodzinnym budżetem itp. - Android Money Manager Ex korzysta z bibliotek ActionBarSherlock i RobotMediaBilling - Licencje open source - Dodanie danych nie powiodło się - Usunięcie danych nie powiodło się - Aktualizacja danych nie powiodła się - Zakończ - Zarządzaj - Połącz z Dropboxem - Odłącz od Dropboxa - Synchronizacja pliku. Proszę czekać… - Pobieranie pliku z Dropboxa. Proszę czekać… - Przesyłanie pliku do Dropboxa. Proszę czekać… - Plik Dropboksa - Ogólne - Wygląd - Podstawowa waluta - Pokazuj otwarte konta - Jeśli niezaznaczone, pokazuje wszystkie konta - Pokazuj ulubione konta - Wersja - Kompilacja - Konto - Lista kont - Nie znaleziono kont - Saldo konta - Uzgodnione saldo - Usuń konto - Nazwa konta - Typ konta - Numer konta - Założone w dniu - Status konta - Ulubione konto - Wybierz walutę - Rozliczeniowe - Inwestycyjne - Cuenta depósito a plazo - Błąd przy dodawaniu konta - Błąd przy aktualizowaniu konta - Waluta jest wymagana - Początkowe saldo konta jest wymagane - Nazwa konta jest wymagana - Typ konta jest wymagany - Status konta jest wymagany - Nazwa podmiotu - Edytuj podmiot - Usuń podmiot - Podmiot - Wybierz podmiot - No znaleziono podmiotów - Z - Aktualizacja podmiotu nie powiodła się - Kategoria - Podkategoria - Nie znaleziono kategorii - Wybierz kategorię - Dodaj kategorię - Dodaj podkategorię - Edytuj kategorię - Usuń kategorię - Nazwa waluty - Symbol waluty - Usuń walutę - Nazwa jednostki - Nazwa podjednostki - Prefiks waluty - Sufiks waluty - Separator dziesiętny - Separator tysięcy - Skala - Kurs wymiany - Nazwa waluty jest wymagana - Kwota - Łączna kwota - Wpłata - Status - Uzgodniona - Nieważna - Monitorowana - Zduplikowana - Brak - Przelew - Typ transakcji - Status - Wydatek - Dodanie transakcji nie powiodło się - Aktualizacja transakcji nie powiodła się - Usuń transakcję - Nowa transakcja - Podmiot jest wymagany - Konto docelowe jest wymagane - Kategoria jest wymagana - Całkowita kwota jest wymagana - O aplikacji - Dodaj - Czy na pewno chcesz usunąć? - Data - Usuń - Pobierz - Edytuj - Logo - Tworzenie/edycja transakcji - Odśwież - Szukaj - Ustawienia - Podsumowanie - Synchronizuj - Otwórz - Użytkownik - Wyślij - Nazwa użytkownika - Do - Strona internetowa - Kontakt - Informacje dostępowe - Saldo początkowe - Notatki - Zamknięty - Tworzenie/edycja waluty - Skórka - Holo Light z ciemnym paskiem akcji - Zamknij aplikację - Czy na pewno chcesz zamknąć aplikację? - Nie znaleziono aplikacji do obsługi żądania wybrania pliku - Uwaga - Wybrany podmiot nie może zostać usunięty, ponieważ istnieją odwołania do niego - Wybrane konto nie może zostać usunięte, ponieważ istnieją odwołania do niego - Wybrana waluta nie może zostać usunięta, ponieważ istnieją odwołania do niej - Wybrana kategoria nie może zostać usunięta, ponieważ istnieją odwołania do niej - Wszystkie transakcje - Z ostatnich 7 dni - Z ostatnich 2 tygodni - Bieżący miesiąc - Bieżący rok - Pokazuj transakcje - Lista zmian - Numer transakcji - Money Manager Ex Podsumowanie - Money Manager Ex Wszystkie konta - Money Manager Ex Dodaj transakcję - Brak regularnych transakcji - Brak - Co tydzień - Co dwa tygodnie - Co miesiąc - Co dwa miesiące - Co kwartał - Co pół roku - Co rok - Co cztery miesiące - Co cztery tygodnie - Codziennie - Za (x) dni - Za (x) miesięcy - Co (x) dni - Co (x) miesięcy - Nieaktywna - dni opóźnienia! - dni pozostało - Tworzenie/edycja regularnej transakcji - Najbliższe wystąpienie - Powtarzaj - Liczba potwórzeń - Następne wystąpienie jest wymagane - Aktywuj - Wprowadź najbliższe wystąpienie - Pomiń najbliższe wystąpienie - Istnieją regularne transakcje, które straciły ważność - Dotknij, aby sprawdzić zaległe transakcje - %1$d zaległych regularnych transakcji - Prześlij opinię - Informacje - Bezpieczeństwo - Aktywuj hasło - Wprowadź kod dostępu - Wprowadź ponownie nowe hasło - Hasła nie zgadzają się - Zmień kod dostępu - Dezaktywuj kod dostępu - Wprowadź poprzedni kod dostępu - Kod dostępu nie został zaktualizowany - Do wyszukiwania można użyć wieloznacznego symbolu % - Przychody a wydatki: bieżący miesiąc - Przychód - Wydatki - Różnica - Brak danych do wyświetlenia - Miesiąc - Bieżący rok - Raporty - Przychody a wydatki - Łącznie - Wszystko - Poprzedni miesiąc - Ostatnie 30 dni - Poprzedni rok - Liczba znalezionych transakcji: %1$d - Format daty - Rok finansowy: początkowy dzień - Rok finansowy: początkowy miesiąc - Baza danych została przeniesiona: %1$s - Kopiowanie bazy danych na zewnętrzny nośnik nie powiodło się - Używasz bazy danych zapisanej w: %1$s - Podziel transakcję - Podziel - Wymagany jest przynajmniej jeden element podzielonej transakcji - Eksportuj dane do pliku CSV - Eksportowanie danych. Prosze czekać… - Dane zostały pomyślnie wyeksportowane do pliku %1$s - Eksport do pliku %1$s nie powiódł się - Android Money Manager Ex jest dostępny za darmo. Jeśli podoba się ta aplikacja, możesz wesprzeć zespół twórców finansowo. - Wesprzyj przy pomocy Google Play In-App Billing. - Wybierz kwotę wsparcia - Wesprzyj - Dziękujemy za wsparcie! - Wesprzyj - Nie, dziękuję - Wesprzyj! - Rosnąco - Malejąco - Sortowanie miesięcy - Katalog Dropbox/Apps/Money Manager Ex Mobile jest pusty. Jeśli wcześniej używałeś MoneyManagerEx, skopiuj bazę danych do tego katalogu, a następnie odśwież. - Wybierz plik z Dropboksa - Ostatnia modyfikacja - Baza danych została pobrana - Aby użyć pobranej bazy danych, dotknij przycisku \"Otwórz bazę danych\" - Dotknij, aby wybrać plik do użycia z Dropboksa - Pobierz z Dropboksa - Dotknij, aby ręcznie pobrać połączony plik z katalogu Dropboksa - Prześlij do Dropboksa - Dotknij, aby ręcznie przesłać połączony plik do katalogu Dropboksa - Baza danych została pomyślnie przesłana - Jak działa Dropbox w aplikacji Money Manager Ex\? - Nie pokazuj ponownie - Otwórz bazę danych - Interwał synchronizacji - Jak często synchronizować? - Od wersji 1.2.0 Money Manager Ex dla Androida zmienił sposób zarządzania synchronizacją z Dropboxem. Użytkownicy, którzy używali wcześniej synchronizacji z Dropboxem, muszą ponownie przeprowadzić konfigurację.\nKonfiguracja synchronizacji z Dropboxem jest dostępna w ustawieniach.\nOd wersji 1.2.0 Money Manager Ex dla Androida może automatycznie synchronizować bazę danych z Dropboxem. - Prześlij bazę danych przy każdej zmianie - Ta opcja pozwala na automatyczne przesłanie bazy danych za każdym razem, gdy zostanie ona zmieniona - Pokazuj saldo każdej transakcji - Wyświetla saldo dla każdej transakcji. Włączenie tej opcji może spowolnić działanie aplikacji - Otwórz bazę danych - Wskazówki - Czcionka - Wybierz czcionkę używaną w całej aplikacji - Rozmiar czcionki - Wybierz rozmiar czcionki używany w całej aplikacji - Bardzo mały - Mały - Domyślnie - Średni - Duży - Pobieranie danych z Dropboksa. Proszę czekać… - Przesyłanie danych do Dropboksa. Proszę czekać… - Cele wydatków - Źródła przychodów - Wyświetlanie podsumowanie Money Manager Ex dla Androida - Pokaż podsumowanie każdego konta w Money Manager Ex dla Androida - Harmonogram sprawdzania zaległych transakcji - Ustaw, o której godzinie aplikacja będzie sprawdzać, czy istnieją zaległe regularne transakcje (domyślnie 08:00) - Twórcy - Największe wypłaty: ostatnie 30 dni - Główne podmioty: ostatnie 30 dni - Nadchodzące transakcje - Ilość - Panel - Baza danych nie jest zsynchronizowana - Ostatnie 3 miesiące - Ostatnie 6 miesięcy - Pusta kategoria - Pusty podmiot - Pomoc - Usuń regularną transakcję - Ostatnie - Konta - Konto docelowe - Konto źródłowe - Domyślny status - Domyślny podmiot - Edycja transakcji - Czy na pewno chcesz usunąć wybraną transakcję? - Czy na pewno chcesz usunąć %d wybranych transakcji? - Kategorie - Waluty - Podmioty - Regularne transakcje - Holo Light - Tworzenie konta - Importuj waluty - Importowanie walut. Proszę czekać… - Kwota większa lub równa - Kwota mniejsza lub równa - Rezultat wyszukiwania - Tworzenie regularnej transakcji - Edycja regularnej transakcji - Co 5 minut - Co 15 minut - Co 30 minut - Co godzinę - Co 2 godziny - Co 6 godzin - Co 12 godzin - Nigdy - Ścieżka do bazy danych nie istnieje - Nie można otworzyć bazy danych do zapisu - Czy chcesz zaimportować walutę? - Przedział czasowy - Pokaż wykres - Dodaj transakcję - Witaj w Money Manager Ex! - Money Manager Ex modeluje wszystkie transakcje jako należące do kont.\n\nAby rozpocząć korzystanie z aplikacji, utwórz listę wszystkich instytucji finansowych, w których posiadasz konto.\n\nKliknij tutaj, aby rozpocząć wprowadzenie swoich kont. - Jeśli używasz już aplikacji Moneye Manager Ex dla systemu Windows, Linux lub Mac OS, połącz tę aplikację z Dropboxem, aby sychronizować swoją bazę danych - Konfiguracja Dropbox - Wyszukiwanie w zawartości tekstów, a nie w ich początkach - Wyszukuj w całych nazwach płatników, kategorii, walut itd., a nie tylko w ich początkach - Oceń aplikację - Język aplikacji - Czeski - Angielski - Hiszpański - Francuski - Hebrajski - Włoski - Portugalski - Portugalski, Brazylia - Rosyjski - Wietnamski - Chiński uproszczony - Chiński tradycyjny - Aktualizowanie kursów wymiany walut. Proszę czekać… - Aktualizowanie kursu wymiany waluty:\n%1$s - Wszystkie kursy wymiany walut zostały pomyślnie zaktualizowane - Zaktualizuj kurs wymiany - Czy chcesz zaktualizować kursy wymiany walut? - Wypłata z %1$s - Wpłata na %1$s - Strona internetowa MoneyManagerEx + Money Manager Ex + Prosta i łatwa w użyciu aplikacja do zarządzania osobistymi wydatkami, kontami bankowymi, rodzinnym budżetem itp. + MoneyManagerEx for Android Project uses ActionBarSherlock library + Licencje open source + Dodanie danych nie powiodło się + Usunięcie danych nie powiodło się + Aktualizacja danych nie powiodła się + Zakończ + Zarządzaj + Połącz z Dropboxem + Odłącz od Dropboxa + Synchronizacja pliku. Proszę czekać… + Pobieranie pliku z Dropboxa. Proszę czekać… + Przesyłanie pliku do Dropboxa. Proszę czekać… + Plik Dropboksa + Ogólne + Look & Feel + Podstawowa waluta + Pokazuj otwarte konta + Jeśli niezaznaczone, pokazuje wszystkie konta + Pokazuj ulubione konta + Wersja + Kompilacja + Database path + Konto + Lista kont + Nie znaleziono kont + Saldo konta + Uzgodnione saldo + Usuń konto + Nazwa konta + Typ konta + Numer konta + Założone w dniu + Status konta + Ulubione konto + Wybierz walutę + Rozliczeniowe + Inwestycyjne + Cuenta depósito a plazo + Błąd przy dodawaniu konta + Błąd przy aktualizowaniu konta + Waluta jest wymagana + Początkowe saldo konta jest wymagane + Nazwa konta jest wymagana + Typ konta jest wymagany + Status konta jest wymagany + Nazwa podmiotu + Edytuj podmiot + Usuń podmiot + Podmiot + Wybierz podmiot + No znaleziono podmiotów + Z + Aktualizacja podmiotu nie powiodła się + Kategoria + Podkategoria + Nie znaleziono kategorii + Wybierz kategorię + Dodaj kategorię + Dodaj podkategorię + Edytuj kategorię + Usuń kategorię + Nazwa waluty + Symbol waluty + Usuń walutę + Nazwa jednostki + Nazwa podjednostki + Prefiks waluty + Sufiks waluty + Separator dziesiętny + Separator tysięcy + Skala + Kurs wymiany + Nazwa waluty jest wymagana + Kwota + Łączna kwota + Wpłata + Status + Uzgodniona + Nieważna + Monitorowana + Zduplikowana + Brak + Przelew + Typ transakcji + Status + Wydatek + Dodanie transakcji nie powiodło się + Aktualizacja transakcji nie powiodła się + Usuń transakcję + Nowa transakcja + Podmiot jest wymagany + Konto docelowe jest wymagane + Kategoria jest wymagana + Całkowita kwota jest wymagana + O aplikacji + Dodaj + Czy na pewno chcesz usunąć? + Data + Usuń + Pobierz + Edytuj + Logo + Tworzenie/edycja transakcji + Odśwież + Szukaj + Ustawienia + Podsumowanie + Synchronizuj + Otwórz + Użytkownik + Wyślij + Nazwa użytkownika + Do + Strona internetowa + Kontakt + Informacje dostępowe + Saldo początkowe + Notatki + Zamknięty + Tworzenie/edycja waluty + Theme + Holo + Holo Light z ciemnym paskiem akcji + Zamknij aplikację + Czy na pewno chcesz zamknąć aplikację? + Nie znaleziono aplikacji do obsługi żądania wybrania pliku + Uwaga + Wybrany podmiot nie może zostać usunięty, ponieważ istnieją odwołania do niego + Wybrane konto nie może zostać usunięte, ponieważ istnieją odwołania do niego + Wybrana waluta nie może zostać usunięta, ponieważ istnieją odwołania do niej + Wybrana kategoria nie może zostać usunięta, ponieważ istnieją odwołania do niej + Wszystkie transakcje + Z ostatnich 7 dni + Z ostatnich 2 tygodni + Bieżący miesiąc + Bieżący rok + Pokazuj transakcje + Lista zmian + Numer transakcji + Money Manager Ex Podsumowanie + Money Manager Ex Wszystkie konta + Money Manager Ex Dodaj transakcję + Brak regularnych transakcji + Brak + Co tydzień + Co dwa tygodnie + Co miesiąc + Co dwa miesiące + Co kwartał + Co pół roku + Co rok + Co cztery miesiące + Co cztery tygodnie + Codziennie + Za (x) dni + Za (x) miesięcy + Co (x) dni + Co (x) miesięcy + Nieaktywna + dni opóźnienia! + dni pozostało + Tworzenie/edycja regularnej transakcji + Najbliższe wystąpienie + Powtarzaj + Liczba potwórzeń + Następne wystąpienie jest wymagane + Aktywuj + Wprowadź najbliższe wystąpienie + Pomiń najbliższe wystąpienie + Istnieją regularne transakcje, które straciły ważność + Dotknij, aby sprawdzić zaległe transakcje + %1$d zaległych regularnych transakcji + Prześlij opinię + Informacje + Bezpieczeństwo + Aktywuj hasło + Wprowadź kod dostępu + Wprowadź ponownie nowe hasło + Hasła nie zgadzają się + Zmień kod dostępu + Dezaktywuj kod dostępu + Wprowadź poprzedni kod dostępu + Kod dostępu nie został zaktualizowany + Do wyszukiwania można użyć wieloznacznego symbolu % + Przychody a wydatki: bieżący miesiąc + Przychód + Wydatki + Różnica + Brak danych do wyświetlenia + Miesiąc + Bieżący rok + Raporty + Przychody a wydatki + Łącznie + Wszystko + Poprzedni miesiąc + Ostatnie 30 dni + Poprzedni rok + Liczba znalezionych transakcji: %1$d + Format daty + Rok finansowy: początkowy dzień + Rok finansowy: początkowy miesiąc + Export database + Baza danych została przeniesiona: %1$s + Kopiowanie bazy danych na zewnętrzny nośnik nie powiodło się + Używasz bazy danych zapisanej w: %1$s + Podziel transakcję + Podziel + Wymagany jest przynajmniej jeden element podzielonej transakcji + Eksportuj dane do pliku CSV + Eksportowanie danych. Prosze czekać… + Dane zostały pomyślnie wyeksportowane do pliku %1$s + Eksport do pliku %1$s nie powiódł się + MoneyManagerEx for Android is provided free. If this application is to your liking, you can support the development team with a donation. + Google Play In-App Billing + Wesprzyj przy pomocy Google Play In-App Billing. + Wybierz kwotę wsparcia + Wesprzyj + Dziękujemy za wsparcie! + Wesprzyj + Nie, dziękuję + Wesprzyj! + Rosnąco + Malejąco + Sortowanie miesięcy + Katalog Dropbox/Apps/Money Manager Ex Mobile jest pusty. Jeśli wcześniej używałeś MoneyManagerEx, skopiuj bazę danych do tego katalogu, a następnie odśwież. + Wybierz plik z Dropboksa + Ostatnia modyfikacja + Dropbox + Baza danych została pobrana + Aby użyć pobranej bazy danych, dotknij przycisku \"Otwórz bazę danych\" + Dotknij, aby wybrać plik do użycia z Dropboksa + Pobierz z Dropboksa + Dotknij, aby ręcznie pobrać połączony plik z katalogu Dropboksa + Prześlij do Dropboksa + Dotknij, aby ręcznie przesłać połączony plik do katalogu Dropboksa + Baza danych została pomyślnie przesłana + Dropbox - Money Manager Ex + Jak działa Dropbox w aplikacji Money Manager Ex\? + Nie pokazuj ponownie + Otwórz bazę danych + Interwał synchronizacji + Jak często synchronizować? + Od wersji 1.2.0 Money Manager Ex dla Androida zmienił sposób zarządzania synchronizacją z Dropboxem. Użytkownicy, którzy używali wcześniej synchronizacji z Dropboxem, muszą ponownie przeprowadzić konfigurację.\nKonfiguracja synchronizacji z Dropboxem jest dostępna w ustawieniach.\nOd wersji 1.2.0 Money Manager Ex dla Androida może automatycznie synchronizować bazę danych z Dropboxem. + Prześlij bazę danych przy każdej zmianie + Ta opcja pozwala na automatyczne przesłanie bazy danych za każdym razem, gdy zostanie ona zmieniona + Pokazuj saldo każdej transakcji + Wyświetla saldo dla każdej transakcji. Włączenie tej opcji może spowolnić działanie aplikacji + Otwórz bazę danych + Database--> + Wskazówki + Czcionka + Wybierz czcionkę używaną w całej aplikacji + Rozmiar czcionki + Wybierz rozmiar czcionki używany w całej aplikacji + Bardzo mały + Mały + Domyślnie + Średni + Duży + Pobieranie danych z Dropboksa. Proszę czekać… + Przesyłanie danych do Dropboksa. Proszę czekać… + Cele wydatków + Źródła przychodów + Wyświetlanie podsumowanie Money Manager Ex dla Androida + Pokaż podsumowanie każdego konta w Money Manager Ex dla Androida + Check time + What time would you check if there are repeating transactions overdue? (default 08:00) + Twórcy + Największe wypłaty: ostatnie 30 dni + Główne podmioty: ostatnie 30 dni + Nadchodzące transakcje + Ilość + Panel + The database is up to date + Ostatnie 3 miesiące + Ostatnie 6 miesięcy + Pusta kategoria + Pusty podmiot + Pomoc + Usuń regularną transakcję + Ostatnie + Konta + Konto docelowe + Konto źródłowe + Domyślny status + Domyślny podmiot + Edycja transakcji + Czy na pewno chcesz usunąć wybraną transakcję? + Czy na pewno chcesz usunąć %d wybranych transakcji? + Kategorie + Waluty + Podmioty + Regularne transakcje + Holo Light + Tworzenie konta + Importuj waluty + Importowanie walut. Proszę czekać… + Kwota większa lub równa + Kwota mniejsza lub równa + Rezultat wyszukiwania + Tworzenie regularnej transakcji + Edycja regularnej transakcji + Co 5 minut + Co 15 minut + Co 30 minut + Co godzinę + Co 2 godziny + Co 6 godzin + Co 12 godzin + Nigdy + Ścieżka do bazy danych nie istnieje + Nie można otworzyć bazy danych do zapisu + Czy chcesz zaimportować walutę? + Przedział czasowy + Pokaż wykres + Dodaj transakcję + Witaj w Money Manager Ex! + Money Manager Ex modeluje wszystkie transakcje jako należące do kont.\n\nAby rozpocząć korzystanie z aplikacji, utwórz listę wszystkich instytucji finansowych, w których posiadasz konto.\n\nKliknij tutaj, aby rozpocząć wprowadzenie swoich kont. + Jeśli używasz już aplikacji Moneye Manager Ex dla systemu Windows, Linux lub Mac OS, połącz tę aplikację z Dropboxem, aby sychronizować swoją bazę danych + Konfiguracja Dropbox + Wyszukiwanie w zawartości tekstów, a nie w ich początkach + Wyszukuj w całych nazwach płatników, kategorii, walut itd., a nie tylko w ich początkach + Oceń aplikację + Application Language + Czeski + Angielski + Hiszpański + Francuski + Hebrajski + Włoski + Portugalski + Portugalski, Brazylia + Rosyjski + Wietnamski + Chiński uproszczony + Chiński tradycyjny + Aktualizowanie kursów wymiany walut. Proszę czekać… + Aktualizowanie kursu wymiany waluty:\n%1$s + Wszystkie kursy wymiany walut zostały pomyślnie zaktualizowane + Zaktualizuj kurs wymiany + Czy chcesz zaktualizować kursy wymiany walut? + Wypłata z %1$s + Wpłata na %1$s + Strona internetowa MoneyManagerEx + You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! + Retrieving status of your donations from Google Play. Please wait… + Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. + Notification Repeating Transaction overdue + Show notification for repeating transaction overdue diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 3eb382a854..285e01689a 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -1,343 +1,355 @@ - - + - Uma aplicação simples e fácil de usar para gerir finanças pessoais, contas bancárias, orçamento familiar, entre outros. - O Projecto Android Money Manager Ex usa as bibliotecas ActionBarSherlock e RobotMediaBilling - Licenças de Código Aberto - Inserção de dados falhou - Exclusão de dados falhou - Actualização de dados falhou - Sair - Gerir - Ligar à Dropbox - Desligar da Dropbox - A sincronizar ficheiro. Aguarde... - Transferindo ficheiros do Dropbox. Aguarde... - Upload do ficheiro para o Dropbox. Aguarde... - Ficheiro Dropbox - Geral - Visualização - Moeda Padrão - Mostra só contas activas - Se não for seleccionado irão aparecer todas as contas. - Mostrar só contas favoritas - Versão - Build - Conta - Lista de Contas - Nenhuma conta encontrada - Saldo - Saldo Reconciliado - Eliminar conta - Nome da conta - Tipo de conta - Nº da conta - Mantida no(a) - Estado da conta - Conta favorita - Escolher Moeda - Ordem - Investimento - Prazo - Erro ao adicionar conta - Erro ao actualizar conta - Moeda é necessária - Saldo inicial da conta é necessário - Nome da conta é necessário - Tipo de conta é necessário - Estado da conta é necessário - Nome do beneficiário - Editar o beneficiário - Eliminar Entidade - Entidades - Escolher entidade - Nenhuma entidade encontrada - De - Actualização do beneficiário falhou - Categorias - Subcategoria - Nenhuma categoria encontrada - Escolher Categoria - Adicionar Categoria - Adicionar subcategoria - Editar Categoria - Eliminar categoria - Nome da moeda - Símbolo da Moeda - Eliminar Moeda - Nome da unidade - Nome de Cêntimos - Símbolo do Prefixo - Símbolo do Sufixo - Separador decimal - Símbolo Grupo - Escala - Conversão - Nome da moeda é necessário - Montante - Quantia Total - Depósito - Estado - Activo - Inactivo - Dar seguimento - Duplicado - Nenhum - Transferência - Tipo de movimento - Estado - Levantamento - Inserção da transação falhou - Actualização da transacção falhou - Eliminar movimento - Nova transacção - Beneficiário é necessário - Para a Conta é necessário - Categoria é necessária - Montante total é necessário - Sobre - Adicionar - Tem certeza que deseja excluir? - Data - Eliminar - Descarregar - Editar - Logotipo - Novo/Editar Movimento - Atualizar - Procurar - Definições - Resumo - Sincronizar - Aberta - Utilizador - Carregar - Nome do Utilizador - Para - Website - Contacto - Informação de Acesso - Saldo inicial - Notas - Fechada - Nova/Editar Moeda - Tema - Holo claro com ActionBar escuro - Fechar aplicação - Deseja fechar a aplicação? - Nenhuma atividade encontrada para lidar com intenção escolher ficheiro - Atenção - O beneficiário selecionado não pode ser excluído porque está referenciado - A conta selecionada não pode ser excluída porque está referenciada - A moeda selecionada não pode ser excluída porque está referenciada - A categoria selecionada não pode ser excluída porque está referenciada - Todas as Transacções - Últimos 7 dias - Últimas 2 semanas - Mês actual - Ano actual - Mostrar movimentos - Registo de Alterações - Nº da Transacção - Resumo do Money Manager Ex - Money Manager Ex Todas as contas - Adicionar Movimento no Money Manager Ex - Esvaziar Movimentos Agendados - Nenhum - Semanal - Quinzenal - Mensal - 2 em 2 Meses - 4 em 4 Meses - 6 em 6 meses - Anual - 4 Meses - 4 Semanas - Diário - Em (x) Dia(s) - Em (x) Mes(es) - Cada (x) Dia(s) - Cada (x) Mes(es) - Desactivado - dia(s) de atraso - dia(s) restante(s) - Novo/Editar Movimento Agendado - Próxima ocorrência - Repetição - Nº de Vezes Repetidas - Próxima ocorrência é necessária - Activar - Introduzir Próxima Ocorrência - Saltar Próxima Ocorrência - Existem movimentos agendados em atraso - Toque para marcar a transação como atrasada - %1$d transacções agendadas em atraso - Envie Comentários - Info - Segurança - Activar senha - Introduza o Código de Acesso - Re-digite a senha nova - Senhas não correspondem - Editar Código de Acesso - Desactivar Código de Acesso - Indique o Código de Acesso anterior - Código de Acesso não foi actualizado - Quando pesquisar pode utilizar o caracter \"%\" - Receitas vs Despesas: Mês actual - Receitas - Despesa - Diferença - Sem dados para apresentar - Mês - Ano - Relatórios - Receitas vs Despesas - Total - Desde sempre - Mês anterior - Últimos 30 Dias - Ano Anterior - Nº de movimentos econtrados: %1$d - Formato de data - Ano financeiro: Dia de início - Ano financeiro: Mês de inicio - A Base de dados foi movida: %1$s - Falha na cópia da Base de dados para a memória externa - Está a utilizar a base de dados gravada em: %1$s - Dividir Movimento - Dividir - Pelo menos um das transações da divisão é necessária - Exportar dados para ficheiro CSV - Exportação de dados. Aguarde... - Os dados foram exportados com êxito para o ficheiro %1$s - Ficheiro %1$s falhou a exportação - O Android Money Manager Ex é fornecido gratuitamente. Se considera esta aplicação útil, apoie a equipa de desenvolvimento com uma pequena doação. - Doar via Google Play Pagamento na aplicação. - Escolha o montante do donativo - Doar - Obrigado pelo donativo! - Doar - Não, obrigado - Doar! - Ascendente - Descendente - Ordenação dos meses - A pasta em Dropbox/Apps/Money Manager Ex Mobile está vazia. Se você já usa MoneyManagerEx copie o seu banco de dados para essa pasta no seu computador, e depois faça a atualizaçao. - Selecione um ficheiro do Dropbox - Última modificação - A sua base de dados foi descarregada - Para usar a base de dados descarregada, toque em Abrir base de dados - Toque para seleccionar o ficheiro a ser usado do Dropbox - Download do Dropbox - Toque para descarregar manualmente o ficheiro da pasta Dropbox - Enviar para o Dropbox - Toque para carregar manualmente o ficheiro para a pasta Dropbox - A sua base de dados foi enviada com sucesso - Como funciona o Dropbox para o Money Manager Ex\? - Não mostrar novamente - Abrir Base de Dados - Intervalo de Sincronização - Quantas vezes deve sincronizar? - A partir da versão 1.2.0 do Ex Money Manager para Android mudou a gestão da sincronização com a Dropbox. Para os utilizadores que já estão a usar a sincronização com a Dropbox, devem refazer a configuração. \ A configuração de sincronização e a seleção da base de dados na Dropbox, que está localizado nas configurações. \ Na versão 1.2.0 do Money Manager Ex para Android pode sincronizar automaticamente a base de dados com Dropbox - Carregar a Base de dados após modificações - Esta opção permite carregar a Base de dados automáticamente logo que faça modificações de dados - Mostrar o saldo de cada movimento - Mostrar o saldo de cada movimento poderá tornar a aplicação mais lenta. - Abrir Base de Dados - Dicas - Tipo de Letra - Escolha o tipo de letra que deseja atribuir à aplicação - Tamanho de Letra - Escolha o tamanho de letra que deseja atribuir à aplicação - Micro - Pequena - Padrão - Média - Grande - Download do Dropbox. Aguarde... - Enviando para o Dropbox. Aguarde... - Despesas - Receitas - Mostrar Resumo do Money Manager Ex - Mostrar Resumo de cada Conta do Money Manager Ex - Verificar a repetição de transações em atraso - Indicar a hora do dia que o aplicativo deve verificar se há repetição de transações em atraso (padrão 08:00) - Créditos - Principais Levantamentos: Últimos 30 dias - Principais Entidades: Últimos 30 dias - Transações futuras - Quantidade - Painel de controle - O banco de dados está sincronizado - Últimos 3 meses - Últimos 6 meses - Categoria vazia - Beneficiário vazio - Ajuda - Apagar repetir o movimento - Último - Contas - Para a conta - Da Conta - Status padrão - Beneficiário padrão - Editar transação - Tem certeza que deseja excluir a transacção selecionada? - Tem certeza que deseja excluir as %d transações seleccionadas? - Categorias - Moedas - Beneficiários - Movimentos Agendados - Holo claro - Nova conta - Importar Moedas - Importação de moedas. Aguarde... - Valor maior ou igual - Valor menor ou igual - Resultado da pesquisa - Nova transação agendada - Editar transação agendada - Cada 5 minutos - A cada 15 minutos - Cada 30 minutos - Cada hora - Cada 2 horas - Cada 6 horas - Cada 12 horas - Nunca - Caminho da base de dados não existe - A base de dados não pode ser aberta para gravação - Deseja importar a moeda? - Período de tempo - Mostrar gráfico - Adicionar Transacção - Bem vindo ao MoneyManagerEx - O MoneyManagerEx modela todas as transacções como pertencentes a uma conta.\n\nPara o ajudar a iniciar, comece por fazer uma lista de todos os bancos onde tem uma conta.\n\nClique aqui para inserir as suas contas. - Se já usa o MoneyManagerEx no Windows , Linux ou Mac, ligue esta aplicação com o Dropbox para sincronizar a sua base de dados - Configurar o Dropbox - Pesquisar no conteúdo do texto e não por texto a começar por - Pesquisar beneficiários, categorias, moedas, etc... pelo conteúdo e não pelos caracteres iniciais - Avaliar aplicação - Liguagem da Aplicação - Czech - inglês - Spanish - French - Hebrew - Italian - Português - Português, Brasil - Russian - Vietnamese - Chinese Simplified - Chinese Traditional - Actualização das taxas de câmbio das moedas. Aguarde... - Actualizando a taxa de câmbio:\n%1$s - Todas as taxas de câmbio das moedas foram actualizadas com sucesso - Atualização da taxa de câmbio - Deseja actualizar a taxa de câmbio? - Levantamentos de %1$s - Depósito para %1$s - Site do MoneyManager + Money Manager Ex + Uma aplicação simples e fácil de usar para gerir finanças pessoais, contas bancárias, orçamento familiar, entre outros. + MoneyManagerEx for Android Project uses ActionBarSherlock library + Licenças de Código Aberto + Inserção de dados falhou + Exclusão de dados falhou + Actualização de dados falhou + Sair + Gerir + Ligar à Dropbox + Desligar da Dropbox + A sincronizar ficheiro. Aguarde... + Transferindo ficheiros do Dropbox. Aguarde... + Upload do ficheiro para o Dropbox. Aguarde... + Ficheiro Dropbox + Geral + Look & Feel + Moeda Padrão + Mostra só contas activas + Se não for seleccionado irão aparecer todas as contas. + Mostrar só contas favoritas + Versão + Build + Database path + Conta + Lista de Contas + Nenhuma conta encontrada + Saldo + Saldo Reconciliado + Eliminar conta + Nome da conta + Tipo de conta + Nº da conta + Mantida no(a) + Estado da conta + Conta favorita + Escolher Moeda + Ordem + Investimento + Prazo + Erro ao adicionar conta + Erro ao actualizar conta + Moeda é necessária + Saldo inicial da conta é necessário + Nome da conta é necessário + Tipo de conta é necessário + Estado da conta é necessário + Nome do beneficiário + Editar o beneficiário + Eliminar Entidade + Entidades + Escolher entidade + Nenhuma entidade encontrada + De + Actualização do beneficiário falhou + Categorias + Subcategoria + Nenhuma categoria encontrada + Escolher Categoria + Adicionar Categoria + Adicionar subcategoria + Editar Categoria + Eliminar categoria + Nome da moeda + Símbolo da Moeda + Eliminar Moeda + Nome da unidade + Nome de Cêntimos + Símbolo do Prefixo + Símbolo do Sufixo + Separador decimal + Símbolo Grupo + Escala + Conversão + Nome da moeda é necessário + Montante + Quantia Total + Depósito + Estado + Activo + Inactivo + Dar seguimento + Duplicado + Nenhum + Transferência + Tipo de movimento + Estado + Levantamento + Inserção da transação falhou + Actualização da transacção falhou + Eliminar movimento + Nova transacção + Beneficiário é necessário + Para a Conta é necessário + Categoria é necessária + Montante total é necessário + Sobre + Adicionar + Tem certeza que deseja excluir? + Data + Eliminar + Descarregar + Editar + Logotipo + Novo/Editar Movimento + Atualizar + Procurar + Definições + Resumo + Sincronizar + Aberta + Utilizador + Carregar + Nome do Utilizador + Para + Website + Contacto + Informação de Acesso + Saldo inicial + Notas + Fechada + Nova/Editar Moeda + Theme + Holo + Holo claro com ActionBar escuro + Fechar aplicação + Deseja fechar a aplicação? + Nenhuma atividade encontrada para lidar com intenção escolher ficheiro + Atenção + O beneficiário selecionado não pode ser excluído porque está referenciado + A conta selecionada não pode ser excluída porque está referenciada + A moeda selecionada não pode ser excluída porque está referenciada + A categoria selecionada não pode ser excluída porque está referenciada + Todas as Transacções + Últimos 7 dias + Últimas 2 semanas + Mês actual + Ano actual + Mostrar movimentos + Registo de Alterações + Nº da Transacção + Resumo do Money Manager Ex + Money Manager Ex Todas as contas + Adicionar Movimento no Money Manager Ex + Esvaziar Movimentos Agendados + Nenhum + Semanal + Quinzenal + Mensal + 2 em 2 Meses + 4 em 4 Meses + 6 em 6 meses + Anual + 4 Meses + 4 Semanas + Diário + Em (x) Dia(s) + Em (x) Mes(es) + Cada (x) Dia(s) + Cada (x) Mes(es) + Desactivado + dia(s) de atraso + dia(s) restante(s) + Novo/Editar Movimento Agendado + Próxima ocorrência + Repetição + Nº de Vezes Repetidas + Próxima ocorrência é necessária + Activar + Introduzir Próxima Ocorrência + Saltar Próxima Ocorrência + Existem movimentos agendados em atraso + Toque para marcar a transação como atrasada + %1$d transacções agendadas em atraso + Envie Comentários + Info + Segurança + Activar senha + Introduza o Código de Acesso + Re-digite a senha nova + Senhas não correspondem + Editar Código de Acesso + Desactivar Código de Acesso + Indique o Código de Acesso anterior + Código de Acesso não foi actualizado + Quando pesquisar pode utilizar o caracter \"%\" + Receitas vs Despesas: Mês actual + Receitas + Despesa + Diferença + Sem dados para apresentar + Mês + Ano + Relatórios + Receitas vs Despesas + Total + Desde sempre + Mês anterior + Últimos 30 Dias + Ano Anterior + Nº de movimentos econtrados: %1$d + Formato de data + Ano financeiro: Dia de início + Ano financeiro: Mês de inicio + Export database + A Base de dados foi movida: %1$s + Falha na cópia da Base de dados para a memória externa + Está a utilizar a base de dados gravada em: %1$s + Dividir Movimento + Dividir + Pelo menos um das transações da divisão é necessária + Exportar dados para ficheiro CSV + Exportação de dados. Aguarde... + Os dados foram exportados com êxito para o ficheiro %1$s + Ficheiro %1$s falhou a exportação + MoneyManagerEx for Android is provided free. If this application is to your liking, you can support the development team with a donation. + Google Play In-App Billing + Doar via Google Play Pagamento na aplicação. + Escolha o montante do donativo + Doar + Obrigado pelo donativo! + Doar + Não, obrigado + Doar! + Ascendente + Descendente + Ordenação dos meses + A pasta em Dropbox/Apps/Money Manager Ex Mobile está vazia. Se você já usa MoneyManagerEx copie o seu banco de dados para essa pasta no seu computador, e depois faça a atualizaçao. + Selecione um ficheiro do Dropbox + Última modificação + Dropbox + A sua base de dados foi descarregada + Para usar a base de dados descarregada, toque em Abrir base de dados + Toque para seleccionar o ficheiro a ser usado do Dropbox + Download do Dropbox + Toque para descarregar manualmente o ficheiro da pasta Dropbox + Enviar para o Dropbox + Toque para carregar manualmente o ficheiro para a pasta Dropbox + A sua base de dados foi enviada com sucesso + Dropbox - Money Manager Ex + Como funciona o Dropbox para o Money Manager Ex\? + Não mostrar novamente + Abrir Base de Dados + Intervalo de Sincronização + Quantas vezes deve sincronizar? + A partir da versão 1.2.0 do Ex Money Manager para Android mudou a gestão da sincronização com a Dropbox. Para os utilizadores que já estão a usar a sincronização com a Dropbox, devem refazer a configuração. \ A configuração de sincronização e a seleção da base de dados na Dropbox, que está localizado nas configurações. \ Na versão 1.2.0 do Money Manager Ex para Android pode sincronizar automaticamente a base de dados com Dropbox + Carregar a Base de dados após modificações + Esta opção permite carregar a Base de dados automáticamente logo que faça modificações de dados + Mostrar o saldo de cada movimento + Mostrar o saldo de cada movimento poderá tornar a aplicação mais lenta. + Abrir Base de Dados + Database--> + Dicas + Tipo de Letra + Escolha o tipo de letra que deseja atribuir à aplicação + Tamanho de Letra + Escolha o tamanho de letra que deseja atribuir à aplicação + Micro + Pequena + Padrão + Média + Grande + Download do Dropbox. Aguarde... + Enviando para o Dropbox. Aguarde... + Despesas + Receitas + Mostrar Resumo do Money Manager Ex + Mostrar Resumo de cada Conta do Money Manager Ex + Check time + What time would you check if there are repeating transactions overdue? (default 08:00) + Créditos + Principais Levantamentos: Últimos 30 dias + Principais Entidades: Últimos 30 dias + Transações futuras + Quantidade + Painel de controle + The database is up to date + Últimos 3 meses + Últimos 6 meses + Categoria vazia + Beneficiário vazio + Ajuda + Apagar repetir o movimento + Último + Contas + Para a conta + Da Conta + Status padrão + Beneficiário padrão + Editar transação + Tem certeza que deseja excluir a transacção selecionada? + Tem certeza que deseja excluir as %d transações seleccionadas? + Categorias + Moedas + Beneficiários + Movimentos Agendados + Holo claro + Nova conta + Importar Moedas + Importação de moedas. Aguarde... + Valor maior ou igual + Valor menor ou igual + Resultado da pesquisa + Nova transação agendada + Editar transação agendada + Cada 5 minutos + A cada 15 minutos + Cada 30 minutos + Cada hora + Cada 2 horas + Cada 6 horas + Cada 12 horas + Nunca + Caminho da base de dados não existe + A base de dados não pode ser aberta para gravação + Deseja importar a moeda? + Período de tempo + Mostrar gráfico + Adicionar Transacção + Bem vindo ao MoneyManagerEx + O MoneyManagerEx modela todas as transacções como pertencentes a uma conta.\n\nPara o ajudar a iniciar, comece por fazer uma lista de todos os bancos onde tem uma conta.\n\nClique aqui para inserir as suas contas. + Se já usa o MoneyManagerEx no Windows , Linux ou Mac, ligue esta aplicação com o Dropbox para sincronizar a sua base de dados + Configurar o Dropbox + Pesquisar no conteúdo do texto e não por texto a começar por + Pesquisar beneficiários, categorias, moedas, etc... pelo conteúdo e não pelos caracteres iniciais + Avaliar aplicação + Application Language + Czech + inglês + Spanish + French + Hebrew + Italian + Português + Português, Brasil + Russian + Vietnamese + Chinese Simplified + Chinese Traditional + Actualização das taxas de câmbio das moedas. Aguarde... + Actualizando a taxa de câmbio:\n%1$s + Todas as taxas de câmbio das moedas foram actualizadas com sucesso + Atualização da taxa de câmbio + Deseja actualizar a taxa de câmbio? + Levantamentos de %1$s + Depósito para %1$s + Site do MoneyManager + You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! + Retrieving status of your donations from Google Play. Please wait… + Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. + Notification Repeating Transaction overdue + Show notification for repeating transaction overdue diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index de2d2c4fe0..7d879efed2 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -1,343 +1,355 @@ - - + - Простое и легкое в использовании приложение для управления личными финансами, банковским счетам, семейным бюджетом, и т.д. - Проект Android Money Manager Ex использует библиотеки ActionBarSherlock и RobotMediaBilling - Лицензии с открытым исходным кодом - Ошибка вставки данных - Ошибка удаления данных - Ошибка обновления данных - Выход - Управление - Соединиться с Dropbox - Отсоединиться от Dropbox - Синхронизирую файл. Пожалуйста подождите… - Загружаю файл из Dropbox. Пожалуйста подождите… - Загружаю файл в Dropbox. Пожалуйста подождите… - Файл Dropbox - Основные - Экран - Базовая валюта - Просмотр открытых счетов - Если не выбрана, будут отображаться все счета - Просмотр избранных счетов - Версия - Номер сборки - Счет - Список счетов - Список счетов пустой - Баланс счета - Выверенный баланс - Удалить счет - Название счета - Тип счета - Номер счета - Открыт в - Состояние счета - Избранный счет - Выберите валюту - Чековый - Инвестиционный - Вклад - Ошибка добавления счета - Ошибка обновления счета - Требуется указать валюту - Требуется указать начальный баланс счета - Требуется указать имя счета - Требуется указать тип счета - Требуется указать статус счета - Имя контрагента - Редактировать контрагента - Удалить контрагента - Контрагент - Выбрать контрагента - Список контрагентов пустой - Из - Ошибка обновления контрагента - Категория - Подкатегория - Список категорий пуст - Выбрать категорию - Добавить категорию - Добавить подкатегорию - Редактировать категорию - Удалить категорию - Название валюты - Символ валюты - Удалить валюту - Наименование целых - Наименование дробных - Символ префикса - Символ суффикса - Разделитель целой и дробной части - Разделитель групп - Дробных - Обменный курс - Требуется указать название валюты - Сумма - Итоговая сумма - Пополнение - Статус - Выверен - Не учитывать - Отслеживать - Повтор - Нет - Перевод - Тип проводки - Статус - Снятие - Ошибка добавления проводки - Ошибка обновления проводки - Удаление проводки - Новая проводка - Требуется указать контрагента - Требуется указать счет получателя - Требуется указать категорию - Требуется указать полную сумму - О программе - Добавить - Вы уверены, что хотите удалить ? - Дата - Удалить - Скачать - Редактировать - Логотип - Добавить/редактировать проводку - Обновить - Поиск - Настройки - Сводка - Синхронизировать - Открыт - Пользователь - Загрузить - Имя пользователя - В - Веб-сайт - Контакты - Информация о доступе - Начальный баланс - Заметки - Закрыт - Создать/Редактировать валюту - Тема - Holo светлая с темным ActionBar - Закрыть приложение - Вы хотите закрыть приложение? - Не обнаружено никакой активности для обработки выбранного файла - Внимание - Контрагент не может быть удален, т.к. на него есть ссылки из проводок - Счет не может быть удален, т.к. на него есть ссылки из проводок - Валюта не может быть удалена, т.к. на нее есть ссылки из проводок - Категория не может быть удалена, т.к. на нее есть ссылки из проводок - Все проводки - За последние 7 дней - За последние 2 недели - Текущий месяц - Текущий год - Показывать проводки - История изменений - Номер проводки - Money Manager Ex Сводка - Money Manager Ex Счета - Money Manager Ex Создать проводку - Запланированные проводки отсутствуют - Нет - Еженедельно - Каждые две недели - Ежемесячно - Каждые два месяца - Ежеквартально - раз в полгода - Ежегодно - Четыре месяца - Четыре недели - Ежедневно - В (x) дней - В (x) месяц - Каждые (x) дней - Каждые (x) месяцев - Неактивна - дней просрочки! - дней осталось - Создать/Редактировать запланированную проводку - Следующее начисление - Повторы - Количество повторов - Требуется указать следующее вхождение - Активировать - Ввести следующее начисление - Пропустить следующее начисление - Запланированная проводка просрочена - Нажмите для проверки наличия просроченных проводок - запланированная проводка просрочена на %1$d - Отправить отзыв - Информация - Безопасность - Активировать пароль - Введите ваш пароль - Повторно введите Ваш новый пароль - Пароли не совпадают - Изменить пароль - Отключить пароль - Введите ваш старый пароль - Пароль не обновлен - Для поиска можно использовать подстановочный символ \'%\' - Доход/Расход: Текущий месяц - Доход - Расход - Разница - Нет данных для отображения - Месяц - Год - Отчеты - Доход/Расход - Итого - Все время - Предыдущий месяц - Последние 30 дней - Предыдущий год - Найдено проводок: %1$d - Формат даты - Финансовый год: День начала - Финансовый год: Месяц начала - База данных была перемещена: %1$s - Копирование базы данных на внешнее хранилище не удалось - Путь до используемой базы данных: %1$s - Разделение проводки - Делить - По крайней мере одна операция в составной проводке требуется - Экспорт данных в CSV файл - Экспорт данных. Пожалуйста подождите… - Данные были успешно выгружены в файл %1$s - Экспорт файла %1$s не удался - Android Money Manager Ex предоставляется бесплатно. Если вам нравиться это приложение, вы можете поддержать команду разработчиков . - Поддержать через Google Play In-App. - Выбрать размер пожертвования - Поддержать - Благодарим за пожертвование! - Поддержать - Нет, спасибо - Поддержать! - По возрастанию - По убыванию - Сортировка по месяцам - Папка Dropbox/Apps/Money Manager Ex Mobile пустая. Если ранее программа MoneyManagerEx использовалась - просто скопируйте файл с базой данный программы в эту папку на компьютере после чего обновите состояние папки в Dropbox. - Выберите файл из Dropbox - Последнее изменение - Ваша база данных была загружена - Дря работы с загруженной базой нажмите Открыть Базу - Нажмите для выбора файла из Dropbox - Загрузка из Dropbox - Нажмите для принудительной загрузки связанного файла из Dropbox - Загрузка в Dropbox - Нажмите для принудительной загрузки файла в папку Dropbox - Ваша базы данных была успешно загружена - Как Dropbox работает с Money Manager Ex\? - Не показывать снова - Открыть БД - Интервал синхронизации - Как часто требуется синхронизация? - В версии 1.2.0 Money Manager Ex для Android изменено управление синхронизацией с Dropbox. Пользователи, которые уже используют синхронизацию с Dropbox, должны переконфигурировать Dropbox. Конфигурация Dropbox, выбор файла БД Dropbox, расположен в настройках.\nВ версии 1.2.0 Money Manager Ex для Android может автоматически синхронизировать БД с Dropbox - Загрузка сразу после изменений - Эта опция позволяет автоматически загружать БД вскоре после ваших изменений - Показывать баланс для каждой проводки - Показывать баланс для каждой проводки. Отображение баланса может замедлить работу приложения. - Открыть Базу данных - Советы - Шрифт приложения - Выберите шрифт - Размер шрифта приложения - Выберите размер шрифта для приложения - Микро - Маленький - По умолчанию - Средний - Большой - Загружаем из Dropbox. Пожалуйста подождите… - Загружаем в Dropbox. Пожалуйста подождите… - Куда расходуются деньги - Откуда приходят деньги - Отображение сводки Money Manager Ex для Android - Просмотр сводки по каждому счету Money Manager Ex для Android - Проверить расписание просроченных запланированных проводок - Указать время, когда приложение должно проверять просроченные запланированные проводки (по умолчанию 08:00) - Благодарность - Топ снятия: Последние 30 дней - Топ получателей: Последние 30 дней - Исходящие проводки - Количество - Панель управления - База данных синхронизирована - Последние 3 месяца - Последние 6 месяцев - Пустая категория - Пустой контрагент - Справка - Удалить запланированные проводки - Последний - Счета - На счет - Со счета - Статус по умолчанию - Контрагент по умолчанию - Редактировать проводку - Вы уверены, что хотите удалить выбранную проводку ? - Вы уверены, что хотите удалить %d выбранных проводок ? - Категории - Валюты - Контрагенты - Запланированные проводки - Holo светлая - Новый счет - Импорт валют - Импортируем валюты. Пожалуйста подождите… - Сумма больше или равно - Сумма меньше или равно - Результат вашего поиска - Новая плановая проводка - Редактировать запланированную проводку - Каждые 5 минут - Каждые 15 минут - Каждые 30 минут - Каждый час - Каждые 2 часа - Каждые 6 часов - Каждые 12 часов - Никогда не - Путь к базе данных не существует - База данных не может быть открыта для записи - Вы хотите импортировать валюту? - Период времени - Показать диаграмму - Добавить транзакцию - Добро пожаловать в MoneyManagerEx - MoneyManagerEx хранит все проводки на ваших счетах.\n\nДля того чтобы вам начать работу, надо создать свои счета.\n\nНажмите здесь, чтобы начать ввод своих счетов. - Если вы уже используете MoneyManagerEx на Windows, Linux или Mac синхронизируйте базу данных приложения через Dropbox - Настройка Dropbox - Поиск по содержимому текста, а не только с начала строки - Поиск среди контрагентов, категорий, валют и.т.д.… по всему содержимому текста, а не только с начала строки - Оценить приложение - Язык приложения - чешский - Английский - Испанский - Французский - Иврит - Итальянский - Португальский - Португальский, Бразильский - Русский - Vietnamese - Китайский (упрощенный) - Китайский (традиционный) - Обновление курсов валют. Пожалуйста подождите… - Обновляем обменный курс:\n%1$s - Все обменные курсы были успешно обновлены - Обновить курс валюты - Вы хотите обновить обменый курс ? - Снятие со счета %1$s - Пополнение счета %1$s - Сайт MoneyManagerEX + Money Manager Ex + Простое и легкое в использовании приложение для управления личными финансами, банковским счетам, семейным бюджетом, и т.д. + Проект MoneyManagerEx для Android использует библиотеку ActionBarSherlock + Лицензии с открытым исходным кодом + Ошибка вставки данных + Ошибка удаления данных + Ошибка обновления данных + Выход + Управление + Соединиться с Dropbox + Отсоединиться от Dropbox + Синхронизирую файл. Пожалуйста подождите… + Загружаю файл из Dropbox. Пожалуйста подождите… + Загружаю файл в Dropbox. Пожалуйста подождите… + Файл Dropbox + Основные + Look & Feel + Базовая валюта + Просмотр открытых счетов + Если не выбрана, будут отображаться все счета + Просмотр избранных счетов + Версия + Номер сборки + Database path + Счет + Список счетов + Список счетов пустой + Баланс счета + Выверенный баланс + Удалить счет + Название счета + Тип счета + Номер счета + Открыт в + Состояние счета + Избранный счет + Выберите валюту + Чековый + Инвестиционный + Вклад + Ошибка добавления счета + Ошибка обновления счета + Требуется указать валюту + Требуется указать начальный баланс счета + Требуется указать имя счета + Требуется указать тип счета + Требуется указать статус счета + Имя контрагента + Редактировать контрагента + Удалить контрагента + Контрагент + Выбрать контрагента + Список контрагентов пустой + Из + Ошибка обновления контрагента + Категория + Подкатегория + Список категорий пуст + Выбрать категорию + Добавить категорию + Добавить подкатегорию + Редактировать категорию + Удалить категорию + Название валюты + Символ валюты + Удалить валюту + Наименование целых + Наименование дробных + Символ префикса + Символ суффикса + Разделитель целой и дробной части + Разделитель групп + Дробных + Обменный курс + Требуется указать название валюты + Сумма + Итоговая сумма + Пополнение + Статус + Выверен + Не учитывать + Отслеживать + Повтор + Нет + Перевод + Тип проводки + Статус + Снятие + Ошибка добавления проводки + Ошибка обновления проводки + Удаление проводки + Новая проводка + Требуется указать контрагента + Требуется указать счет получателя + Требуется указать категорию + Требуется указать полную сумму + О программе + Добавить + Вы уверены, что хотите удалить ? + Дата + Удалить + Скачать + Редактировать + Логотип + Добавить/редактировать проводку + Обновить + Поиск + Настройки + Сводка + Синхронизировать + Открыт + Пользователь + Загрузить + Имя пользователя + В + Веб-сайт + Контакты + Информация о доступе + Начальный баланс + Заметки + Закрыт + Создать/Редактировать валюту + Theme + Holo + Holo светлая с темным ActionBar + Закрыть приложение + Вы хотите закрыть приложение? + Не обнаружено никакой активности для обработки выбранного файла + Внимание + Контрагент не может быть удален, т.к. на него есть ссылки из проводок + Счет не может быть удален, т.к. на него есть ссылки из проводок + Валюта не может быть удалена, т.к. на нее есть ссылки из проводок + Категория не может быть удалена, т.к. на нее есть ссылки из проводок + Все проводки + За последние 7 дней + За последние 2 недели + Текущий месяц + Текущий год + Показывать проводки + История изменений + Номер проводки + Money Manager Ex Сводка + Money Manager Ex Счета + Money Manager Ex Создать проводку + Запланированные проводки отсутствуют + Нет + Еженедельно + Каждые две недели + Ежемесячно + Каждые два месяца + Ежеквартально + раз в полгода + Ежегодно + Четыре месяца + Четыре недели + Ежедневно + В (x) дней + В (x) месяц + Каждые (x) дней + Каждые (x) месяцев + Неактивна + дней просрочки! + дней осталось + Создать/Редактировать запланированную проводку + Следующее начисление + Повторы + Количество повторов + Требуется указать следующее вхождение + Активировать + Ввести следующее начисление + Пропустить следующее начисление + Запланированная проводка просрочена + Нажмите для проверки наличия просроченных проводок + запланированная проводка просрочена на %1$d + Отправить отзыв + Информация + Безопасность + Активировать пароль + Введите ваш пароль + Повторно введите Ваш новый пароль + Пароли не совпадают + Изменить пароль + Отключить пароль + Введите ваш старый пароль + Пароль не обновлен + Для поиска можно использовать подстановочный символ \'%\' + Доход/Расход: Текущий месяц + Доход + Расход + Разница + Нет данных для отображения + Месяц + Год + Отчеты + Доход/Расход + Итого + Все время + Предыдущий месяц + Последние 30 дней + Предыдущий год + Найдено проводок: %1$d + Формат даты + Финансовый год: День начала + Финансовый год: Месяц начала + Export database + База данных была перемещена: %1$s + Копирование базы данных на внешнее хранилище не удалось + Путь до используемой базы данных: %1$s + Разделение проводки + Делить + По крайней мере одна операция в составной проводке требуется + Экспорт данных в CSV файл + Экспорт данных. Пожалуйста подождите… + Данные были успешно выгружены в файл %1$s + Экспорт файла %1$s не удался + MoneyManagerEx для Android предоставляется бесплатно.Если вам понравилось это приложение, вы можете поддержать разработчиков отправив пожертвование. + Google Play In-App Billing + Поддержать через Google Play In-App. + Выбрать размер пожертвования + Поддержать + Благодарим за пожертвование! + Поддержать + Нет, спасибо + Поддержать! + По возрастанию + По убыванию + Сортировка по месяцам + Папка Dropbox/Apps/Money Manager Ex Mobile пустая. Если ранее программа MoneyManagerEx использовалась - просто скопируйте файл с базой данный программы в эту папку на компьютере после чего обновите состояние папки в Dropbox. + Выберите файл из Dropbox + Последнее изменение + Dropbox + Ваша база данных была загружена + Дря работы с загруженной базой нажмите Открыть Базу + Нажмите для выбора файла из Dropbox + Загрузка из Dropbox + Нажмите для принудительной загрузки связанного файла из Dropbox + Загрузка в Dropbox + Нажмите для принудительной загрузки файла в папку Dropbox + Ваша базы данных была успешно загружена + Dropbox - Money Manager Ex + Как Dropbox работает с Money Manager Ex\? + Не показывать снова + Открыть БД + Интервал синхронизации + Как часто требуется синхронизация? + В версии 1.2.0 Money Manager Ex для Android изменено управление синхронизацией с Dropbox. Пользователи, которые уже используют синхронизацию с Dropbox, должны переконфигурировать Dropbox. Конфигурация Dropbox, выбор файла БД Dropbox, расположен в настройках.\nВ версии 1.2.0 Money Manager Ex для Android может автоматически синхронизировать БД с Dropbox + Загрузка сразу после изменений + Эта опция позволяет автоматически загружать БД вскоре после ваших изменений + Показывать баланс для каждой проводки + Показывать баланс для каждой проводки. Отображение баланса может замедлить работу приложения. + Открыть Базу данных + Database--> + Советы + Шрифт приложения + Выберите шрифт + Размер шрифта приложения + Выберите размер шрифта для приложения + Микро + Маленький + По умолчанию + Средний + Большой + Загружаем из Dropbox. Пожалуйста подождите… + Загружаем в Dropbox. Пожалуйста подождите… + Куда расходуются деньги + Откуда приходят деньги + Отображение сводки Money Manager Ex для Android + Просмотр сводки по каждому счету Money Manager Ex для Android + Check time + What time would you check if there are repeating transactions overdue? (default 08:00) + Благодарность + Топ снятия: Последние 30 дней + Топ получателей: Последние 30 дней + Исходящие проводки + Количество + Панель управления + База данных уже обновлена + Последние 3 месяца + Последние 6 месяцев + Пустая категория + Пустой контрагент + Справка + Удалить запланированные проводки + Последний + Счета + На счет + Со счета + Статус по умолчанию + Контрагент по умолчанию + Редактировать проводку + Вы уверены, что хотите удалить выбранную проводку ? + Вы уверены, что хотите удалить %d выбранных проводок ? + Категории + Валюты + Контрагенты + План транзакций + Holo светлая + Новый счет + Импорт валют + Импортируем валюты. Пожалуйста подождите… + Сумма больше или равно + Сумма меньше или равно + Результат вашего поиска + Новая плановая проводка + Редактировать запланированную проводку + Каждые 5 минут + Каждые 15 минут + Каждые 30 минут + Каждый час + Каждые 2 часа + Каждые 6 часов + Каждые 12 часов + Никогда не + Путь к базе данных не существует + База данных не может быть открыта для записи + Вы хотите импортировать валюту? + Период времени + Показать диаграмму + Добавить транзакцию + Добро пожаловать в MoneyManagerEx + MoneyManagerEx хранит все проводки на ваших счетах.\n\nДля того чтобы вам начать работу, надо создать свои счета.\n\nНажмите здесь, чтобы начать ввод своих счетов. + Если вы уже используете MoneyManagerEx на Windows, Linux или Mac синхронизируйте базу данных приложения через Dropbox + Настройка Dropbox + Поиск по содержимому текста, а не только с начала строки + Поиск среди контрагентов, категорий, валют и.т.д.… по всему содержимому текста, а не только с начала строки + Оценить приложение + Application Language + чешский + Английский + Испанский + Французский + Иврит + Итальянский + Португальский + Португальский, Бразильский + Русский + Vietnamese + Китайский (упрощенный) + Китайский (традиционный) + Обновление курсов валют. Пожалуйста подождите… + Обновляем обменный курс:\n%1$s + Все обменные курсы были успешно обновлены + Обновить курс валюты + Вы хотите обновить обменый курс ? + Снятие со счета %1$s + Пополнение счета %1$s + Сайт MoneyManagerEX + Вы уже поддержали разработчиков MoneyManagerEx для Android внеся пожертвование!\n\nБольшое спасибо от группы разработчиков! + Запрашиваем статус ваших пожертвований через Google Play. Пожалуйста подождите… + Невозможно использовать функцию оплаты из программы. Проверьте, что у вас установлена последняя версия приложения Google Play Store. + Notification Repeating Transaction overdue + Show notification for repeating transaction overdue diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 00644586b3..e77a31cd5d 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -1,284 +1,355 @@ - - + - Một ứng dụng đơn giản và dễ dàng sử dụng để quản lý tài chính cá nhân, tài khoản ngân hàng, ngân sách gia đình, và v.v... - Giấy phép mã nguồn mở - Thoát - Quản lý - Liên kết đến Dropbox - Hủy liên kết khỏi Dropbox - Chung - Hiển thị - Tiền tệ cơ sở - Xem các tài khoản mở - Nếu không được chọn sẽ hiện tất cả tài khoản - Xem tài khoản ưa thích - Phiên bản - Xây dựng - Tài khoản - Danh sách tài khoản - Không tìm thấy tài khoản - Số dư tài khoản - Xoá tài khoản - Tổ chức tại - Kiểm tra - Đầu tư - Kỳ hạn - Xoá người nhận thanh toán - Người nhận thanh toán - Chọn người nhận thanh toán - Không có người nhận thanh toán tìm thấy - Từ - Danh mục - Không danh mục tìm thấy - Chọn danh mục - Thêm danh mục - Xóa danh mục - Xóa tiền tệ - Tỷ lệ - Chuyển đổi - Số lượng - Tiền gửi - Tình trạng - Hòa giải - Trống - Theo dõi - Trùng lặp - Không - Truyền - Loại giao dịch - Tình trạng - Rút tiền - Xóa bỏ giao dịch - Giới thiệu - Thêm - Ngày - Xóa - Tải về - Sửa - Biểu tượng - Giao dịch Mới/Sửa - Làm mới - Tìm kiếm - Thiết đặt - Tóm lược - Đồng bộ - Mở - Người dùng - Tải lên - Tên người dùng - Tới - Website - Liên hệ - Ghi chú - Đã đóng - Mới/Sửa tiền tệ - Sáng Holo với Thanh Hoạt Động Màu Tối - Bạn có muốn đóng ứng dụng? - Không có hoạt động tìm thấy để xử lý ý định chọn tập tin - Chú ý - Không thể xóa người nhận thanh toán được chọn vì đã tồn tại các ràng buộc - Không thể xóa tài khoản được chọn vì đã tồn tại các ràng buộc - Không thể xóa tiền tệ được chọn vì đã tồn tại các ràng buộc - Không thể xóa danh mục được chọn vì đã tồn tại các ràng buộc - Tất cả giao dịch - 7 ngày qua - 2 tuần cuối - Tháng hiện tại - Năm hiện tại - Hiển thị giao dịch - Thay đổi - Số giao dịch - Tóm lược Money Manager Ex - Tất cả Tài khoản Money Manager Ex - Thêm giao dịch Money Manager Ex - Làm trống giao dịch lặp lại - Không - Hàng Tuần - Mỗi 2 tuần - Hàng Tháng - Mỗi 2 tháng - Hàng quý - Nửa năm - Hàng Năm - 4-Tháng - 4-Tuần - Hàn ngày - Trong (x) ngày - Trong (x) tháng - Mỗi (x) ngày - Mỗi (x) tháng - Không hoạt động - ngày quá hạn! - ngày còn lại - Mới/Sửa giao dịch lặp lại - Lần xuất hiện tiếp theo - Lặp lại - Lần lặp lại - Lần xuất hiện tiếp theo là cần thiết - Kích hoạt - Nhập việc xảy ra tiếp theo - Bỏ qua lần xảy ra tiếp theo - Có giao dịch lặp lại hết hạn - Chạm để kiểm tra giao dịch quá hạn - %1$d giao dịch lặp lại quá hạn - Gửi phản hồi - Thông tin - Bảo mật - Bật mã khóa - Nhập mã khóa của bạn - Nhập lại mã mới của bạn - Mật mã không khớp - Sửa mã khóa - Vô hiệu mã khóa - Nhập mã khóa trước đó của bạn - Mã khóa không được cập nhật - Để tra cứu bạn có thể sử dụng ký tự đại diện % - Thu nhập vs Chi phí: Tháng hiện tại - Thu nhập - Chi phí - Sự khác biệt - Không có dữ liệu để hiển thị - Tháng - Năm - Báo cáo - Thu nhập Vs Chi phí - Tổng cộng - Tất cả thời gian - Tháng trước - 30 Ngày qua - Năm trước - Số giao dịch được tìm thấy: %1$d - Định dạng ngày - Năm tài chính: Ngày bắt đầu - Năm tài chính: Tháng bắt đầu - Cơ sở dữ liệu đã chuyển: %1$s - Sao chép CSDL trên lưu trữ ngoài bị lỗi - Bạn đang dùng CSDL được lưu trong: %1$s - Phân chia giao dịch - Phân chia - Ít nhất phải có một giao dịch được chọn - Xuất dữ liệu ra tệp CSV - Đang xuất dữ liệu. Vui lòng chờ… - Dữ liệu đã được xuất thành công ra tệp %1$s - Xuất tập tin %1$s bị lỗi - Android Money Manager Ex được cung cấp miễn phí. Nếu ứng dụng này đúng ý thích của bạn, bạn có thể hỗ trợ nhóm phát triển với một tài trợ. - Tặng thông qua Google Play trong ứng dụng thanh toán. - Chọn một số tiền tặng - Tặng tiền - Cảm ơn bạn đã tặng! - Tặng tiền - Không, cảm ơn - Tặng tiền! - Tăng dần - Giảm dần - Xếp theo Tháng - Thư mục trong Dropbox/Ứng dụng/Money Manager Ex Di Động đang trống. Nếu bạn đã dùng Money Manager Ex sao chép cơ sở dữ liệu vào thư mục này của bạn trong máy tính của bạn, và sau đó bạn thực hiện làm mới. - Chọn một tập tin từ Dropbox - Sửa đổi cuối - Cơ sở dữ liệu của bạn đã được tải về - Để sử dụng cơ sở dữ liệu tải về, chạm vào Mở cơ sở dữ liệu - Chạm để chọn tập tin để sử dụng từ Dropbox - Tải về từ Dropbox - Chạm để tùy chọn tải về tập tin được liên kết từ thư mục Dropbox - Tải lên Dropbox - Chạm để tùy chọn tải lên các tập tin được liên kết vào thư mục Dropbox - Cơ sở dữ liệu của bạn đã được tải lên thành công - Dropbox làm việc cho Money Manager Ex như thế nào\? - Không hiện lại nữa - Mở Cơ sở dữ liệu - Thời gian đồng bộ - Tần suất đồng bộ là bao lâu ? - Từ phiên bản 1.2.0 của Money Manager Ex cho Android đã thay đổi quản lý đồng bộ hoá với Dropbox. Cho người dùng những người đã sử dụng đồng bộ với Dropbox, bạn phải thực hiện cấu hình lại. \nCấu hình của đồng bộ với Dropbox và lựa chọn cơ sở dữ liệu, được nằm trong thiết đặt. \nTừ phiên bản 1.2.0 của Money Manager Ex cho Android có thể tự động đồng bộ cơ sở dữ liệu với Dropbox - Tải lên cơ sở dữ liệu ngay lập tức lúc thay đổi - Tùy chọn này cho phép tự động tải lên ngay sau khi bạn thay đổi cơ sở dữ liệu - Hiện số dư cho mỗi giao dịch - Hiện số dư cho cho mỗi giao dịch. Hiển thị số dư có thể làm ứng dụng chậm hơn - Mở Cơ sở dữ liệu - Mẹo - Font Ứng dụng - Chọn font bạn muốn cấp cho ứng dụng - Cỡ chữ Ứng dụng - Chọn cỡ chữ bạn muốn cấp cho ứng dụng - Cực nhỏ - Nhỏ - Mặc định - Vừa - Lớn - Đang tải xuống từ Dropbox. Vui lòng chờ… - Đang tải lên Dropbox. Vui lòng chờ… - Nơi tiền Đi - Nơi tiền Đến - Hiển thị tóm tắt về Money Manager Ex cho Android - Xem tóm tắt của mỗi tài khoản Money Manager Ex cho Android - Lịch trình kiểm tra Giao dịch lặp lại quá hạn - Chỉ ra thời gian trong ngày ứng dụng nên kiểm tra xem có giao dịch lặp lại quá hạn (mặc định 08:00) - Tác giả - Rút tiền hàng đầu: 30 ngày qua - Người thanh toán hàng đầu: 30 ngày qua - Giao dịch sắp tới - Số lượng - Bảng điều khiển - Cơ sở dữ liệu được đồng bộ - 3 tháng qua - 6 tháng qua - Làm trống Danh mục - Làm trống Người thanh toán - Trợ giúp - Xoá giao dịch lặp lại - Đã qua - Tài khoản - Tới Tài khoản - Từ tài khoản - Trạng thái mặc định - Người nhận thanh toán mặc định - Sửa giao dịch - Bạn có chắc bạn muốn xóa giao dịch đã chọn không? - Bạn có chắc bạn muốn xóa %d giao dịch đã chọn? - Danh mục - Tiền tệ - Người nhận thanh toán - Giao dịch lặp lại - Holo Sáng - Tài khoản mới - Nhập tiền tệ - Đang nhập tiền tệ. Vui lòng chờ… - Số tiền lớn hơn hoặc bằng - Số tiền ít hơn hoặc bằng - Kết quả tìm kiếm của bạn - Giao dịch lặp lại mới - Chỉnh sửa giao dịch lặp lại - Mỗi 5 phút - Mỗi 15 phút - Mỗi 30 phút - Mỗi giờ - Mỗi 2 giờ - Mỗi 6 giờ - Mỗi giờ 12 - Không bao giờ - Con đường cơ sở dữ liệu không tồn tại - Cơ sở dữ liệu không thể được mở cho việc ghi - Bạn có muốn nhập tiền tệ? - Khung thời gian - Hiển thị biểu đồ - Thêm giao dịch - Chào mừng đến với MoneyManagerEx! - Nếu bạn đã sử dụng MoneyManagerEx trên Windows, Linux hoặc Mac liên kết ứng dụng này với Dropbox để đồng bộ cơ sở dữ liệu của bạn - Cấu hình Dropbox - Tìm kiếm bằng nội dung văn bản và không phải bằng văn bản bắt đầu với - Đánh giá Ứng dụng - Ngôn ngữ ứng dụng - Tiếng Séc - Tiếng Anh - Tiếng Tây Ban Nha - Tiếng Pháp - Tiếng Do Thái - Tiếng Ý - Tiếng Nga - Tiếng Việt - Tiếng Trung giản thể - Tiếng Trung truyền thống - Cập Nhật Tỷ giá hối đoái - Rút khỏi từ %1$s - Khoản tiền gửi tới %1$s + Money Manager Ex + Một ứng dụng đơn giản và dễ dàng sử dụng để quản lý tài chính cá nhân, tài khoản ngân hàng, ngân sách gia đình, và v.v... + MoneyManagerEx for Android Project uses ActionBarSherlock library + Giấy phép mã nguồn mở + Chèn dữ liệu bị lỗi + Xóa dữ liệu thất bại + Cập nhật dữ liệu thất bại + Thoát + Quản lý + Liên kết đến Dropbox + Hủy liên kết khỏi Dropbox + Đang đồng bộ tập tin. Vui lòng chờ... + Đang tải tập tin từ Dropbox. Vui lòng chờ... + Đang tải tập tin tới Dropbox. Vui lòng chờ... + Tập tin Dropbox + Chung + Look & Feel + Tiền tệ cơ sở + Xem các tài khoản mở + Nếu không được chọn sẽ hiện tất cả tài khoản + Xem tài khoản ưa thích + Phiên bản + Xây dựng + Database path + Tài khoản + Danh sách tài khoản + Không tìm thấy tài khoản + Số dư tài khoản + Số dư đối chiếu + Xoá tài khoản + Tên tài khoản + Loại tài khoản + Số tài khoản + Tổ chức tại + Trạng thái tài khoản + Tài khoản ưa thích + Chọn loại tiền tệ + Kiểm tra + Đầu tư + Kỳ hạn + Lỗi chèn tài khoản + Lỗi cập nhật tài khoản + Tiền tệ cần phải có + Số dư tài khoản ban đầu là cần thiết + Tên tài khoản được yêu cầu + Loại tài khoản được yêu cầu + Trạng thái tài khoản được yêu cầu + Tên người nhận thanh toán + Chỉnh sửa người nhận thanh toán + Xoá người nhận thanh toán + Người nhận thanh toán + Chọn người nhận thanh toán + Không có người nhận thanh toán tìm thấy + Từ + Cập Nhật người nhận thanh toán bị lỗi + Danh mục + Danh mục phụ + Không danh mục tìm thấy + Chọn danh mục + Thêm danh mục + Thêm danh mục phụ + Sửa Danh mục + Xóa danh mục + Tên tiền tệ + Ký hiệu tiền tệ + Xóa tiền tệ + Tên đơn vị + Tên Cent + Biểu tượng tiền tố + Biểu tượng hậu tố + Kí tự thập phân + Kí tự nhóm + Tỷ lệ + Chuyển đổi + Tên tiền tệ là cần thiết + Số lượng + Tổng số tiền + Tiền gửi + Tình trạng + Hòa giải + Trống + Theo dõi + Trùng lặp + Không + Truyền + Loại giao dịch + Tình trạng + Rút tiền + Chèn giao dịch không thành công + Cập nhật giao dịch không thành công + Xóa bỏ giao dịch + Giao dịch mới + Người nhận thanh toán là cần thiết + Tới Tài Khoản được yêu cầu + Danh mục được yêu cầu + Tổng số tiền được yêu cầu + Giới thiệu + Thêm + Bạn có chắc muốn xóa không? + Ngày + Xóa + Tải về + Sửa + Biểu tượng + Giao dịch Mới/Sửa + Làm mới + Tìm kiếm + Thiết đặt + Tóm lược + Đồng bộ + Mở + Người dùng + Tải lên + Tên người dùng + Tới + Website + Liên hệ + Thông tin truy cập + Số dư ban đầu + Ghi chú + Đã đóng + Mới/Sửa tiền tệ + Theme + Holo + Sáng Holo với Thanh Hoạt Động Màu Tối + Đóng ứng dụng + Bạn có muốn đóng ứng dụng? + Không có hoạt động tìm thấy để xử lý ý định chọn tập tin + Chú ý + Không thể xóa người nhận thanh toán được chọn vì đã tồn tại các ràng buộc + Không thể xóa tài khoản được chọn vì đã tồn tại các ràng buộc + Không thể xóa tiền tệ được chọn vì đã tồn tại các ràng buộc + Không thể xóa danh mục được chọn vì đã tồn tại các ràng buộc + Tất cả giao dịch + 7 ngày qua + 2 tuần cuối + Tháng hiện tại + Năm hiện tại + Hiển thị giao dịch + Thay đổi + Số giao dịch + Tóm lược Money Manager Ex + Tất cả Tài khoản Money Manager Ex + Thêm giao dịch Money Manager Ex + Làm trống giao dịch lặp lại + Không + Hàng Tuần + Mỗi 2 tuần + Hàng Tháng + Mỗi 2 tháng + Hàng quý + Nửa năm + Hàng Năm + 4-Tháng + 4-Tuần + Hàn ngày + Trong (x) ngày + Trong (x) tháng + Mỗi (x) ngày + Mỗi (x) tháng + Không hoạt động + ngày quá hạn! + ngày còn lại + Mới/Sửa giao dịch lặp lại + Lần xuất hiện tiếp theo + Lặp lại + Lần lặp lại + Lần xuất hiện tiếp theo là cần thiết + Kích hoạt + Nhập việc xảy ra tiếp theo + Bỏ qua lần xảy ra tiếp theo + Có giao dịch lặp lại hết hạn + Chạm để kiểm tra giao dịch quá hạn + %1$d giao dịch lặp lại quá hạn + Gửi phản hồi + Thông tin + Bảo mật + Bật mã khóa + Nhập mã khóa của bạn + Nhập lại mã mới của bạn + Mật mã không khớp + Sửa mã khóa + Vô hiệu mã khóa + Nhập mã khóa trước đó của bạn + Mã khóa không được cập nhật + Để tra cứu bạn có thể sử dụng ký tự đại diện % + Thu nhập vs Chi phí: Tháng hiện tại + Thu nhập + Chi phí + Sự khác biệt + Không có dữ liệu để hiển thị + Tháng + Năm + Báo cáo + Thu nhập Vs Chi phí + Tổng cộng + Tất cả thời gian + Tháng trước + 30 Ngày qua + Năm trước + Số giao dịch được tìm thấy: %1$d + Định dạng ngày + Năm tài chính: Ngày bắt đầu + Năm tài chính: Tháng bắt đầu + Export database + Cơ sở dữ liệu đã chuyển: %1$s + Sao chép CSDL trên lưu trữ ngoài bị lỗi + Bạn đang dùng CSDL được lưu trong: %1$s + Phân chia giao dịch + Phân chia + Ít nhất phải có một giao dịch được chọn + Xuất dữ liệu ra tệp CSV + Đang xuất dữ liệu. Vui lòng chờ… + Dữ liệu đã được xuất thành công ra tệp %1$s + Xuất tập tin %1$s bị lỗi + MoneyManagerEx for Android is provided free. If this application is to your liking, you can support the development team with a donation. + Google Play In-App Billing + Tặng thông qua Google Play trong ứng dụng thanh toán. + Chọn một số tiền tặng + Tặng tiền + Cảm ơn bạn đã tặng! + Tặng tiền + Không, cảm ơn + Tặng tiền! + Tăng dần + Giảm dần + Xếp theo Tháng + Thư mục trong Dropbox/Ứng dụng/Money Manager Ex Di Động đang trống. Nếu bạn đã dùng Money Manager Ex sao chép cơ sở dữ liệu vào thư mục này của bạn trong máy tính của bạn, và sau đó bạn thực hiện làm mới. + Chọn một tập tin từ Dropbox + Sửa đổi cuối + Dropbox + Cơ sở dữ liệu của bạn đã được tải về + Để sử dụng cơ sở dữ liệu tải về, chạm vào Mở cơ sở dữ liệu + Chạm để chọn tập tin để sử dụng từ Dropbox + Tải về từ Dropbox + Chạm để tùy chọn tải về tập tin được liên kết từ thư mục Dropbox + Tải lên Dropbox + Chạm để tùy chọn tải lên các tập tin được liên kết vào thư mục Dropbox + Cơ sở dữ liệu của bạn đã được tải lên thành công + Dropbox - Money Manager Ex + Dropbox làm việc cho Money Manager Ex như thế nào\? + Không hiện lại nữa + Mở Cơ sở dữ liệu + Thời gian đồng bộ + Tần suất đồng bộ là bao lâu ? + Từ phiên bản 1.2.0 của Money Manager Ex cho Android đã thay đổi quản lý đồng bộ hoá với Dropbox. Cho người dùng những người đã sử dụng đồng bộ với Dropbox, bạn phải thực hiện cấu hình lại. \nCấu hình của đồng bộ với Dropbox và lựa chọn cơ sở dữ liệu, được nằm trong thiết đặt. \nTừ phiên bản 1.2.0 của Money Manager Ex cho Android có thể tự động đồng bộ cơ sở dữ liệu với Dropbox + Tải lên cơ sở dữ liệu ngay lập tức lúc thay đổi + Tùy chọn này cho phép tự động tải lên ngay sau khi bạn thay đổi cơ sở dữ liệu + Hiện số dư cho mỗi giao dịch + Hiện số dư cho cho mỗi giao dịch. Hiển thị số dư có thể làm ứng dụng chậm hơn + Mở Cơ sở dữ liệu + Database--> + Mẹo + Font Ứng dụng + Chọn font bạn muốn cấp cho ứng dụng + Cỡ chữ Ứng dụng + Chọn cỡ chữ bạn muốn cấp cho ứng dụng + Cực nhỏ + Nhỏ + Mặc định + Vừa + Lớn + Đang tải xuống từ Dropbox. Vui lòng chờ… + Đang tải lên Dropbox. Vui lòng chờ… + Nơi tiền Đi + Nơi tiền Đến + Hiển thị tóm tắt về Money Manager Ex cho Android + Xem tóm tắt của mỗi tài khoản Money Manager Ex cho Android + Check time + What time would you check if there are repeating transactions overdue? (default 08:00) + Tác giả + Rút tiền hàng đầu: 30 ngày qua + Người thanh toán hàng đầu: 30 ngày qua + Giao dịch sắp tới + Số lượng + Bảng điều khiển + The database is up to date + 3 tháng qua + 6 tháng qua + Làm trống Danh mục + Làm trống Người thanh toán + Trợ giúp + Xoá giao dịch lặp lại + Đã qua + Tài khoản + Tới Tài khoản + Từ tài khoản + Trạng thái mặc định + Người nhận thanh toán mặc định + Sửa giao dịch + Bạn có chắc bạn muốn xóa giao dịch đã chọn không? + Bạn có chắc bạn muốn xóa %d giao dịch đã chọn? + Danh mục + Tiền tệ + Người nhận thanh toán + Giao dịch lặp lại + Holo Sáng + Tài khoản mới + Nhập tiền tệ + Đang nhập tiền tệ. Vui lòng chờ… + Số tiền lớn hơn hoặc bằng + Số tiền ít hơn hoặc bằng + Kết quả tìm kiếm của bạn + Giao dịch lặp lại mới + Chỉnh sửa giao dịch lặp lại + Mỗi 5 phút + Mỗi 15 phút + Mỗi 30 phút + Mỗi giờ + Mỗi 2 giờ + Mỗi 6 giờ + Mỗi giờ 12 + Không bao giờ + Con đường cơ sở dữ liệu không tồn tại + Cơ sở dữ liệu không thể được mở cho việc ghi + Bạn có muốn nhập tiền tệ? + Khung thời gian + Hiển thị biểu đồ + Thêm giao dịch + Chào mừng đến với MoneyManagerEx! + MoneyManagerEx mô hình tất cả giao dịch thuộc về các tài khoản.\n\nĐể giúp bạn thực hiện, bắt đầu bằng cách làm một danh sách tất cả các tổ chức tài chính, nơi bạn giữ một tài khoản.\n\nChạm ở đây để bắt đầu nhập các tài khoản của bạn. + Nếu bạn đã sử dụng MoneyManagerEx trên Windows, Linux hoặc Mac liên kết ứng dụng này với Dropbox để đồng bộ cơ sở dữ liệu của bạn + Cấu hình Dropbox + Tìm kiếm bằng nội dung văn bản và không phải bằng văn bản bắt đầu với + Tìm kiếm người nhận thanh toán, danh mục, loại tiền tệ, v.v... theo nội dung và không theo bắt đầu các kí tự + Đánh giá Ứng dụng + Application Language + Tiếng Séc + Tiếng Anh + Tiếng Tây Ban Nha + Tiếng Pháp + Tiếng Do Thái + Tiếng Ý + Tiếng Bồ Đào Nha + Tiếng Bồ Đào Nha, Brazil + Tiếng Nga + Tiếng Việt + Tiếng Trung giản thể + Tiếng Trung truyền thống + Đang cập nhật tỷ giá hối đoái của tiền tệ. Vui lòng chờ... + Đang cập nhậy tỉ giá hối đoái:\n%1$s + Tất cả tỷ giá hối đoái của tiền tệ đã được cập nhật thành công + Cập Nhật Tỷ giá hối đoái + Bạn có muốn cập nhật tỷ giá hối đoái? + Rút khỏi từ %1$s + Khoản tiền gửi tới %1$s + Trang web MoneyManagerEx + You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! + Retrieving status of your donations from Google Play. Please wait… + Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. + Notification Repeating Transaction overdue + Show notification for repeating transaction overdue diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 1dc64db739..aaa5529ec0 100755 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -1,344 +1,355 @@ - - + - © 2012 The Android Money Manager Ex 專案 - 一個簡單易用的管理個人財務、銀行帳戶、家庭預算等的應用程式。 - Android Money Manager Ex 專案使用 ActionBarSherlock 和 RobotMediaBilling 程式庫 - 開放原始碼授權 - 新增資料失敗 - 刪除資料失敗 - 更新資料失敗 - 離開 - 管理 - 連結至 Dropbox - 斷開 Dropbox 連結 - 同步檔案中,請稍候... - 由 Dropbox 下載檔案中,請稍候… - 上傳檔案至 Dropbox 中,請稍候… - Dropbox 檔案 - 一般 - 顯示 - 預設貨幣 - 顯示已啟用帳戶 - 未勾選將顯示全部帳戶 - 顯示常用帳戶 - 版本 - 建立於 - 帳戶 - 帳戶清單 - 無帳戶存在 - 結餘 - 已核實 - 刪除帳戶 - 帳戶名稱 - 帳戶類型 - 帳戶號碼 - 商戶名稱 - 帳戶狀態 - 常用帳戶 - 選擇貨幣 - 支票/存款/信用卡 - 投資 - 限期 - 新增帳戶失敗 - 更新帳戶失敗 - 需要貨幣 - 需要帳戶初始金額 - 需要帳戶名稱 - 需要帳戶類型 - 需要帳戶狀態 - 受帳人名稱 - 編輯受帳人 - 刪除受帳人 - 受帳人 - 選擇受帳人 - 無受帳人存在 - - 更新受帳人失敗 - 類型 - 子類別 - 無類型存在 - 選擇類型 - 新增類型 - 新增副類型 - 編輯類別 - 刪除類型 - 貨幣名稱 - 貨幣代碼 - 刪除貨幣 - 單位名稱 - 1/100單位 - 前綴符號 - 後綴符號 - 小數點文字 - 每3位數分隔文字 - 比例 - 轉換為基本利率 - 需要貨幣名稱 - 金額 - 金額 - 收入 - 狀態 - 已核實 - 作廢 - 需要追蹤 - 重複的 - 未核實 - 轉帳 - 交易種類 - 狀態 - 支出 - 新增交易失敗 - 更新交易失敗 - 刪除交易 - 新增交易 - 要需受帳人 - 需要轉帳帳戶 - 需要類型 - 需要總金額 - 關於 - 新增 - 你確定要刪除? - 日期 - 刪除 - 下載 - 編輯 - Logo - 新增/編輯交易 - 重新整理 - 搜尋 - 設定 - 摘要 - 同步 - 啟用 - 使用者 - 上傳 - 使用者姓名 - - 網站 - 聯絡 - 登入資訊 - 初始金額 - 備註 - 關閉 - 新增/編輯貨幣 - 布景主題 - Holo Light With Dark ActionBar - 離開 - 你確定要離開? - 無檔案管理程式 - 注意 - 受帳人不能被刪除,因為它已被使用 - 帳戶不能被刪除,因為它已被使用 - 貨幣不能被刪除,因為它已被使用 - 類型不能被刪除,因為它已被使用 - 所有交易紀錄 - 最近7天 - 最近2週 - 本月 - 今年 - 顯示交易紀錄 - 更新日誌 - 交易編號 - Money Manager Ex 摘要 - Money Manager Ex 全部帳戶 - Money Manager Ex 新增交易 - 無循環交易 - - 每週 - 雙週 - 每月 - 雙月 - 每季 - 每半年 - 每年 - 每四個月 - 每四週 - 每日 - 再 (x) 日 - 再 (x) 月 - 每 (x) 日 - 每 (x) 月 - 未啟用 - 日 - 過期 - 日 - 到期 - 新增/編輯循環交易 - 下次到期日 - 重複類型 - 重複次數 - 需要下次到期的交易 - 啟動 - 確認下次交易 - 跳過下次交易 - 有過期的循環交易 - 點擊以檢查逾期交易 - %1$d 循環交易過期 - 傳送建議 - 關於 - 安全 - 啟用密碼 - 輸入你的密碼 - 重新輸入您的新密碼 - 密碼不匹配 - 編輯密碼 - 取消密碼 - 輸入你的前次密碼 - 密碼未更新 - 搜尋時可用 % 作為萬用字元 - 損益表: 本月 - 收入 - 支出 - 結餘 - 無資料 - - - 報表 - 損益表 - 總計 - 全部 - 前一個月 - 最近30天 - 前一年 - 交易次數: %1$d - 日期格式 - 會計年度:起日 - 會計年度:起月 - 資料庫已移動: %1$s - 複製資料庫到外部儲存空間失敗 - 你的資料庫儲存在: %1$s - 拆分交易 - 拆分 - 需要至少一筆拆分交易 - 將資料匯出到 CSV 檔 - 匯出資料中,請稍候... - 資料已成功匯出到 %1$s - 匯出檔案 %1$s 失敗 - Android Money Manager Ex 是免費軟體。假如你喜歡本程式,你可以捐款以支援開發團隊。 - 透過 Google Play In-App Billing 捐款 - 選擇捐款金額 - 捐款 - 感謝你的捐款! - 捐款 - 不,謝謝 - 捐款! - 順序 - 反序 - 月排序 - Dropbox/Apps/Money Manager Ex Mobile 的資料夾無檔案。如果您已使用過 MoneyManagerEx ,請使用電腦將資料庫複製到此資料夾,然後再次更新。 - 從 Dropbox 選擇一個檔案 - 上次異動 - 您的資料庫已被下載 - 若要使用資料庫下載,點擊開啟資料庫 - 請從 Dropbox 選擇要使用的檔案 - 從 Dropbox 下載 - 點擊後從 Dropbox 資料夾手動下載連結的檔 - 上傳到 Dropbox - 點擊後手動上傳連結的檔案到 Dropbox 資料夾 - 您的資料庫已經上傳成功 - Dropbox 在 Money Manager Ex 裡的功用為何? - 不要再顯示 - 開啟資料庫 - 同步時間間隔 - 同步週期為何? - Money Manager Ex for Android 1.2.0版修改了同步 Dropbox 的機制,已使用同步 Dropbox 的使用者必須重新設定。\nDropbox 與資料庫同步的設定,在設定選單中。\n自 Money Manager Ex for Android 1.2.0版開始能自動和 Dropbox 同步資料庫。 - 資料庫有異動時立即上傳 - 當你異動資料庫時會立即自動上傳 - 顯示每筆交易金額 - 顯示每筆交易金額,這會使本程式顯示地非常慢 - 開啟資料庫 - 提示 - 字型 - 選擇字型 - 字型大小 - 選擇字型大小 - 微小 - - 預設 - - - 從 Dropbox 下載,請稍候... - 上傳到 Dropbox,請稍候... - 支出 - 收入 - 顯示 Money Manager Ex for Android 摘要 - 觀看所有帳戶摘要 Money Manager Ex for Android - 排程檢查循環交易是否過期 - 指定每天檢查循環交易是否過期的時間 (預設 08:00) - 鳴謝 - 支出最多之類型: 最近30天 - 交易金額最多之受帳人: 最近30天 - 即將到來的交易項目 - 次數 - 統計表板 - 資料庫已同步 - 最近3月 - 最近6月 - 無類型 - 無受帳人 - 說明 - 刪除循環交易 - 最後 - 帳戶 - 到帳戶 - 從帳戶 - 預設狀態 - 預設受帳人 - 編輯交易 - 你確定要刪除所選的交易紀錄? - 你確定要刪除所選的 %d 筆交易紀錄? - 類型 - 貨幣 - 受帳人 - 循環交易 - Holo Light - 新增帳戶 - 匯入貨幣 - 匯入貨幣中,請稍候... - 金額大於或等於 - 金額小於或等於 - 您搜尋的結果 - 新增循環交易 - 編輯循環交易 - 每隔 5 分鐘 - 每隔 15 分鐘 - 每隔 30 分鐘 - 每小時 - 每隔 2 小時 - 每隔 6 小時 - 每隔 12 小時 - 永遠不要 - 資料庫路徑不存在 - 該資料庫無法開啟以寫入 - 你要匯入貨幣嗎? - 時間框架 - 顯示圖表 - 新增交易 - 歡迎使用 MoneyManagerEx - MoneyManagerEx 令所有交易皆屬於帳戶。\ n\ n為了能讓您正常使用,請以建立所有金融機構的帳戶開始。\n\n點選此處後進入你的帳戶。 - 如果您已經在 Windows 、 Linux 或 Mac 上使用 MoneyManagerEx,將此程式連結到 Dropbox 可以同步您的資料庫 - 設定 Dropbox - 由文字內容搜尋,且不是以文字開頭的文件 - 由內容而非起始的文字搜尋受帳人、類型、貨幣等 - 幫我們評分 - 應用程式語系 - 捷克文 - 英語 - 西班牙文 - 法文 - 希伯來文 - 義大利文 - 葡萄牙文 - 巴西葡萄牙文 - 俄語 - 越南文 - 簡體中文 - 正體中文 - 更新匯率中,請稍候... - 更新匯率:\n%1$s - 已更新所有的貨幣匯率 - 更新匯率 - 你想要更新匯率嗎? - 由 %1$s 匯出 - 匯入到 %1$ s - MoneyManagerEx 網站 + Money Manager Ex + 一個簡單易用的管理個人財務、銀行帳戶、家庭預算等的應用程式。 + MoneyManagerEx for Android Project uses ActionBarSherlock library + 開放原始碼授權 + 新增資料失敗 + 刪除資料失敗 + 更新資料失敗 + 離開 + 管理 + 連結至 Dropbox + 斷開 Dropbox 連結 + 同步檔案中,請稍候... + 由 Dropbox 下載檔案中,請稍候… + 上傳檔案至 Dropbox 中,請稍候… + Dropbox 檔案 + 一般 + Look & Feel + 預設貨幣 + 顯示已啟用帳戶 + 未勾選將顯示全部帳戶 + 顯示常用帳戶 + 版本 + 建立於 + Database path + 帳戶 + 帳戶清單 + 無帳戶存在 + 結餘 + 已核實 + 刪除帳戶 + 帳戶名稱 + 帳戶類型 + 帳戶號碼 + 商戶名稱 + 帳戶狀態 + 常用帳戶 + 選擇貨幣 + 支票/存款/信用卡 + 投資 + 限期 + 新增帳戶失敗 + 更新帳戶失敗 + 需要貨幣 + 需要帳戶初始金額 + 需要帳戶名稱 + 需要帳戶類型 + 需要帳戶狀態 + 受帳人名稱 + 編輯受帳人 + 刪除受帳人 + 受帳人 + 選擇受帳人 + 無受帳人存在 + + 更新受帳人失敗 + 類型 + 子類別 + 無類型存在 + 選擇類型 + 新增類型 + 新增副類型 + 編輯類別 + 刪除類型 + 貨幣名稱 + 貨幣代碼 + 刪除貨幣 + 單位名稱 + 1/100單位 + 前綴符號 + 後綴符號 + 小數點文字 + 每3位數分隔文字 + 比例 + 轉換為基本利率 + 需要貨幣名稱 + 金額 + 金額 + 收入 + 狀態 + 已核實 + 作廢 + 需要追蹤 + 重複的 + 未核實 + 轉帳 + 交易種類 + 狀態 + 支出 + 新增交易失敗 + 更新交易失敗 + 刪除交易 + 新增交易 + 要需受帳人 + 需要轉帳帳戶 + 需要類型 + 需要總金額 + 關於 + 新增 + 你確定要刪除? + 日期 + 刪除 + 下載 + 編輯 + Logo + 新增/編輯交易 + 重新整理 + 搜尋 + 設定 + 摘要 + 同步 + 啟用 + 使用者 + 上傳 + 使用者姓名 + + 網站 + 聯絡 + 登入資訊 + 初始金額 + 備註 + 關閉 + 新增/編輯貨幣 + Theme + Holo + Holo Light With Dark ActionBar + 離開 + 你確定要離開? + 無檔案管理程式 + 注意 + 受帳人不能被刪除,因為它已被使用 + 帳戶不能被刪除,因為它已被使用 + 貨幣不能被刪除,因為它已被使用 + 類型不能被刪除,因為它已被使用 + 所有交易紀錄 + 最近7天 + 最近2週 + 本月 + 今年 + 顯示交易紀錄 + 更新日誌 + 交易編號 + Money Manager Ex 摘要 + Money Manager Ex 全部帳戶 + Money Manager Ex 新增交易 + 無循環交易 + + 每週 + 雙週 + 每月 + 雙月 + 每季 + 每半年 + 每年 + 每四個月 + 每四週 + 每日 + 再 (x) 日 + 再 (x) 月 + 每 (x) 日 + 每 (x) 月 + 未啟用 + 日 - 過期 + 日 - 到期 + 新增/編輯循環交易 + 下次到期日 + 重複類型 + 重複次數 + 需要下次到期的交易 + 啟動 + 確認下次交易 + 跳過下次交易 + 有過期的循環交易 + 點擊以檢查逾期交易 + %1$d 循環交易過期 + 傳送建議 + 關於 + 安全 + 啟用密碼 + 輸入你的密碼 + 重新輸入您的新密碼 + 密碼不匹配 + 編輯密碼 + 取消密碼 + 輸入你的前次密碼 + 密碼未更新 + 搜尋時可用 % 作為萬用字元 + 損益表: 本月 + 收入 + 支出 + 結餘 + 無資料 + + + 報表 + 損益表 + 總計 + 全部 + 前一個月 + 最近30天 + 前一年 + 交易次數: %1$d + 日期格式 + 會計年度:起日 + 會計年度:起月 + Export database + 資料庫已移動: %1$s + 複製資料庫到外部儲存空間失敗 + 你的資料庫儲存在: %1$s + 拆分交易 + 拆分 + 需要至少一筆拆分交易 + 將資料匯出到 CSV 檔 + 匯出資料中,請稍候... + 資料已成功匯出到 %1$s + 匯出檔案 %1$s 失敗 + MoneyManagerEx for Android is provided free. If this application is to your liking, you can support the development team with a donation. + Google Play In-App Billing + 透過 Google Play In-App Billing 捐款 + 選擇捐款金額 + 捐款 + 感謝你的捐款! + 捐款 + 不,謝謝 + 捐款! + 順序 + 反序 + 月排序 + Dropbox/Apps/Money Manager Ex Mobile 的資料夾無檔案。如果您已使用過 MoneyManagerEx ,請使用電腦將資料庫複製到此資料夾,然後再次更新。 + 從 Dropbox 選擇一個檔案 + 上次異動 + Dropbox + 您的資料庫已被下載 + 若要使用資料庫下載,點擊開啟資料庫 + 請從 Dropbox 選擇要使用的檔案 + 從 Dropbox 下載 + 點擊後從 Dropbox 資料夾手動下載連結的檔 + 上傳到 Dropbox + 點擊後手動上傳連結的檔案到 Dropbox 資料夾 + 您的資料庫已經上傳成功 + Dropbox - Money Manager Ex + Dropbox 在 Money Manager Ex 裡的功用為何? + 不要再顯示 + 開啟資料庫 + 同步時間間隔 + 同步週期為何? + Money Manager Ex for Android 1.2.0版修改了同步 Dropbox 的機制,已使用同步 Dropbox 的使用者必須重新設定。\nDropbox 與資料庫同步的設定,在設定選單中。\n自 Money Manager Ex for Android 1.2.0版開始能自動和 Dropbox 同步資料庫。 + 資料庫有異動時立即上傳 + 當你異動資料庫時會立即自動上傳 + 顯示每筆交易金額 + 顯示每筆交易金額,這會使本程式顯示地非常慢 + 開啟資料庫 + Database--> + 提示 + 字型 + 選擇字型 + 字型大小 + 選擇字型大小 + 微小 + + 預設 + + + 從 Dropbox 下載,請稍候... + 上傳到 Dropbox,請稍候... + 支出 + 收入 + 顯示 Money Manager Ex for Android 摘要 + 觀看所有帳戶摘要 Money Manager Ex for Android + Check time + What time would you check if there are repeating transactions overdue? (default 08:00) + 鳴謝 + 支出最多之類型: 最近30天 + 交易金額最多之受帳人: 最近30天 + 即將到來的交易項目 + 次數 + 統計表板 + The database is up to date + 最近3月 + 最近6月 + 無類型 + 無受帳人 + 說明 + 刪除循環交易 + 最後 + 帳戶 + 到帳戶 + 從帳戶 + 預設狀態 + 預設受帳人 + 編輯交易 + 你確定要刪除所選的交易紀錄? + 你確定要刪除所選的 %d 筆交易紀錄? + 類型 + 貨幣 + 受帳人 + 循環交易 + Holo Light + 新增帳戶 + 匯入貨幣 + 匯入貨幣中,請稍候... + 金額大於或等於 + 金額小於或等於 + 您搜尋的結果 + 新增循環交易 + 編輯循環交易 + 每隔 5 分鐘 + 每隔 15 分鐘 + 每隔 30 分鐘 + 每小時 + 每隔 2 小時 + 每隔 6 小時 + 每隔 12 小時 + 永遠不要 + 資料庫路徑不存在 + 該資料庫無法開啟以寫入 + 你要匯入貨幣嗎? + 時間框架 + 顯示圖表 + 新增交易 + 歡迎使用 MoneyManagerEx + MoneyManagerEx 令所有交易皆屬於帳戶。\ n\ n為了能讓您正常使用,請以建立所有金融機構的帳戶開始。\n\n點選此處後進入你的帳戶。 + 如果您已經在 Windows 、 Linux 或 Mac 上使用 MoneyManagerEx,將此程式連結到 Dropbox 可以同步您的資料庫 + 設定 Dropbox + 由文字內容搜尋,且不是以文字開頭的文件 + 由內容而非起始的文字搜尋受帳人、類型、貨幣等 + 幫我們評分 + Application Language + 捷克文 + 英語 + 西班牙文 + 法文 + 希伯來文 + 義大利文 + 葡萄牙文 + 巴西葡萄牙文 + 俄語 + 越南文 + 簡體中文 + 正體中文 + 更新匯率中,請稍候... + 更新匯率:\n%1$s + 已更新所有的貨幣匯率 + 更新匯率 + 你想要更新匯率嗎? + 由 %1$s 匯出 + 匯入到 %1$ s + MoneyManagerEx 網站 + You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! + Retrieving status of your donations from Google Play. Please wait… + Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. + Notification Repeating Transaction overdue + Show notification for repeating transaction overdue diff --git a/res/values/prefids.xml b/res/values/prefids.xml index 8399c0759d..98855df826 100644 --- a/res/values/prefids.xml +++ b/res/values/prefids.xml @@ -29,18 +29,19 @@ versiondate sqliteversion dropbox2download - dropbox2upload - dropbox2howitworks - dropbox2servicetimesrepeat - dropbox2uploadimmediate - transactionshownbalance - prefdatabasebackup - prefapplicationfont - prefapplicationfontsize - prefrepeatingtransactionchecktime - prefdropboxwiki - prefdefaultstatus - prefdefaultpayee - preftextsearchtype - preflocale + dropbox2upload + dropbox2howitworks + dropbox2servicetimesrepeat + dropbox2uploadimmediate + transactionshownbalance + prefdatabasebackup + prefapplicationfont + prefapplicationfontsize + prefrepeatingtransactionchecktime + prefdropboxwiki + prefdefaultstatus + prefdefaultpayee + preftextsearchtype + preflocale + prefrepeatingtransactionnotifications \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 6c97e613e2..34c3940794 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -185,7 +185,7 @@ Closed New/Edit Currency - Theme application + Theme Holo Holo Light With Dark ActionBar @@ -371,8 +371,8 @@ Displays the summary of Money Manager Ex for Android View the summary of each account Money Manager Ex for Android - Schedule Check Repeating Transaction Overdue - Indicate what time of day the application should check if there are repeating transaction overdue (default 08:00) + Check time + What time would you check if there are repeating transactions overdue? (default 08:00) Credits @@ -470,8 +470,11 @@ Withdrawal From %1$s Deposit To %1$s MoneyManagerEx Website - + You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! Retrieving status of your donations from Google Play. Please wait… Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. + + Notification Repeating Transaction overdue + Show notification for repeating transaction overdue \ No newline at end of file diff --git a/res/xml/prefrences.xml b/res/xml/prefrences.xml index 5a0d2721e9..0b44c1c89d 100644 --- a/res/xml/prefrences.xml +++ b/res/xml/prefrences.xml @@ -1,14 +1,14 @@ - + - + - + - + - + - + @@ -43,21 +43,28 @@ - + + android:title="@string/search_text_contain_title" /> + + - + - + - + @@ -112,7 +119,7 @@ android:key="@string/pref_disable_passcode" android:title="@string/preferences_disable_passcode" /> - + @@ -125,7 +132,7 @@ + android:title="@string/dropbox"> @@ -136,9 +143,9 @@ diff --git a/src/com/money/manager/ex/core/MoneyManagerBootReceiver.java b/src/com/money/manager/ex/core/MoneyManagerBootReceiver.java index 5f98b029f9..c8121859ac 100644 --- a/src/com/money/manager/ex/core/MoneyManagerBootReceiver.java +++ b/src/com/money/manager/ex/core/MoneyManagerBootReceiver.java @@ -15,39 +15,41 @@ public class MoneyManagerBootReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - try { - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - // compose intent - Intent i = new Intent(context, RepeatingTransactionReceiver.class); - PendingIntent pending = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT); - // take hour to start - String hour = PreferenceManager.getDefaultSharedPreferences(context).getString(PreferencesConstant.PREF_REPEATING_TRANSACTION_CHECK, "08:00"); - // take a calendar and current time - Calendar calendar = Calendar.getInstance(); - Calendar currentCalendar = Calendar.getInstance(); - currentCalendar.setTimeInMillis(System.currentTimeMillis()); - // set time preferences - calendar.add(Calendar.DAY_OF_YEAR, currentCalendar.get(Calendar.DAY_OF_YEAR)); - calendar.set(Calendar.SECOND, currentCalendar.get(Calendar.SECOND)); - calendar.set(Calendar.MILLISECOND, currentCalendar.get(Calendar.MILLISECOND)); - calendar.set(Calendar.DATE, currentCalendar.get(Calendar.DATE)); - calendar.set(Calendar.MONTH, currentCalendar.get(Calendar.MONTH)); - calendar.set(Calendar.YEAR, currentCalendar.get(Calendar.YEAR)); - calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hour.substring(0, 2))); - calendar.set(Calendar.MINUTE, Integer.parseInt(hour.substring(3, 5))); - // add one day if hour was passed - if (calendar.getTimeInMillis() < currentCalendar.getTimeInMillis()) { - calendar.add(Calendar.DATE, 1); - } - // cancel old pending intent - alarmManager.cancel(pending); - // start alarmanager - alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending); - } catch (Exception e) { - Log.e(MoneyManagerBootReceiver.class.getSimpleName(), e.getMessage()); - } - } + @Override + public void onReceive(Context context, Intent intent) { + try { + if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PreferencesConstant.PREF_REPEATING_TRANSACTION_NOTIFICATIONS, true)) { + AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + // compose intent + Intent i = new Intent(context, RepeatingTransactionReceiver.class); + PendingIntent pending = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT); + // take hour to start + String hour = PreferenceManager.getDefaultSharedPreferences(context).getString(PreferencesConstant.PREF_REPEATING_TRANSACTION_CHECK, "08:00"); + // take a calendar and current time + Calendar calendar = Calendar.getInstance(); + Calendar currentCalendar = Calendar.getInstance(); + currentCalendar.setTimeInMillis(System.currentTimeMillis()); + // set time preferences + calendar.add(Calendar.DAY_OF_YEAR, currentCalendar.get(Calendar.DAY_OF_YEAR)); + calendar.set(Calendar.SECOND, currentCalendar.get(Calendar.SECOND)); + calendar.set(Calendar.MILLISECOND, currentCalendar.get(Calendar.MILLISECOND)); + calendar.set(Calendar.DATE, currentCalendar.get(Calendar.DATE)); + calendar.set(Calendar.MONTH, currentCalendar.get(Calendar.MONTH)); + calendar.set(Calendar.YEAR, currentCalendar.get(Calendar.YEAR)); + calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hour.substring(0, 2))); + calendar.set(Calendar.MINUTE, Integer.parseInt(hour.substring(3, 5))); + // add one day if hour was passed + if (calendar.getTimeInMillis() < currentCalendar.getTimeInMillis()) { + calendar.add(Calendar.DATE, 1); + } + // cancel old pending intent + alarmManager.cancel(pending); + // start alarmanager + alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending); + } + } catch (Exception e) { + Log.e(MoneyManagerBootReceiver.class.getSimpleName(), e.getMessage()); + } + } } diff --git a/src/com/money/manager/ex/preferences/PreferencesConstant.java b/src/com/money/manager/ex/preferences/PreferencesConstant.java index 46fc234e84..140419a0b1 100644 --- a/src/com/money/manager/ex/preferences/PreferencesConstant.java +++ b/src/com/money/manager/ex/preferences/PreferencesConstant.java @@ -46,11 +46,12 @@ public class PreferencesConstant { public static final String PREF_LOCALE = "preflocale"; // others preference setting don't display public static final String PREF_DROPBOX_ACCOUNT_PREFS_NAME = "com.money.manager.ex_dropbox_preferences"; - public static final String PREF_DROPBOX_ACCESS_KEY_NAME = "ACCESS_KEY"; - public static final String PREF_DROPBOX_ACCESS_SECRET_NAME = "ACCESS_SECRET"; + public static final String PREF_DROPBOX_ACCESS_KEY_NAME = "ACCESS_KEY"; + public static final String PREF_DROPBOX_ACCESS_SECRET_NAME = "ACCESS_SECRET"; public static final String PREF_DROPBOX_REMOTE_FILE = "DROPBOX_REMOTE_FILE"; // check repeating transacion public static final String PREF_REPEATING_TRANSACTION_CHECK = "prefrepeatingtransactionchecktime"; + public static final String PREF_REPEATING_TRANSACTION_NOTIFICATIONS = "prefrepeatingtransactionnotifications"; // Wiki dropbox public static final String PREF_DROPBOX_WIKI = "prefdropboxwiki"; } From 1a63888f2c81bea0526348edccc5b6010e9ba6ca Mon Sep 17 00:00:00 2001 From: AlessandroLazzari Date: Mon, 27 Oct 2014 21:53:03 +0100 Subject: [PATCH 12/12] update transaltions --- build.gradle | 2 +- res/raw/changelog.xml | 5 +-- res/values-cs/strings.xml | 35 ++++++++++--------- res/values-fr/strings.xml | 5 +-- res/values-he/strings.xml | 3 +- res/values-hu/strings.xml | 23 ++++++------ res/values-it/strings.xml | 3 +- res/values-pl/strings.xml | 33 ++++++++--------- res/values-pt/strings.xml | 33 ++++++++--------- res/values-ru/strings.xml | 23 ++++++------ res/values-vi/strings.xml | 3 +- res/values-zh-rTW/strings.xml | 35 ++++++++++--------- res/values/privatestrings.xml | 2 +- .../money/manager/ex/AccountListActivity.java | 8 +++-- ...gorySubCategoryExpandableListActivity.java | 24 +++++++------ .../ex/CurrencyFormatsListActivity.java | 8 +++-- src/com/money/manager/ex/PayeeActivity.java | 8 +++-- 17 files changed, 136 insertions(+), 117 deletions(-) diff --git a/build.gradle b/build.gradle index 0bb66b00c6..f321482d46 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ android { applicationId 'com.money.manager.ex' minSdkVersion 8 targetSdkVersion 19 - versionCode 586 + versionCode 597 versionName '1.4.15' } sourceSets { diff --git a/res/raw/changelog.xml b/res/raw/changelog.xml index 51d3eb6098..0bea88e938 100644 --- a/res/raw/changelog.xml +++ b/res/raw/changelog.xml @@ -1,9 +1,10 @@ - + + Added setting to enable/disable repeating transaction notifications Fixed issue that shows the messagebox of the donation, even if you've already donated + Fixed issue in searching of accounts, categories, currencies and payees Migrate to Google In App Billing v3 - Remove libray Robotmedia Fixed other minor bugs diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index e8add6496a..53008da04b 100755 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -1,8 +1,9 @@ - + + Money Manager Ex Jednoduchá a snadno použitelná aplikace pro správu osobních financí, bankovních účtů, rodinného rozpočtu a tak dále. - MoneyManagerEx for Android Project uses ActionBarSherlock library + MoneyManagerEx pro Android projekt používá knihovny ActionBarSherlock Open source licence Vkládání dat se nezdařilo Mazání dat se nezdařilo @@ -16,14 +17,14 @@ Nahrávám souboru na Dropbox. Počkejte prosím… Soubor Dropbox Obecné - Look & Feel + Vzhled & chování Základní měna Zobrazit otevřené účty Pokud není vybráno pak zobrazit všechny účty Zobrazit oblíbené účty Verze Build - Database path + Cesta k databázi Účet Seznam účtů Nenalezeny žádné účty @@ -122,7 +123,7 @@ Poznámky Zavřený Nová/úprava měny - Theme + Vzhled Holo Holo světlé s tmavou lištou Ukončit aplikaci @@ -204,7 +205,7 @@ Formát data Fiskální rok: První den Fiskální rok: První měsíc - Export database + Export databáze Databáze byla přesunuta: %1$s Kopírování databáze na externí úložiště selhalo Používáte databázi uloženou na: %1$s @@ -215,7 +216,7 @@ Exportuji data. Čekejte prosím… Data byla úspěšně uložena do souboru %1$s Export souboru %1$s selhal - MoneyManagerEx for Android is provided free. If this application is to your liking, you can support the development team with a donation. + MoneyManagerEx pro Android je poskytován zdarma. Je-li tato aplikace podle vašich představ, můžete podpořit vývojový tým obdarováním. Google Play In-App Billing Přispět přes Google Play In-App Billing. Vyberte částku příspěvku @@ -251,7 +252,7 @@ Zobrazí zůstatek pro každou transakci Zobrazí zůstatek pro každou transakci. Zobrazení zůstatku může zpomalit aplikaci Otevřít databázi - Database--> + Databáze--> Tipy Písmo aplikace Vyberte písmo, které má používat aplikace @@ -268,15 +269,15 @@ Peníze příchozí Zobrazit přehled v Money Manager Ex pro Android Zobrazit Shrnutí každého účtu v Money Manager Ex pro Android - Check time - What time would you check if there are repeating transactions overdue? (default 08:00) + Čas kontroly + V kolik hodin chcete zkontrolovat, zda jsou zpožděné opakující se transakce? (výchozí 08:00) Poděkování Největší výběry: Posledních 30 dní Největší příjemci: Posledních 30 dní Očekávané transakce Množství Přehled - The database is up to date + Databáze je aktuální Poslední 3 měsíce Posledních 6 měsíců Prázdná kategorie @@ -326,7 +327,7 @@ Hledání v textu podle obsahu a nikoli počátečních písmen Hledání příjemců, kategorií, měn, apod… podle obsahu a nikoli počátečních písmen Hodnocení aplikace - Application Language + Jazyk aplikace Čeština English Španělština @@ -347,9 +348,9 @@ Výběr z %1$s Vkad do %1$s Web MoneyManagerEx - You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! - Retrieving status of your donations from Google Play. Please wait… - Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. - Notification Repeating Transaction overdue - Show notification for repeating transaction overdue + Již jste podporoval rozvoj MoneyManagerEx pro Android obdarováním! \n\nVývojový tým vám děkuje! + Načítání stavu vašich darů ze služby Google Play. Počkejte prosím… + Nelze použít aplikaci in-fakturace. Zkontrolujte, zda je nainstalována nejnovější verze aplikace Play Store. + Oznámení trvalých příkazů po splatnosti + Zobrazit upozornění pro trvaké příkazy po splatnosti diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index e0d63ae68a..b51bbd9e6e 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -1,8 +1,9 @@ - + + Money Manager Ex Une application simple et facile à utiliser pour gérer ses finances personnelles, comptes bancaires, budget familial… - MoneyManagerEx for Android Project uses ActionBarSherlock library + MoneyManagerEx pour Android utilise ActionBarSherlock library License open source L\'insertion de la base de données a échoué Suppression des données échouée diff --git a/res/values-he/strings.xml b/res/values-he/strings.xml index 0cde7c5a83..81a7349feb 100644 --- a/res/values-he/strings.xml +++ b/res/values-he/strings.xml @@ -1,4 +1,5 @@ - + + Money Manager Ex יישום לניהול כספים אישי, פשוט וקל לשימוש, לניהול חשבונות בנק, תקציב משפחה, וכן הלאה. diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 7f1260834f..667a922593 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -1,4 +1,5 @@ - + + Money Manager Ex Egy egyszerű és könnyen használható alkalmazás, amely segít, hogy kézben tartsa pénzügyeit, kezelje a bankszámláit és a családi költségvetést. @@ -16,14 +17,14 @@ Állomány feltöltés Dropbox-ba. Kérem várjon… Dropbox állomány Általános - Look & Feel + Megjelenés Alapértelmezett pénznem Nyitott számlák megjelenítése Ha nincs bejelölve, akkor minden számlát megjelenít Kedvenc számlák megjelenítése Verzió Build - Database path + Adatbázis elérési út Számla Számla lista Nincsenek számlák @@ -122,7 +123,7 @@ Jegyzetek Zárt Új pénznem/szerkesztés - Theme + Téma Holo Holo light sötét műveleti sávval Kilépés @@ -204,7 +205,7 @@ Dátum formátum Pénzügyi év: Kezdő nap Pénzügyi év: Kezdő hónap - Export database + Adatbázis export Az adatbázis másolása megtörtént: %1$s Az adatbázis másolása sikertelen Ün ezt az adatbázist használja: %1$s @@ -251,7 +252,7 @@ Tranzakciónkénti egyenleg Mutatja az egyenleget tranzakciónként is. Ez a megjelenítés lassíthatja a program működését Adatbázis megnyitása - Database--> + Adatbázis--> Tippek Alkalmazás betűtípusa Válasszon betűtípust az alkalmazásban @@ -268,8 +269,8 @@ Bevételek Money Manager Ex for Android összegzés megjelenítése Minden számla összegzésének megjelenítése - Check time - What time would you check if there are repeating transactions overdue? (default 08:00) + Ellenőrzés ideje + Mikor szeretné ellenőrizni az ismétlődő tranzakciók esedékességét? (alapértelmezett idő 08:00) Készítők Legnagyobb kiadások: Elmúlt 30 nap Top partnerek: Elmúlt 30 nap @@ -326,7 +327,7 @@ Keresés a szöveg tartalmában Partner, kategória, pénznem, stb… keresése tartalom, és nem kezdő karakter alapján is Alkalmazás értékelése - Application Language + Alkalmazás nyelve Cseh Angol Spanyol @@ -350,6 +351,6 @@ Ön már támogatta a Money Manager Ex for Android program fejlesztését adományával!\n\nKöszönjük a fejlesztő csapat nevében! Támogatási állapotának lekérése a Google Play szerveréről. Kérem, várjon… Nem tudjuk használni az alkalmazáson belüli számlázást. Ellenőrizze, hogy a Play Áruház legfrissebb verziója van-e telepítve az eszközére. - Notification Repeating Transaction overdue - Show notification for repeating transaction overdue + Értesítés ismétlődő tranzakciók esedékességéről + Esedékességi értesítés megjelenítése az ismétlődő tranzakciók esetén diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 21add04f9c..eb1b893607 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -1,4 +1,5 @@ - + + Money Manager Ex Una applicazione semplice e facile da usare per gestire finanze personali, conti bancari, budget familiare, etc. diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index ebfb48bf05..9022ab7518 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -1,8 +1,9 @@ - + + Money Manager Ex Prosta i łatwa w użyciu aplikacja do zarządzania osobistymi wydatkami, kontami bankowymi, rodzinnym budżetem itp. - MoneyManagerEx for Android Project uses ActionBarSherlock library + MoneyManagerEx dla Androida używa biblioteki ActionBarSherlock Licencje open source Dodanie danych nie powiodło się Usunięcie danych nie powiodło się @@ -23,7 +24,7 @@ Pokazuj ulubione konta Wersja Kompilacja - Database path + Ścieżka do bazy danych Konto Lista kont Nie znaleziono kont @@ -122,7 +123,7 @@ Notatki Zamknięty Tworzenie/edycja waluty - Theme + Motyw Holo Holo Light z ciemnym paskiem akcji Zamknij aplikację @@ -204,7 +205,7 @@ Format daty Rok finansowy: początkowy dzień Rok finansowy: początkowy miesiąc - Export database + Eksportuj bazę danych Baza danych została przeniesiona: %1$s Kopiowanie bazy danych na zewnętrzny nośnik nie powiodło się Używasz bazy danych zapisanej w: %1$s @@ -215,7 +216,7 @@ Eksportowanie danych. Prosze czekać… Dane zostały pomyślnie wyeksportowane do pliku %1$s Eksport do pliku %1$s nie powiódł się - MoneyManagerEx for Android is provided free. If this application is to your liking, you can support the development team with a donation. + MoneyManagerEx dla Androida jest dostępny bezpłatnie. Jeżeli podoba ci się ta aplikacja, możesz wesprzeć zespół twórców dotacją. Google Play In-App Billing Wesprzyj przy pomocy Google Play In-App Billing. Wybierz kwotę wsparcia @@ -251,7 +252,7 @@ Pokazuj saldo każdej transakcji Wyświetla saldo dla każdej transakcji. Włączenie tej opcji może spowolnić działanie aplikacji Otwórz bazę danych - Database--> + Baza danych--> Wskazówki Czcionka Wybierz czcionkę używaną w całej aplikacji @@ -268,15 +269,15 @@ Źródła przychodów Wyświetlanie podsumowanie Money Manager Ex dla Androida Pokaż podsumowanie każdego konta w Money Manager Ex dla Androida - Check time - What time would you check if there are repeating transactions overdue? (default 08:00) + Czas sprawdzania + O której godzinie sprawdzać, czy istnieją zaległe regularne transakcje? (domyślnie 8:00) Twórcy Największe wypłaty: ostatnie 30 dni Główne podmioty: ostatnie 30 dni Nadchodzące transakcje Ilość Panel - The database is up to date + Baza danych jest aktualna Ostatnie 3 miesiące Ostatnie 6 miesięcy Pusta kategoria @@ -326,7 +327,7 @@ Wyszukiwanie w zawartości tekstów, a nie w ich początkach Wyszukuj w całych nazwach płatników, kategorii, walut itd., a nie tylko w ich początkach Oceń aplikację - Application Language + Język aplikacji Czeski Angielski Hiszpański @@ -347,9 +348,9 @@ Wypłata z %1$s Wpłata na %1$s Strona internetowa MoneyManagerEx - You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! - Retrieving status of your donations from Google Play. Please wait… - Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. - Notification Repeating Transaction overdue - Show notification for repeating transaction overdue + Już wsparłeś rozwój MoneyManagerEx dla Android dotacją.\n\nPodziękowania od zespołu twórców! + Pobieranie stanu dotacji z Google Play. Proszę czekać… + Nie można skorzystać z zakupów w aplikacji. Sprawdź, czy zainstalowana jest najnowsza wersja aplikacji Sklep Play. + Powiadomienie o zaległych regularnych transakcjach + Pokazuj powiadomienia o zaległych regularnych transakcjach diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 285e01689a..a19fbbb8af 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -1,8 +1,9 @@ - + + Money Manager Ex Uma aplicação simples e fácil de usar para gerir finanças pessoais, contas bancárias, orçamento familiar, entre outros. - MoneyManagerEx for Android Project uses ActionBarSherlock library + O Projecto MoneyManagerEx para Android usa a biblioteca ActionBarSherlock Licenças de Código Aberto Inserção de dados falhou Exclusão de dados falhou @@ -23,7 +24,7 @@ Mostrar só contas favoritas Versão Build - Database path + Caminho para a Base de Dados Conta Lista de Contas Nenhuma conta encontrada @@ -122,7 +123,7 @@ Notas Fechada Nova/Editar Moeda - Theme + Tema Holo Holo claro com ActionBar escuro Fechar aplicação @@ -204,7 +205,7 @@ Formato de data Ano financeiro: Dia de início Ano financeiro: Mês de inicio - Export database + Exportar base de dados A Base de dados foi movida: %1$s Falha na cópia da Base de dados para a memória externa Está a utilizar a base de dados gravada em: %1$s @@ -215,7 +216,7 @@ Exportação de dados. Aguarde... Os dados foram exportados com êxito para o ficheiro %1$s Ficheiro %1$s falhou a exportação - MoneyManagerEx for Android is provided free. If this application is to your liking, you can support the development team with a donation. + MoneyManagerEx para o Android é fornecido gratuitamente. Se este aplicativo é do seu agrado, você pode oferecer suporte à equipe de desenvolvimento com uma doação. Google Play In-App Billing Doar via Google Play Pagamento na aplicação. Escolha o montante do donativo @@ -251,7 +252,7 @@ Mostrar o saldo de cada movimento Mostrar o saldo de cada movimento poderá tornar a aplicação mais lenta. Abrir Base de Dados - Database--> + Base de dados--> Dicas Tipo de Letra Escolha o tipo de letra que deseja atribuir à aplicação @@ -268,15 +269,15 @@ Receitas Mostrar Resumo do Money Manager Ex Mostrar Resumo de cada Conta do Money Manager Ex - Check time - What time would you check if there are repeating transactions overdue? (default 08:00) + Verificar tempo + A que horas vai verificar se há transacções recorrentes em atraso? (padrão 08:00) Créditos Principais Levantamentos: Últimos 30 dias Principais Entidades: Últimos 30 dias Transações futuras Quantidade Painel de controle - The database is up to date + A base de dados está actualizada Últimos 3 meses Últimos 6 meses Categoria vazia @@ -326,7 +327,7 @@ Pesquisar no conteúdo do texto e não por texto a começar por Pesquisar beneficiários, categorias, moedas, etc... pelo conteúdo e não pelos caracteres iniciais Avaliar aplicação - Application Language + Idioma da aplicação Czech inglês Spanish @@ -347,9 +348,9 @@ Levantamentos de %1$s Depósito para %1$s Site do MoneyManager - You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! - Retrieving status of your donations from Google Play. Please wait… - Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. - Notification Repeating Transaction overdue - Show notification for repeating transaction overdue + Você já apoiou o desenvolvimento do MoneyManagerEx para o Android com a sua doação! \n\nObrigada da equipe de desenvolvimento! + Recuperando o status das suas doações da Google Play. Aguarde... + Não é possível usar facturação na app. Verifique se a versão mais recente do aplicativo Play Store está instalada. + Notificação de transacção recorrente em atraso + Mostrar notificação para transacção recorrente em atraso diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 7d879efed2..b86fdd6ca7 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -1,4 +1,5 @@ - + + Money Manager Ex Простое и легкое в использовании приложение для управления личными финансами, банковским счетам, семейным бюджетом, и т.д. @@ -16,14 +17,14 @@ Загружаю файл в Dropbox. Пожалуйста подождите… Файл Dropbox Основные - Look & Feel + Внешний вид Базовая валюта Просмотр открытых счетов Если не выбрана, будут отображаться все счета Просмотр избранных счетов Версия Номер сборки - Database path + Путь к базе данных Счет Список счетов Список счетов пустой @@ -122,7 +123,7 @@ Заметки Закрыт Создать/Редактировать валюту - Theme + Тема оформления Holo Holo светлая с темным ActionBar Закрыть приложение @@ -204,7 +205,7 @@ Формат даты Финансовый год: День начала Финансовый год: Месяц начала - Export database + Экспорт базы данных База данных была перемещена: %1$s Копирование базы данных на внешнее хранилище не удалось Путь до используемой базы данных: %1$s @@ -251,7 +252,7 @@ Показывать баланс для каждой проводки Показывать баланс для каждой проводки. Отображение баланса может замедлить работу приложения. Открыть Базу данных - Database--> + База данных--> Советы Шрифт приложения Выберите шрифт @@ -268,8 +269,8 @@ Откуда приходят деньги Отображение сводки Money Manager Ex для Android Просмотр сводки по каждому счету Money Manager Ex для Android - Check time - What time would you check if there are repeating transactions overdue? (default 08:00) + Время проверки + В какое время проверять, если есть просроченные запланированные проводки? (по умолчанию 08:00) Благодарность Топ снятия: Последние 30 дней Топ получателей: Последние 30 дней @@ -326,7 +327,7 @@ Поиск по содержимому текста, а не только с начала строки Поиск среди контрагентов, категорий, валют и.т.д.… по всему содержимому текста, а не только с начала строки Оценить приложение - Application Language + Язык приложения чешский Английский Испанский @@ -350,6 +351,6 @@ Вы уже поддержали разработчиков MoneyManagerEx для Android внеся пожертвование!\n\nБольшое спасибо от группы разработчиков! Запрашиваем статус ваших пожертвований через Google Play. Пожалуйста подождите… Невозможно использовать функцию оплаты из программы. Проверьте, что у вас установлена последняя версия приложения Google Play Store. - Notification Repeating Transaction overdue - Show notification for repeating transaction overdue + Уведомление запланированных просроченных проводок + Показать уведомления для запланированных и просроченных проводок diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index e77a31cd5d..93e6e89e5b 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -1,4 +1,5 @@ - + + Money Manager Ex Một ứng dụng đơn giản và dễ dàng sử dụng để quản lý tài chính cá nhân, tài khoản ngân hàng, ngân sách gia đình, và v.v... diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index aaa5529ec0..5d37fe350c 100755 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -1,8 +1,9 @@ - + + Money Manager Ex 一個簡單易用的管理個人財務、銀行帳戶、家庭預算等的應用程式。 - MoneyManagerEx for Android Project uses ActionBarSherlock library + MoneyManagerEx for Android 專案使用 ActionBarSherlock 程式庫 開放原始碼授權 新增資料失敗 刪除資料失敗 @@ -16,14 +17,14 @@ 上傳檔案至 Dropbox 中,請稍候… Dropbox 檔案 一般 - Look & Feel + 外觀和感覺 預設貨幣 顯示已啟用帳戶 未勾選將顯示全部帳戶 顯示常用帳戶 版本 建立於 - Database path + 資料庫位置 帳戶 帳戶清單 無帳戶存在 @@ -122,7 +123,7 @@ 備註 關閉 新增/編輯貨幣 - Theme + 主題 Holo Holo Light With Dark ActionBar 離開 @@ -204,7 +205,7 @@ 日期格式 會計年度:起日 會計年度:起月 - Export database + 匯出資料庫 資料庫已移動: %1$s 複製資料庫到外部儲存空間失敗 你的資料庫儲存在: %1$s @@ -215,7 +216,7 @@ 匯出資料中,請稍候... 資料已成功匯出到 %1$s 匯出檔案 %1$s 失敗 - MoneyManagerEx for Android is provided free. If this application is to your liking, you can support the development team with a donation. + MoneyManagerEx for Android 是免費軟體。如果您喜歡本程式,您可以捐款支援開發團隊。 Google Play In-App Billing 透過 Google Play In-App Billing 捐款 選擇捐款金額 @@ -251,7 +252,7 @@ 顯示每筆交易金額 顯示每筆交易金額,這會使本程式顯示地非常慢 開啟資料庫 - Database--> + 資料庫--> 提示 字型 選擇字型 @@ -268,15 +269,15 @@ 收入 顯示 Money Manager Ex for Android 摘要 觀看所有帳戶摘要 Money Manager Ex for Android - Check time - What time would you check if there are repeating transactions overdue? (default 08:00) + 檢查時間 + 何時檢查是否有循環交易逾期?(預設 08:00) 鳴謝 支出最多之類型: 最近30天 交易金額最多之受帳人: 最近30天 即將到來的交易項目 次數 統計表板 - The database is up to date + 資料庫已更新 最近3月 最近6月 無類型 @@ -326,7 +327,7 @@ 由文字內容搜尋,且不是以文字開頭的文件 由內容而非起始的文字搜尋受帳人、類型、貨幣等 幫我們評分 - Application Language + 應用程式語言 捷克文 英語 西班牙文 @@ -347,9 +348,9 @@ 由 %1$s 匯出 匯入到 %1$ s MoneyManagerEx 網站 - You already supported the development of MoneyManagerEx for Android with your donation!\n\nThank you from development team! - Retrieving status of your donations from Google Play. Please wait… - Cannot use the in-app billing. Check whether the latest version of the Play Store application is installed. - Notification Repeating Transaction overdue - Show notification for repeating transaction overdue + 您已經捐款支持 MoneyManagerEx for android 的開發! \n\n開發團隊感謝您! + 正由 Google Play 檢查您的捐贈情形。請稍候… + 無法透過應用程式支付。請檢查是否安裝了最新版本的 Google Play 商店。 + 循環交易逾期通知 + 顯示循環交易逾期通知 diff --git a/res/values/privatestrings.xml b/res/values/privatestrings.xml index d38fffc2a7..001da4f6a4 100644 --- a/res/values/privatestrings.xml +++ b/res/values/privatestrings.xml @@ -1,5 +1,5 @@ user_size - © 2012-2014 Alessandro Lazzari + © 2012-2014 Alessandro Lazzari\r\nAndroid Money Manager Ex Project \ No newline at end of file diff --git a/src/com/money/manager/ex/AccountListActivity.java b/src/com/money/manager/ex/AccountListActivity.java index 2669c1fb47..71218f6d0e 100644 --- a/src/com/money/manager/ex/AccountListActivity.java +++ b/src/com/money/manager/ex/AccountListActivity.java @@ -146,11 +146,13 @@ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuIn public Loader onCreateLoader(int id, Bundle args) { switch (id) { case ID_LOADER_ACCOUNT: - String select = null; + String whereClause = null; + String selectionArgs[] = null; if (!TextUtils.isEmpty(mCurFilter)) { - select = TableAccountList.ACCOUNTNAME + " LIKE '" + mCurFilter + "%'"; + whereClause = TableAccountList.ACCOUNTNAME + " LIKE ?"; + selectionArgs = new String[] {mCurFilter + "%"}; } - return new CursorLoader(getActivity(), mAccount.getUri(), mAccount.getAllColumns(), select, null, "upper(" + TableAccountList.ACCOUNTNAME + ")"); + return new CursorLoader(getActivity(), mAccount.getUri(), mAccount.getAllColumns(), whereClause, selectionArgs, "upper(" + TableAccountList.ACCOUNTNAME + ")"); } return null; diff --git a/src/com/money/manager/ex/CategorySubCategoryExpandableListActivity.java b/src/com/money/manager/ex/CategorySubCategoryExpandableListActivity.java index 91363ad193..a761835424 100644 --- a/src/com/money/manager/ex/CategorySubCategoryExpandableListActivity.java +++ b/src/com/money/manager/ex/CategorySubCategoryExpandableListActivity.java @@ -17,11 +17,6 @@ ******************************************************************************/ package com.money.manager.ex; -import java.text.Normalizer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - import android.app.Activity; import android.app.AlertDialog; import android.content.ContentValues; @@ -60,6 +55,11 @@ import com.money.manager.ex.database.TableSubCategory; import com.money.manager.ex.fragment.BaseExpandableListFragment; import com.money.manager.ex.fragment.BaseFragmentActivity; + +import java.text.Normalizer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; /** * * @author Alessandro Lazzari (lazzari.ale@gmail.com) @@ -247,13 +247,15 @@ public Loader onCreateLoader(int id, Bundle args) { mSubCategories.clear(); // load data - String select = null; + String whereClause = null; + String selectionArgs[] = null; if (!TextUtils.isEmpty(mCurFilter)) { - select = QueryCategorySubCategory.CATEGNAME + " LIKE '" + mCurFilter + "%' OR " - + QueryCategorySubCategory.SUBCATEGNAME + " LIKE '" + mCurFilter + "%'"; - } - return new CursorLoader(getActivity(), mCategorySub.getUri(), mCategorySub.getAllColumns(), select, - null, QueryCategorySubCategory.CATEGNAME + ", " + QueryCategorySubCategory.SUBCATEGNAME); + whereClause = QueryCategorySubCategory.CATEGNAME + " LIKE ? OR " + + QueryCategorySubCategory.SUBCATEGNAME + " LIKE ?"; + selectionArgs = new String[] {mCurFilter + "%", mCurFilter + "%"}; + } + return new CursorLoader(getActivity(), mCategorySub.getUri(), mCategorySub.getAllColumns(), whereClause, + selectionArgs, QueryCategorySubCategory.CATEGNAME + ", " + QueryCategorySubCategory.SUBCATEGNAME); } return null; } diff --git a/src/com/money/manager/ex/CurrencyFormatsListActivity.java b/src/com/money/manager/ex/CurrencyFormatsListActivity.java index 20457e8e84..74ac7084eb 100644 --- a/src/com/money/manager/ex/CurrencyFormatsListActivity.java +++ b/src/com/money/manager/ex/CurrencyFormatsListActivity.java @@ -187,11 +187,13 @@ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuIn public Loader onCreateLoader(int id, Bundle args) { switch (id) { case ID_LOADER_CURRENCY: - String select = null; + String whereClause = null; + String selectionArgs[] = null; if (!TextUtils.isEmpty(mCurFilter)) { - select = TableCurrencyFormats.CURRENCYNAME + " LIKE '" + mCurFilter + "%'"; + whereClause = TableCurrencyFormats.CURRENCYNAME + " LIKE ?"; + selectionArgs = new String[] {mCurFilter + "%"}; } - return new CursorLoader(getActivity(), mCurrency.getUri(), mCurrency.getAllColumns(), select, null, "upper(" + TableCurrencyFormats.CURRENCYNAME + ")"); + return new CursorLoader(getActivity(), mCurrency.getUri(), mCurrency.getAllColumns(), whereClause, selectionArgs, "upper(" + TableCurrencyFormats.CURRENCYNAME + ")"); } return null; diff --git a/src/com/money/manager/ex/PayeeActivity.java b/src/com/money/manager/ex/PayeeActivity.java index d968cba6a7..c7a35aadd9 100644 --- a/src/com/money/manager/ex/PayeeActivity.java +++ b/src/com/money/manager/ex/PayeeActivity.java @@ -142,11 +142,13 @@ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuIn public Loader onCreateLoader(int id, Bundle args) { switch (id) { case ID_LOADER_PAYEE: - String select = null; + String whereClause = null; + String selectionArgs[] = null; if (!TextUtils.isEmpty(mCurFilter)) { - select = TablePayee.PAYEENAME + " LIKE '" + mCurFilter + "%'"; + whereClause = TablePayee.PAYEENAME + " LIKE ?";// + mCurFilter + "%'"; + selectionArgs = new String[] {mCurFilter + '%'}; } - return new CursorLoader(getActivity(), mPayee.getUri(), mPayee.getAllColumns(), select, null, "upper(" + TablePayee.PAYEENAME + ")"); + return new CursorLoader(getActivity(), mPayee.getUri(), mPayee.getAllColumns(), whereClause, selectionArgs, "upper(" + TablePayee.PAYEENAME + ")"); } return null;