代码有啥问题

Posted

技术标签:

【中文标题】代码有啥问题【英文标题】:What is wrong with the code代码有什么问题 【发布时间】:2011-09-12 08:22:21 【问题描述】:

我编写了 PhoneStateListener,它通过广播接收器监听电话事件。我在TelephonyManager.CALL_STATE_IDLE 收到以下错误

06-10 13:50:48.360: 详细/错误(4686):URI: 内容://com.android.contacts/phone_lookup/, 呼叫用户:com.emergency.alert, 调用包:com.emergency.alert

代码如下

public class MyPhoneStateListener extends PhoneStateListener 
    public Context context;
    //private static MediaPlayer mMediaPlayer;
    private Uri alert;
    private static Uri prev_ringtone;
    public static final String PREFS_NAME = "ealertprefs";
    public static int phone_state;
    public EmergencyAdapter dbHelper;   
    private String fetchName;
    @Override
    public void onCallStateChanged(int state, String incomingNumber) 
        // TODO Auto-generated method stub      
        switch(state)
        case TelephonyManager.CALL_STATE_IDLE:
            try 
                if(call_from_elist(incomingNumber))                    
                    retrieve_phone();                       
                
            
            catch(Exception e) 
                Log.v("ERROR", e.getMessage());
            
            Log.v("CALL", "IDLE");
        break;
        case TelephonyManager.CALL_STATE_OFFHOOK:                                   
                //retrieve_phone();                                 
        break;
        case TelephonyManager.CALL_STATE_RINGING:
          if(call_from_elist(incomingNumber)) 
              set_uri();
              wake_up_phone();
              send_notification();                       
                 
        break;
        
    
    private void retrieve_phone() 
        AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);        
        am.setRingerMode(phone_state);
        RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, prev_ringtone);
    
    private boolean call_from_elist(String number) 
        String[] projection = new String[] 
                PhoneLookup._ID,
                PhoneLookup.DISPLAY_NAME ;

        // encode the phone number and build the filter URI
        Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));

        // query time
        Cursor c = context.getContentResolver().query(contactUri, projection, null, null, null);

        // if the query returns 1 or more results
        // return the first result
        Log.v("ELIST", "LOG");
        if (c.moveToFirst()) 
            Log.v("ELIST", "LOG2");
            String _id = c.getString(c
                    .getColumnIndex(ContactsContract.Contacts._ID));
            dbHelper = new EmergencyAdapter(context);
            dbHelper.open();
            Log.v("CALLER", _id);
            Cursor cursor = dbHelper.fetchEntry_call(Long.parseLong(_id));
            Log.v("CALLER", ""+cursor.getCount());
            if(cursor.getCount() > 0)              
                fetchName = cursor.getString(1);
                Log.v("CALLER", fetchName);         
                return true;
            
            else               
                return false;
                       
        
        return false;
    
    private void wake_up_phone() 
        AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
        phone_state = am.getRingerMode();
        Log.v("WAKEUP", Integer.toString(phone_state));
        RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, alert);
        am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);        

    
    private void send_notification()
        NotificationManager notifier = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);                
        int icon = R.drawable.icon;
        Notification notification = new Notification(icon,"Simple Notification",System.currentTimeMillis());        
        Intent toLaunch = new Intent(context, main.class);
        PendingIntent contentIntent = PendingIntent.getActivity(context, 0, toLaunch, 0);        
        notification.setLatestEventInfo(context, "Emergency Alert", "Emergency call received from "+fetchName, contentIntent);        
        notification.flags |= Notification.FLAG_AUTO_CANCEL;                              
        notifier.notify(0x007, notification);
    
    private void set_uri() 
        SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
        String ringtone = settings.getString("call_uri", "");
        if(ringtone.equals("")) 
            this.alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        
        else 
            this.alert = Uri.parse(ringtone);
                
        prev_ringtone = RingtoneManager.getActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE);
    

此错误仅发生在 TelephonyManager.CALL_STATE_IDLE 情况下。请提供任何解决此问题的方法。

堆栈跟踪是

06-10 15:32:39.332: 错误/AndroidRuntime(5559):致命 例外:主要 06-10 15:32:39.332: 错误/Android 运行时(5559): java.lang.IllegalArgumentException: 网址: 内容://com.android.contacts/phone_lookup/, 呼叫用户:com.emergency.alert, 调用包:com.emergency.alert 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:144) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:114) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 android.content.ContentProviderProxy.bulkQueryInternal(ContentProviderNative.java:372) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 android.content.ContentProviderProxy.query(ContentProviderNative.java:408) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 android.content.ContentResolver.query(ContentResolver.java:264) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 com.emergency.alert.MyPhoneStateListener.call_from_elist(MyPhoneStateListener.java:72) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 com.emergency.alert.MyPhoneStateListener.onCallStateChanged(MyPhoneStateListener.java:36) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 android.telephony.PhoneStateListener$2.handleMessage(PhoneStateListener.java:391) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 android.os.Handler.dispatchMessage(Handler.java:99) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 android.os.Looper.loop(Looper.java:143) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 android.app.ActivityThread.main(ActivityThread.java:4196) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 java.lang.reflect.Method.invokeNative(Native 方法) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 java.lang.reflect.Method.invoke(Method.java:507) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 06-10 15:32:39.332: 错误/AndroidRuntime(5559):在 dalvik.system.NativeStart.main(Native 方法)

【问题讨论】:

尝试将实际异常添加到 Log.v() 调用中,因为它会将异常的完整详细信息转储到 LogCat: Log.v( "TAG", "Where it was caught", e);然后提供发生故障时被转储的堆栈跟踪的 LogCat。 我已经发布了堆栈跟踪,请看一下,如果你发现了什么,请告诉我 【参考方案1】:

我认为您的问题是,当您收到 CALL_STATE_IDLE 时,未设置 incomingNumber 变量,因为没有活动或正在响铃的呼叫,因此没有与当前电话状态关联的电话号码。然后,您正在执行联系人查找失败,因为您没有在查询中包含有效的电话号码。

因此,当您实际上没有要搜索的电话号码时,您会尝试查找联系人。

【讨论】:

谢谢所以解决办法是在振铃状态的本地静态变量中设置电话号码? 不,因为没有与 CALL_STATE_IDLE 关联的电话号码,因此在没有活动呼叫时查找当前活动的呼叫者没有任何意义。【参考方案2】:

啊,我以前见过这个错误,

您的 URI 格式错误,因为您将其设置为默认铃声

 prev_ringtone = RingtoneManager.getActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE);

但是默认铃声没有设置,所以你得到一个空白字符串/null或其他一些错误。

为了清楚起见,检查这个问题和答案:How to play ringtone/alarm sound in Android

【讨论】:

以上是关于代码有啥问题的主要内容,如果未能解决你的问题,请参考以下文章

代码有啥问题

我的 mysqli 代码有啥问题?

以下代码有啥问题?

这个 orderByChild Firebase 实时代码有啥问题?

2的幂?代码有啥问题

下面的代码有啥问题?