2015-09-14 4 views
0

привет Приложения для Android 5 ошибок силы близко, но не проблема для Android 4, пожалуйста, помогите мнеошибка: принудительно закрыть Android программу

ошибки LogCat:

09-13 13:23:50.441: W/IInputConnectionWrapper(1627): showStatusIcon on inactive InputConnection 
    09-13 13:24:02.697: I/Choreographer(1627): Skipped 189 frames! The application may be doing too much work on its main thread. 
    09-13 13:24:05.527: W/Resources(1627): Converting to string: TypedValue{t=0x10/d=0x1 a=-1} 
    09-13 13:24:05.531: W/Resources(1627): Converting to string: TypedValue{t=0x10/d=0x5 a=-1} 
    09-13 13:24:05.591: W/Resources(1627): Converting to string: TypedValue{t=0x10/d=0x2 a=-1} 
    09-13 13:24:06.952: I/Choreographer(1627): Skipped 111 frames! The application may be doing too much work on its main thread. 
    09-13 13:24:08.230: I/Choreographer(1627): Skipped 123 frames! The application may be doing too much work on its main thread. 
    09-13 13:24:10.963: E/Autocall(1627): -----Recording stoped 
    09-13 13:24:10.963: E/MediaRecorder(1627): stop called in an invalid state: 0 
    09-13 13:24:10.994: D/AndroidRuntime(1627): Shutting down VM 
    09-13 13:24:11.061: E/AndroidRuntime(1627): FATAL EXCEPTION: main 
    09-13 13:24:11.061: E/AndroidRuntime(1627): Process: com.example.c, PID: 1627 
    09-13 13:24:11.061: E/AndroidRuntime(1627): java.lang.RuntimeException: Unable to start receiver com.example.c.AutoAnswerReceiver: java.lang.IllegalStateException 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  at android.app.ActivityThread.handleReceiver(ActivityThread.java:2619) 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  at android.app.ActivityThread.access$1700(ActivityThread.java:151) 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1380) 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  at android.os.Handler.dispatchMessage(Handler.java:102) 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  at android.os.Looper.loop(Looper.java:135) 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  at android.app.ActivityThread.main(ActivityThread.java:5257) 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  at java.lang.reflect.Method.invoke(Native Method) 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  at java.lang.reflect.Method.invoke(Method.java:372) 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
    09-13 13:24:11.061: E/AndroidRuntime(1627): Caused by: java.lang.IllegalStateException 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  at android.media.MediaRecorder.stop(Native Method) 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  at com.example.c.AutoAnswerReceiver.onReceive(AutoAnswerReceiver.java:223) 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  at android.app.ActivityThread.handleReceiver(ActivityThread.java:2612) 
    09-13 13:24:11.061: E/AndroidRuntime(1627):  ... 9 more 

AutoAnswerReceiver активность

public class AutoAnswerReceiver extends BroadcastReceiver { 
    private static MediaRecorder recorder; 
    public static boolean recordStarted=false; 
    private Context ctx; 

