মোবাইল ডেটা কন্ট্রোল: সীমাবদ্ধতা ও বিকল্প
গুরুত্বপূর্ণ সতর্কতা: Android 5.0 (Lollipop, API 21) থেকে নন-সিস্টেম অ্যাপের জন্য মোবাইল ডেটা প্রোগ্রাম্যাটিকভাবে অন/অফ করা সম্ভব নয়। এই টিউটোরিয়াল শুধু ঐতিহাসিক রেফারেন্স ও শেখার উদ্দেশ্যে।
কেন কাজ করে না?
MODIFY_PHONE_STATEপারমিশন শুধু সিস্টেম/সিগনেচার অ্যাপের জন্যTelephonyManager.setDataEnabled()হিডেন API (Reflection দিয়ে কল করা যায়তো API 19 পর্যন্ত)- Android 5.0+ এ Reflection-ও ব্লক করা হয়েছে
- Rooted ফোনেও কাজ করে না (SELinux এনফোর্সিং)
ঐতিহাসিক কোড (শুধু রেফারেন্স)
// এটি বর্তমানে কাজ করে না - শুধু শিক্ষার্থীদের জন্য
public void setMobileDataState(boolean enabled) {
try {
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Method method = tm.getClass().getDeclaredMethod("setDataEnabled", boolean.class);
method.setAccessible(true);
method.invoke(tm, enabled);
} catch (Exception e) {
e.printStackTrace(); // SecurityException হবে
}
}
বিকল্প পদ্ধতিগুলো (কাজ করে)
১. ইউজারকে Settings-এ পাঠান (সেরা পদ্ধতি)
Intent intent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS); // অথবা Intent intent = new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS); // অথবা জেনারিক Intent intent = new Intent(Settings.ACTION_SETTINGS); startActivity(intent);
২. Quick Settings Tile (Android 7.0+)
নোটিফিকেশন শেডে কাস্টম টাইল যোগ করে এক-ট্যাপে ডেটা অন/অফ:
// AndroidManifest.xml
<service
android:name=".DataTileService"
android:icon="@drawable/ic_data"
android:label="Mobile Data"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
// DataTileService.java
public class DataTileService extends TileService {
@Override
public void onClick() {
super.onClick();
// ইউজারকে সেটিংসে পাঠান
startActivityAndCollapse(new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS));
}
}
৩. Device Owner / Profile Owner (Enterprise)
যদি আপনার অ্যাপ Device Owner হয় (MDM সমাধান):
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); ComponentName admin = new ComponentName(this, AdminReceiver.class); dpm.setGlobalSetting(admin, Settings.Global.MOBILE_DATA, enabled ? 1 : 0);
৪. Root + Shell Command (শুধু রুটেড ফোন)
// সুডো অ্যাক্সেস থাকলে
Runtime.getRuntime().exec("su -c svc data disable"); // অফ
Runtime.getRuntime().exec("su -c svc data enable"); // অন
লেআউট উদাহরণ (UI মকআপ)
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<Switch
android:id="@+id/switchData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Mobile Data (Redirects to Settings)" />
</LinearLayout>
MainActivity.java (বাস্তব কাজের কোড)
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
Switch switchData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
switchData = findViewById(R.id.switchData);
switchData.setOnCheckedChangeListener((buttonView, isChecked) -> {
// সরাসরি ডেটা অন/অফ না করেই সেটিংস পেজে পাঠান
Intent intent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
startActivity(intent);
// UI ফিডব্যাক
Toast.makeText(this, "Please toggle mobile data in Settings", Toast.LENGTH_SHORT).show();
// সইচ রিসেট করুন যাতে মিসলিডিং না হয়
switchData.setChecked(!isChecked);
});
}
}
সারামারি
| পদ্ধতি | কার্য করবে? | ব্যাখ্যা |
|---|---|---|
| Reflection (setDataEnabled) | ❌ না | API 21+ এ ব্লক করা |
| Settings Redirect | ✅ হ্যাঁ | স্ট্যান্ডার্ড, ইউজার-ফ্রেন্ডলি |
| Quick Settings Tile | ✅ হ্যাঁ | এক-ট্যাপ অ্যাক্সেস, API 24+ |
| Device Owner (MDM) | ✅ হ্যাঁ | এন্টারপ্রাইজ অ্যাপের জন্য |
| Root Shell | ⚠️ শুধু রুট | সাধারণ ইউজারের জন্য নয় |