# Native Code > برنامه نویسی موبایل > Android Studio >  بدست آوردن شماره تلفن سیم کارت

## hosseinaryai

سلام دوستان ..
می خواستم بدونم با چه کدی میشه شماره تلفن سیم کارتی که توی گوشی هست رو بدست اورد ؟
و اگه گوشی دو سیم کارته باشه هم میشه شماره ی هر دو تا سیم کارتو بدست اورد ؟ .. اگه اوهوم ، چطور میشه این کارو کرد ..
ممنونم

----------


## iman0111

از قطعه کد زیر استفاده کن ببین جواب میده یا نه 

TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVI  CE); a
String number = tm.getLine1Number(); b


بعد دسترسی زیر رو تو منیفست بهش بده 

</><uses-permission android:name="android.permission.READ_PHONE_STATE"  >

----------


## hosseinaryai

ممنونم از راهنماییت .. از این کد قبلن هم استفاده کردم اما چیزی بر نمی گردونه .. البته گوشی من دو سیم کارته اس .. میگم شاید واسه خاطر اون باشه که نتونسته شماره رو پیدا کنه ..

----------


## Nevercom

این رو تست کن: http://stackoverflow.com/a/17499889/1686304

----------


## saeed_g21

کلا همچین سرویسی در اپراتورهای ایران فعال نیست 

گشتم نبود نگرد نیست

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

----------


## pbm_soy

سلام

بهتر بود توضیح کاملتر میدادید!
مثلا اون کدی که دویتمون گذاشتن کاملا درسته و برای بدست آوردن شماره سیم کارت است!
این دستورات شماره را ازکجای دستگاه میخواند؟ دقیقا از بخش settings -> about device -> status -> my phone number
اگر دراینجا شماره ای موجود باشد میتوانید آنرا با دستوری که دربالا عنوان شده بخوانید
ولی در این محل باید بطور اتوماتیک ازطریق اپراتورهای سیمکارت پرشوند درواقع اپراتورها شماره سیمکارت و اطلاعاتی دیگر را باید برای دستگاه گوشی انتشار دهد ولی شرکتهای ایرانی اینکار را انجام نمیدهند. و گوشی هم در بخش my phone number چیزی ثبت نمیکند مگر اینکه شما بصورت دستی شماره خود را در این بخش ثبت کنید تا برنامه ها بتوانند از این شماره استفاده کنند. (روش دوم)

----------


## hosseinaryai

خب خب خب ، ممنونم *pbm_soy* بابت توضیحات کامل و جامعی که دادی .. 
اوهوم ، کدی که دوستمون *iman0111* گذاشت همونطور که خودتم گفتی کاملن درست بود .. من در ادامه ی اون کد تونستم با این خط :


```
String number = tm.getSimOperator();
```

کد اپراتورو بدست بیارم و همچنین با این خط :


```
String number = tm.getNetworkOperatorName();
```

حتا نام اپراتور رو هم برگردوند ، اما کمیتش در برگردوندن شماره تلفن به اون دلیلی که خودت اشاره کردی لنگ می زنه .. 
کدی که دوسمون *Nevercom* گذاشت هم درسته .. و فرقش با کد *iman0111* در اینه که با جزئیات بیشتری به قضیه نگاه می کنه و برای گوشی های چند سیم کارته مفیده .. (تو گوشی های چند سیم کارته کد *iman0111* فقط اطلاعات سیم کارت اولو بر می گردونه .. )
و اما در آخر هم باید تشکر کنم از *saeed_g21* عزیز که در راستای چالش سطل آب یخ ، سطل آب پاکی رو خالی کرد رو دستمون ..  :لبخند گشاده!: 
ممنونم از همتون ..  :تشویق:

----------


## Nevercom

برای تکمیل صحبت ها، وقتی سوالتون رو خوندم ناخودآگاه دریافت IMEI اومد تو ذهنم (چون خودم باهاش برخورد داشتم) و حواسم نبود که دنبال شماره تلفن هستید.
در مورد شماره تلفن هم صحبت دوستان رو تایید می کنم، هیچ راه قابل اطمینانی برای دریافت شماره تلفن وجود نداره. (حتی همون IMEI هم در مواردی مقداری نامعتبر رو برمیگردونه)

----------


## saeed_g21

> (حتی همون IMEI هم در مواردی مقداری نامعتبر رو برمیگردونه)


تنها چیزی که به ذهنم میرسه که باعث میشه IMEI مقداری نامعتبر برای خودش میگیره این هست که دستگاه فاقد سیم کارت است و توسط Wifi به نت وصل میشه
مثل : تبلتهای بدون سیم کارت

