Android NFC优惠券应用程序意外终止

时间:2012-11-25 18:40:58

标签: java android api sharedpreferences nfc

感谢对NFC和一些特定内容的回复,我已经理解并设法编译了一个代码,用户可以在其中读取标记,如果标记包含与我的代码类似的字符串,优惠券将被添加(图像更改),整数增加1.此整数将由SharedPreferences保存,用于确定用户已收集的优惠券数量并将其显示在简历上。

然而,在编译之后,当我尝试运行它时,我的应用程序立即停止。有人可以帮我查看我可能出错的地方吗?我知道它有点长,但我真的不知道出了什么问题。

@TargetApi(10)    
//I have to use this line of code because I'm targetted to code at API 8 but some NFC functionalities that I use requires API 10.

public class CouponManager extends Activity {

        private static final String TAG = "NFCReadTag";
        private NfcAdapter mNfcAdapter;
        private IntentFilter[] mNdefExchangeFilters;
        private PendingIntent mNfcPendingIntent;
        public static final String PREF_FILE_NAME = "PrefFile";

        private int[] images = new int[10];

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.coupon_layout);

            //List of images
            images[0]=R.drawable.cp0;
            images[1]=R.drawable.cp1;
            images[2]=R.drawable.cp2;
            images[3]=R.drawable.cp3;
            images[4]=R.drawable.cp4;
            images[5]=R.drawable.cp5;
            images[6]=R.drawable.cp6;
            images[7]=R.drawable.cp7;
            images[8]=R.drawable.cp8;
            images[9]=R.drawable.cp9;
            images[10]=R.drawable.cp10;

            //Restore preferences 
            SharedPreferences preferences = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
            int storedPreference = preferences.getInt("storedInt", 0);

            //Image to use depending on coupon collected
            final ImageView img = new ImageView(this);

            if(storedPreference!=10)
            {
                img.setImageResource(images[storedPreference]);
            }
            else
            {
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setCancelable(false);
                builder.setTitle("Redeem Your Coupon?");
                builder.setInverseBackgroundForced(true);
                builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which)
                    {
                        dialog.dismiss();
                        SharedPreferences preferences = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
                        SharedPreferences.Editor editor = preferences.edit();
                        editor.putInt("storedInt", 0); // value to store
                        editor.commit();    
                        img.setImageResource(images[0]);
                    }
                });
                builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        img.setImageResource(images[10]);
                    }
                });
            }


            //Check and send Intent from NFC tag discovered
            mNfcAdapter = NfcAdapter.getDefaultAdapter(this);

            mNfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
                    getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP
                    | Intent.FLAG_ACTIVITY_CLEAR_TOP), 0);


            IntentFilter coupontag = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
            coupontag.addDataScheme("http");
            coupontag.addDataAuthority("www.ichatime.com", null);
            coupontag.addDataPath(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);

            mNdefExchangeFilters = new IntentFilter[] { coupontag };

        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.activity_main, menu);
            return true;
        }

        @Override
        protected void onResume() {
            super.onResume();
            if(mNfcAdapter != null) {
                mNfcAdapter.enableForegroundDispatch(this, mNfcPendingIntent,
                    mNdefExchangeFilters, null);
            } else {
                Toast.makeText(getApplicationContext(), "Sorry, No NFC Adapter found.", Toast.LENGTH_SHORT).show();
            }


        }

        @Override
        protected void onPause() {
            super.onPause();
            if(mNfcAdapter != null) mNfcAdapter.disableForegroundDispatch(this);
        }

        @Override
        protected void onStop() {
            super.onStop();

            // We need an Editor object to make preference changes.
              // All objects are from android.context.Context
                SharedPreferences preferences = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
                int storedPreference = preferences.getInt("storedInt", 0);

                SharedPreferences.Editor editor = preferences.edit();
                editor.putInt("storedInt", storedPreference); // value to store
                editor.commit();    
        }

        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);      
            SharedPreferences preferences = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
            int storedPreference = preferences.getInt("storedInt", 0);

            if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
                NdefMessage[] messages = null;
                Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
                if (rawMsgs != null) {
                    messages = new NdefMessage[rawMsgs.length];
                    for (int i = 0; i < rawMsgs.length; i++) {
                        messages[i] = (NdefMessage) rawMsgs[i];
                    }
                }
                if(messages[0] != null) {
                    String result="";
                    byte[] payload = messages[0].getRecords()[0].getPayload();
                    // this assumes that we get back am SOH followed by host/code
                    for (int b = 1; b<payload.length; b++) { // skip SOH
                        result += (char) payload[b];
                    }
                    if (result == "ichatime.com")
                        {
                        final ImageView img = new ImageView(this);
                        Toast.makeText(getApplicationContext(), "Coupon collected!", Toast.LENGTH_SHORT).show();

                        if (storedPreference!=10)
                        {
                            storedPreference++;
                            SharedPreferences.Editor editor = preferences.edit();
                            editor.putInt("storedInt", storedPreference);
                            img.setImageResource(images[storedPreference]);
                        }
                            if (storedPreference==10)
                            {
                                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                                builder.setCancelable(false);
                                builder.setTitle("Redeem Your Coupon?");
                                builder.setInverseBackgroundForced(true);
                                builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int which)
                                    {
                                        dialog.dismiss();
                                        SharedPreferences preferences = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
                                        SharedPreferences.Editor editor = preferences.edit();
                                        editor.putInt("storedInt", 0); // value to store
                                        editor.commit();    
                                        img.setImageResource(images[0]);
                                    }
                                });
                                builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int which) {
                                        dialog.dismiss();
                                        img.setImageResource(images[10]);
                                    }
                                });
                            }
                        else
                        {
                            SharedPreferences.Editor editor = preferences.edit();
                            editor.putInt("storedInt", 10);
                            img.setImageResource(images[10]);
                        }}
                    else 
                    {
                        Toast.makeText(getApplicationContext(), "Wrong tag detected!", Toast.LENGTH_SHORT).show();
                    }
                    //Debugging Mode to see what is contained in the tags.
            //          Toast.makeText(getApplicationContext(), "Tag Contains " + result, Toast.LENGTH_SHORT).show();
                }
            }
        }

}

