onesignal pushe.co s-3.664-0.699-5.062-2.099c-1.397-1.398-2.097-3.087-2.097-5.065s0.699-3.667,2.097-5.065c1.397-1.399,3.085-2.099,5.062-2.099 s3.664,0.699,5.062,2.099C223.888,120.556,224.587,122.244,224.587,124.223z"/>

Eclipse

راه‌اندازی

اضافه کردن کتابخانه‌ها

  • ابتدا از این لینک فایل‌های لازم را دانلود کرده و اکسترکت کنید.
  • در اکلیپس از منوی File گزینه‌ی import را انتخاب کرده و از بخش Android گزینه‌ی Existing android code into workspace را انتخاب کنید.
  • با استفاده از Browse فولدر اکسترکت‌شده را بیابید و تمام موارد را با فعال‌بودن تیک Copy projects into workspace اضافه‌نمایید.
  • روی پروژه راست‌کلیک کرده و Properties را انتخاب کند.
  • در تب Android بخش Library با استفاده از گزینه‌ی Add تمام لایبرری‌های اضافه‌شده را انتخاب و به Dependencyها اضافه‌کنید.

با توجه به اینکه اکلیپس نسخه‌های متعددی دارد و به روز بودن کتابخانه های آن برای اجرای پوشه اهمیت دارد، پیشنهاد ما دانلود و استفاده از نسخه‌های زیر است تا برای نصب با مشکلی مواجه نشوید.

برای استفاده از پوشه باید Android SDK خود را بروز نمایید.

تغییرات AndroidManifest.xml

  • وارد پنل کاربری پوشه شوید و در قسمت اپلیکیشن‌ها، روی آیکون دریافت منیفست بزنید (این آیکون را با کلیک بر روی علامت سه نقطه ی گوشه ی کارت اپلیکیشن می توانید ببینید).
  • منیفست مربوط به اکلیپس را انتخاب کنید و محتویات آن را با توجه به راهنمای موجود، از قسمت‌های مربوطه کپی کرده و به AndroidManifest.xml پروژه خود اضافه کنید.

در صورتی‌که هنگام اجرای پروژه لایبرری android-support-v4 را قبلا داشته‌اید، آن‌را حذف کنید تا از لایبرری موجود در پوشه استفاده شود.

فعال‌کردن پوشه

در اکتیویتی اصلی برنامه‌ی خود ابتدا در بخش import خط زیر را اضافه کنید:

import co.ronash.pushe.Pushe;

سپس در onCreate کد زیر را اضافه کنید:

Pushe.initialize(this, true);

استفاده همزمان با فایربیس و سایر سرویس‌ها

پوشه برای دریافت اعلان از از سرویس FCM گوگل استفاده می‌کند. در صورتی که پوشه تنها سرویسی در اپلیکیشن شما باشد که از این سرویس استفاده می‌کند، با دنبال کردن همان مراحلی که در قسمت راه‌اندازی توصیح داده شد همه چیز به درستی کار خواهد کرد و نیازی به انجام کار اضافه‌ای برای راه‌ اندازی FCM نیست.

ولی در مواردی که غیر از پوشه سرویس دیگری نیز بخواهد از FCM استفاده کند، مثلا اگر خود شما بخواهید مستقیما از Firebase استفاده کنید و پیغام‌های FCM دریافت کنید، تداخل پیش خواهد آمد چرا که در هر اپلیکیشن تنها یک سرویس گوش‌دهنده به پیغام‌های FCM می‌تواند وجود داشته باشد. اگر بیش از یک سرویس گوش‌دهنده تعریف شود، پیغام‌هایی که به اپلیکیشن می‌رسند به صورت تصادفی تنها به دست یکی از این سرویس‌ها خواهد رسید و این باعث مختل شدن عملیات برنامه می‌شود.

برای رفع این مشکل لازم است مراحل زیر را در راه اندازی طی کنید:

  1. سرویس گوش دهنده FCM پوشه را غیر فعال کنید
  2. سرویس گوش دهنده FCM خود را فعال کنید
  3. با دریافت پیغام‌های FCM و رخ دادن رویداد‌های مربوط به آن در سرویس خود، پوشه را مطلع کنید

