مهدی عادلی فر
بنیانگذار توسینسو و برنامه نویس

آموزش دریافت و پردازش درخواست های App های دیگر در برنامه اندروید

در مطلب قبلی در مورد نحوه باز کردن یک activity از برنامه دیگر و همچنین دریافت پاسخ از آن activity صحبت کردیم. در این مطلب قضیه را برعکس نگاه می کنیم که چگونه می توان درخواست های اپ های دیگر را پاسخ داد. این قضیه می تواند خیلی مهم باشد. مثلا شما یک موزیک پلیرنصب می کنید و وقتی یک فایل موسیقی را باز می کنید اندروید از کجا می فهمد که کدام برنامه ها را برای شما لیست کند؟

دوره های شبکه، برنامه نویسی، مجازی سازی، امنیت، نفوذ و ... با برترین های ایران

یا وقتی که شما یک عکس را باز می کنید اگر برای باز شدن آن یک برنامه پیش فرض انتخاب نکرده باشد یک لیست از برنامه های عکس به آن نشان می دهد؟ می خواهیم بدانیم که چگونه می توان برنامه خود را در این لیست ها قرار بدهیم و وقتی که کاربر برنامه ما را انتخاب کرد چگونه بتوانیم داده ها را از برنامه مورد نظر خوانده و آن را در برنامه خودمان پردازش کنیم. برای این که اندروید بفهمد که برای باز کردن یک فایل خاص یا یک Uri خاص را با برنامه ما باز کند باید در داخل فایل manifest تغییراتی ایجاد کنیم.

این تغییرات اضافه کردن قسمت intent-filter به این فایل است. برای این کار باید یک تگ intent-filter را به تگ activity اضافه می کنیم. وقتی که برنام شما بر روی یک دستگاه نصب می شود اندروید intent-filter های آن را بررسی می کند و هنگامی که با استفاده از متد های startActivity, startActivityForResult استفاده می کنید و intent شما ضمنی است سیستم به دنبال activity هایی می گردد که در intent-filter خود قابلیت باز کردن فایل های مورد نظر را داشته باشند. در ادامه توضیح می دهیم که روش کار به چه شکل است

اضافه کردن intent filter

برای این که بتوان intentهای مشخص شده را توسط برنامه پذیرفت باید شرایط زیر را برای آن در نظر گرفت تا intent های ورودی را قبول کند. این شرط ها در تگ intent-filter ها قرار می گیرند. این تگ ها عبارتند از

  • Action: این قسمت نام کاری است که انجام می شود. معمولا نام action یک نامی است که در داخل اندروید تعریف شده است برای مثال ACTIONVIEW و ACTIONSEND دو عدد نام action می باشند. برای مشخص کردن action ها از تگ <action> استفاده می شود.
  • Data: یک توضیحی است که مربوط به داده های موجود در intent است. این قسمت با استفاده از <data> مشخص می شود. با استفاده از این قسمت شما می توانید MIME type یا URI یا URI scheme یا ترکیبی از آنها را در intent-filter قرار دهید. که هر کدام داخل یک تگ <data> قرار می گیرد.
  • Category: این قسمت شامل یک سری اطلاعات بیشتر در مورد activity است که قرار است intent را دریافت کند. با توجه این که وضعیت کاربر و این که محل کاربر کجا باشد category های مختلفی وجود دارد که این category ها به ندرت استفاده می شوند. همه ی intent های ضمنی کاربر به طور پیش فرض با category به نام CATEGORY_DEFAULT تعریف می شوند. در کد زیر یک activity تعریف کرده ایم که مقادیری را که توضیح داده ایم را در intent-filter آن قرار داده ایم.
<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
        <data android:mimeType="image/*"/>
    </intent-filter>
</activity>

Activity بالا رشته و عکس را می پذیرد. هر intent که به صورت ضمنی باشد و به سمت یک برنامه دیگر ارسال شود فقط یک نوع داده و action دارد. هرکدام از activity ها هم باید فقط یک نوع اکشن را بپذیرند و اگر بخواهیم که برنامه ما بیش از یک action را بپذیرد باید از دو intent-filter استفاده کنیم. برای مثال ما در کد زیر یک intent-filter تعریف کرده ایم که اکشن send و دیگری اکشن sendto را پشتیبانی می کند. زیرا که این دو اکشن از نظر داده ای و عمل با هم متفاوت هستند.

<activity android:name="ShareActivity">
    <!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
    <intent-filter>
        <action android:name="android.intent.action.SENDTO"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="sms" />
        <data android:scheme="smsto" />
    </intent-filter>
    <!-- filter for sending text or images; accepts SEND action and text or image data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

پردازش Intent ورودی

تا به این جا گفتیم که چطوری یک activity تعریف کنیم که بتواند درخواست های اپ های دیگر را دریافت کند. در این بخش فرض می کنیم که از این مرحله گذشتیم و به مرحله ای رسیدیم که باید داده ای را که از یک برنامه دیگر به سمت برنام ما آمده پردازش کنیم. ما می توانیم با استفاده ازمتد getIntent مقادیر intent ارسال شده را ببینیم و با آن کار کنیم. از متد getIntent باید در متد onCreate, یا onStart استفاده کنیم. در کد زیر یک نمونه برای پردازش داده ورودی آورده شده است.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    // Get the intent that started this activity
    Intent intent = getIntent();
    Uri data = intent.getData();

    // Figure out what to do based on the intent type
    if (intent.getType().indexOf("image/") != -1) {
        // داده ورودی از نوع عکس است
    } else if (intent.getType().equals("text/plain")) {
        // داده ورودی از نوع متن است    }
}

بازگرداندن نتیجه پردازش به activity ارسال کننده

Activity ارسال کننده اکتیویتی ای است که یک درخواست برای ما ارسال کرده است. حال ما درخواست را در برنامه خود پردازش کرده و الان باید نتیجه را به activity ارسال کننده برگشت بدهیم. برای این کار به راحتی از متد setResult استفاده خواهیم کرد. و برای این که activity ما بسته شود و به activity ارسال کننده بازگشت داده شویم از متد finish استفاده می کنیم. در کد زیر ما یک جواب تولید کرده ایم و به ارسال کننده پاسخ می دهیم.

Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"));
setResult(Activity.RESULT_OK, result);
finish();

متد setResult یک ورودی به نام result code دارد که مشخص می کند که کار به درستی انجام شده است یا خیر و این resultCode به همراه نتیجه به activity درخواست کننده ارسال می شود. مقادیری که می توان برای result code در نظر گرفت RESULTOK و RESULTCANCELED می باشد. البته می توان یک عدد صحیح را نیز به عنوان result code ارسال کرد.


مهدی عادلی فر
مهدی عادلی فر

بنیانگذار توسینسو و برنامه نویس

مهدی عادلی، بنیان گذار TOSINSO. کارشناس ارشد نرم افزار کامپیوتر از دانشگاه صنعتی امیرکبیر و #C و جاوا و اندروید کار می کنم. در زمینه های موبایل و وب و ویندوز فعالیت دارم و به طراحی نرم افزار و اصول مهندسی نرم افزار علاقه مندم.

نظرات