0

my question is about Android studio. I am trying to implement the method: setNetworkSelectionModeManual from the TelephonyManager library, but I haven't had any success.

Whenever it is getting called, the app crashes. It is probably a permission thing, would appreciate anyone be able to help?

The code:

public void startTimer(){
    countDownTimer = new CountDownTimer(timeLeftInMillisecond,1000) {
        @Override
        public void onTick(long l) {
            timeLeftInMillisecond = l;
            updateTimer();
        }

        @Override
        public void onFinish() {
            //switching to a different network by mpln
            boolean networkChanged = tm.setNetworkSelectionModeManual("USAW6", false);
                //restart timer
            countDownTimer.start();
        }
    }.start();

The error in logcat:

07-22 18:14:04.941 27289-27310/com.example.yakir.webbing_hlr E/OpenGLRenderer: allen debug liyu Key: 0
07-22 18:14:04.944 27289-27310/com.example.yakir.webbing_hlr E/OpenGLRenderer: allen debug liyu Key: 34359738371
07-22 18:14:04.945 27289-27310/com.example.yakir.webbing_hlr E/OpenGLRenderer: allen debug liyu Key: 240518168576
07-22 18:14:04.946 27289-27310/com.example.yakir.webbing_hlr E/OpenGLRenderer: allen debug liyu Key: 68724719680
07-22 18:14:08.062 27289-27289/com.example.yakir.webbing_hlr I/hwaps: JNI_OnLoad
07-22 18:14:08.110 27289-27310/com.example.yakir.webbing_hlr E/OpenGLRenderer: allen debug liyu Key: 103084458052
07-22 18:14:18.107 27289-27289/com.example.yakir.webbing_hlr E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.yakir.webbing_hlr, PID: 27289
    java.lang.NoSuchMethodError: No virtual method setNetworkSelectionModeManual(Ljava/lang/String;Z)Z in class Landroid/telephony/TelephonyManager; or its super classes (declaration of 'android.telephony.TelephonyManager' appears in /system/framework/framework.jar:classes2.dex)
        at com.example.yakir.webbing_hlr.MainActivity$2.onFinish(MainActivity.java:74)
        at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:127)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:156)
        at android.app.ActivityThread.main(ActivityThread.java:6523)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
07-22 18:14:18.158 27289-27289/com.example.yakir.webbing_hlr I/Process: Sending signal. PID: 27289 SIG: 9
Elletlar
  • 3,136
  • 7
  • 32
  • 38
  • This is my code: – user3420917 Jul 22 '18 at 18:18
  • Please don't post links to images of the code. 1. We cannot answer because we would have to type out your code from the image 2. It makes it impossible to verify in Android Studio any answers that we might give 3. It ruins search engine searches since all keywords are missing from your post 4. This post becomes worthless once that link breaks. [How to ask](https://stackoverflow.com/help/how-to-ask) – Elletlar Jul 22 '18 at 21:02
  • Can you please paste the text of the crash log into the report. Also can I see the code for updateTimer? Is it updating views inside the fragment/activity? I haven't checked the docs, but I believe onTick is called on a worker thread. If that's the case you will have to call runOnUiThread to update the views. – Elletlar Jul 23 '18 at 01:02
  • Sure, the logcat presents the following around the time the app crashes: E/AndroidRuntime: FATAL EXCEPTION: main at com.example.yakir.webbing_hlr.MainActivity$2.onFinish(MainActivity.java:74) at android.os.CountDownTimer$1.handleMessage – user3420917 Jul 23 '18 at 01:15
  • The update timer method: public void updateTimer(){ int minutes = (int)timeLeftInMillisecond/60000; int seconds = (int)timeLeftInMillisecond%60000/1000; String timeLeftText = minutes+":"; if(seconds<10){ timeLeftText += "0"; } timeLeftText+=seconds; timer.setText(timeLeftText); } – user3420917 Jul 23 '18 at 01:20
  • Thanks. In future, add all the new info to the original post not the comments. I put an answer below. If you have any questions about the answer, make a comment on the *answer*, not here. Cheers! – Elletlar Jul 23 '18 at 09:14
  • Hi @MatejMecka would you consider up-voting this question now? The poster who is relatively new to Stack Overflow has improved it by adding the text of the source code and adding the stack trace. It will help him earn some rep to use the site more fully. Cheers! – Elletlar Jul 23 '18 at 10:38

1 Answers1

1

The problem is that the app only works on Android 9 or above devices [Android P: API: 28] due to this method call setNetworkSelectionModeManual()

setNetworkSelectionModeManual(Ljava/lang/String;Z)Z in class 
Landroid/telephony/TelephonyManager; or its super classes (declaration of 
'android.telephony.TelephonyManager' appears in 
/system/framework/framework.jar:classes2.dex) at 
com.example.yakir.webbing_hlr.MainActivity$2.onFinish(MainActivity.java:74) at 

The setNetworkSelectionModeManual method was only added in API level 28 [Android P / Android 9]

setNetworkSelectionModeManual added in API level 28 public boolean setNetworkSelectionModeManual (String operatorNumeric, boolean persistSelection) Ask the radio to connect to the input network and change selection mode to manual.

Requires Permission: MODIFY_PHONE_STATE or that the calling app has carrier privileges (see hasCarrierPrivileges()).

Android Version History

I cannot see all the relevant code, but there is something in your activity either calling that method or doing a telephony related task that causes that method to be called.

Solutions:

  • Do not call the method
  • Set the minimum API in the gradle file to 28 to prevent old devices running the app
  • Run your app on the Android P emulator
  • Sometimes new APIs are added the compatibility libraries as well
  • Only run the code if the API level is high enough

Sample:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { // or 28
   // Call the method
} else {
   // Call different methods, possibly deprecated ones that do the same thing
}
Elletlar
  • 3,136
  • 7
  • 32
  • 38
  • One last thing, please click on the grey check mark to accept the answer. Otherwise, it remains in an unanswered question state on the system. Also, it gives whoever answered the question some additional reputation points. It is a good way to say thank you to them for helping. Cheers! – Elletlar Jul 23 '18 at 10:33
  • I tried re-building for API 28 and ran through the emulator, still the app crashed.. – user3420917 Jul 23 '18 at 20:01
  • Re-building for API 28 alone won't solve the issue because it will still crash on any pre-28 phone. You have to ensure that the phone/emulator is also on API 28. If it still crashes on the API 28 emulator then it will not be due to java.lang.NoSuchMethodError/setNetworkSelectionModeManual. It will likely be a new crash. So you'll have to investigate that strack trace to see what's happening. Cheers! – Elletlar Jul 23 '18 at 20:09
  • Thank you, yeah it was on a new emulator that is API28 as well. I suspect that this is a system permission required issue.. Maybe only rooted devices would be able to run this kind of things. – user3420917 Jul 24 '18 at 18:08
  • Yeah in addition to the API level issue: it requires MODIFY_PHONE_STATE which is a system level permission, sorry I didn't notice that before [How to Grant MODIFY_PHONE_STATE](https://stackoverflow.com/questions/4715250/how-to-grant-modify-phone-state-permission-for-apps-ran-on-gingerbread)...That's going to be a problem... – Elletlar Jul 24 '18 at 18:31
  • Yeah, unfortunately it seems impossible to grant this permission, unless rooted phones could perhaps run these things.. But it is already going too deep.. – user3420917 Jul 25 '18 at 06:44
  • I wonder if there is anyway for getting that permission on a rooted phone – user3420917 Jul 25 '18 at 21:15