    String phoneNumber; 
    byte[] incrept; 
    byte[] decrpt; 
    String selected_song_name; 
    private static String recordPath; 
    public static boolean wasRinging = false; 
    Boolean isOffHook = false; 
    private static String inCall; 
    DatabaseHandler db; 
    SharedPreferences prefs; 
    Context context; 
    AudioManager am; 
    Cursor c; 
    boolean callAgain; 
    String key_which_call; 
    String key_sms_template; 
    String contactId=null; 
@Override 
public void onReceive(Context context, Intent intent) { 
    //Toast.makeText(context, "Receiver called", Toast.LENGTH_SHORT).show(); 
    prefs = PreferenceManager.getDefaultSharedPreferences(context); 
    String phone_state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); 
    db=new DatabaseHandler(context); 
    this.context=context; 
    key_which_call=prefs.getString("list_answer_calls", "1"); 
    am= (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 

    key_sms_template=prefs.getString("key_sms_template", "I am in meeting.Please call later."); 
    if (phone_state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { 
     inCall = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER); 
     c=db.getPhoneCall(inCall); 
     Calendar cal=Calendar.getInstance(); 
     if(c.moveToFirst()) 
     { 
      String lastCallAt=c.getString(2); 
      long millis=Long.parseLong(lastCallAt); 
      long curr_mills=cal.getTimeInMillis(); 
      long diff=curr_mills-millis; 
      int hours=(int) (diff/(1000*60*60)); 
      //Toast.makeText(context, "Last call :"+new Date(millis)+" hours:"+hours+"diff:"+diff, Toast.LENGTH_LONG).show(); 
      Log.d("AutocallAnswer", "Last call :"+new Date(millis)+" hours:"+hours+"diff:"+diff); 
      if(hours>=1) 
      { 
       callAgain=true; 
       db.updatePhoneCall(String.valueOf(cal.getTimeInMillis()), inCall); 
      } 
      else 
      { 
       callAgain=false; 
      } 
     } 
     else 
     { 
      String millis=String.valueOf(cal.getTimeInMillis()); 
      db.addCallCount(inCall,millis); 
      callAgain=true; 
     } 

     if(callAgain) 
     { 
      if(prefs.getBoolean("key_callsms", false)) 
      { 
       //Toast.makeText(context, "In SMS", Toast.LENGTH_SHORT).show(); 
       //sendMessage(inCall); 
       setRingerSilent(); 
       try { 
        Log.e("CallService", "-------> Delay :"+prefs.getString("list_delay_calls", "2")+"hello"); 
        Thread.sleep(Integer.parseInt(prefs.getString("list_delay_calls", "2")) * 1000); 
       } catch (InterruptedException e) { 
        // We don't really care 
       } 
       try { 
        endInCall(); 
       } catch (Exception e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       sendMessage(inCall); 


      } 
      else if(prefs.getBoolean("key_callrecord", false)) 
      { 

       if(key_which_call.equals("1")) 
       { 
       // setRingerSilent(); 
        wasRinging=true; 
        context.startService(new Intent(context, AutoAnswerIntentService.class)); 

       } 
       else if(key_which_call.equals("2") || key_which_call.equals("3")) 
       { 
        if(contactExists(context, inCall)) 
        { 
        // setRingerSilent(); 
         wasRinging=true; 
         context.startService(new Intent(context, AutoAnswerIntentService.class)); 

        } 
       } 
       //Toast.makeText(context, "Incoming call"+inCall, Toast.LENGTH_SHORT).show(); 

      } 
     } 
     else 
     { 
      if(prefs.getBoolean("key_callsms", false) || prefs.getBoolean("key_callrecord", false)) 
      { 
       if(prefs.getBoolean("key_callsms", false)) 
       { 
        setRingerSilent(); 
       } 
       if(key_which_call.equals("1")) 
       { 
        //setRingerSilent(); 
        wasRinging=true; 
        context.startService(new Intent(context, AutoAnswerIntentService.class)); 

       } 
       else if(key_which_call.equals("2") || key_which_call.equals("3")) 
       { 
        if(contactExists(context, inCall)) 
        { 
         //setRingerSilent(); 
         wasRinging=true; 
         context.startService(new Intent(context, AutoAnswerIntentService.class)); 

        } 
       } 
      } 

     } 

    } 
    else if(phone_state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) 
    { 
     //Toast.makeText(context, "Call answered:"+inCall, Toast.LENGTH_SHORT).show(); 

     if(wasRinging==true) 
     { 
      //Toast.makeText(context, "call recording", Toast.LENGTH_SHORT).show(); 
      //startRecording(); 
      startRecording(); 
     } 

    } 
    else if(phone_state.equals(TelephonyManager.EXTRA_STATE_IDLE)) 
    { 
     wasRinging=false; 

     setRingerNormal(); 
     //Toast.makeText(context, "Call Ended", Toast.LENGTH_SHORT).show(); 
     if(recordStarted) 
     { 

      Log.e("Autocall", "-----Recording stoped"); 
      if(recorder!=null) 
      { 
       recorder.stop(); 
       recorder.release(); 
      } 

       String name=getContactName(context, inCall); 
       Uri photoUri=getPhotoUri(); 
       String photo=null; 
       if(name==null) 
       { 
        name="Unkonown"; 
        photo="NA"; 
       } 
       if(photoUri==null) 
       { 
        photo="NA"; 
       } 
       else 
        photo=photoUri.toString(); 
       CallRecord callRecord=new CallRecord(); 
       callRecord.setName(name); 
       callRecord.setNumber(inCall); 
       callRecord.setPhotoUri(photo); 
       callRecord.setCallTime(String.valueOf(Calendar.getInstance().getTimeInMillis())); 
       callRecord.setRecordPath(recordPath); 
       db.addCallHistory(callRecord); 
       //Toast.makeText(context, "Call recorded saved", Toast.LENGTH_SHORT).show(); 
       createNotification(); 

      recordStarted = false; 

     } 
    } 
} 

@SuppressWarnings("unchecked") 
public void endInCall() throws Exception 
{ 
    TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 
    Class c = Class.forName(tm.getClass().getName()); 
    Method m = c.getDeclaredMethod("getITelephony"); 
    m.setAccessible(true); 
    Object telephonyInterface = m.invoke(tm); 

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

    // Invoke endCall() 
    methodEndCall.invoke(telephonyInterface); 
} 
private void sendMessage(String number) 
{ 
    try { 
     SmsManager smsManager = SmsManager.getDefault(); 
     smsManager.sendTextMessage(number, null, key_sms_template, null, null); 
     // Toast.makeText(context, "SMS sent.",Toast.LENGTH_LONG).show(); 
     } catch (Exception e) { 
     Toast.makeText(context, 
     "SMS faild, please try again.", 
     Toast.LENGTH_LONG).show(); 
     e.printStackTrace(); 
     } 
} 
private void setRingerSilent() 
{ 
    //For Normal mode 


    //For Silent mode 
    am.setRingerMode(AudioManager.RINGER_MODE_SILENT); 

    //For Vibrate mode 
    //am.setRingerMode(AudioManager.RINGER_MODE_VIBRATE); 
} 
private void setRingerNormal() 
{ 
    am.setRingerMode(AudioManager.RINGER_MODE_NORMAL); 
} 
private int getNotifCount() 
{ 
    return prefs.getInt("notifCount", 1); 
} 

public void createNotification() { 
    // Prepare intent which is triggered if the 
    // notification is selected 

    // call widget update 
    Intent intentW = new Intent(context, AutoCallAnswerWidget.class); 
    intentW.setAction("android.appwidget.action.APPWIDGET_UPDATE"); 
    int ids[] = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, AutoCallAnswerWidget.class)); 
    intentW.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,ids); 
    context.sendBroadcast(intentW); 
    ////////////////////////// 
    NotificationCompat.Builder mBuilder=new NotificationCompat.Builder(context); 
    mBuilder.setContentTitle("New voice message"); 
    mBuilder.setTicker("Explicit:New message received"); 
    int notifNumber=getNotifCount(); 
    notifNumber++; 
    mBuilder.setNumber(notifNumber); 
    mBuilder.setContentText("You have "+notifNumber+" new voice message"); 
    //mBuilder.setSubText("You have "+notifNumber+" new voice message"); 
    mBuilder.setSmallIcon(R.drawable.wicon); 
    int notifId=1; 
    Intent intent=new Intent(context,InboxActivity.class); 
    TaskStackBuilder stackBuilder=TaskStackBuilder.create(context); 
    stackBuilder.addParentStack(InboxActivity.class); 
    stackBuilder.addNextIntent(intent); 

    PendingIntent pendingIntent=stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT|PendingIntent.FLAG_ONE_SHOT); 
    mBuilder.setContentIntent(pendingIntent); 
    NotificationManager nm=(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 
    //mBuilder.setNumber(1); 


    mBuilder.setAutoCancel(true); 
    mBuilder.setDefaults(Notification.DEFAULT_SOUND|Notification.DEFAULT_VIBRATE); 
    nm.notify(notifId, mBuilder.build()); 
    Editor editor=prefs.edit(); 
    editor.putInt("notifCount", notifNumber); 
    editor.commit(); 
    } 