Logcat错误:

>11-26 01:16:11.869: D/AndroidRuntime(550): Shutting down VM
>
11-26 01:16:11.869: W/dalvikvm(550): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
>
11-26 01:16:11.929: I/dalvikvm(550): threadid=3: reacting to signal 3
>
11-26 01:16:11.979: E/AndroidRuntime(550): FATAL EXCEPTION: main
>
**11-26 01:16:11.979: E/AndroidRuntime(550): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ponpon/com.example.ponpon.MainActivity}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ponpon/com.example.ponpon.CouponManager}: java.lang.ArrayIndexOutOfBoundsException: length=10; index=10**
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.ActivityThread.access$600(ActivityThread.java:123)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.os.Handler.dispatchMessage(Handler.java:99)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.os.Looper.loop(Looper.java:137)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.ActivityThread.main(ActivityThread.java:4424)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at java.lang.reflect.Method.invokeNative(Native Method)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at java.lang.reflect.Method.invoke(Method.java:511)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at dalvik.system.NativeStart.main(Native Method)
>
11-26 01:16:11.979: E/AndroidRuntime(550): Caused by: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ponpon/com.example.ponpon.CouponManager}: java.lang.ArrayIndexOutOfBoundsException: length=10; index=10
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.ActivityThread.startActivityNow(ActivityThread.java:1797)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:135)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:347)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:682)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.widget.TabHost.setCurrentTab(TabHost.java:346)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.widget.TabHost.addTab(TabHost.java:236)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at com.example.ponpon.MainActivity.onCreate(MainActivity.java:37)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.Activity.performCreate(Activity.java:4465)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  ... 11 more
>
11-26 01:16:11.979: E/AndroidRuntime(550): Caused by: java.lang.ArrayIndexOutOfBoundsException: length=10; index=10
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at com.example.ponpon.CouponManager.onCreate(CouponManager.java:53)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.Activity.performCreate(Activity.java:4465)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
>
11-26 01:16:11.979: E/AndroidRuntime(550):  ... 21 more

我的阵列出了什么问题?谢谢你的澄清!

2 个答案:

答案 0 :(得分:0)

我似乎通过将数组计数加1来解决问题。我不明白的是,我想在数组中保留11个项目,所以不是

private int [] images = new int [10]够吗?

根据我的理解,int [0]保留第一个值,因此int [10]将保留第11个值?谢谢你们!

答案 1 :(得分:0)

您的logcat正在onCreate方法上打印一个ArrayOutOfBounds异常。

问题是你要声明一个10个项目大小的数组,然后尝试在其上放置11个项目。

你必须声明一个新的int [11]数组。