مشخصات مقاله
-
2658
-
0.0
-
14402
-
0
-
0
آموزش Intent در اندروید
آموزش Intent در Android
این مبحث به آموزش نحوه ی استفاده از Intent جهت برقراری ارتباط بین کامپوننت ها و اجزا نرم افزاری مختلف اندروید می پردازد.
آموزش اجرا و راه اندازی دیگر کامپوننت ها و اجزا نرم افزاری اندروید به وسیله ی intent ها (تبادل اطلاعات بین اجزا و کامپوننت های مختلف به وسیله ی آبجکت های intent)
Intent ها پیغام هایی هستند که به واسطه ی آن ها از سیستم تقاضای انجام کار یا عملیات خاصی را می کنید. در واقع با استفاده از آبجکت intent می توانید بین کامپوننت های مختلف یک اپلیکیشن و حتی کامپوننت های نرم افزاری دیگر اپلیکیشن ها تعامل بر قرار نمایید و اطلاعات رد و بدل کنید. برای مثال، یک Activity می تواند activity دیگر را جهت عکس گرفتن اجرا کند.
به وسیله ی intent ها می توانید service ها و Activity ها را اجرا کنید یا مقادیری را از یک activity به activity دیگری ارسال نمایید.
Intent ها آبجکت یا نمونه هایی از جنس کلاس android.content.Intent هستند. کد شما می تواند آبجکت های intent را به سیستم اندروید ارسال کرده و صریحا اعلام کند کدام کامپوننت ها هدف و مد نظر شما هستند. به طور مثال، می توانید یک activity را به کمک متد startActivity() راه اندازی کنید (تعریف کنید که این intent باید فقط به قصد اجرای activity بکار گرفته شود).
داده های مورد نظر را می توانید برای ارسال به activity دیگر داخل Bundle قرار دهید. داده هایی که داخل این آبجکت قرار دادید توسط کامپوننت مد نظر دریافت و مورد استفاده قرار می گیرد.
در سیستم اندروید استفاده ی مجدد از دیگر کامپوننت های اپلیکیشن تحت عنوان task شناخته می شود. یک اپلیکیشن می تواند برای انجام عملیات خاصی به دیگر کامپوننت های اندروید دسترسی داشته باشد. به عنوان مثال می توانید از یک کامپوننت اپلیکیشن خود، کامپوننت دیگری در سیستم عامل اندروید را فعال سازی نمایید که فایل های تصویری را مدیریت می کند، با اینکه این کامپوننت به اپلیکیشن جاری تعلق ندارد. سپس در این کامپوننت عکس دلخواه را انتخاب کرده و به اپلیکیشن خود برای استفاده از عکس انتخابی باز گردید.
این این جریان تعامل و تبادل اطلاعات در زیر به تصویر کشیده شده است.
آموزش راه اندازی Activity ها به وسیله ی آبجکت intent
به منظور راه اندازی یک activity، می توانید متد startActivity(intent) را بکار ببرید. این متد در سطح آبجکت Context تعریف شده است. کلاس Activity از این کلاس پدر ارث بری داشته و متعاقبا متد ذکر شده را نیز از این کلاس به ارث می برد و آن را در بدنه ی خود فراخوانی می کند.
کد زیر نحوه ی راه اندازی یک activity از طریق آبجکت intent را به نمایش می گذارد:
# Start the activity connect to the # specified class Intent i = new Intent(this, ActivityTwo.class); startActivity(i);
Activity هایی که توسط activity های دیگر راه اندازی می شوند در اصطلاح sub-activity خوانده می شوند.
آموزش راه اندازی service ها
گفتنی است که توسط intent ها می توان service ها را نیز راه اندازی نمود. کافی است متد startService(Intent) را فراخوانی نمایید.
آموزش ارسال intent های صریح/explicit و ضمنی/implicit
Intent صریح یا explicit برای صدا زدن و به اجرا در آوردن service یا Activity مشخصی مورد استفاده قرار می گیرد. در این سناریو کاربر نمی تواند تصمیم بگیرد رخداد مورد نظر توسط کدام کامپوننت انجام شود، برای مثال شرایطی را در نظر بگیرید که برنامه ی کاربردی شما دو Activity دارد و شما می خواهید از طریق activity اول به activity دوم راه پیدا کنید. در این حالت لازم است از intent صریح استفاده نمایید. به عبارت دیگر به منظور برقراری ارتباط بین بخش های داخلی یک نرم افزار از intent صریح استفاده می شود. Intent های ضمنی هدف و کامپوننت مد نظر خود را با نام مشخص نمی کنند و معمولا برای راه اندازی کامپوننت دیگر نرم افزار ها مورد استفاده قرار می گیرند. به بیان دیگر زمانی که می خواهید سیستم اندروید عملیاتی را انجام دهد و برای شما چندان اهمیتی ندارد این کار توسط کدام activity یا service انجام می شود، می بایست از intent ضمنی استفاده نمایید. در این سناریو سیستم اندروید تمامی کامپوننت هایی که قابلیت انجام درخواست را دارند، فهرست می کند و کاربر می تواند تصمیم بگیرد درخواست توسط کدام کامپوننت اجرا شود.
کد زیر نحوه ی ایجاد یک intent صریح و ارسال آن به سیستم Android جهت راه اندازی activity دیگر را نمایش می دهد.
Intent i = new Intent(this, ActivityTwo.class);
i.putExtra("Value1", "This value one for ActivityTwo ");
i.putExtra("Value2", "This value two ActivityTwo");
همان طور که در بالا ذکر شد، هنگامی که intent درخواست انجام عملیات خاصی را از سیستم اندروید می کند، اندروید تمامی نرم افزارهایی که برای اجرای این درخواست و عملیات ثبت شده اند را شناسایی کرده و برای کاربر فهرست می کند. این کار توسط intent filter صورت می پذیرد. برای مثال، کد زیر از اندروید درخواست مشاهده ی یک صفحه ی وب را می کند. تمامی مرورگرهای وب که برای این منظور ثبت شده اند، توسط اندروید شناسایی شده و برای کاربر جهت انتخاب، نمایش داده می شود. این کار توسط intent filter امکان پذیر می باشد.
کد زیر به سیستم اندروید اعلام می کند که یک صفحه ی وب را باز کند. تمامی مرورگر های نصب شده بر روی سیستم که برای این intent ثبت شده اند، لیست می شوند و کاربر یکی از آن ها را برای مشاهده ی صفحه انتخاب می کند.
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.vogella.com"));
startActivity(i);
آموزش انتقال و تبادل اطلاعات بین activity ها و service ها
آموزش ارسال داده به کامپوننت مقصد
در زمان تعریف یک intent بایستی اطلاعات مرتبط با آن intent را نیز مشخص نمایید. در حقیقت یک intent می تواند دربردارنده ی یک سری اطلاعات پایه ای پیرامون خود باشد همچون اینکه چه عملیاتی باید انجام شود و چه نوع و غیره ... برای هر نوع درخواست نیز ممکن است اطلاعات بیشتری نیاز باشد. یک intent می تواند همچنین داده های اضافی در نمونه ای از کلاس (آبجکت) Bundle داشته باشد که به راحتی از طریق متد getExtras() قابل بازیابی است.
شما می توانید داده های اضافی را مستقیما از طریق نسخه های overload شده ی متد putExtra() از آبجکت های Intent، (نمونه ای از کلاس) Bundle قرار دهید. داده های اضافی در قالب جفت های کلید/مقدار هستند. کلید همیشه از نوع String است و مقادیر آن را می توانید از نوع داده ای اولیه int، float یا آبجکت های از نوع String، Bundle، Parceable و Serializable تنظیم نمایید.
کامپوننت دریافت کننده می تواند به این اطلاعات از طریق توابع getAction() و getData() آبجکت Intent دسترسی داشته باشد. خود آبجکت Intent را نیز می توان از طریق متد getIntent() بازیابی نمود.
کامپوننتی که دریافت کننده ی این intent است، می تواند با فراخوانی getIntent() .getExtras() به داده های اضافی دسترسی داشته باشد. این عملیات در تکه کد زیر به نمایش گذاشته شده است.
Bundle extras = getIntent().getExtras();
if (extras == null) {
return;
}
// get data via the key
String value1 = extras.getString(Intent.EXTRA_TEXT);
if (value1 != null) {
// do something with the data
}
نمونه: استفاده از intent جهت به اشتراک گذاری اطلاعات
اغلب اپلیکیشن های اندروید این امکان را به شما می دهند تا داده هایی را با کاربران که عضو اپلیکیشن های Facebbok، G+، Gmail و Twitter هستند به اشتراک بگذارید. در واقع می توانید داده های مورد نظر را از طریق آبجکت Intent به یکی از این کامپوننت ها ارسال کنید. تکه کد زیر روش استفاده از intent جهت به اشتراک گذاری اطلاعات را نمایش می دهد:
// this runs, for example, after a button click
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(android.content.Intent.EXTRA_TEXT, "News for you!");
startActivity(intent);
آموزش بازیابی اطلاعات از یک subactivity
یک activity را می توانید با اعمال دکمه ی بازگشت در نمایشگر گوشی خود پایان دهید. با فشردن این دکمه، متد finish() فراخوانی می شود. چنانچه activity مورد نظر با صدا خوردن متد startActivity(Intent) اجرا شده باشد، در آن صورت فراخواننده انتظار بازگشت هیچ نتیجه یا بازخوردی از activity مزبور را ندارد.
اگر activity را با فراخوانی متد startActivityForResult() راه اندازی کرده باشید، در آن صورت subactivity طبق انتظار، نتیجه ای را برمی گرداند. با پایان یافتن subactivity، متد onActivityResult() در subactivity فرخوانده می شود و شما می توانید عملیاتی را با توجه به نتیجه بازگشتی انجام دهید.
در فراخوانی متد startActivityForResult() شما می توانید کدی (resultcode) جهت شناسایی activity راه اندازی شده تعریف نمایید. این کد به شما بازگردانده می شود. activity فراخوانده شده نیز می تواند کدی داشته باشد که فراخواننده به کمک آن می تواند تشخیص دهد آیا activity لغو شده یا خیر.
Sub-activity با استفاده از finish() یک intent جدید ایجاد کرده و داده ها را در آن می ریزد. سپس به واسطه ی فراخوانی متد setResult() نتیجه را تنظیم می کند.
نمونه کد زیر نشان می دهد چگونه با اجرای متد startActivityForResult() (و ارسال کلاس ایجاد شده از intent به عنوان آرگومان به این متد)، یک intent را فعال و به اصطلاح trigger نمایید.
public void onClick(View view) {
Intent i = new Intent(this, ActivityTwo.class);
i.putExtra("Value1", "This value one for ActivityTwo ");
i.putExtra("Value2", "This value two ActivityTwo");
// set the request code to any code you like,
// you can identify the callback via this code
startActivityForResult(i, REQUEST_CODE);
}
زمانی که متد startActivityForResult() را صدا می زنید، activity راه اندازی شده sub-activity خوانده می شود.
هنگامی که subactivity بسته می شود، به دنبالش داده ها را از طریق آبجکت intent به فراخواننده ی خود ارسال می کند. این عملیات داخل بدنه ی finish() پیاده سازی می شود.
@Override
public void finish() {
// Prepare data intent
Intent data = new Intent();
data.putExtra("returnKey1", "Swinging on a star. ");
data.putExtra("returnKey2", "You could be better then you are. ");
// Activity finished ok, return the data
setResult(RESULT_OK, data);
super.finish();
}
با بسته شدن یا به پایان رسیدن subactivity، متد onActivityResult() در سطح کلاس activity فراخواننده صدا خورده می شود.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
if (data.hasExtra("returnKey1")) {
Toast.makeText(this, data.getExtras().getString("returnKey1"),
Toast.LENGTH_SHORT).show();
}
}
}
آموزش ثبت و معرفی intent filter برای intent
Intent filter چیست؟
Intent ها رخداد یک اتفاق را به سیستم اندروید اعلان می کنند و در پی آن تمامی Activity و Service هایی که برای آن اتفاق در سیستم ثبت شده اند، صدا خورده و اجرا می شوند. Intent ها معمولا عملیاتی که باید اجرا شوند را شرح داده و اطلاعاتی را نیز درباره ی عملیاتی که باید اجرا شود ارائه می دهد. برای مثال، اپلیکیشن شما می تواند جهت دسترسی به آدرس URL خاص، با استفاده از آبجکت intent یک کامپوننت مرورگر را راه اندازی کند. در تکه کد زیر این عملیات به نمایش گذاشته شده است.
String url = "http://www.vogella.com"; Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(url)); startActivity(i);
اینجا یک سوال مطرح می شود: چگونه سیستم اندروید می تواند کامپوننت هایی را که قادر به اجرای درخواست intent خاص و واکنش نشان دادن به آن هستند را شناسایی کند؟
همان طور که گفته شد سیستم اندروید به وسیله ی intent filter تشخیص می دهد آیا یک برنامه ی کاربردی قابلیت اجرای درخواست معینی را دارد یا خیر. در سیستم اندروید برنامه نویس می تواند با استفاده از intent filter امکاناتی که نرم افزار دارد را اعلان کند. کد زیر یک activity را برای intent ثبت می کند. این intent زمانی که کاربر می خواهد یک صفحه ی وب را باز کند، فعال شده و فراخوانی می گردد. مثال زیر یک activity ویژه ی ACTION_SEND ثبت می کند. همان طور که در کد زیر می بینید activity حاضر تنها قادر به پردازش داده هایی از نوع text/plain می باشد (با استفاده از intent-filter خود را مربوط به این داده اعلان یا ثبت کرده است.) اگر یک کامپوننت intent filter تعریف نکند، در آن صورت فقط intent صریح می تواند آن را فراخوانی کند.
با استفاده از intent ها می توان پیغام هایی (broadcast message) را به سیستم اندروید ارسال کرد. Broadcast receiver می تواند به رخدادی گوش فرا داده (register کرده) و زمانی که رخداد اتفاق افتاد، از آن مطلع شود.
گاهی لازم می شود برنامه نویس بررسی کرده و مطمئن شوید آیا کامپوننت خاص برای یک intent ثبت شده و به آن گوش می دهد یا خیر. برای مثال، می خواهید ببینید آیا intent receiver خاصی (یک کامپوننت) وجود دارد یا خیر، و در صورت وجود آن کامپوننت قابلیت خاصی را در اپلیکیشن خود فعال نمایید. با توجه به نتیجه ی بازگشتی می توانید اپلیکیشن خود را تنظیم کنید. برای مثال، می توانید برخی از آیتم های منو را غیرفعال ساخته یا پنهان نمایید. تمرین زیر نشان می دهد چگونه با استفاده از یک intent صریح، یک subactivity را راه اندازی نموده و به آن داده هایی را ارسال کنید.
یک پروژه ی جدید اندروید به نام com.vogella.android.intent.explicit ایجاد کرده (این اسم را در فیلد package وارد نمایید) و activity آن را MainActivity نام گذاری نمایید.
یک فایل layout جدید به نام activity_result.xml ایجاد نمایید. در گام بعدی یک activity جدید ایجاد خواهید کرد که از این فایل layout استفاده می کند. کلاس activity دیگری به نام ResultActivity تعریف نموده و کد موجود در بدنه ی این کلاس را مانند نمونه ی زیر نگارش نمایید. کلاس activity فوق را به فایل AndroidManifest.xml اضافه نمایید. از آنجایی که activity ذکر شده توسط acitivity دیگری (کلاس MainActivity) راه اندازی می شود، از این به بعد تحت عنوان subactivity به آن اشاره می کنیم. Subactivity را با کلیک بر روی یک دکمه در صفحه ی اصلی برنامه که همان کلاس MainActivity محسوب می شود، راه اندازی نمایید. کد زیر شما را در خصوص پیاده سازی این عملیات راهنمایی می کند. با نوشتن دستورات مناسب بجای TODO ها در کد برنامه، اپلیکیشن خود را طوری بنویسید که ResultActivity با فراخوانی متد OnClick() راه اندازی شود (به محض کلیک بر روی دکمه در صفحه ی اصلی، اپلیکیشن کاربر را به activity دوم هدایت کند). پس از اتمام این بخش از تمرین، اپلیکیشن خود را راه اندازی نموده و مطمئن شوید که کاربر با کلیک بر روی دکمه در صفحه ی اول اپلیکیشن، به activity دوم راه پیدا می کند. کلاس MainActivity می بایست مقدار EditText را به subactivity ارسال کند. برای این منظور کافی است متد putExtra("yourKey", string) را بر روی آبجکت Intent بکار ببرید.
حال داده های ارسالی از activity اصلی اپلیکیشن را از Bundle که بخشی از آبجکت intent است با فراخوانی متد getIntent().getExtras() در کلاس ResultActivity بازیابی نمایید.
در تمرین زیر کدی به متن برنامه اضافه می کنید که با کلیک کاربر بر روی دکمه ی Backدر activity دوم، داده هایی را از subactivity به activity اصلی اپلیکیشن ارسال کند. در جایگاه TODO ها در کد فوق، بدنه ی متد finish() را پیاده سازی نمایید.
متد startActivityForResult() را در کلاس MainActivity فراخوانی نمایید تا subactivity راه اندازی شود. این کار به شما امکان می دهد تا متد onActivityResult() را برای دریافت داده از subactivity فراخوانی نمایید. حال داده های ارسالی extra که همراه با آبجکت bundle از activity دوم ارسال شده، استخراج نمایید. با تکمیل این تمرین، پیاده سازی activity شما می بایست مشابه کد کلاس های زیر باشد. یک دکمه ی دیگر به فایل layout مربوط به activity خود اضافه نمایید. کلیک بر روی این دکمه می بایست این امکان را فراهم بیاورد تا متن EditText را به اشتراک بگذارید. برای ارسال اطلاعات از اپلیکیشن دیگر، می بایست مقدار مربوطه را در ثابت Intent.ACTION_SEND قرار دهید. سپس یک متد با این تعریف public void shareData(View view) بر اساس تکه کد زیر در activity خود ایجاد نمایید. این متد را به وسیله ی property یا خصوصیت android:onClick در فایل layout خود به دکمه ی مربوطه متصل نمایید. سپس این برنامه را اجرا نموده و بر روی دکمه ی مورد نظر کلیک کنید. در محیط شبیه ساز، قاعدتا تنها برنامه ای که به این intent گوش فرا می دهد و در سیستم اندروید برای آن ثبت شده و متعاقبا مستقیما راه اندازی می شود، اپلیکیشن ارسال SMS می باشد.
در تمرین زیر یک activity را در فایل XML خود به عنوان مرورگر ثبت می کنید. پس از این کار، هر زمان که کاربر می خواهد آدرس URL ای که با http آغاز می شود را مشاهده کند، activity ای ذکر شده، برای پردازش intent مربوطه در دسترس خواهد بود. یک پروژه ی اندروید و یک activity به ترتیب به نام های de.vogella.android.intent.browserfilter و BrowserActivity ایجاد نمایید. Attribute های android:name و android:scheme را در فایل تنظیمات AndroidManifest.xml به ترتیب باIntent.Action_VIEW و "http" مقداردهی نمایید. همچنین لازم است در فایل manifest اجازه ی دسترسی به اینترنت را از طریق تگ uses-permission تنظیم نمایید. حال فایل layout مربوطه را به صورت زیر ویرایش نمایید. کد کلاس activity را نیز به ترتیب زیر ویرایش نمایید.
اپلیکیشن خود را نصب نمایید. زمانی که یک intent را جهت مشاهده ی محتویات صفحه ی URL فراخوانی یا فعال می کنید، کاربر قاعدتا باید بتواند پیاده سازی سفارشی مرورگر شما را انتخاب کند. پس از انتخاب کامپوننت دلخواه از میان کامپوننت های پیشنهادی توسط سیستم، کد HTML مورد نظر ابتدا در حافظه بارگذاری شده، سپس در المان رابط کاربری TextView به نمایش در می آید. در صورت تمایل می توانید TextView را با یک WebView جایگزین نموده و اپلیکیشن خود را به یک مرورگر واقعی تبدیل نمایید. WebView خود درخواست HTTP را برای شما مدیریت و بارگذاری می کند. کافی است آدرس URL را به واسطه ی متد loadURL به آن تخصیص دهید. مثال زیر نمایش می دهد چگونه می توان با استفاده از یک intent، عکس دلخواه را از اپلیکیشن های تخصیص یافته برای این منظور در سیستم اندروید، انتخاب نمود
یک پروژه ی جدید اندروید و یک activity به ترتیب با نام های de.vogella.android.imagepick و ImagePickActivity ایجاد نمایید. کد کلاس activity خود را به صورت زیر ویرایش نمایید. با توجه به کدی که برای اپلیکیشن خود نوشته اید، باید پس از اجرای آن بتوانید عکس دلخواه را از image library مستقر در دستگاه اندروید خود انتخاب نموده و سپس آن را به ImageView تخصیص دهید. تمرین زیر نحوه ی استفاده از intent های ضمنی جهت راه اندازی activity ها در سیستم اندروید را برای شما شرح می دهد.
یک پروژه ی جدید و یک activity به ترتیب به نام های de.vogella.android.intent.implicit و CallIntentsActivity ایجاد نمایید. فایل layout مربوط به activity مورد نظر را به صورت زیر ویرایش نمایید. برای اینکه بتوانید از intent های مورد نظر استفاده کنید، لازم است مجوزهای مربوطه را در فایل تنظیمات AndroidManifest.xml ثبت نمایید. در واقع فایل تنظیمات اپلیکیشن شما می بایست مجوزهای زیر را (در تگ uses-permission) در خود به صورت زیر داشته باشد. کد کلاس activity خود را به صورت زیر ویرایش نمایید. با اجرای اپلیکیشن می بینید که یک لیست کشویی به برنامه اضافه شده که کلیک بر روی هر یک از آن ها به اجرا و راه اندازی activity های مربوطه منتهی می شود. اگر بخاطر داشته باشید، شما هیچ اپلیکیشن مشخصی را به عنوان دریافت کننده ی intent به طور صریح مشخص نکردید (تنها عملیاتی که باید انجام شود را قید نمودید ). این امر به شما اجازه می دهد تا task هایی با وابستگی کم (loosely coupled) تعریف نمایید که قابلیت استفاده از کامپونتت های اپلیکیشن های مختلف را فراهم می آورد (در این سناریو، سیستم اندروید تمامی کامپوننت هایی که برای این intent تخصیص یافته و قابلیت اجرای درخواست آن را دارند، شناسایی کرده و لیستی از کامپوننت های مزبور را برای کاربر لیست می کند. سپس کاربر تصمیم می گیرد activity را با کدام کامپوننت باز کند).
But how does the Android system identify the components which can react to a certain intent?
در سیستم اندروید، کامپوننت ها می توانند به وسیله ی intent filter خود را برای عملیات یا داده ای خاص ثبت کنند و در واقع اعلان نمایند که قابلیت انجام درخواست و عملیات intent مورد نظر را دارند. به بیانی دیگر intent filter با تعریف قابلیت های یک کامپوننت، نوع intent ای که یک activity، service یا broadcast receiver قادر به پاسخ گویی آن است را مشخص می کند.
کامپوننت های اندروید intent filter را یا به صورت static و ثابت در فایل AndroidManifest.xml تعریف می کنند و یا در خصوص broadcast reciever به صورت dynamic و از طریق کدنویسی. Intent filter از طریق category، action و data تعریف می شود (در فایل تنظیمات به وسیله ی تگ
می توانید فهرستی از actionها، categoryها و data هایی را که با هر کدام از کامپوننت های activity، service یا broadcast receiver مرتبط هستند را معرفی کنید). intent filter می تواند meta data نیز داشته باشد.
زمانی که یک intent به سیستم اندروید ارسال می شود، محیط (platform) یا بستر اجرای android دریافت کننده ی آن را شناسایی می کند. این کار را با استفاده از داده های موجود در آبجکت intent انجام می دهد. در صورتی که چندین کامپوننت برای یک intent filter ثبت نام کرده و گوش بدهند، در آن صورت سیستم اندروید لیستی از کامپوننت هایی که باید راه اندازی شده و پردازش یا درخواست را اجرا کنند برای کاربر نمایش داده و به دنبال آن کاربر می تواند تصمیم بگیرد کدام کامپوننت باید اجرا شود.
آموزش تعریف intent filter
می توانید کامپوننت های اندرویدی خود را به وسیله ی intent filter برای event و رخدادهای خاص معرفی کنید (در واقع به کامپوننت ها اعلان کنید که به رخدادهای مورد نظر گوش داده و منتظر فعال شدن آن ها باشند). در صورتی که این کار برای کامپوننت معینی انجام نشده باشد، آنگاه فقط intent های صریح (explicit) می توانند آن کامپوننت را فراخوانی کنند. مبحث حاضر نحوه ی ثبت یک کامپوننت برای intent معین را با ذکر مثال شرح می دهد. نکته ی مهم و کلیدی این است که کامپوننت ها برای action، mime-type مناسب ثبت نام کرده و گوش فرادهند و meta-data (اطلاعاتی پایه ای درباره ی intent) مربوطه را دربر گیرد.
اگر شما چنین intent ای را به سیستم اندروید ارسال کنید، سیستم تمامی کامپوننت هایی که برای این intent به ثبت رسیده اند را شناسایی می کند. در صورتی که چندین کامپوننت برای این intent ثبت شده باشند، سیستم اندروید آن ها را برای کاربر لیست می کند و کاربر می تواند تصمیم بگیرد با کامپوننت درخواست اجرا شود.
مثال: ثبت و تخصیص یک activity به عنوان مرورگر
مثال: ثبت و تخصیص یک activity برای intent به اشتراک گذاری و ارسال اطلاعات
آموزش گوش فرا دادن به event ها (ارسال پیغام به سیستم اندروید از طریق intent)
اپلیکیشن شما نیز می تواند به رخدادهای سیستم همچون دریافت ایمیل جدید، بالا آمدن سیستم، تماس جدید گوش فرا داده، و متناسب با آن عکس العمل مربوطه را نشان دهد.
آموزش شناسایی intent receiver های مربوطه/بررسی اینکه آیا یک کامپوننت به intent خاصی گوش فرا می دهد/برای آن ثبت شده یا خیر
برای این منظور می توانید از کلاس PackageManager استفاده کنید.
نمونه کد زیر بررسی می کند آیا کامپوننتی برای intent مورد نظر ثبت شده است یا خیر. کافی است intent خود را ساخته و آن را به متد زیر به عنوان آرگومان ارسال کنید.
public static boolean isIntentAvailable(Context ctx, Intent intent) {
final PackageManager mgr = ctx.getPackageManager();
List
تمرین: راه اندازی activity به وسیله ی intent صریح
آموزش ساخت پروژه و فایل layout اصلی
حال محتویات فایل layout این activity را به صورت زیر ویرایش نمایید:
آموزش ایجاد یک فایل layout جدید
اسم فایل را activity_result.xml انتخاب کرده و سپس دکمه ی Finish را فشار دهید. فایل layout خود را طوری ویرایش کنید که کد آن مشابه فایل XML زیر باشد.
آموزش ایجاد یک activity دیگر
package com.vogella.android.intent.explicit;
import android.app.Activity;
import android.os.Bundle;
public class ResultActivity extends Activity {
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_result);
}
}
آموزش راه اندازی subactivity
package com.vogella.android.intent.explicit;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View view) {
EditText text = (EditText) findViewById(R.id.inputforintent);
// used later
String value = text.getText().toString();
// TODO 1 create new Intent(context, class)
// use the activity as context parameter
// and "ResultActivity.class" for the class parameter
// TODO 2 start second activity with
// startActivity(intent);
}
}
آموزش انتقال داده (ارسال مقدار) از activity اول به activity دوم (ResultActivity)
آموزش دریافت اطلاعات ارسالی از activity اول (داده های intent) در ResultActivity
حال مقدار extra را با فراخوانی متد extras.getString("yourkey") بر روی آبجکت bundle که در نتیجه ی فراخوانی متد getExtras() بدست آوردید، بازیابی نمایید.
این مقدار می بایست داخل کلاس TextView با ID یا شناسه ی displayintentextra جایگذاری شود.
تمرین: بازیابی داده ها از ResultActivity (انتقال داده ها از activity دوم به activity اصلی برنامه)
برای نیل به این هدف، متد finish() را در کلاس ResultActivity پیاده سازی می کنید.
@Override
public void finish() {
// TODO 1 create new Intent
// Intent intent = new Intent();
// TODO 2 read the data of the EditText field
// with the id returnValue
// TODO 3 put the text from EditText
// as String extra into the intent
// use editText.getText().toString();
// TODO 4 use setResult(RESULT_OK, intent);
// to return the Intent to the application
super.finish();
}
آموزش دریافت و ارزیابی داده های بازگشتی (ارسالی از activity دوم) در کلاس MainActivity
بد نیست همراه داده های extra یک پیغام Toast نیز برای کاربر نمایش داده و اطمینان دهید که داده ها طبق انتظار دریافت شدند. کد زیر شما را در خصوص پیاده سازی این عملیات راهنمایی می کند:
package com.vogella.android.intent.explicit;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends Activity {
// constant to determine which sub-activity returns
private static final int REQUEST_CODE = 10;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View view) {
EditText text = (EditText) findViewById(R.id.inputforintent);
String string = text.getText().toString();
Intent i = new Intent(this, ResultActivity.class);
i.putExtra("yourkey", string);
// TODO 2.. now use
// startActivityForResult(i, REQUEST_CODE);
}
// TODO 3 Implement this method
// assumes that "returnkey" is used as key to return the result
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
if (data.hasExtra("returnkey")) {
String result = data.getExtras().getString("returnkey");
if (result != null && result.length() > 0) {
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
}
}
}
}
}
راه حل: استفاده از intent ها
package com.vogella.android.intent.explicit;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;
public class ResultActivity extends Activity {
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_result);
Bundle extras = getIntent().getExtras();
String inputString = extras.getString("yourkey");
TextView view = (TextView) findViewById(R.id.displayintentextra);
view.setText(inputString);
}
@Override
public void finish() {
Intent intent = new Intent();
EditText editText= (EditText) findViewById(R.id.returnValue);
String string = editText.getText().toString();
intent.putExtra("returnkey", string);
setResult(RESULT_OK, intent);
super.finish();
}
}
package com.vogella.android.intent.explicit;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
// constant to determine which sub-activity returns
private static final int REQUEST_CODE = 10;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View view) {
EditText text = (EditText) findViewById(R.id.inputforintent);
String string = text.getText().toString();
Intent i = new Intent(this, ResultActivity.class);
i.putExtra("yourkey", string);
startActivityForResult(i, REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
if (data.hasExtra("returnkey")) {
String result = data.getExtras().getString("returnkey");
if (result != null && result.length() > 0) {
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
}
}
}
}
}
تمرین: استفاده از intent به اشتراک گذاری و تبادل اطلاعات
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "REPLACE WITH YOUR TEXT");
startActivity(sharingIntent);
تمرین: تخصیص و ثبت یک activity به عنوان مرورگر
هدف اصلی
activity نام برده کد HTML این صفحه را دانلود کرده و آن را در یک TextView به نمایش می گذارد.
ایجاد پروژه
آموزش ثبت و تخصیص یک activity به عنوان مرورگر
package de.vogella.android.intent.browserfilter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.StrictMode;
import android.widget.TextView;
public class BrowserActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// To keep this example simple, we allow network access
// in the user interface thread
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
setContentView(R.layout.main);
Intent intent = getIntent();
TextView text = (TextView) findViewById(R.id.textView);
// To get the action of the intent use
String action = intent.getAction();
if (!action.equals(Intent.ACTION_VIEW)) {
throw new RuntimeException("Should not happen");
}
// To get the data use
Uri data = intent.getData();
URL url;
try {
url = new URL(data.getScheme(), data.getHost(), data.getPath());
BufferedReader rd = new BufferedReader(new InputStreamReader(
url.openStream()));
String line = "";
while ((line = rd.readLine()) != null) {
text.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
آموزش تست برنامه
در این راستا یک دکمه ی اضافی به اپلیکیشن خود اضافه می کنید که با کلیک بر روی آن کد intent فراخوانی می شود.
intent = new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.vogella.com"));
startActivity(intent);
آموزش تبدیل اپلیکیشن به یک مرورگر واقعی
تمرین: انتخاب یک عکس به وسیله ی آبجکت intent
هدف
آموزش ایجاد پروژه
فایل layout مربوط به activity_main.xml را به صورت زیر ویرایش نمایید.
package de.vogella.android.imagepick;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class ImagePickActivity extends Activity {
private static final int REQUEST_CODE = 1;
private Bitmap bitmap;
private ImageView imageView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView = (ImageView) findViewById(R.id.result);
}
public void pickImage(View View) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
InputStream stream = null;
if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK)
try {
// recyle unused bitmaps
if (bitmap != null) {
bitmap.recycle();
}
stream = getContentResolver().openInputStream(data.getData());
bitmap = BitmapFactory.decodeStream(stream);
imageView.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (stream != null)
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
تست اپلیکیشن
تمرین: استفاده از intent های ضمنی جهت راه اندازی activity ها
هدف
ایجاد پروژه
در این مثال، با پیاده سازی کلاس Spinner، یک لیست کشویی ایجاد می کنید که به کاربر اجازه می دهد تا خود تصمیم بگیرد کدام intent را فراخوانی کند. محتوای این لیست کشویی (Spinner) را مقادیر static و ثابت تعریف خواهید نمود.
برای این منظور فایل intents.xml زیر را در پوشه ی res/values ایجاد نمایید.
package de.vogella.android.intent.implicit;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
public class CallIntentsActivity extends Activity {
private Spinner spinner;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter adapter = ArrayAdapter.createFromResource(this,
R.array.intents, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
}
public void onClick(View view) {
int position = spinner.getSelectedItemPosition();
Intent intent = null;
switch (position) {
case 0:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.vogella.com"));
break;
case 1:
intent = new Intent(Intent.ACTION_CALL,
Uri.parse("tel:(+49)12345789"));
break;
case 2:
intent = new Intent(Intent.ACTION_DIAL,
Uri.parse("tel:(+49)12345789"));
startActivity(intent);
break;
case 3:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("geo:50.123,7.1434?z=19"));
break;
case 4:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("geo:0,0?q=query"));
break;
case 5:
intent = new Intent("android.media.action.IMAGE_CAPTURE");
break;
case 6:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("content://contacts/people/"));
break;
case 7:
intent = new Intent(Intent.ACTION_EDIT,
Uri.parse("content://contacts/people/1"));
break;
}
if (intent != null) {
startActivity(intent);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK && requestCode == 0) {
String result = data.toURI();
Toast.makeText(this, result, Toast.LENGTH_LONG);
}
}
}
تست اپلیکیشن