با طی کردن این مراحل، تنها گوش دهنده به پیغام‌های FCM گوش دهنده تعریف شده شما خواهد بود که همه‌ی پیغام‌های FCM را دریافت خواهد کرد و پیغام‌های مربوط به پوشه را به کتابخانه‌ی پوشه تحویل می‌دهد.

در ادامه نحوه اعمال این مراحل را قدم به فدم توضیح می‌دهیم:

۱. غیر فعال کردن سرویس FCM پوشه

برای غیر فعال کردن سرویس FCM پوشه، عبارت زیر را در تگ <application> فایل منیفست خود بگذارید:

<service
    android:name="co.ronash.pushe.fcm.FcmService" 
    tools:node="remove" />

در صورتی که با پیغام خطا مواجه شدید بررسی کنید که عبارت xmlns:tools="http://schemas.android.com/tools" در پارامتر‌های تگ <manifest> ابتدای فایل وجود داشته باشد، به این شکل:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="...">

۲. ایجاد سرویس FCM برنامه

در صورتی که از قبل سرویس FCM برای برنامه‌ی خود ایجاد کرده‌اید می‌توانید از این مرحله بگذرید.

یک کلاس جدید بسازید که از کلاس FirebaseMessagingService ارث می‌برد. در مثال زیر اسم کلاس را MyFcmService گذاشتیم ولی شما می‌توانید اسم دلخواه خود را استفاده کنید.

public class MyFcmService extends FirebaseMessagingService {

}

سرویس جدید را با گذاشتن عبارت زیر در تگ <application> فایل منیفست خود فعال کنید. توجه داشته باشید که نام کلاس را با نام کلاس تعریف شده خود جایگزین کنید.

<service android:name=".MyFcmService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

۳. رساندن پیغام‌ها و رویداد‌ها به پوشه

در کلاس تعریف شده در مرحله قبل، تابع‌های زیر را به همراه کد داخل آن‌ها پیاده‌سازی کنید:

public class MyFcmService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        if (Pushe.getFcmHandler(this).onMessageReceived(remoteMessage)) {
            // Message belongs to Pushe, no further action needed
            return;   
        }

        // Message does not belong to Pushe, process message...
    }

    @Override
    public void onNewToken(String s) {
        Pushe.getFcmHandler(this).onNewToken(s);
    }

    @Override
    public void onMessageSent(String s) {
        Pushe.getFcmHandler(this).onMessageSent(s);
    }

    @Override
    public void onSendError(String s, Exception e) {
        Pushe.getFcmHandler(this).onSendError(s, e);
    }

    @Override
    public void onDeletedMessages() {
        Pushe.getFcmHandler(this).onDeletedMessages();
    }    
}

هر بار که یک پیغام FCM به برنامه شما می‌رسد، تابع onMessageReceived کلاس شما صدا زده می‌شود. همانطور که در مثال بالا مشاهده می‌کنید در پیاده‌سازی این تابع، شما با استفاده از عبارت زیر پوشه را از دریافت پیغام مطلع می‌کنید:

Pushe.getFcmHandler(this).onMessageRecevied(remoteMessage)

با این کار پیغام به دست پوشه نیز می‌رسد و اگر پیغام مربوط به کتابخانه‌ی پوشه باشد عملیات لازم بر روی آن انجام می‌شود. در صورتی که پیغام مربوط به پوشه باشد عبارت بالا مقدار true بر می‌گرداند و شما نیازی نیست عملیات بیشتری روی این پیغام انجام دهید. در صورتی که از عبارت بالا مقدار false گرفتید به این معنی است که پیغام مربوط به پوشه نیست و شما باید بسته به نیاز خود عملیات مورد نظر را برای آن انجام دهید.

سایر توابع کلاس تعریف شده زمان رخ دادن رویداد‌های مختلف مربوط به FCM صدا زده می‌شوند. همانطور که در مثال بالا نشان داده شده، نیاز است که شما هنگام رخ دادن این رویدادها با صدا زدن تابع مربوطه از کتابخانه‌ی پوشه، پوشه را از رخ دادن این رویدادها مطلع کنید.

امکانات

دریافت اطلاعات دلخواه با فرمت JSON

شما میتوانید از طریق پنل برای اپلیکیشن خود اطلاعات دلخواه در قالب یک JSON ارسال کنید. برای اینکه بتوانید از این اطلاعات در اپلیکیشن خود استفاده کنید مراحل زیر را انجام دهید.

  • کد زیر را در AndroidManifest.xml داخل بدنه تگ <application> اضافه کنید.