public void startRecording() 
{ 
    try 
    { 
     Log.e("AutoAnswerReceiver", "Hello ----> auto answer called"); 
     recorder = new MediaRecorder(); 
     recorder.reset(); 
     recorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
     recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
     recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 
     File file = createDirIfNotExists("AUD"+getTimeStamp()); 
     recorder.setOutputFile(file.getAbsolutePath()); 
     recordPath=file.getAbsolutePath(); 
     recorder.prepare(); 
     recorder.start(); 
     recordStarted = true; 

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


} 
public static String getTimeStamp() { 
     Time now = new Time(); 
     now.setToNow(); 
     String sTime = now.format("%Y_%m_%d_%H_%M_%S"); 
     return sTime; 
    } 
public File createDirIfNotExists(String path) 
{ 
    selected_song_name = path; 
    String dirpath=prefs.getString("key_voicemail_path", null); 
    if(dirpath==null) 
     dirpath=Environment.getExternalStorageDirectory()+ "/CallRecorder"; 
    File folder = new File(dirpath); 
    if (!folder.exists()) 
    { 
     if (!folder.mkdirs()) 
     { 
      Log.e("TravellerLog :: ", "folder is created"); 
     } 
    } 
    String list_file_type=prefs.getString("list_file_type", "2"); 
    String fileExt=null; 
    if(list_file_type.equals("2")) 
     fileExt=".mp3"; 
    else 
     fileExt=".amr"; 
    File file = new File(folder, path + fileExt); 
    try 
    { 
     if (!file.exists()) 
     { 
      if (file.createNewFile()) 
      { 
       Log.e("TravellerLog :: ", "file is created"); 
      } 

     } 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
     Log.e("AutoAnswerReceiver", "Error:"+e.toString()); 
    } 
    return file; 
} 


public String getContactName(Context context, String phoneNumber) { 
    ContentResolver cr = context.getContentResolver(); 
    Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber)); 
    Cursor cursor = cr.query(uri, new String[]{PhoneLookup.DISPLAY_NAME,PhoneLookup._ID}, null, null, null); 
    if (cursor == null) { 
     return null; 
    } 

    String contactName = null; 
    if(cursor.moveToFirst()) { 
     contactName = cursor.getString(cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME)); 
     contactId=cursor.getString(cursor.getColumnIndex(PhoneLookup._ID)); 
    } 

    if(cursor != null && !cursor.isClosed()) { 
     cursor.close(); 
    } 

    return contactName; 
} 
public boolean contactExists(Context context, String number) 
{ 
    /// number is the phone number 
    Uri lookupUri = Uri.withAppendedPath(
    PhoneLookup.CONTENT_FILTER_URI, 
    Uri.encode(number)); 
    String[] mPhoneNumberProjection = { PhoneLookup._ID, PhoneLookup.NUMBER, PhoneLookup.DISPLAY_NAME }; 
    Cursor cur = context.getContentResolver().query(lookupUri,mPhoneNumberProjection, null, null, null); 
    try 
    { 
     if (cur.moveToFirst()) 
     { 
      return true; 
     } 
    } 
    finally 
    { 
     if (cur != null) 
      cur.close(); 
    } 
    return false; 
} 

