تماشای برخط [لینک مستقیم] فیلم «آموزش نحوه استفاده از مفاهیم آشکار»
زیر نویس انگلیسی [English Subtitle]
نسخه pdf این آموزش[1.75 مگابایت]
تا اینجا یاد گرفتیم که چطور با فعالیت ها (activities) کار کنیم، اگه یادتون باشه برای شروع فعالیت Dovomi از intent استفاده کردیم، کار مفهوم (intent) اینه که یه عنصری از برنامه تون رو فعال کنه.
دو نوع مفهوم (intent) وجود داره، مفاهیم آشکار و مفاهیم ضمنی یا مجازی.
با مفاهیم آشکار، یک عنصر مشخصی از برنامه رو برای فعال شدن تعیین میکنیم. مثلا میخوایم یه فعالیت(activity) دیگه رو تو برناممون اجرا کنیم، از یه مفهوم آشکار استفاده میکنیم که آشکارا به سیستم بگه میخوام اون فعالیت رو فعال(اجرا) کنم.
مفاهیم ضمنی (که تو پست بعدی بهش میپردازیم) در واقع یک پیام کلی برای سیستم میفرستن : که آیا برنامهای در سیستم عامل این گوشی وجود داره که بتونه این مفهوم رو اجرا کنه؟ اگه وجود داشته باشه لیست این برنامهها به کاربر پیشنهاد میشه و کاربر یکی رو انتخاب میکنه و از این طریق اون چیزی که با مفهوم فرستاده شده (ورودیهای intent) اجرا میشه.
خوب الان میخوایم رو مفاهیم آشکار تمرکز کنیم. برای شروع یه پروژه بسازید با دوتا فعالیت (activitie) که تو فعالیت اصلی (main) یه متنی که قابل نوشتن باشه یعنی کاربر میتونیه توش متن وارد کنه (از توی Text Fields اولی رو انتخاب کنید) و یه دکمه (برای اینکه به فعالیت دوم بره)، فعالیت دوم هم یه فیلد متنی ساده داشته باشه.(حواستون باشه که فعالیت دوم رو هم تو فایل manifest تعریف کنید).
۲.کاری که با این برنامه میخوایم بکنیم اینه که : کاربر یه متنی رو تو فیلد متنی قابل نوشتن مینویسه و دکمه رو میزنه، فعالیت دوم باز میشه و متنی که نوشته بوده رو نشون میده. یعنی میخوایم یاد بگیریم اطلاعاتی رو از یه فعالیت به فعالیت دیگه منتقل کنیم.
اول به فایل main.java می ریم و یه مرجع(اشارهگر) از دکمه و فیلد متنی میگیریم. با نوشتن این کد
EditText matn = findViewById(R.id.editText1);
یه مرجع از فیلد متنی قابل نوشتنمون میگیریم. خوب بازهم با ctrl+1 خطاهای برنامه رو درست میکنیم. (اینجا کافیه فقط cast انجام بدید.) همین کارو برای دکمه انجام میدیم.
Button d = findViewById(R.id.button1);
و برای دکمه تابع setOnclickListener رو صدا میزنیم تا کارایی که قراره با فشردن دکمه انجام بشه رو تعیین کنیم. با نوشتن این کد :
d.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}
});
همون طور که قبلا گفته شد بعد از نوشتن new (خط اول) اگه بنویسید onclick و بعد ctrl+space رو بزنید خودش بهتون ادامهاش رو پیشنهاد میده و روی OnClickListener که کلیک کنید، بقیهاش رو خودش مینویسه.
۳.الان قصد داریم که یه intent بسازیم، همون طور که قبلا اشاره شد intent یک راه برای فعال کردن جزئی از برنامه است. پس برای اینکه یه نمونه از کلاس Intent بسازیم، مینویسیم Intent و یه اسم براش میذاریم و newاش میکنیم. (با ctrl+space، اون گزینه رو انتخاب میکنیم که مناسبه پاس کردن یه فعالیته -تو تصویر مشخصه-)
برای ورودیهای سازندهی intent، اول باید مولفهای که این درخواست رو کرده بنویسیم یعنی Main.this (که یه مرجع به این فعالیت اصلی هست). برای ورودی دوم، باید کلاس فعالیتی رو بدیم که میخوایم اجرا بشه یعنی Dovomi.class. پس کدمون اینجوری میشه :
Intent mafhoom = new Intent(Main.this, Dovomi.class);
در واقع ما میتونستیم همین قسمت (new Intent(Main.this, Dovomi.class رو به عنوان ورودی startActvity به کار ببریم (مثل آموزش قبلی) ولی این دفعه میخوایم یه چیزایی رو ضمیمهی mafhoom کنیم. چیزی که میخوایم اضافه کنیم همون متنیه که کاربر تو matn وارد میکنه. برای این کار از تابع putExtra از شی mafhoom استفاده میکنیم.
۴.ورودی اول این تابع یه رشته (String) است که به عنوان اسم اون کلیدی که میخوایم اضافه کنیم به کار برده میشه و ورودی دوم از هر نوعی میتونه باشه و ما چون اون متن رو میخوایم بفرستیم، برای ورودی دوم هم نوع رشته (String) رو انتخاب میکنیم. اسم کلید رو میذارم “matneVaredShode” و برای بازیابی اطلاعاتی که داخل matn (متنی که قراره کاربر وارد کنه) وجود داره، باید از تابع getText استفاده کنیم و اگه دقت کنید میبینید که خروجی این تابع از نوع Editable هست نه از نوع رشتهی خام پس با اضافه کردن ()toString. اونو به رشتهی خام تبدیل میکنیم.
mafhoom.putExtra("matneVaredShode", matn.getText().toString());
از matn ایراد میگیره و با زدن ctrl+1 بهمون پیشنهاد میکنه که اونو به final تغییر بدیم (چون قراره ازش تو یه کنترل کننده وقایع ناشناس استفاده کنیم).
ما اون اطلاعاتی که میخواستیم به فعالیت Dovomi بفرستیم رو به mafhoom اضافه کردیم، حالا وقتی میخوایم فعالیت جدید رو شروع کنیم، این اطلاعات براش فرستاده میشه. تابع startActivity رو استفاده میکنیم و mafhoom رو به عنوان ورودی براش میفرستیم.
startActivity(mafhoom);
۵.خوب تا اینحا دیگه کار ما با Main.java تموم میشه، حالا باید به Dovomi.java بریم و اطلاعاتی که همراه mafhoom فرستاده شده بازیابی کنیم و تو textView نشون بدیم. برای شروع اول یه مرجع از فیلد متنی میگیریم با این کد :
TextView matni = (TextView) findViewById(R.id.textView1);
برای اینکه این فیلد متنی، متن دلخواه ما رو نشون بده باید از تابع setText استفاده کنیم(هرچی به عنوان ورودی بفرستیم رو نشون میده)، برای گرفتن همون متنی رو که توسط mafhoom فرستاده شده، اول باید با getIntent مفهومی که این فعالیت رو اجرا کرده رو به دست بیاریم، و بعد از تابع getExtra برای گرفتن اطلاعات داخل intent استفاده میکنیم، که در واقع تمام اطلاعاتی که بهش داده بودیم رو برمیگردونه. اما ما فقط اون قسمتی از اطلاعاتش رو میخوایم که با کلید “matneVaredShode” مشخص شده (اگرچه در این تمرین قفط همین یدونه رو همراه mafhoom فرستادیم). و چون اون اطلاعاتی که میخوایم از نوع رشته است، از تابع getString استفاده میکنیم و کلید رو بهش میدیم.
matni.setText(getIntent().getExtras().getString("matneVaredShode"));
۶.حالا برنامه رو اجرا میکنیم و میبینیم همون متنی که تو فعالیت اصلی وارد کردیم تو فعالیت دوم نشون داده میشه 🙂
تماشای برخط [لینک مستقیم] فیلم «آموزش نحوه استفاده از مفاهیم ضمنی»
زیرنویس انگلیسی [English Subtitile]
دریافت نسخه ی pdf این آموزش [2.78 مگابایت]
حالا که خوب مفاهیم آشکار رو متوجه شدیم، وقتشه که به مفاهیم ضمنی بپردازیم، برای درک بهتر از یه مثال شروع میکنیم.
خوب برگردیم به ادامه آموزش، گفتیم که برنامهی Gallery با استفاده از یه مفهوم (intent) یه پیغام به سیستم میفرسته، حالا از کجا بفهمیم، این مفهوم چه پیغامی رو به فرستاده؟ برای اینکار دکمهی share رو تو شبیهساز میزنیم بعد به ایکلیپس میریم و اگه تو LogCat نگاه کنیم، خط های آخرش نوشته :
Starting: Intent { act=android.intent.action.SEND type=image/jpeg ...
android.intent.action.SEND یه مفهوم ضمنیه، که همراه با خودش نوع دادهای تصویر از نوع jpeg رو داره.
۲.بیاید یه برنامه بسازیم که بتونه به پیغامی که دکمهی share میده، جواب بده. اول یه پروژهی جدید میسازیم، بعد به AndroidManifest.xml میریم، جایی که میتونیم یه مفهوم ضمنی بسازیم، توی پروژه یه فعالیت (activity) اصلی داریم که من اسمشو گذاشتم main. و مشاهده میکنید که برای این فعالیت یه intent-filter وجود داره که قبلا دریارهاش توضیح دادم. برای ساختن یه مفهوم دیگه، همون بلوک intent-filter رو کپی میکنیم، هر کدوم از این بلوکها به سیستم میگه که این فعالیت قادر به مدیریت این مفاهیمه.
در قسمت action کد جدید به جای MAIN می نویسیم، SEND.
برای category هم مقدار DEFAULT رو به جای LAUNCHER مینویسیم. این category به سیستم میگه که این مفهوم ا چه نوعیه که معمولا همون مقدار پیش فرض رو می ذاریم و خلاص :دی
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
۳.مورد بعدی که باید اضافه کنیم، یه تگ data است که نوع دادهای که میتونیم با این مفهوم مدیریت کنیم رو به اندروید میگه. یکی از حصوصیاتش mimetype هست که مساوی */image می ذاریم به این معنی که هرنوع عکسی رو می تونه مدیریت کنه.
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
با اضافه کردن همین چند خط کد، برنامه مون این توانایی رو پیدا میکنه که اگه کسی خواست عکسی رو بفرسته و روی دکمهی share کلیک کرد، ما هم میتونیم اون رو براش مدیریت کنیم.
۴.وقتی عکس از برنامهی Gallery برامون فرستاده شد، بیاید یه راهی برای نمایش اون فراهم کنیم. به فایل main.xml داخل layout میریم و اون فیلد متنی رو پاک میکنیم. و از ستون سمت چپ تو قسمت Images & Media یه کدوم از گزینه هایی که می تونه تصویر رو نشون بده رو انتخاب میکنیم، و یه عکس الکی می ذاریم روش.
بعد به فایل جاوای مربوط به این xml میریم، که main.java هست. اول یه مرجع از اون imageView که تو فایل xml گذاشتیم میگیریم. با نوشتن این کد (قبلا مفصل توضیح داده شده):
ImageView image = (ImageView) findViewById(R.id.imageView1);
۵.حالا میخوایم اون عکسی که از Gallery برامون فرستاده میشه رو به عنوان محتویات این imageView قرار بدیم. با استفاده از تابع setImageURI از کلاس imageView. این تابع باید به جایی اشاره کنه که قراره از اونجا محتویات تصویر مشخص بشه. و ما میخوایم این محتویات رو از مفهوم ضمنی بگیریم، پس مینویسیم (تو پست قبل توضیح دادم):
image.setImageURI(getIntent().getExtras().get(Intent.EXTRA_STREAM));
از setImageURI خطا میگیره، باید crtl+1 رو بزنید و اولین گزینه ی تصحیح اینه که cast کنید. پس اینجوری می شه:
image.setImageURI((Uri) getIntent().getExtras().get(Intent.EXTRA_STREAM));
این Intent.EXTRA_STREAM تمام رشته ای که این مفهوم میفرسته رو میگیره که در واقع آدرس URI همون عکسه است.
۶.برنامه رو run کنید. وقتی بالا میاد یه خطا میگیره که انتظارش هم میرفت، چون وقتی همین جوری برنامه رو اجرا کنید آدرس هیچ عکسی فرستاده نشده و موقعی که دارید واقعا برنامه تولید میکنید باید به این خطاها فکر کنید و راه حلی براشون پیدا کنید.
۷.حالا به Gallery میریم و روی عکس دکمهی share رو میزنیم، و میبینیم که برنامهی ما هم به لیستی که میتونه این کارو انجام بده اضافه شده!
و با انتخاب برنامهی خودمون میبینیم که عکس فرستاده شده نمایش داده میشه.
برگرفته شده از AndroidCode.ir