<service
    android:name=".MyPushListener"
    android:exported="false">
    <intent-filter>
        <action android:name="co.ronash.pushe.RECEIVE" />
    </intent-filter>
</service>
<!--PushListener can be somewhere else according to your packaging-->
  • در پروژه خود یک class جدید ایجاد کنید و برای آن یک نام انتخاب کنید. پیشنهاد ما نام MyPushListener می باشد.
  • کد زیر را در آن قرار دهید. بر روی PusheListenerService و JSONObject که به رنگ قرمز در آمده اند رفته و کلید Alt+Enter را بزنید تا کتابخانه‌های مربوطه به پروژه شما اضافه شوند.
public class MyPushListener extends PusheListenerService {
    @Override
    public void onMessageReceived(JSONObject customContent,JSONObject pushMessage){
        android.util.Log.i("Pushe","Custom json Message: "+ customContent.toString());
        // Your Code
    }
}
  • از این طریق JSON دریافت می‌شود و با قرار دادن کد خود به جای // Your Code می‌توانید از آن استفاده کنید.
  • وقتی از کلاس PusheListenerService ارث بری می‌کنید، داخل متد onMessageReceived دو شیء از نوع JSONObject دریافت می‌کنید که پارامتر اول JSON ارسالی و پارامتر دوم محتوای پوش نمایش داده شده است.
  • برای مثال اگر در JSON ارسالی خود کلید‌های content و title را دارید و می‌خواهید آن را در LogCat نشان دهید، این کد را اضافه می‌کنید:

مثال: JSON ارسال شده

{
    "title": "تیتر",
    "content": "متن"
}
public class MyPushListener extends PusheListenerService{
    @Override
    public void onMessageReceived(JSONObject customContent,JSONObject pushMessage) {
        if (customContent == null || customContent.length() == 0)
            return; //json is empty
        android.util.Log.i("Pushe","Custom json Message: "+ customContent.toString()); //print json to logCat
        //Do something with json
      try{
            String s1 = customContent.getString("title");
            String s2 = customContent.getString("content");
            android.util.Log.i("Pushe","Json Message\n title: " + s1 + "\n content: " + s2);
      } catch (JSONException e) {
            android.util.Log.e("TAG","Exception in parsing json" ,e);
      }
 }

به همین ترتیب اگر شما مقادیر int یا boolean در JSON ارسالی گذاشته اید، با دستورهای

message.getInt(نام کلید)
message.getBoolean(نام کلید)

آن مقدار را از JSON دریافتی می‌گیرید و برحسب اینکه می‌خواهید با آن چه کاری انجام دهید، کد لازم را اضافه می‌کنید.

رسیورهای دریافت کلیک / رد اعلان

شما می‌توانید با ثبت یک رسیور در برنامه‌تان، از کلیک شدن یا رد کردن اعلان مطلع شوید. برای این کار یک BroadcastReceiver در فایل AndroidManifest.xml برنامه خودتان اضافه کنید و اینتنت فیلترهای زیر را در آن اضافه کنید. سه اینتنت فیلتر برای سه اتفاق زدن بر روی اعلان، رد کردن اعلان و کلیک شدن دکمه‌ای از اعلان معرفی شده است. می‌توانید هر سه را استفاده کنید یا فقط یکی یا دو تا را بسته به نیازمندی خودتان مشخص کنید.

این قابلیت برای نسخه های اندروید 8 و بالاتر کارایی ندارد.

<receiver android:name=".NotifBroadcastReceiver">
    <intent-filter>
        <action android:name="YOUR_PKG_NAME.pusheco.NOTIF_CLICKED"/>
        <action android:name="YOUR_PKG_NAME.pusheco.NOTIF_DISMISSED" />
        <action android:name="YOUR_PKG_NAME.pusheco.NOTIF_BTN_CLICKED" />
    </intent-filter>
</receiver>

در کلاس BroadcastReceiver هم کدی شبیه به زیر اضافه کنید:

  • دقت کنید که YOUR_PKG_NAME همان نام پکیج شماست.
public class NotifBroadcastReceiver
extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

    if(intent.getAction().equals("YOUR_PKG_NAME.pusheco.NOTIF_CLICKED")){
        Log.i("Pushe","Broadcast YOUR_PKG_NAME.pusheco.NOTIF_CLICKED received");
        //add your logic here
    }