public Uri getPhotoUri() { 
    long contID=0; 
    try { 
     ContentResolver contentResolver = context.getContentResolver(); 
     contID=Long.parseLong(contactId); 
     Cursor cursor = contentResolver 
       .query(ContactsContract.Data.CONTENT_URI, 
         null, 
         ContactsContract.Data.CONTACT_ID 
           + "=" 
           + contactId 
           + " AND " 

           + ContactsContract.Data.MIMETYPE 
           + "='" 
           + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE 
           + "'", null, null); 

     if (cursor != null) { 
      if (!cursor.moveToFirst()) { 
       return null; // no photo 
      } 
     } else { 
      return null; // error in cursor process 
     } 

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

    Uri person = ContentUris.withAppendedId(
      ContactsContract.Contacts.CONTENT_URI, contID); 
    return Uri.withAppendedPath(person, 
      ContactsContract.Contacts.Photo.CONTENT_DIRECTORY); 
} 

} 

ответ

0

Ваш медиамагнитофон не находится в состоянии записи, когда вызывается stop(). Ниже приведена возможная причина, если это относится к Android 5.

В вашем коде вы используете широковещательный приемник для обработки входящих широковещательных сообщений всякий раз, когда происходит изменение состояния телефона. В основном 3 состояния, которые вы могли бы получить от intent.getStringExtra(TelephonyManager.EXTRA_STATE): EXTRA_STATE_IDLE, EXTRA_STATE_RINGING и EXTRA_STATE_OFFHOOK. onReceiver() призван к изменению состояния.

Последовательность изменения состояния, как правило: EXTRA_STATE_RINGING (входящий звонок) ->EXTRA_STATE_OFFHOOK (разговор) ->EXTRA_STATE_IDLE (повесьте трубку).

Ваш код основывается на изменении состояния для начала/остановки записи.

Замечено, что в Android 5, система может посылать повторяющиеся PhoneStateChange события (например, EXTRA_STATE_RINGING ->EXTRA_STATE_RINGING ->EXTRA_STATE_OFFHOOK ->EXTRA_STATE_OFFHOOK ->EXTRA_STATE_IDLE ->EXTRA_STATE_IDLE).

В приведенной выше последовательности ваш код остановит рекордер в первом EXTRA_STATE_IDLE, позвонив по номеру recorder.stop(). После получения второго EXTRA_STATE_IDLE ваш код может снова позвонить recorder.stop(), что приведет к незаконному состоянию.

Ваш код уже использует переменную recordStarted, чтобы проверить, была ли запись начата, до остановки рекордера. Однако переменная recordStarted сбрасывается только в конце обработки EXTRA_STATE_IDLE, в течение которой может передаваться второй EXTRA_STATE_IDLE.

Для лучшего охранника снова возможность дублированных вызовов к recorder.stop(), быстро исправить это установить recordStarted к ложным как можно скорее, чтобы свести к минимуму вероятность того, что дубликат EXTRA_STATE_IDLE вызовет второй recorder.stop()

else if(phone_state.equals(TelephonyManager.EXTRA_STATE_IDLE)) 
    { 
     wasRinging=false; 

     setRingerNormal(); 

     if(recordStarted) 
     { 
      recordStarted = false; 

      Log.e("Autocall", "-----Recording stoped"); 

      : 
      createNotification(); 

     } 

Вы также можете объявить переменную recordStarted в качестве летучей -

public static volatile boolean recordStarted=false; 
+0

пожалуйста изменить мой код, я не расслышал –

+0

ответа разработан. – headuck

+0

Я изменил код в соответствии с вашими заказами, но аудиофайлы хранятся дважды. Пожалуйста, помогите –

Смежные вопросы