سورس بارکد خوان اندروید | android barcode qr code source
سورس بارکد خوان اندروید طراحی شده توسط کتابخانه Google Mobile Vision
امروز بارکد ها و کد های QR بصورت گسترده در تلفن اسمارت فون ها استفاده می شوند.با استفاده از کد های QR شما می توانید عکس ، متن ، لینک و یا هر چیز دیگری را ذخیره کنید.در اندروید این امکان به شما داده شده است که اطلاعاتی که توسط بارکد ذخیره شده است را استخراج کنید که این کار با استفاده از کتابخانه Google Vision صورت می گیرد .
گرچه کتابخانه های دیگر هم موجود هستن که کار مشابه انجام می دهند ولی بهترین آن های Google Vision است زیرا علاوه بر خواندن بارکد ها امکاناتی مانند تشخیص چهره و تشخیص متن هم به شما می دهد.
کدهای موجود در این سورس و آموزش آنها را در زیر مطالعه کنید :
1- Google Mobile Vision API
Google Mobile Vision Api به شما این امکان را می دهد که در فیلم ها و عکس ها، بارکد ها ؛ چهره ها و متن را تشخیص دهید و می توانید از این امکان به صورت جدا یا با هم استفاده کنید.
در این مقاله قصد داریم نحوه تشخیص بارکد را توضیح دهیم که امروز در فروشگاه ها ، هتل ها و … بسیار استفاده می شود.در این مقاله سعی می شود نحوه ساخت یک برنامه بارکد فیلم را توضیح و مراحل ان را به شما نشان دهیم .
کتابخانه Google Vision بخشی از Play Service هست و باید در پروژه اضافه کرد(build.gradle.)
compile 'com.google.android.gms:play-services-vision:11.0.2'
2- کتابخانه Barcode Scanner
ما کتابخانه ای را برای شما آماده کرده ایم که دقیقا شبیه کتابخانه Google Vision می باشد. در این کتابخانه باگ هایی که Google Vision داشته است برطرف شده است و چندین ساختار مانند callbacks به آن اضافه شده است .
3-نحوه استفاده از کتابخانه Barcode
مراحل زیر را برای افزودن کتابخانه های barcode / qrcode به پروژه خود طی کنید.
1-افزودن کتابخانه های androidhive barcode reader و google vision به فایل build.gradle.
dependencies { // barcode reader library implementation 'info.androidhive:barcode-reader:1.1.2' // google vision library implementation 'com.google.android.gms:play-services-vision:11.0.2' }
2-افزودن barcode camera fragment به activity یا fragment
<fragment android:id="@+id/barcode_scanner" android:name="info.androidhive.barcode.BarcodeReader" android:layout_width="match_parent" android:layout_height="match_parent" app:auto_focus="true" app:use_flash="false" />
3-اجرا کردن Activity از BarcodeReader.BarcodeReaderListener و override کردن متدد های ضروری
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.SparseArray; import com.google.android.gms.vision.barcode.Barcode; import java.util.List; import info.androidhive.barcode.BarcodeReader; public class MainActivity extends AppCompatActivity implements BarcodeReader.BarcodeReaderListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scan); } @Override public void onScanned(Barcode barcode) { // single barcode scanned } @Override public void onScannedMultiple(List<Barcode> list) { // multiple barcodes scanned } @Override public void onBitmapScanned(SparseArray<Barcode> sparseArray) { // barcode scanned from bitmap image } @Override public void onScanError(String s) { // scan error } }
4-اجرا برنامه و اسکن کردن بارکد یا کد های Qr .نتیجه اسکن در متددهای onScanned() یا onScannedMultiple() برمی گردد
3.1- افزودن خط نشانگر اسکن
ما در بسیاری از برنامه اسکنر می بینیم که خط نشانگری برای اسکن کردن در دوربین موبایل نشان داده می شود.برای بدست آوردن این ، ما کلاس reusable را در همان کتابخانه اضافه می کنیم که باعث اضافه شدن خط نشانگر در صفحه دوربین می شود.
برای افزودن اسکن کردن انیمیشنی باید info.androidhive.barcode.ScannerOverlay در همان activity در camera fragment جایگزین کرد.
<info.androidhive.barcode.ScannerOverlay android:layout_width="match_parent" android:layout_height="match_parent" android:background="#44000000" app:line_color="#7323DC" app:line_speed="6" app:line_width="4" app:square_height="200" app:square_width="200"/>
4- ساخت پروژه جدید ( ساخت برنامه اسکن بلیط )
اکنون که کتابخانه barcode scanning آماده است چگونگی استفاده کردن از کتابخانه در موارد واقعی را با هم بررسی خواهیم کرد.در این برنامه ما فقط به توضیح اسکن بارکد نمی پردازیم بلکه نحوه ساخت UI پیچیده ، ساخت Rest api برای گرفتن فیلم به صورت json و نوشتن view classes سفارشی نیز خواهیم پرداخت.
4.1 – Rest Api
برای ساخت چنین برنامه ای ما نیاز به Rest Api خواهیم داشت که بتواند به وسیله بارکد فیلم در پایگاه داده فیلم ها جستجو انجام دهد.برای این کار ما یک Rest Api ساده ساختیم که چند پرامتر به صورت جیکیوئری دریافت می کند و در بانک اطلاعاتی جستجو را انجام میدهد.در ادامه چند عکس برای تست این قسمت موجود است.
اکنون همه اطلاعات مورد نظر برای شروع پروژه را در اختیار داریم.پس بریم یک پروژه جدید در Android Studio بسازیم.
1- از طریق منوی File ⇒ New Project یک پروژه جدید ایجاد کنید و نام آن را MovieTickets قرار دهید. سپس پکیج نیم آن را تعیین کنید.
2-فایل build.gradle را باز کنید و موارد زیر رو به آن اضافه کنید.
app/build.gradle dependencies { implementation 'com.google.android.gms:play-services-vision:11.0.2' // vision barcode scanner implementation 'info.androidhive:barcode-reader:1.1.2' // glide image library implementation 'com.github.bumptech.glide:glide:4.0.0-RC1' annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0-RC1' implementation 'com.android.volley:volley:1.0.0' implementation 'com.google.code.gson:gson:2.6.2' }
3-موارد زیر را نیز به فایل های مربوطه در زیر شاخه res اضافه کنید.
strings.xml <resources> <string name="app_name">Movie Tickets</string> <string name="title_activity_ticket">Book Ticket</string> <string name="lbl_duration">DURATION</string> <string name="lbl_genre">GENRE</string> <string name="lbl_rating">RATING</string> <string name="lbl_price">PRICE</string> <string name="btn_buy_now">BUY NOW</string> <string name="btn_coming_soon">COMING SOON</string> <string name="msg_no_ticket_found">No ticket found. Try scanning the QR Codes from http://api.androidhive.info/qrcodes/</string> </resources>
dimens.xml <?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="dimen_20">20dp</dimen> <dimen name="dimen_10">10dp</dimen> <dimen name="activity_margin">16dp</dimen> <dimen name="lbl_directory">14dp</dimen> <dimen name="lbl_movie_name">28dp</dimen> <dimen name="img_poster_height">220dp</dimen> <dimen name="dimen_40">40dp</dimen> </resources>
colors.xml <?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#6d0094</color> <color name="colorPrimaryDark">#6d0094</color> <color name="colorAccent">#ff2068</color> <color name="colorAccentSecondary">#ad1a7f</color> <color name="viewBg">#f8f8f8</color> <color name="btn_disabled">#999</color> <color name="lbl_value">#222222</color> </resources>
4-یک کلاس به نام MyApplication.java بسازید و کد های زیر را به آن اضافه کنید.اینجا ما یک نمونه volley می سازیم.
MyApplication.java import android.app.Application; import android.text.TextUtils; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.toolbox.Volley; /** * Created by ravi on 31/07/17. */ public class MyApplication extends Application { public static final String TAG = MyApplication.class .getSimpleName(); private RequestQueue mRequestQueue; private static MyApplication mInstance; @Override public void onCreate() { super.onCreate(); mInstance = this; } public static synchronized MyApplication getInstance() { return mInstance; } public RequestQueue getRequestQueue() { if (mRequestQueue == null) { mRequestQueue = Volley.newRequestQueue(getApplicationContext()); } return mRequestQueue; } public <T> void addToRequestQueue(Request<T> req, String tag) { // set the default tag if tag is empty req.setTag(TextUtils.isEmpty(tag) ? TAG : tag); getRequestQueue().add(req); } public <T> void addToRequestQueue(Request<T> req) { req.setTag(TAG); getRequestQueue().add(req); } public void cancelPendingRequests(Object tag) { if (mRequestQueue != null) { mRequestQueue.cancelAll(tag); } } }
5-فایل AndroidManifest.xml باز کنید و کلاس MyApplication را مطابق کد زیر به تگ <applicaton> اضافه کنید و همچنین مجوز INTERNET را نیز اضافه کنید. این مجوز برای درست کردن http calls مورد استفاده قرار میگیرد.
AndroidManifest.xml &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;?xml version="1.0" encoding="utf-8"?&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" package="info.androidhive.movietickets"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;uses-permission android:name="android.permission.INTERNET" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;application android:name=".MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;activity android:name=".MainActivity" android:screenOrientation="portrait" android:theme="@style/AppTheme.NoActionBar"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;intent-filter&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;action android:name="android.intent.action.MAIN" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;category android:name="android.intent.category.LAUNCHER" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/intent-filter&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/activity&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;activity android:name=".ScanActivity" android:screenOrientation="portrait" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;activity android:name=".TicketActivity" android:label="@string/title_activity_ticket" android:screenOrientation="portrait" android:theme="@style/AppTheme.NoActionBar"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/activity&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/application&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/manifest&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;
6-در زیر پوشه res ⇒ drawable یک فایل xml به نام bg_gradient.xml بسازید. این فایل برای پس زمینه View ها مورد استفاده قرار می گیرد.
bg_gradient.xml &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;?xml version="1.0" encoding="utf-8"?&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;gradient android:angle="135" android:centerColor="@color/colorAccentSecondary" android:endColor="@color/colorPrimary" android:startColor="@color/colorAccent" android:type="linear" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;corners android:radius="0dp" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/shape&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;
4.2-افزودن Landing Screen
در landing screen چندین text field و دکمه برای باز کردن اسکنر دوربین وجود دارد.نکته جالب در خصوص این بخش اضافه کردن gradient background به activity می باشد.
7-لایوت main activity خود را باز کنید و کدهای زیر را به آن اضافه کنید.
&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;?xml version="1.0" encoding="utf-8"?&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_gradient" tools:context="info.androidhive.movietickets.MainActivity"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerInParent="true" android:gravity="center" android:orientation="vertical" android:paddingLeft="40dp" android:paddingRight="40dp"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;ImageView android:id="@+id/icon" android:layout_width="100dp" android:layout_height="100dp" android:layout_centerHorizontal="true" android:clickable="true" android:foreground="?attr/selectableItemBackground" android:src="@drawable/qrcode" android:tint="@android:color/white" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:fontFamily="sans-serif-light" android:gravity="center" android:text="Scan the QR code on the poster and book your movie tickets" android:textColor="@android:color/white" android:textSize="16dp" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/LinearLayout&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;Button android:id="@+id/btn_scan" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="40dp" android:background="@android:color/transparent" android:foreground="?attr/selectableItemBackground" android:paddingLeft="20dp" android:paddingRight="20dp" android:fontFamily="sans-serif-medium" android:text="Scan QR Code" android:textColor="@android:color/white" android:textSize="18sp" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/RelativeLayout&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;
8-main activity را باز کنید و تغییرات الزامی زیر را حتما اعمال کنید در این اکتیویتی متد transparentToolbar() باعث ایجاد نوار ابزار شفاف می شود.
MainActivity.java import android.app.Activity; import android.content.Intent; import android.graphics.Color; import android.os.Build; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.SparseArray; import android.view.View; import android.view.Window; import android.view.WindowManager; import com.google.android.gms.vision.barcode.Barcode; import java.util.List; import info.androidhive.barcode.BarcodeReader; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // making toolbar transparent transparentToolbar(); setContentView(R.layout.activity_main); findViewById(R.id.btn_scan).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(MainActivity.this, ScanActivity.class)); } }); } private void transparentToolbar() { if (Build.VERSION.SDK_INT &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;= 19 &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; Build.VERSION.SDK_INT &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt; 21) { setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true); } if (Build.VERSION.SDK_INT &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;= 19) { getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } if (Build.VERSION.SDK_INT &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;= 21) { setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false); getWindow().setStatusBarColor(Color.TRANSPARENT); } } private void setWindowFlag(Activity activity, final int bits, boolean on) { Window win = activity.getWindow(); WindowManager.LayoutParams winParams = win.getAttributes(); if (on) { winParams.flags |= bits; } else { winParams.flags &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;= ~bits; } win.setAttributes(winParams); } }
اکنون اگر برنامه را اجرا کنید شما صفحه ای همانند تصویر زیر خواهید دید.
4.3-افزودن صفحه اسکن بلیط
9-با رفتن به مسیر File ⇒ New ⇒ Activity ⇒ Empty Activity یک activity به نام ScanActivity.java بسازید
10-لایوت مربوط به اکتیویتی activity_scan.xml را باز کرده و قطعه Barcode Reader را همانند کد زیر به آن اضافه کنید.
activity_scan.xml &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;?xml version="1.0" encoding="utf-8"?&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="info.androidhive.movietickets.ScanActivity"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;fragment android:id="@+id/barcode_scanner" android:name="info.androidhive.barcode.BarcodeReader" android:layout_width="match_parent" android:layout_height="match_parent" app:auto_focus="true" app:use_flash="false" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;info.androidhive.barcode.ScannerOverlay android:layout_width="match_parent" android:layout_height="match_parent" android:background="#44000000" app:line_color="#7323DC" app:line_speed="6" app:line_width="4" app:square_height="200" app:square_width="200" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/RelativeLayout&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;
11-فایل ScanActivity.java را باز کرده و تغییرات الزامی زیر را اعمال کنید.
*اجرا activity از BarcodeReader.BarcodeReaderListener
*Override کردن متدهای onScanned(), onScannedMultiple() و بقیه متدها.
*barcodeReader.playBeep() باعث ایجاد صدا می شود که بارکد اسکن شده است.
*و…. (مطابق کد زیر تغییرات را اعمال کنید)
ScanActivity.java package info.androidhive.movietickets; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.SparseArray; import android.widget.Toast; import com.google.android.gms.vision.barcode.Barcode; import java.util.List; import info.androidhive.barcode.BarcodeReader; public class ScanActivity extends AppCompatActivity implements BarcodeReader.BarcodeReaderListener { BarcodeReader barcodeReader; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scan); // get the barcode reader instance barcodeReader = (BarcodeReader) getSupportFragmentManager().findFragmentById(R.id.barcode_scanner); } @Override public void onScanned(Barcode barcode) { // playing barcode reader beep sound barcodeReader.playBeep(); // ticket details activity by passing barcode Intent intent = new Intent(ScanActivity.this, TicketActivity.class); intent.putExtra("code", barcode.displayValue); startActivity(intent); } @Override public void onScannedMultiple(List&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;Barcode&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; list) { } @Override public void onBitmapScanned(SparseArray&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;Barcode&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; sparseArray) { } @Override public void onScanError(String s) { Toast.makeText(getApplicationContext(), "Error occurred while scanning " + s, Toast.LENGTH_SHORT).show(); } }
برنامه را اجرا کنید و یک بارکد را اسکن کنید .نتیجه اسکن در تابع onScanned() برمی گردد.
4.4- افزودن صفحه نمایش جزئیات بلیط اسکن شده
اکنون باید جزییات فیلم را که توسط بارکد خوانده شده است در صفحه نمایش ، نمایش دهیم.
12-یک کلاس بسازید به نام TicketView.java. این یک کلاس ساده برای نمایش view است.
TicketView.java import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.DashPathEffect; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.util.AttributeSet; import android.widget.LinearLayout; /** * Created by ravi tamada on 29/07/17. * Ticket view creates view with view punches making circular holes * in the view */ public class TicketView extends LinearLayout { private Bitmap bm; private Canvas cv; private Paint eraser; private int holesBottomMargin = 70; private int holeRadius = 40; public TicketView(Context context) { super(context); Init(); } public TicketView(Context context, AttributeSet attrs) { super(context, attrs); Init(); } public TicketView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); Init(); } private void Init() { eraser = new Paint(); eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); eraser.setAntiAlias(true); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (w != oldw || h != oldh) { bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); cv = new Canvas(bm); } super.onSizeChanged(w, h, oldw, oldh); } @Override protected void onDraw(Canvas canvas) { int w = getWidth(); int h = getHeight(); bm.eraseColor(Color.TRANSPARENT); // set the view background color cv.drawColor(Color.WHITE); // drawing footer square contains the buy now button Paint paint = new Paint(); paint.setARGB(255, 250, 250, 250); paint.setStrokeWidth(0); paint.setStyle(Paint.Style.FILL); cv.drawRect(0, h, w, h - pxFromDp(getContext(), holesBottomMargin), paint); // adding punching holes on the ticket by erasing them cv.drawCircle(0, 0, holeRadius, eraser); // top-left hole cv.drawCircle(w / 2, 0, holeRadius, eraser); // top-middle hole cv.drawCircle(w, 0, holeRadius, eraser); // top-right cv.drawCircle(0, h - pxFromDp(getContext(), holesBottomMargin), holeRadius, eraser); // bottom-left hole cv.drawCircle(w, h - pxFromDp(getContext(), holesBottomMargin), holeRadius, eraser); // bottom right hole // drawing the image canvas.drawBitmap(bm, 0, 0, null); // drawing dashed lines at the bottom Path mPath = new Path(); mPath.moveTo(holeRadius, h - pxFromDp(getContext(), holesBottomMargin)); mPath.quadTo(w - holeRadius, h - pxFromDp(getContext(), holesBottomMargin), w - holeRadius, h - pxFromDp(getContext(), holesBottomMargin)); // dashed line Paint dashed = new Paint(); dashed.setARGB(255, 200, 200, 200); dashed.setStyle(Paint.Style.STROKE); dashed.setStrokeWidth(2); dashed.setPathEffect(new DashPathEffect(new float[]{10, 5}, 0)); canvas.drawPath(mPath, dashed); super.onDraw(canvas); } public static float pxFromDp(final Context context, final float dp) { return dp * context.getResources().getDisplayMetrics().density; } }
13-یک کلاس از طریق مسیر File ⇒ New ⇒ Activity ⇒ Empty Activity به نام TicketResultActivity.java بسازید.
14-فایل layout مربوط به activity_ticket_result.xml باز کنید و دستورات زیر را به آن اضافه کنید.
activity_ticket_result.xml &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;?xml version="1.0" encoding="utf-8"?&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_gradient" android:descendantFocusability="beforeDescendants" android:fitsSystemWindows="true" tools:context=".TicketResultActivity"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;android.support.design.widget.AppBarLayout foreground="?android:windowContentOverlay" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?actionBarSize" android:background="@color/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/android.support.v7.widget.Toolbar&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/android.support.design.widget.AppBarLayout&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;include layout="@layout/content_ticket_details"/&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/android.support.design.widget.CoordinatorLayout&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;
content_ticket_details.xml &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;?xml version="1.0" encoding="utf-8"?&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_gradient" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context=".TicketResultActivity"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;TextView android:id="@+id/txt_error" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerInParent="true" android:gravity="center_horizontal" android:text="@string/msg_no_ticket_found" android:textColor="@android:color/white" android:padding="@dimen/dimen_20" android:textSize="16dp" android:visibility="gone" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;info.androidhive.movietickets.TicketView android:id="@+id/layout_ticket" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="@dimen/dimen_20" android:layout_marginRight="@dimen/dimen_20" android:layout_marginTop="@dimen/dimen_20" android:background="@android:color/transparent" android:orientation="vertical" android:paddingTop="@dimen/dimen_10" android:visibility="gone"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;TextView android:id="@+id/director" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:fontFamily="sans-serif-condensed" android:paddingLeft="@dimen/activity_margin" android:paddingRight="@dimen/activity_margin" android:paddingTop="@dimen/activity_margin" android:textAllCaps="true" android:textSize="@dimen/lbl_directory" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;TextView android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:fontFamily="sans-serif-condensed" android:paddingLeft="16dp" android:paddingRight="16dp" android:textAllCaps="true" android:textColor="#111" android:maxLines="1" android:ellipsize="end" android:textSize="@dimen/lbl_movie_name" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;ImageView android:id="@+id/poster" android:layout_width="match_parent" android:layout_height="@dimen/img_poster_height" android:layout_marginBottom="@dimen/activity_margin" android:layout_marginTop="@dimen/activity_margin" android:scaleType="centerCrop" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingLeft="@dimen/activity_margin" android:paddingRight="@dimen/activity_margin" android:weightSum="2"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:fontFamily="sans-serif-condensed" android:text="@string/lbl_duration" android:textSize="12dp" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;TextView android:id="@+id/duration" android:layout_width="match_parent" android:layout_height="wrap_content" android:fontFamily="sans-serif-condensed" android:textColor="@color/lbl_value" android:textSize="22dp" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/LinearLayout&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:fontFamily="sans-serif-condensed" android:text="@string/lbl_genre" android:textSize="12dp" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;TextView android:id="@+id/genre" android:layout_width="match_parent" android:layout_height="wrap_content" android:fontFamily="sans-serif-condensed" android:textAllCaps="true" android:textColor="@color/lbl_value" android:textSize="22dp" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/LinearLayout&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/LinearLayout&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:orientation="horizontal" android:paddingLeft="16dp" android:paddingRight="16dp" android:weightSum="2"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:fontFamily="sans-serif-condensed" android:text="@string/lbl_rating" android:textSize="12dp" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;TextView android:id="@+id/rating" android:layout_width="match_parent" android:layout_height="wrap_content" android:fontFamily="sans-serif-condensed" android:textColor="@color/lbl_value" android:textSize="22dp" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/LinearLayout&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:fontFamily="sans-serif-condensed" android:text="@string/lbl_price" android:textSize="12dp" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;TextView android:id="@+id/price" android:layout_width="match_parent" android:layout_height="wrap_content" android:fontFamily="sans-serif-condensed" android:textAllCaps="true" android:textColor="@color/lbl_value" android:textSize="22dp" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/LinearLayout&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/LinearLayout&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/info.androidhive.movietickets.TicketView&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;Button android:id="@+id/btn_buy" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="10dp" android:background="@android:color/transparent" android:fontFamily="sans-serif-condensed" android:foreground="?attr/selectableItemBackground" android:paddingLeft="@dimen/activity_margin" android:paddingRight="@dimen/activity_margin" android:textColor="@color/colorPrimary" android:textSize="26dp" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;ProgressBar android:id="@+id/progressBar" android:layout_width="@dimen/dimen_40" android:layout_height="@dimen/dimen_40" android:layout_centerInParent="true" android:indeterminateTint="@android:color/white" android:indeterminateTintMode="src_atop" android:visibility="visible" /&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/RelativeLayout&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;
15-فایل TicketResultActivity.java را باز کنید و کد ها را مانند کد های زیر اصلاح کنید.
TicketResultActivity.java import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.util.Log; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.JsonObjectRequest; import com.bumptech.glide.Glide; import com https://espanol....ico/.google.gson.Gson; import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.SerializedName; import org.json.JSONObject; public class TicketResultActivity extends AppCompatActivity { private static final String TAG = TicketResultActivity.class.getSimpleName(); // url to search barcode private static final String URL = "https://api.androidhive.info/barcodes/search.php?code="; private TextView txtName, txtDuration, txtDirector, txtGenre, txtRating, txtPrice, txtError; private ImageView imgPoster; private Button btnBuy; private ProgressBar progressBar; private TicketView ticketView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_ticket_result); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); txtName = findViewById(R.id.name); txtDirector = findViewById(R.id.director); txtDuration = findViewById(R.id.duration); txtPrice = findViewById(R.id.price); txtRating = findViewById(R.id.rating); imgPoster = findViewById(R.id.poster); txtGenre = findViewById(R.id.genre); btnBuy = findViewById(R.id.btn_buy); imgPoster = findViewById(R.id.poster); txtError = findViewById(R.id.txt_error); ticketView = findViewById(R.id.layout_ticket); progressBar = findViewById(R.id.progressBar); String barcode = getIntent().getStringExtra("code"); // close the activity in case of empty barcode if (TextUtils.isEmpty(barcode)) { Toast.makeText(getApplicationContext(), "Barcode is empty!", Toast.LENGTH_LONG).show(); finish(); } // search the barcode searchBarcode(barcode); } /** * Searches the barcode by making http call * Request was made using Volley network library but the library is * not suggested in production, consider using Retrofit */ private void searchBarcode(String barcode) { // making volley's json request JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET, URL + barcode, null, new Response.Listener&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;JSONObject&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;() { @Override public void onResponse(JSONObject response) { Log.e(TAG, "Ticket response: " + response.toString()); // check for success status if (!response.has("error")) { // received movie response renderMovie(response); } else { // no movie found showNoTicket(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e(TAG, "Error: " + error.getMessage()); showNoTicket(); } }); MyApplication.getInstance().addToRequestQueue(jsonObjReq); } private void showNoTicket() { txtError.setVisibility(View.VISIBLE); ticketView.setVisibility(View.GONE); progressBar.setVisibility(View.GONE); } /** * Rendering movie details on the ticket */ private void renderMovie(JSONObject response) { try { // converting json to movie object Movie movie = new Gson().fromJson(response.toString(), Movie.class); if (movie != null) { txtName.setText(movie.getName()); txtDirector.setText(movie.getDirector()); txtDuration.setText(movie.getDuration()); txtGenre.setText(movie.getGenre()); txtRating.setText("" + movie.getRating()); txtPrice.setText(movie.getPrice()); Glide.with(this).load(movie.getPoster()).into(imgPoster); if (movie.isReleased()) { btnBuy.setText(getString(R.string.btn_buy_now)); btnBuy.setTextColor(ContextCompat.getColor(this, R.color.colorPrimary)); } else { btnBuy.setText(getString(R.string.btn_coming_soon)); btnBuy.setTextColor(ContextCompat.getColor(this, R.color.btn_disabled)); } ticketView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); } else { // movie not found showNoTicket(); } } catch (JsonSyntaxException e) { Log.e(TAG, "JSON Exception: " + e.getMessage()); showNoTicket(); Toast.makeText(getApplicationContext(), "Error occurred. Check your LogCat for full report", Toast.LENGTH_SHORT).show(); } catch (Exception e) { // exception showNoTicket(); Toast.makeText(getApplicationContext(), "Error occurred. Check your LogCat for full report", Toast.LENGTH_SHORT).show(); } } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { finish(); } return super.onOptionsItemSelected(item); } private class Movie { String name; String director; String poster; String duration; String genre; String price; float rating; @SerializedName("released") boolean isReleased; public String getName() { return name; } public String getDirector() { return director; } public String getPoster() { return poster; } public String getDuration() { return duration; } public String getGenre() { return genre; } public String getPrice() { return price; } public float getRating() { return rating; } public boolean isReleased() { return isReleased; } } }
اکنون کار به پایان رسید و شما میتوانید برنامه را اجرا کنید و از آن لذت ببرید.