نحوه ی مخفی کردن آیکون و اجرا کردن با کد ussd در اندروید
امروز میخواهیم در مورد یک روش خوب برای مخفی کردن برنامه های امنیتی و اجرا کردن آنها با استفاده از کد ussd که خودمان تعریف میکنیم صحبت کنیم.
شاید بخواهید برنامه ای بنویسید که اطلاعات خاصی را در خود نگهداری کند یا حتی یک پیام رسان بنویسید و دوس دارید قابلیت مخفی شدن را در خود داشته باشند.
خب گیریم که برنامه ی خودمون رو مخفی کردیم!
چجوری میخواهیم اجراش کنیم؟!
جواب این سوال خیلی ساده است ، با zeroToHero همراه باشید تا یک مدل از این برنامه را بنویسیم.
یک کلاس به نام App میسازیم و از Application ارث بری میکنیم و کد زیر را داخل آن کپی میکنیم.
package com.example.ahmad.hiddenapp; import android.app.Application; import android.content.Context; import android.content.SharedPreferences; public class App extends Application { public static SharedPreferences sharedPreferences; public static SharedPreferences.Editor shared; @Override public void onCreate() { super.onCreate(); sharedPreferences = getSharedPreferences("app",Context.MODE_PRIVATE); shared = sharedPreferences.edit(); App.shared.putBoolean("first",false); App.shared.putString("code",""); shared.commit(); } }
مقادیر sharedPreferences ها رو تعریف میکنیم.
حالا باید یک BroadcastReceiver بنویسیم تا تماس های خروجی رو به ما اطلاع بده.
package com.example.ahmad.hiddenapp; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; public class OutgoingReceiver extends BroadcastReceiver { public OutgoingReceiver() { } @Override public void onReceive(Context context, Intent intent) { String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); String code = App.sharedPreferences.getString("code",""); if(number.equals("*"+code+"#")){ Intent run = new Intent(); run.setClassName(context.getPackageName(), ActivityMain.class.getName()); run.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(run); } } }
در متد onReceive با استفاده از کد زیر شماره تلفن شماره گیری شده رو بدست میاریم.
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
و با این قسمت از کد بررسی میکنیم که آیا شمارهی گرفته شده همون کد رزرو شده برای این برنامه هست یا نه که اگر بود activity مربوطه رو اجرا میکنیم.
Intent run = new Intent(); run.setClassName(context.getPackageName(), ActivityMain.class.getName()); run.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(run);
ما به یک activity جهت اجرا شدن به عنوان launcher نیاز داریم که تا وقتی آیکون رو مخفی نکردیم و کدی رو براش در نظر نگرفتیم برایمان قابل اجرا باشد.
کد آن را تحت عنوان ActivityStartup در برنامه کپی کنید.
package com.example.ahmad.hiddenapp; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; public class ActivityStartup extends AppCompatActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = new Intent(ActivityStartup.this,ActivityMain.class); finish(); startActivity(intent); } }
یک لایه با نام activity_main.xml میسازیم و کد های زیر رو داخلش اضافه میکنیم.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.ahmad.hiddenapp.ActivityMain"> <EditText android:id="@+id/txtCode" android:layout_width="300dp" android:layout_height="50dp" android:layout_centerHorizontal="true" android:layout_marginTop="100dp" android:hint="کد خود را وارد کنید" /> <Button android:id="@+id/btnOk" android:layout_width="100dp" android:layout_height="50dp" android:text="باشه" android:background="#00f240" android:layout_centerVertical="true" android:layout_centerHorizontal="true"> </Button> </RelativeLayout>
حالا ActivityMain رو میسازیم و کد زیر رو داخلش کپی میکنیم.
package com.example.ahmad.hiddenapp; import android.content.ComponentName; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; public class ActivityMain extends AppCompatActivity { Button btnOk ; EditText edtCode; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (App.sharedPreferences.getBoolean("first",false)){ PackageManager p = getPackageManager(); ComponentName componentName = new ComponentName(ActivityMain.this, ActivityStartup.class.getName()); p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); } btnOk = (Button) findViewById(R.id.btnOk); edtCode = (EditText) findViewById(R.id.txtCode); btnOk.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(!edtCode.getText().toString().equals("")){ App.shared.putBoolean("first",true); App.shared.putString("code",edtCode.getText().toString()); App.shared.commit(); PackageManager p = getPackageManager(); ComponentName componentName = new ComponentName(ActivityMain.this, ActivityStartup.class.getName()); p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); ActivityMain.this.finish(); } } }); } }
برای مخفی کردن آیکون از این قسمت کد استفاده میکنیم.(وقتی که کد اجرای ussd توسط کاربر رزرو شده باشد که مقدار first به true تغییر کند)
if (App.sharedPreferences.getBoolean("first",false)){ PackageManager p = getPackageManager(); ComponentName componentName = new ComponentName(ActivityMain.this, ActivityStartup.class.getName()); p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); }
با این قسمت هم میتوانیم کد مورد نظر را set کنیم.
btnOk.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(!edtCode.getText().toString().equals("")){ App.shared.putBoolean("first",true); App.shared.putString("code",edtCode.getText().toString()); App.shared.commit(); PackageManager p = getPackageManager(); ComponentName componentName = new ComponentName(ActivityMain.this, ActivityStartup.class.getName()); p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); ActivityMain.this.finish(); } } });
خب تا اینجای کار به نظر میاد برنامه ی کاملی رو نوشته باشیم ، اما فایل manifest رو فراموش نکنید.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.ahmad.hiddenapp"> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/> <application android:name=".App" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <receiver android:name=".OutgoingReceiver"> <intent-filter> <action android:name="android.intent.action.NEW_OUTGOING_CALL"></action> </intent-filter> </receiver> <activity android:name=".ActivityStartup"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ActivityMain"> <intent-filter > <action android:name="android.intent.action.MAIN" ></action> </intent-filter> </activity> </application> </manifest>
برای اینکه اجازه داشته باشیم که اطلاعات موقع گرفتن تماس رو داشته باشیم باید premission زیر وارد شود.
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
برای شناساندن کلاس App بعنوان application کد زیر را به فایل بالا باید اضافه کنیم.
android:name=".App"
خط زیر نیز برای شناسایی BroadcastReceiver باید داخل فایل manifest داشته باشیم.
<receiver android:name=".OutgoingReceiver"> <intent-filter> <action android:name="android.intent.action.NEW_OUTGOING_CALL"></action> </intent-filter> </receiver>
میتوانید این این قطعه کد نیز برای نمایش دوبارهی آیکون استفاده کنید.
PackageManager p = getPackageManager(); ComponentName componentName = new ComponentName(ActivityMain.this, ActivityStartup.class.getName()); p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
امیدوارم که از این آموزش لذت برده باشید.
سوالاتتون رو میتونید در همین صفحه در قسمت نظرات مطرح کنید.
موفق باشید.
مطالب زیر را حتما مطالعه کنید
آموزش Gradle – اهمیت Project Automation
درک مفهوم کدنویسی تمیز در اندروید
5 هک ساده برای کاهش سایز فایل APK
آشنایی با RecyclerView در اندروید
Open/Closed Principle در قوانین Solid
توابع در زبان برنامه نویسی Kotlin
2 Comments
Join the discussion and tell us your opinion.
دیدگاهتان را بنویسید لغو پاسخ
برای نوشتن دیدگاه باید وارد بشوید.
ممنون. مطلب خیلی جدید و به روزی بود. انشااله از این مطالب بیشتر بذارین.
خواهش میکنم.
ممنون از نظرتون.
چشم حتما.
ما سعی میکنیم مطالب هم در حد zero باشن و هم در حد hero برای همین مطالب قدیمی یا راحت رو هم باید بزاریم دیگه 😉