2016-09-16 2 views
6

Ich muss Anruf durch Code in der oberen Version von Android trennen.Programmatisch Anruf in Android Marshmallow Version trennen

Laut Dokument sind wir nicht dazu berechtigt, da es privat ist.

Bei der Suche über SO habe ich verschiedene Lösungen gefunden, die bis zum Lollipop funktionieren.

Inline ist, was ich bis jetzt versucht habe.

Ansatz One:

public void disconnectCall(String type){ 
     try { 
      String serviceManagerName = "android.os.ServiceManager"; 
      String serviceManagerNativeName = "android.os.ServiceManagerNative"; 
      String telephonyName = "com.android.internal.telephony.ITelephony"; 
      Class<?> telephonyClass; 
      Class<?> telephonyStubClass; 
      Class<?> serviceManagerClass; 
      Class<?> serviceManagerNativeClass; 
      Method telephonyEndCall; 
      Object telephonyObject; 
      Object serviceManagerObject; 
      telephonyClass = Class.forName(telephonyName); 
      telephonyStubClass = telephonyClass.getClasses()[0]; 
      serviceManagerClass = Class.forName(serviceManagerName); 
      serviceManagerNativeClass = Class.forName(serviceManagerNativeName); 
      Method getService = // getDefaults[29]; 
        serviceManagerClass.getMethod("getService", String.class); 
      Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class); 
      Binder tmpBinder = new Binder(); 
      tmpBinder.attachInterface(null, "fake"); 
      serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder); 
      IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone"); 
      Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class); 
      telephonyObject = serviceMethod.invoke(null, retbinder); 
      telephonyEndCall = telephonyClass.getMethod("endCall"); 
      telephonyEndCall.invoke(telephonyObject); 

      // Reject call and send SMS 
      if (type.equalsIgnoreCase("reject")) { 
       SmsManager smsManager = SmsManager.getDefault(); 
       smsManager.sendTextMessage(_incomingNumber, null, "Hey! I am driving right now. Please call me back after some time", null, null); 
       Toast.makeText(context, "CALL REJECTED", Toast.LENGTH_SHORT).show(); 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

Ansatz Zwei:

public boolean killCall(Context context) { 
     try { 
      // Get the boring old TelephonyManager 
      TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 

      // Get the getITelephony() method 
      Class classTelephony = Class.forName(telephonyManager.getClass().getName()); 
      Method methodGetITelephony = classTelephony.getDeclaredMethod("getITelephony"); 

      // Ignore that the method is supposed to be private 
      methodGetITelephony.setAccessible(true); 

      // Invoke getITelephony() to get the ITelephony interface 
      Object telephonyInterface = methodGetITelephony.invoke(telephonyManager); 

      // Get the endCall method from ITelephony 
      Class telephonyInterfaceClass = Class.forName(telephonyInterface.getClass().getName()); 
      Method methodEndCall = telephonyInterfaceClass.getDeclaredMethod("endCall"); 

      // Invoke endCall() 
      methodEndCall.invoke(telephonyInterface); 

     } catch (Exception ex) { // Many things can go wrong with reflection calls 
      return false; 
     } 
     return true; 
    } 

Ansatz Drei:

public void endCall(Context context) { 
     TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 
     try { 
      Class c = Class.forName(tm.getClass().getName()); 
      Method m = c.getDeclaredMethod("getITelephony"); 
      m.setAccessible(true); 
      Object telephonyService = m.invoke(tm); 

      c = Class.forName(telephonyService.getClass().getName()); 
      m = c.getDeclaredMethod("endCall"); 
      m.setAccessible(true); 
      m.invoke(telephonyService); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

Antwort

6

Above ment itioned Approach funktioniert. Ich habe gerade eine Laufzeitberechtigung für CALL_PHONE für M + -Versionen von Android hinzugefügt.

Folgen Inline-Erwähnungen:

definieren Permission in Android Manifest-Datei.

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

Jetzt Laufzeit Erlaubnis für M + Version von Android erhalten.

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
     { 

      if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) 
      { 
       ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, PERMISSION_ACCESS_CALL_PHONE); 
      } 
      else 
      { 
       // Proceed as we already have permission. 
      } 
     } 
     else 
     { 
      // Proceed as we need not get the permission 
     } 


@Override 
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
     switch (requestCode) { 
      case PERMISSION_ACCESS_CALL_PHONE: 
       if (grantResults.length > 0 && grantResults[0] PackageManager.PERMISSION_GRANTED) { 
        // All good! 

        //Toast.makeText(context, "All Good", Toast.LENGTH_SHORT).show(); 
       } else { 
        finish(); 
        //Toast.makeText(this, "Need call phone permission", Toast.LENGTH_SHORT).show(); 
       } 

       break; 
     } 
    } 

Jetzt Inline-Methode verwenden Anruf pro-grammatisch zu trennen.

private void declinePhone(Context context) throws Exception { 

     try { 

      String serviceManagerName = "android.os.ServiceManager"; 
      String serviceManagerNativeName = "android.os.ServiceManagerNative"; 
      String telephonyName = "com.android.internal.telephony.ITelephony"; 
      Class<?> telephonyClass; 
      Class<?> telephonyStubClass; 
      Class<?> serviceManagerClass; 
      Class<?> serviceManagerNativeClass; 
      Method telephonyEndCall; 
      Object telephonyObject; 
      Object serviceManagerObject; 
      telephonyClass = Class.forName(telephonyName); 
      telephonyStubClass = telephonyClass.getClasses()[0]; 
      serviceManagerClass = Class.forName(serviceManagerName); 
      serviceManagerNativeClass = Class.forName(serviceManagerNativeName); 
      Method getService = // getDefaults[29]; 
      serviceManagerClass.getMethod("getService", String.class); 
      Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class); 
      Binder tmpBinder = new Binder(); 
      tmpBinder.attachInterface(null, "fake"); 
      serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder); 
      IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone"); 
      Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class); 
      telephonyObject = serviceMethod.invoke(null, retbinder); 
      telephonyEndCall = telephonyClass.getMethod("endCall"); 
      telephonyEndCall.invoke(telephonyObject); 

     } catch (Exception e) { 
      e.printStackTrace(); 
      Log.d("unable", "msg cant dissconect call...."); 

     } 

Das ist es! Du bist startklar.

Prost!

+0

Danke! Das ist die Arbeitslösung auch für MM –

Verwandte Themen