----------


## Nevercom

IMEI کاملاً وابسته به اسلات سیم کارت هست و دستگاهی که اسلات سیم کارت نداشته باشه، IMEI رو گزارش نمیده.
در عوض ما یک Android ID داریم که قابل اعتمادتر هست، اما با تعویض رام یا Factory Reset مقدارش عوض میشه.
یکی از مواردی که پیش اومده بود برای گوشی های سامسونگ بود فکر کنم که یک رده از محصولاتش همه یک IMEI رو گزارش می دادند.

کلاً IMEI رو نباید بعنوان یک شناسه برای تشخیص دستگاه درنظر گرفت، چون احتمال اینکه حتی در گوشی ها هم قابل تشخیص نباشه وجود داره (البته این احتمال خیلی زیاد نیست).

به هرحال گوگل Android ID رو بعنوان یک شناسه ی منحصربفرد برای دستگاه پیشنهاد میده

----------


## pbm_soy

سلام

ببخشید این تاپیک را بالا اوردم ولی یه چیزی همینجوری به ذخنم آمد گفتم بدنباشه مطرح کنم

* اگر توسط برنامه بتونیم یک اس ام اس به خود این سیمکارت بفرستیم و در زمان رسیدن پیام شماره فرستنده را از آن بگیریم! چطور است آیا قابل پیاده سازی است؟ (من فقط ایده به ذهنم آمد و مطرحش کردم) تنها جای مشکل دار این روش این است که ما شماره سیمکارت را نداریم که بتونیم به خودمان پیام بفرستیم!
+ میخواستم این مورد را یادآوری کنم که در شبکه کامپیوتری ، کامپیوتر خودم با چندین آدرس قابل آدرس دهی است مانند localhost - 127.0.0.1 -  و آی پی خود اون دستگاه و حتی نقطه در بخش آدرس به معنی کامپیوتر خودم است. آیا در شبکه موبایل همچین چیزی وجود ندارد؟!

* روش دیگر، اگر میشد یک سرور USSD راه اندازی کرد که بارسیدن یک درخواست شماره موبایل فرستنده درخواست را نتیجه برای متقاضی بفرستد

منتظر نظرات دوستان هستم

----------


## slr560

> سلام
> 
> ببخشید این تاپیک را بالا اوردم ولی یه چیزی همینجوری به ذخنم آمد گفتم بدنباشه مطرح کنم
> 
> * اگر توسط برنامه بتونیم یک اس ام اس به خود این سیمکارت بفرستیم و در زمان رسیدن پیام شماره فرستنده را از آن بگیریم! چطور است آیا قابل پیاده سازی است؟ (من فقط ایده به ذهنم آمد و مطرحش کردم) تنها جای مشکل دار این روش این است که ما شماره سیمکارت را نداریم که بتونیم به خودمان پیام بفرستیم!
> + میخواستم این مورد را یادآوری کنم که در شبکه کامپیوتری ، کامپیوتر خودم با چندین آدرس قابل آدرس دهی است مانند localhost - 127.0.0.1 -  و آی پی خود اون دستگاه و حتی نقطه در بخش آدرس به معنی کامپیوتر خودم است. آیا در شبکه موبایل همچین چیزی وجود ندارد؟!
> 
> * روش دیگر، اگر میشد یک سرور USSD راه اندازی کرد که بارسیدن یک درخواست شماره موبایل فرستنده درخواست را نتیجه برای متقاضی بفرستد
> 
> منتظر نظرات دوستان هستم


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

در رابطه با بحث دوم هم باید بگم که هزینه رزرو شماره ussd برای هر اپراتوری فرق میکنه
ایرانسل ۱۰۰ میلیون تومان میگیره  :لبخند گشاده!: 
اگه ۱۰۰ میلیون داری یاعلی

----------


## Nevercom

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


اگر دسترسی ارسال SMS داشته باشید، سیستم عامل دخالتی نمیکنه

ولی به هرحال ارسال SMS بدون اجازه ی کاربر به قصد دریافت شماره ش کار درستی نیست.

----------


## pbm_soy

> اگر دسترسی ارسال SMS داشته باشید، سیستم عامل دخالتی نمیکنه
> 
> ولی به هرحال ارسال SMS بدون اجازه ی کاربر به قصد دریافت شماره ش کار درستی نیست.