    else if(intent.getAction().equals("YOUR_PKG_NAME.NOTIF_DISMISSED")){
        Log.i("Pushe", "Broadcast YOUR_PKG_NAME.NOTIF_DISMISSED received");
        //add your logic here
    }

    else if(intent.getAction().equals("YOUR_PKG_NAME.pusheco.NOTIF_BTN_CLICKED")){
        String btnId = intent.getStringExtra("pushe_notif_btn_id");
        Log.i("Pushe", "Broadcast YOUR_PKG_NAME.pusheco.NOTIF_BTN_CLICKED received. BtnId = "+btnId);
        //add your logic here
        }
    }
}

در حالتی که یک دکمه اعلان کلیک شود، شناسه آن دکمه را که یکی از اعداد ۱ تا ۳ هست می‌توانید داشته باشید و از روی آن اینکه چه دکمه‌ای کلیک شده است را متوجه می‌شوید.

تاپیک (topic)

شما می‌توانید کاربران خود را در تاپیک یا تاپیک‌های متفاوت ثبت نام کنید و برحسب علاقمندی کاربران یا دسته‌بندی خودتان به تاپیک مرتبط پوش بفرستید. مثلا اگر شما اپلیکیشن خبری دارید و کاربرانی به اخبار ورزشی علاقمند هستند و عده ای به اخبار فرهنگی، می توانید دسته اول را در تاپیک ورزشی و دسته دوم را در تاپیک فرهنگی ثبت نام کنید و هنگام ارسال پوش، برحسب محتوای پوش‌تان به تاپیک مرتبط آن را ارسال کنید تا فقط کاربران علاقمند به آن موضوع آن را دریافت کنند. برای استفاده از این امکان باید کاربران خود را در تاپیک مورد نظر عضو کنید. فرض کنید نام تاپیک مورد نظرتان ‍‍‍sport باشد. برای عضویت در این تاپیک از دستور زیر استفاده کنید:

Pushe.subscribe(context, "sport");

برای لغو عضویت از این تاپیک از دستور زیر استفاده کنید:

Pushe.unsubscribe(context, "sport");

توجه داشته باشید که توابع مربوط به عضو شدن و لغو عضویت در تاپیک باید بعد از پایان Pushe.initialize اجرا شوند. بنابراین آنها را بلافاصله بعد از Pushe.initialize قرار ندهید.

غیرفعال کردن نمایش پوش

می‌توانید نمایش پوش را غیرفعال کنید. مثلا در تنظیمات اپلیکیشن خود امکان دریافت نکردن پوش را برای کاربر قرار دهید و طبق انتخاب کاربر آن را فعال یا غیرفعال کنید. برای غیرفعال کردن نمایش پوش از دستور زیر استفاده کنید:

Pushe.setNotificationOff(context);

برای فعال سازی دوباره ی نمایش پوش از دستور زیر استفاده کنید:

Pushe.setNotificationOn(context);

ارسال پوش از یک دستگاه به دستگاه دیگر

می‌توانید مستقیم از یک دستگاه به دستگاه دیگر اعلان بفرستید. برای این کار باید شناسه‌ی پوشه‌ی آن دستگاه یعنی pusheId آن را داشته باشید. برای بدست آوردن شناسه هر دستگاه می توانید به روش زیر عمل کنید:

String pid = Pushe.getPusheId(context);

به این روش pid هر دستگاه را می توانید بدست بیاورید و آن‌ها را در سرور خود ذخیره کنید تا برای ارسال اعلان به دستگاه از آن استفاده کنید.

  • برای ارسال اعلان ساده از دستور زیر استفاده کنید:
Pushe.sendSimpleNotifToUser(context, "pid_a0e3-82ac-a0", "title", "content");
  • پارمتر اول context، پارامتر دوم pusheId است و پارامتر سوم و چهارم به ترتیب تیتر و متن اعلان هستند.
  • برای ارسال اعلان پیشرفته از این دستور استفاده کنید:
Pushe.sendAdvancedNotifToUser(context, "pid_a0e3-82ac-a0", "{ \"title\":\"تست\", \"content\":\"پیام ارسالی از یک دستگاه \" }");
  • پارمتر اول context، پارامتر دوم pusheId است و پارامتر سوم یک رشته با فرمت JSON هست که مشخصات اعلان پیشرفته را تعیین می کند. برای دیدن فرمت JSON به [اینجا]() مراجعه کنید.
  • برای ارسال JSON دلخواه از دستور زیر استفاده کنید:
Pushe.sendCustomJsonToUser(context, "pid_a0e3-82ac-a0", "{ \"key1\":\"value1\", \"key2\":\"value2\" }");

در این حالت پارامتر سوم یک رشته با فرمت JSON هست که اطلاعاتی که می خواهید ارسال کنید را به فرمت JSON داخلش دارد. نکته مهم: توابع ارسال اعلان به دستگاه دیگر و عضویت یا لغو عضویت در تاپیک را بعد از اطمینان از اینکه عملیات initialization پوشه انجام شده است، صدا بزنید. برای این کار به روش زیر عمل کنید:

if (Pushe.isPusheInitialized(context)) {
    Pushe.sendSimpleNotifToUser(context, "pid_a0e3-82ac-a0", "title", "content");
}

ایجاد و حذف کانال نوتیفیکیشن در اپلیکیشن (Android 8.0+ only)

در اندروید ۸ به بعد قابلیتی برای تعریف کانال نوتیفیکیشن در اپلیکیشن ایجاد شده است. به این شکل که در برنامه خود یک یا چند کانال نوتیفیکیشن تعریف می کنید و در زمان ارسال اعلان پیشرفته با وارد کردن Channel-Id آن کانال می‌توانید اعلان را برای آن کانال خاص ارسال کنید. مزیت این کار این هست که کاربر می تواند دریافت نوتیفیکیشن از بعضی کانال‌ها را غیرفعال کند و همچنان می‌تواند از یک یا چند کانال دیگر اعلان بگیرد. فراخوانی تابع ایجاد یا حذف کانال در حالتی که برنامه شما روی اندروید زیر ۸ اجرا شود، اثری ندارد. همچنین اگر بیشتر از یکبار تابع ایجاد کانال را صدا بزنید هم فقط یکبار کانال ایجاد می‌شود و مشکلی ایجاد نمی‌کند. با استفاده از دستور زیر در برنامه خود می توانید کانال نوتیفیکشن تعریف کنید:

    Pushe.createNotificationChannel(
                context,
                "MY_CHANNEL_ID", //channelId
                "all news channel", //Channel Name
                "", //description about channel
                4, //importance: Number between 0 to 5 (5 is the most important)
                true, //enableLight
                true, //enableViberation
                true, //showBadge
                Color.BLUE, //led color
                new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400} // Vibrate mode (can be Nullable)
    );

پروگارد

در صوتی که قصد دارید پروگارد را فعال کنید کد زیر را در فایل پروگارد خود اضافه کنید.

# Ronash proguard
-keepattributes Exceptions

-keep public class co.ronash.pushe.Pushe {
    public static void initialize(android.content.Context, boolean);
    public static void subscribe(android.content.Context, java.lang.String);
    public static void unsubscribe(android.content.Context, java.lang.String);
    public static void setNotificationOff(android.content.Context);
    public static void setNotificationOn(android.content.Context);
    public static boolean isPusheInitialized(android.content.Context);
    public static java.lang.String getPusheId(android.content.Context);
    public static void sendCustomJsonToUser(android.content.Context, java.lang.String, java.lang.String);
    public static void sendSimpleNotifToUser(android.content.Context, java.lang.String, java.lang.String, java.lang.String);
    public static void sendAdvancedNotifToUser(android.content.Context, java.lang.String, java.lang.String);
    public static void createNotificationChannel(android.content.Context, java.lang.String, java.lang.String, java.lang.String, int, boolean, boolean, boolean, int, long[]);
    public static void removeNotificationChannel(android.content.Context, java.lang.String);
    public static void sendEvent(android.content.Context, java.lang.String);
    public static void sendEvent(android.content.Context, co.ronash.pushe.Event);
    public static FcmHandler getFcmHandler(android.content.Context);
    public static com.google.firebase.FirebaseApp getFirebaseApp(android.content.Context);
    public static com.google.firebase.messaging.FirebaseMessaging getFirebaseMessaging(android.content.Context);
    public static co.ronash.pushe.fcm.FcmHandler getFcmHandler(android.content.Context);
}


