2011-01-17 31 views
37

Tôi viết một ứng dụng cố gắng sửa đổi trạng thái cuộc gọi điện thoại. Nó hoạt động tốt trên Android 2.2 trở xuống, nhưng ném một ngoại lệ trên Android 2.3 vì thiếu sự cho phép trên android.permission.MODIFY_PHONE_STATE quyền (Tôi đã tuyên bố quyền này trên AndroidManifest.xml). Bất kỳ ý tưởng? Bên dưới là nhật ký ngoại lệ:Cách cấp quyền MODIFY_PHONE_STATE cho các ứng dụng chạy trên Gingerbread

01-15 09:14:23.210: ERROR/AndroidRuntime(404): FATAL EXCEPTION: main 
01-15 09:14:23.210: ERROR/AndroidRuntime(404): java.lang.RuntimeException: Unable to start receiver test.PhoneReceiver: java.lang.SecurityException: Neither user 10031 nor current process has android.permission.MODIFY_PHONE_STATE. 
01-15 09:14:23.210: ERROR/AndroidRuntime(404):  at android.app.ActivityThread.handleReceiver(ActivityThread.java:1780) 
01-15 09:14:23.210: ERROR/AndroidRuntime(404):  at android.app.ActivityThread.access$2400(ActivityThread.java:117) 
01-15 09:14:23.210: ERROR/AndroidRuntime(404):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:978) 
01-15 09:14:23.210: ERROR/AndroidRuntime(404):  at android.os.Handler.dispatchMessage(Handler.java:99) 
01-15 09:14:23.210: ERROR/AndroidRuntime(404):  at android.os.Looper.loop(Looper.java:123) 
01-15 09:14:23.210: ERROR/AndroidRuntime(404):  at android.app.ActivityThread.main(ActivityThread.java:3647) 
01-15 09:14:23.210: ERROR/AndroidRuntime(404):  at java.lang.reflect.Method.invokeNative(Native Method) 
01-15 09:14:23.210: ERROR/AndroidRuntime(404):  at java.lang.reflect.Method.invoke(Method.java:507) 
01-15 09:14:23.210: ERROR/AndroidRuntime(404):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
01-15 09:14:23.210: ERROR/AndroidRuntime(404):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
01-15 09:14:23.210: ERROR/AndroidRuntime(404):  at dalvik.system.NativeStart.main(Native Method) 
+0

Tham khảo [Shamrflow của bài viết Dưới đây] (http://stackoverflow.com/questions/10054348) –

Trả lời

21

MODIFY_PHONE_STATE là quyền chỉ dành cho hệ thống, do đó, ứng dụng không được phép tải xuống.

Điều này có thể đã thay đổi so với các phiên bản trước của nền tảng, nhưng điều đó là ổn vì nó chỉ bảo vệ các API riêng, vì vậy nếu bạn đang thực hiện điều gì đó yêu cầu, bạn đang sử dụng các API riêng không được hỗ trợ và sẽ dẫn đến những thứ như ứng dụng của bạn vi phạm các bản dựng nền tảng khác nhau.

Ngăn xếp thu thập dữ liệu bạn bao gồm chưa hoàn tất, vì vậy không có cách nào để cho biết bạn đang thực sự làm gì.

+1

Ứng dụng của tôi cố chặn cuộc gọi đến dựa trên API nội bộ. Điều đó hoạt động hoàn hảo trên Android 2.2 trở về trước, nhưng Android 2.3. Bạn có ý tưởng nào không? –

+7

Có, bạn đang sử dụng API riêng tư và API không còn hoạt động nữa. Đây là những gì xảy ra khi bạn dựa vào API. Đây là lý do tại sao chúng tôi cố gắng hết sức để làm rõ khi bạn không sử dụng API công khai và có nguy cơ gặp sự cố. – hackbod

+4

Android rất cần một API điện thoại công cộng đầy đủ thích hợp! Xin vui lòng!! :) –

-3

Nếu ứng dụng của bạn cho Gingerbread đang chạy trên máy tính bảng và không có điện thoại thì hành vi này được mong đợi. Bạn sẽ cần phải thực hiện các quyền liên quan đến điện thoại trong tệp kê khai của bạn không bắt buộc để chạy trên máy tính bảng.

Hãy thử điều này trong biểu hiện của bạn:

<uses-feature android:name="android.hardware.telephony" 
    android:required="false" /> 

Tất nhiên, tôi đang làm cho một giả định lớn về máy tính bảng. Bạn cũng có thể xem tham chiếu Android here.

+3

Cảm ơn. Ứng dụng của tôi sử dụng các tính năng liên quan đến điện thoại. Nó biến thành vấn đề trên Gingerbread/Android 2.3, nhưng luôn hoạt động tốt trên Android 2.2 –

54