بحث اجازه کاربر و کم کردن هزینه را فعلا کنار داشته باشید ، مشکلات را یکی یکی حل میکردیم! فوقش در اول کار میشد به کاربر یک هشدار میدادیم که اینقدر تومان کسر خواهد شد!
درمورد دوم USSD اینقدر گرونه ؟! آیا برای راه اندازی USSD سرور این اپراتورها راهنما یا نمونه قرارداد و یا تعرفه هزینه ها را جائی نذاشتن؟ بیشتر آشنا بشیم (هرچند گرونه)
نمیشه با این شرکتهایی که USSD دارند صحبت کرد که یک سرویس اینجوری داشته باشند؟ یا این سرویس را با درنظر گرفتن هزینه ای ، از ما برنامه سرویس را بگیرند و اجرا کنند.
اصلا جایی لیست رسمی از این شرکتها وجود دارد؟

----------


## Nevercom

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

اپراتورها در وهله ی اول با شرکت های کوچک قرارداد نمیبندن، حتی شما نمیتونید توزیع کننده ی رسمی شارژ ایرانسل هم باشید و باید از شرکت های واسطه شارژ رو تهیه کنید.
در مورد USSD محدودیت های بیشتری اعمال میشه و به هیچ وجه به شرکت های کوچک این خدمات ارائه نمیشه و هزینه ی خیلی زیادی داره.

درعوض شرکت هایی هستن که درگاه USSD رو ارائه میدن، اما خدماتشون محدود به فروش شارژ، عملیات بانکی و پرداخت قبض میشه.

در مورد نیاز فعلی شما، کافیه یک پنل SMS تهیه کنید، و هنگام ثبت نام به کاربر بگید برای تایید هویتش یک SMS ارسال میشه (Whatsapp فکر کنم همچین کاری میکرد). شماره ی پنلتون که ثابت هست، و می تونید امکانات زیادی از طریق پنل SMS برای کاربران ایجاد کنید.

----------


## pbm_soy

به نظرم با این مورد دوم بشه به نتیجه هایی رسید و فکر میکنم تنها روش همین باشه!

----------


## meysam jahedi

> این رو تست کن: http://stackoverflow.com/a/17499889/1686304


سلام