-keep public class co.ronash.pushe.fcm.FcmHandler { *; }

-keep class co.ronash.pushe.Event$* {
    *;
}

-keep class co.ronash.pushe.Event { *; }
-keep class co.ronash.pushe.EventAction { *; }



-keep public class co.ronash.pushe.PusheListenerService {
    public void onMessageReceived(org.json.JSONObject, org.json.JSONObject);
}

-keep public class co.ronash.pushe.receiver.UpdateReceiver
-keep public class co.ronash.pushe.receiver.PusheGcmReceiver


# google gms proguard
-keep public class com.google.android.gms.**
-dontwarn com.google.android.gms.**

# google paly services proguard
-keep class * extends java.util.ListResourceBundle {
    protected java.lang.Object[][] getContents();
}

-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
    public static final *** NULL;
}

-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
    @com.google.android.gms.common.annotation.KeepName *;
}

-keepnames class * implements android.os.Parcelable {
    public static final ** CREATOR;}


-keep class **.R
-keep class **.R$* {
    <fields>;
}


#evernote Job scheduler
-dontwarn com.evernote.android.job.gcm.**
-dontwarn com.evernote.android.job.util.GcmAvailableHelper

-keep public class com.evernote.android.job.v21.PlatformJobService
-keep public class com.evernote.android.job.v14.PlatformAlarmService
-keep public class com.evernote.android.job.v14.PlatformAlarmReceiver
-keep public class com.evernote.android.job.JobBootReceiver
-keep public class com.evernote.android.job.JobRescheduleService

# Firebase
-dontwarn com.google.android.gms.measurement.AppMeasurement*
-dontwarn com.google.firebase.components.Component$Instantiation

-keepclassmembers class * extends com.google.android.gms.internal.ads.zzbbo {
  <fields>;
}

عیب یابی

شما می‌توانید خطاهای عمومی موجود در هنگام نصب در اندروید را در این لینک مشاهده نمایید. موارد عنوان شده در زیر تنها مربوط به اکلیپس هستند.


Unable to execute dex: Multiple dex files define …

این مشکل به دلیل تکراری اضافه‌شدن یک لایبرری به پروژه رخ می‌دهد. برای حل این مشکل بایستی فایل jar تکراری را در پروژه یافته و یکی را نگه‌داشته و بقیه را حذف کنید.

برای مثال خطای زیر مربوط به لایبرری android-support-v4 است که در پوشه موجود است و در صورت وجودداشتن در پروژه این مشکل رخ می‌دهد:

Unable to execute dex: Multiple dex files define Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat;

در صورت حل نشدن مشکل با شرح آن به پشتیبانی پوشه مورد را اطلاع دهید.


NoClassDevFound

عموما این مشکل به دلیل به روز نبودن فایل android-support-v4.jar در اکلیپس شما است. یکی از مقدمات مهم برای صحیح اجرا شدن کتابخانه پوشه، وجود داشتن و قدیمی نبودن فایل android-support-v4.jar می باشد. برای به روز رسانی این فایل را دانلود کنید و آن را جایگزین فایل android-support-v4.jar پروژه خود کنید. برای این کار به Workspace خود بروید و وارد فولدر پروژه و سپس وارد فولدر libs شوید و این فایل را جایگزین کنید و اگر این فایل از قبل موجود نیست آن را در این فولدر قرار دهید.


co.ronash.pushe.controller.controllers.c.d(Unknown Source)

عموما این مشکل به دلیل به روز نبودن فایل android-support-v4.jar در اکلیپس شما است. یکی از مقدمات مهم برای صحیح اجرا شدن کتابخانه پوشه، وجود داشتن و قدیمی نبودن فایل android-support-v4.jar می باشد. برای به روز رسانی این فایل را دانلود کنید و آن را جایگزین فایل android-support-v4.jar پروژه خود کنید. برای این کار به Workspace خود بروید و وارد فولدر پروژه و سپس وارد فولدر libs شوید و این فایل را جایگزین کنید و اگر این فایل از قبل موجود نیست آن را در این فولدر قرار دهید.

همیشه در کنارتان هستیم

در اولین فرصت با ایمیل به شما پاسخ خواهیم داد.

شاید جواب سوال شما اینجا باشد: سوالات متداول ، مستندات
وارد کردن تمامی فیلد ها الزامی است.
پیام شما با موفقیت ارسال شد