Sự cố bạn gặp phải đã được giới thiệu trong Android 2.3 (Gingerbread). Bất kỳ mã nào bạn có yêu cầu MODIFY_PHONE_STATE sẽ hoạt động tất cả các cách lên đến (và bao gồm) Android 2.2, nhưng sẽ phá vỡ cho Android 2.3+.

A change was checked in bởi David Brown giới hạn việc sử dụng quyền MODIFY_PHONE_STATE đối với các ứng dụng hệ thống. ứng dụng hệ thống là một trong hai

  1. Pre-cài đặt vào một thư mục hệ thống trên ROM
  2. Biên soạn bởi một nhà sản xuất sử dụng chứng chỉ bảo mật của họ

tôi nghi ngờ bạn đang cố gắng sử dụng một API ẩn như ITelephony . Tôi đã - và tôi bị đốt cháy bởi sự thay đổi này. Sự biện minh của đội Android là nó là một API ẩn mà bạn không nên sử dụng nó ngay từ đầu.

Điều đó nói rằng, đã có an enhancement request mở để tạo ra một API điện thoại công cộng thích hợp, nhưng Google đã giết vé. Có vẻ lập trường của họ là họ không có ý định đảo chiều và các API này không dành cho tiêu dùng công cộng.

+0

liên kết bị hỏng trong câu trả lời của bạn, bạn có thể biết nó có thể tìm thấy ở đâu bây giờ? – donfuxx

4

Tôi đã nhận được giải pháp.

Thay vì ghi đè màn hình cuộc gọi đến, hãy làm hai điều sau. cho phép bạn truy cập nút chấp nhận và từ chối và cũng cho phép bạn hiển thị màn hình phía trên màn hình cuộc gọi đến.

(1) Làm cho lớp một nhận:

public class MyPhoneReceiver extends BroadcastReceiver { 
@Override 
public void onReceive(final Context context, final Intent intent) { 
    Bundle extras = intent.getExtras(); 
    if (extras != null) 
    { 
     String state = extras.getString(TelephonyManager.EXTRA_STATE); 
     if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) 
      String phoneNumber = extras.getString(TelephonyManager.EXTRA_INCOMING_NUMBER); 

     Intent i = new Intent(context, IncomingCallActivity.class); 
     i.putExtras(intent); 
     i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     context.startActivity(i); 
    } 
    } 
} 

(2) xml hoạt động của bạn trông giống như:

RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:layout_gravity="top" 
android:gravity="top" 
android:orientation="vertical" 
android:windowAnimationStyle="@android:style/Animation.Translucent" 
android:windowBackground="@android:color/transparent" 
android:windowIsTranslucent="true" 

(3) Hãy bố trí của hoạt động của bạn trong suốt (mà sẽ đến trên màn hình gọi), viết mã bên dưới vào menifest

<activity android:name=".IncomingCallActivity" 
     android:theme="@android:style/Theme.Translucent"> 
</activity> 

(4) Trong menifest thêm bộ thu truyền rộng

<receiver android:name="MyPhoneReceiver" > 
     <intent-filter> 
      <action android:name="android.intent.action.PHONE_STATE" > 
      </action> 
     </intent-filter> 
</receiver> 

(5) thêm bên dưới mã trong onCreate() của IncomingCallActivity

Cheers!

Hãy cho tôi biết nếu bạn gặp phải bất kỳ sự cố nào!

+1

Bạn có nghĩa là bạn đã sử dụng thành công kỹ thuật aidl và sử dụng logic trên cho hoạt động để cho phép người dùng trả lời cuộc gọi bằng cách sử dụng các nút trên màn hình (u được xác định trong hoạt động xml) của bạn? Điều đó sẽ rất tuyệt, nếu nó thực sự hoạt động theo cách đó .. –

+0

Không, mã này sẽ cho phép bạn đặt mọi thứ lên trên màn hình cuộc gọi đến ban đầu và cho phép bạn truy cập vào nút gọi đến và gọi đi mặc định cùng một lúc .. – Dhrupal

+0

@Dhrupal, bạn có thể giải thích thêm về cách bạn đã làm nó. Bạn đang thực sự làm gì trong hoạt động của mình. Tôi có requiremnet tương tự, tôi muốn hiển thị một số thông tin bổ sung cho các cuộc gọi đến – png

5

Hãy thử điều này.

public static void answerPhoneHeadsethook(Context context) { 
    // Simulate a press of the headset button to pick up the call 
    // SettingsClass.logMe(tag, "Simulating headset button"); 
    Intent buttonDown = new Intent(Intent.ACTION_MEDIA_BUTTON); 
    buttonDown.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK)); 
    context.sendOrderedBroadcast(buttonDown, "android.permission.CALL_PRIVILEGED"); 

    // froyo and beyond trigger on buttonUp instead of buttonDown 
    Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON); 
    buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK)); 
    context.sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED"); 
} 
+1

Điều này làm việc với tôi android 4.1.2 Xperia –

+0

Làm việc cho 2.3.3 nhưng không hoạt động cho 4.1.2 –