کسی میتونه برای این دستورات یه توضیح فارسی بنویسه ؟ 

  public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TelephonyInfo telephonyInfo = TelephonyInfo.getInstance(this);

        String imeiSIM1 = telephonyInfo.getImeiSIM1();
        String imeiSIM2 = telephonyInfo.getImeiSIM2();

        boolean isSIM1Ready = telephonyInfo.isSIM1Ready();
        boolean isSIM2Ready = telephonyInfo.isSIM2Ready();

        boolean isDualSIM = telephonyInfo.isDualSIM();

        TextView tv = (TextView) findViewById(R.id.tv);
        tv.setText(" IME1 : " + imeiSIM1 + "\n" +
                " IME2 : " + imeiSIM2 + "\n" +
                " IS DUAL SIM : " + isDualSIM + "\n" +
                " IS SIM1 READY : " + isSIM1Ready + "\n" +
                " IS SIM2 READY : " + isSIM2Ready + "\n");
    }
}

 public final class TelephonyInfo {

    private static TelephonyInfo telephonyInfo;
    private String imeiSIM1;
    private String imeiSIM2;
    private boolean isSIM1Ready;
    private boolean isSIM2Ready;

    public String getImeiSIM1() {
        return imeiSIM1;
    }

    /*public static void setImeiSIM1(String imeiSIM1) {
        TelephonyInfo.imeiSIM1 = imeiSIM1;
    }*/

    public String getImeiSIM2() {
        return imeiSIM2;
    }

    /*public static void setImeiSIM2(String imeiSIM2) {
        TelephonyInfo.imeiSIM2 = imeiSIM2;
    }*/

    public boolean isSIM1Ready() {
        return isSIM1Ready;
    }

    /*public static void setSIM1Ready(boolean isSIM1Ready) {
        TelephonyInfo.isSIM1Ready = isSIM1Ready;
    }*/

    public boolean isSIM2Ready() {
        return isSIM2Ready;
    }

    /*public static void setSIM2Ready(boolean isSIM2Ready) {
        TelephonyInfo.isSIM2Ready = isSIM2Ready;
    }*/

    public boolean isDualSIM() {
        return imeiSIM2 != null;
    }

    private TelephonyInfo() {
    }

    public static TelephonyInfo getInstance(Context context){

        if(telephonyInfo == null) {

            telephonyInfo = new TelephonyInfo();

            TelephonyManager telephonyManager = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE  ));

            telephonyInfo.imeiSIM1 = telephonyManager.getDeviceId();;
            telephonyInfo.imeiSIM2 = null;

            try {
                telephonyInfo.imeiSIM1 = getDeviceIdBySlot(context, "getDeviceIdGemini", 0);
                telephonyInfo.imeiSIM2 = getDeviceIdBySlot(context, "getDeviceIdGemini", 1);
            } catch (GeminiMethodNotFoundException e) {
                e.printStackTrace();

                try {
                    telephonyInfo.imeiSIM1 = getDeviceIdBySlot(context, "getDeviceId", 0);
                    telephonyInfo.imeiSIM2 = getDeviceIdBySlot(context, "getDeviceId", 1);
                } catch (GeminiMethodNotFoundException e1) {
                    //Call here for next manufacturer's predicted method name if you wish
                    e1.printStackTrace();
                }
            }

            telephonyInfo.isSIM1Ready = telephonyManager.getSimState() == TelephonyManager.SIM_STATE_READY;
            telephonyInfo.isSIM2Ready = false;

            try {
                telephonyInfo.isSIM1Ready = getSIMStateBySlot(context, "getSimStateGemini", 0);
                telephonyInfo.isSIM2Ready = getSIMStateBySlot(context, "getSimStateGemini", 1);
            } catch (GeminiMethodNotFoundException e) {

                e.printStackTrace();

                try {
                    telephonyInfo.isSIM1Ready = getSIMStateBySlot(context, "getSimState", 0);
                    telephonyInfo.isSIM2Ready = getSIMStateBySlot(context, "getSimState", 1);
                } catch (GeminiMethodNotFoundException e1) {
                    //Call here for next manufacturer's predicted method name if you wish
                    e1.printStackTrace();
                }
            }
        }

        return telephonyInfo;
    }

    private static String getDeviceIdBySlot(Context context, String predictedMethodName, int slotID) throws GeminiMethodNotFoundException {

        String imei = null;

        TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE  );

        try{

            Class<?> telephonyClass = Class.forName(telephony.getClass().getName());

            Class<?>[] parameter = new Class[1];
            parameter[0] = int.class;
            Method getSimID = telephonyClass.getMethod(predictedMethodName, parameter);

            Object[] obParameter = new Object[1];
            obParameter[0] = slotID;
            Object ob_phone = getSimID.invoke(telephony, obParameter);

            if(ob_phone != null){
                imei = ob_phone.toString();

            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new GeminiMethodNotFoundException(predictedMethodName)  ;
        }

        return imei;
    }

    private static  boolean getSIMStateBySlot(Context context, String predictedMethodName, int slotID) throws GeminiMethodNotFoundException {

        boolean isReady = false;

        TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE  );

        try{

            Class<?> telephonyClass = Class.forName(telephony.getClass().getName());

            Class<?>[] parameter = new Class[1];
            parameter[0] = int.class;
            Method getSimStateGemini = telephonyClass.getMethod(predictedMethodName, parameter);

            Object[] obParameter = new Object[1];
            obParameter[0] = slotID;
            Object ob_phone = getSimStateGemini.invoke(telephony, obParameter);

            if(ob_phone != null){
                int simState = Integer.parseInt(ob_phone.toString());
                if(simState == TelephonyManager.SIM_STATE_READY){
                    isReady = true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new GeminiMethodNotFoundException(predictedMethodName)  ;
        }

        return isReady;
    }


    private static class GeminiMethodNotFoundException extends Exception {

        private static final long serialVersionUID = -996812356902545308L;

        public GeminiMethodNotFoundException(String info) {
            super(info);
        }
    }
}

دستورات بالا رو مینویسم و IME1و IME2 رو میده اما چیزی به نام شماره تلفن سیمکارت نمیده . 

ادامه کدهاش رو تو سایت اینا هستش که نمیدونم کجا باید نوشته بشن ؟ و برای چی هستن ؟

  public static void printTelephonyManagerMethodNamesForThisDevice(Cont  ext context) {

    TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE  );
    Class<?> telephonyClass;
    try {
        telephonyClass = Class.forName(telephony.getClass().getName());
        Method[] methods = telephonyClass.getMethods();
        for (int idx = 0; idx < methods.length; idx++) {

            System.out.println("\n" + methods[idx] + " declared by " + methods[idx].getDeclaringClass());
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
} 





telephonyInfo.imeiSIM1 = getDeviceIdBySlot(context, "getDeviceIdDs", 0);
telephonyInfo.imeiSIM2 = getDeviceIdBySlot(context, "getDeviceIdDs", 1);

----------

