我怎么可以单独在列表视图中的Andr​​oid呼入呼​​出记录文件 [英] how can i separate incoming and outgoing call recorded files in listview in android

查看:158
本文介绍了我怎么可以单独在列表视图中的Andr​​oid呼入呼​​出记录文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

*我开发记录应用程序。因为它会记录所有来电和去电,并正在显示在列表视图这些调用。我想显示传入和传出的录像文件独立的符号。我怎样才能分开吧。请提供解决方案。如果可能的话提供源$ C ​​$ C。 感谢you.am新到Android development.please任何一个可以告诉我的解决方案。

  CallBroadCastReceiver.java

公共类CallBroadcastReceiver扩展的BroadcastReceiver
 

{     公共无效的onReceive(上下文的背景下,意图意图){         Log.d(CallRecorder,CallBroadcastReceiver:的onReceive了意图:+ intent.toString());

 如果(intent.getAction()。等于(Intent.ACTION_NEW_OUTGOING_CALL)){
        字符串numberToCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);

        Log.d(CallRecorder,CallBroadcastReceiver意图有EXTRA_PHONE_NUMBER:+ numberToCall);
    }
    PhoneListener phoneListener =新PhoneListener(上下文);
    TelephonyManager电话=(TelephonyManager)
        context.getSystemService(Context.TELEPHONY_SERVICE);
    telephony.listen(phoneListener,PhoneStateListener.LISTEN_CALL_STATE);
    Log.d(PhoneStateReceiver:的onReceive,设置PhoneStateListener);
}
 

} *

  PhoneListener.java


公共类PhoneListener扩展PhoneStateListener
 

{     私人上下文的背景下;

 公共PhoneListener(上下文C){
    Log.i(CallRecorder,PhoneListener构造);
    上下文= C;
}

公共无效onCallStateChanged(INT状态,串incomingNumber)
{
    Log.d(CallRecorder,PhoneListener :: onCallStateChanged状态:+状态+incomingNumber:+ incomingNumber);

    开关(州){
    案例TelephonyManager.CALL_STATE_IDLE:
        Log.d(CallRecorder,CALL_STATE_IDLE,回采记录);
        布尔停止= context.stopService(新意图(背景下,RecordService.class));
        Log.i(CallRecorder,stopService为RecordService返回+停止);
        打破;
    案例TelephonyManager.CALL_STATE_RINGING:
        Log.d(CallRecorder,CALL_STATE_RINGING);
        打破;
    案例TelephonyManager.CALL_STATE_OFFHOOK:
        Log.d(CallRecorder,CALL_STATE_OFFHOOK开始记录);
        意图callIntent =新的意图(背景下,RecordService.class);
        组件名名称= context.startService(callIntent);
        如果(空==名){
            Log.e(CallRecorder,startService为RecordService返回null组件名);
        } 其他 {
            Log.i(CallRecorder,startService返回+ name.flattenToString());
        }
        打破;
    }
}




  CallLog.java


  公共类CallLoglist扩展活动
  {
  私人最终字符串变量=CallRecorder;
  私人的ListView的fileList = NULL;
  //公共静态ArrayAdapter<字符串> fAdapter = NULL;
  私人搜索栏搜索栏;
  私人的MediaPlayer媒体播放器=新的MediaPlayer();
  公共静态的ImageButton暂停按钮;
   公众的TextView startTimeField,endTimeField;
  AudioManager audioManager;
  公共静态最后弦乐STORAG​​E_LOCATIONN = Environment.getExternalStorageDirectory()+/安卓/数据/ com.callrecorder /收藏夹;
  处理器seekHandler =新的处理程序();
  对话seekDialog;
  私营公用事业utils的;
  长totalDuration,currentDuration;
  公共静态ImageView的IMG;
  的String [] DLIST;
  字符串recordlist;
  私有列表fAdapter;
  ArrayList的<字符串>一个列表;
  光标managedCursor;
  StringBuffer的某人;
  公共字符串名称;
  公共串号;
  文件源;
  CallLoglist CC;
  公共静态布尔SS;
  字符串phNumber;
  公共静态INT一个;
  公共静态编辑器编辑;
  公共静态共享preferences preF;

  公共静态的ArrayList<布尔> ARR =新的ArrayList<布尔>();

  私有类CallItemClickListener实现AdapterView.OnItemClickListener {
    @覆盖
    公共无效onItemClick(适配器视图<>母公司视图中查看,INT位置,长ID)
    {
        view.showContextMenu();

        CharSequence中=(为CharSequence)parent.getItemAtPosition(位置);
        Log.w(TAG,CallLog刚刚得到一个项目点击+ S);

        //文件F =新的文件(RecordService.DEFAULT_STORAG​​E_LOCATION +/+ s.toString());


        / *布尔useMediaController = TRUE;

        如果(useMediaController){
            意图playIntent =新的意图(getApplicationContext(),CallPlayer.class); //Intent.ACTION_VIEW);
            开放的我们的uri = Uri.fromFile(F);
            playIntent.setData(URI);
            startActivity(playIntent);

        } 其他 {
            playFile(s.toString());
        } * /


      }
    }


         @燮pressLint(ShowToast)
      @覆盖
     公共无效的onCreate(包savedInstanceState)
      {
         super.onCreate(savedInstanceState);
     audioManager =(AudioManager)getSystemService(Context.AUDIO_SERVICE);
     的setContentView(R.layout.call_log);
     的fileList =(ListView控件)findViewById(R.id.play_file_list);
     IMG =(ImageView的)findViewById(R.id.image);
     上下文的背景下= getApplicationContext();
     setVolumeControlStream(AudioManager.STREAM_MUSIC);
     utils的=新的实用程序();
     文件DIR =新的文件(RecordService.LOCATION);
     DLIST = dir.list();
     ALIST =新的ArrayList<字符串>(Arrays.asList(DLIST));
     Log.v(豪情,录音文件+ recordlist);
     fAdapter =新的列表(此,ALIST);
     fileList.setAdapter(fAdapter);
     fileList.setOnItemClickListener(新CallItemClickListener());
     registerForContextMenu(fileList)中的;
     preF = getShared preferences(MM,MODE_PRIVATE);
     ED = pref.edit();
    / * ed.putString(RR,R.drawable.arrow);
    ed.putString(重,R.drawable.arroww); * /
    ed.commit();

    ////////////////

    / *的String []投影=新的String [] {android.provider.CallLog.Calls.NUMBER,android.provider.CallLog.Calls.DATE,android.provider.CallLog.Calls.CACHED_NAME};
     乌里接触= android.provider.CallLog.Calls.CONTENT_URI;

     光标managedCursor = managedQuery(联系人,投影,NULL,NULL,android.provider.CallLog.Calls.DATE +ASC);
     getColumnData(managedCursor);

     }

      私人无效getColumnData(光标CUR){
       尝试{
        如果(cur.moveToFirst()){

            长日期;
            INT名称列= cur.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
            INT numberColumn = cur.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
            INT dateColumn = cur.getColumnIndex(android.provider.CallLog.Calls.DATE);

            的System.out.println(阅读呼叫详细:);
            做 {
                名称= cur.getString(名称列);
                数= cur.getString(numberColumn);
                日期= cur.getLong(da​​teColumn);
                的System.out.println(数字+:+新的日期(日期)+:+姓名);


            }而(cur.moveToNext());
            }
           }

          最后{
              cur.close();
          } * /
          }




       公共无效onCreateContextMenu(文本菜单菜单,视图V,
        ContextMenuInfo menuInfo){
         // TODO自动生成方法存根
      super.onCreateContextMenu(菜单,V,menuInfo);
       MenuInflater米= getMenuInflater();
        m.inflate(R.menu.nn,菜单);

          }


      @燮pressLint({ShowToast,SdCardPath})
     @覆盖
     公共布尔onContextItemSelected(菜单项项){
    // TODO自动生成方法存根
    AdapterContextMenuInfo信息=(AdapterContextMenuInfo)item.getMenuInfo();
    INT指数= info.position;
    recordlist = alist.get(指数);

    // PP = DLIST。
    开关(item.getItemId()){

    案例R.id.play:

        seekDialog =新的对话框(本);
        seekDialog.setTitle(玩);
        seekDialog.setContentView(R.layout.dialog);
        startTimeField =(TextView中)seekDialog.findViewById(R.id.textView1);
        endTimeField =(TextView中)seekDialog.findViewById(R.id.textView2);
        暂停按钮=(的ImageButton)seekDialog.findViewById(R.id.imageButton2);
        搜索栏=(搜索栏)seekDialog.findViewById(R.id.seek);
        seekDialog.show();

        Log.v(文件,+指数);
        如果(媒体播放器!= NULL){

            mediaPlayer.release();
        }

        /*mediaPlayer=MediaPlayer.create(this,Uri.parse(Environment.getExternalStorageDirectory()。getAbsolutePath()
                +/Android/data/com.callrecorder/recordings/+ pathh)); * /
        媒体播放器= MediaPlayer.create(这一点,Uri.parse(Environment.getExternalStorageDirectory()。getAbsolutePath()
                +/Android/data/com.callrecorder/recordings/+ recordlist));
        mediaPlayer.start();
        seekUpdation();
        totalDuration = mediaPlayer.getDuration();
        seekbar.setMax((INT)totalDuration);

        pauseButton.setOnClickListener(新OnClickListener(){

            @覆盖
            公共无效的onClick(视图v){
                // TODO自动生成方法存根
                如果(mediaPlayer.isPlaying())
                {
                    mediaPlayer.pause();
                    pauseButton.setImageResource(R.drawable.play);
                    Toast.makeText(getApplicationContext(),暂停,1000).show();
                }
                其他
                {
                    mediaPlayer.start();
                    pauseButton.setImageResource(R.drawable.pause);
                    Toast.makeText(getApplicationContext(),玩,1000).show();
                }

            }
        });

        seekDialog.setOnDismissListener(新OnDismissListener(){

            @覆盖
            公共无效onDismiss(DialogInterface对话){
                // TODO自动生成方法存根
                mediaPlayer.release();

            }
        });

        seekbar.setOnSeekBarChangeListener(新OnSeekBarChangeListener(){

            @覆盖
            公共无效onStopTrackingTouch(搜索栏搜索栏){
                // TODO自动生成方法存根

            }

            @覆盖
            公共无效onStartTrackingTouch(搜索栏搜索栏){
                // TODO自动生成方法存根

            }

            @覆盖
            公共无效onProgressChanged(搜索栏搜索栏,INT进步,
                    布尔FROMUSER){
                // TODO自动生成方法存根
                如果(FROMUSER)
                {
                    mediaPlayer.pause();
                    seekbar.setProgress(mediaPlayer.getCurrentPosition());
                    seekbar.setMax(mediaPlayer.getDuration());
                    mediaPlayer.seekTo(进度);
                    mediaPlayer.start();
                    pauseButton.setImageResource(R.drawable.pause);
                    seekUpdation();
                }
                }
              });

           打破;
         案例R.id.delete:
        Toast.makeText(getApplicationContext(),删除,1000).show();
        //新的文件(Environment.getExternalStorageDirectory()+/ callrecorder /+ pathh).delete();
        新的文件(Environment.getExternalStorageDirectory()getAbsolutePath()+/Android/data/com.callrecorder/recordings/+ recordlist。).delete();
        alist.remove(指数);
        alist.clear();
        fAdapter.notifyDataSetChanged();
        fAdapter.notifyDataSetInvalidated();

         打破;

        案例R.id.favorites:

        Toast.makeText(getApplicationContext(),favouraties,1000).show();
        来源=新的文件(Environment.getExternalStorageDirectory()+/Android/data/com.callrecorder/recordings/+ recordlist);

        文件DIR =新的文件(STORAG​​E_LOCATIONN);

        如果(!dir.exists())
        {
            尝试 {

                dir.mkdir();

            }赶上(例外五){
                // TODO:处理异常

            }
        }

        尝试 {
            InputStream的时间=新的FileInputStream(源);
            的OutputStream OUT =新的FileOutputStream(STORAG​​E_LOCATIONN +/+ recordlist);

            //传输的字节从以出
            byte []的BUF =新的字节[1024];
            INT LEN;

            而((LEN = in.read(BUF))大于0){
                out.write(BUF,0,的len);
            }
            附寄();
            out.close();


          }赶上(例外五){
            // TODO:处理异常
            Log.v(copyyy,errorrrrr);
         }
         source.delete();
         alist.remove(指数);
         fAdapter.notifyDataSetChanged();
         fAdapter.notifyDataSetInvalidated();
         打破;

          默认:
         }
         返回super.onContextItemSelected(项目);
          }

           可运行的银行经营=新的Runnable(){
          @覆盖公共无效的run(){

         尝试 {
            seekUpdation();
         }赶上(例外五){
            // TODO:处理异常
         }

         尝试 {
            totalDuration = mediaPlayer.getDuration();
            currentDuration = mediaPlayer.getCurrentPosition();
            //显示总持续时间
            endTimeField.setText(+ utils.milliSecondsToTimer(totalDuration));
            //显示的时间内完成演奏
            startTimeField.setText(+ utils.milliSecondsToTimer(currentDuration));
            seekbar.setProgress((INT)currentDuration); //移动搜索栏
            //更新进度条
            / * INT进度=(INT)(utils.getProgressPercentage(currentDuration,totalDuration));
                  //Log.d("Progress,+进展);
                  seekbar.setProgress(进度); * /
            // seekHandler.postDelayed(此,100);

            }赶上(例外五){
            // TODO:处理异常
           }
          }
        };

        公共无效seekUpdation(){

          //seekbar.setProgress(mediaPlayer.getCurrentPosition());

         //mHandler.postDelayed(mUpdateTimeTask,100);
          seekHandler.postDelayed(银行经营,1000);

          }
           公共无效的OnStart()
         {
            super.onStart();
        Log.i(TAG,CallLog ONSTART);
           }

        公共无效onRestart()
          {
           super.onRestart();
           Log.i(TAG,CallLog onRestart);
          }

       / *公共无效onResume()
         {
        super.onResume();
          //Log.i(TAG,CallLog onResume即将再次载入记录列表,做这项工作?);

           loadRecordingsFromDir();

            } * /

      @覆盖
       保护无效的onDestroy(){
            / *如果(NULL!=媒体播放器){
          mediaPlayer.release();
           } * /
         super.onDestroy();
         如果(媒体播放器!= NULL){
         //mediaPlayer.stop();
         mediaPlayer.release();
         媒体播放器= NULL;

           }

             }


        ///////////////////////////////////////////


          私有类列表扩展了BaseAdapter
    {

    私人CallLoglist callLog;
    私人的ArrayList<字符串>一个列表;

    公示名单(CallLoglist callLog,ArrayList的<字符串> ALIST){
        // TODO自动生成构造函数存根
        this.callLog = callLog;
        this.alist = ALIST;
    }

    @覆盖
    公众诠释getCount将(){
        // TODO自动生成方法存根
        返回alist.size();
    }

    @覆盖
    公共对象的getItem(INT位置){
        // TODO自动生成方法存根
        返回null;
    }

    @覆盖
    众长getItemId(INT位置){
        // TODO自动生成方法存根
        返回的位置;
    }

    @覆盖
    公共查看getView(INT位置,视图V,ViewGroup中父){
        // TODO自动生成方法存根


        LayoutInflater充气=(LayoutInflater)getApplicationContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        V = inflater.inflate(R.layout.calllist,父母,假);
        TextView中的TextView =(TextView中)v.findViewById(R.id.text);
        ImageView的ImageView的=(ImageView的)v.findViewById(R.id.image);
        textView.setText(alist.get(位置));
        串AA = pref.getString(RR,);
        串峰dd = pref.getString(重,);

        如果(aa.equals(0)){
            imageView.setImageResource(R.drawable.arrow);
        }
        其他 {
            imageView.setImageResource(R.drawable.arroww);
        }
        //imageView.setImageResource(R.drawable.arrow);

        // TextView的文字=(TextView的)v.findViewById(R.id.namee);


        /*if(arr.get(position))
        {
            imageView.setImageResource(R.drawable.arrow);
        }
        其他 {
            imageView.setImageResource(R.drawable.arroww);
        } * /


        返回伏;
       }

       }








  Recordservice.java



  *公共类RecordService
   延伸服务
   实现MediaRecorder.OnInfoListener,MediaRecorder.OnErrorListener
  {
  私有静态最后字符串变量=CallRecorder;
  //公共静态最后弦乐DEFAULT_STORAG​​E_LOCATION =/ SD卡/ callrecorder;
  公共静态最后弦乐DEFAULT_STORAG​​E_LOCATION =/ SD卡/安卓/数据/ com.callrecorder /录音;
  私有静态最终诠释RECORDING_NOTIFICATION_ID = 1;
  私人MediaRecorder记录= NULL;
  私人布尔isRecording = FALSE;
  私人字符串传入的;
  私人吐司的大小;
  公共静态文件记录= NULL ;;
  意向意图;
  私人文件makeOutputFile(共享preferences preFS)
  {
     文件DIR =新的文件(DEFAULT_STORAG​​E_LOCATION);
     //测试目录是否存在和可写
     如果(!dir.exists()){
        尝试 {
            dir.mkdirs();
        }赶上(例外五){
            Log.e(CallRecorder,RecordService:makeOutputFile无法创建目录+方向+:+ E);
            吐司T = Toast.makeText(getApplicationContext(),CallRecorder无法创建目录+方向+来存储录音:+ E,Toast.LENGTH_LONG);
            t.show();
            返回null;
         }
       } 其他 {
        如果(!dir.canWrite()){
            Log.e(TAG,RecordService:makeOutputFile没有写权限的目录:+方向);
            吐司T = Toast.makeText(getApplicationContext(),CallRecorder没有该目录的目录的写权限+方向+来存储录音,Toast.LENGTH_LONG);
            t.show();
            返回null;
         }
       }
       字符串preFIX =CAL;
       //字符串preFIX = PhoneListener.incoming;

       INT audiosource =的Integer.parseInt(prefs.getString(preferences preF_AUDIO_SOURCE,1));
        // preFIX + = - + audiosource;

        preFIX + =+ PhoneListener.incoming;
       字符串后缀=;
        INT AudioFormat的=的Integer.parseInt(prefs.getString(preferences preF_AUDIO_FORMAT,1));
       开关(AudioFormat的){
       案例MediaRecorder.OutputFormat.THREE_GPP:
        后缀=.3gpp;
        打破;
       案例MediaRecorder.OutputFormat.MPEG_4:
        后缀=.MPG;
        打破;
       案例MediaRecorder.OutputFormat.RAW_AMR:
        后缀=.AMR;
        打破;
       }
      尝试 {
        返回File.createTempFile(preFIX,后缀,DIR);
        }赶上(IOException异常E){
        Log.e(CallRecorder,RecordService:makeOutputFile无法创建临时文件+方向+:+ E);
         吐司T = Toast.makeText(getApplicationContext(),CallRecorder无法创建临时文件+方向+:+ E,Toast.LENGTH_LONG);
        t.show();
        返回null;
        }
         }
        公共无效的onCreate()
        {
       super.onCreate();
       记录=新MediaRecorder();
       Log.i(CallRecorder,的onCreate创建MediaRecorder对象);
       }
       @燮pressLint(ShowToast)
         公共无效ONSTART(意向意图,诠释startId){
        Log.i(CallRecorder,RecordService:onStartCommand时调用isRecording:+ isRecording);
      如果(isRecording)回报;
       上下文C = getApplicationContext();
      共享preferences preFS = preferenceManager.getDefaultShared preferences(C);
      布尔shouldRecord = prefs.getBoolean(preferences preF_RECORD_CALLS,假的。);
       如果(!shouldRecord){
        Log.i(CallRecord,RecordService:onStartCommand用preF_RECORD_CALLS假的,没有记录);
         返回;
        }
        INT audiosource =的Integer.parseInt(prefs.getString(preferences preF_AUDIO_SOURCE,1));
        INT AudioFormat的=的Integer.parseInt(prefs.getString(preferences preF_AUDIO_FORMAT,1));
         记录= makeOutputFile(preFS);
         如果(记录== NULL){
         记录= NULL;
         返回; //返回0;
        }
       Log.i(CallRecorder,RecordService将CONFIG MediaRecorder与audiosource:+ audiosource +AudioFormat的:+ AudioFormat的);
        尝试 {
        recorder.reset();
        recorder.setAudioSource(audiosource);
        Log.d(CallRecorder,设置audiosource+ audiosource);
        recorder.setOutputFormat(AudioFormat的);
        Log.d(CallRecorder,设置输出+ AudioFormat的);
        recorder.setAudioEn codeR(MediaRecorder.AudioEn coder.DEFAULT);
        Log.d(CallRecorder,设置连接codeR默认);
        recorder.setOutputFile(recording.getAbsolutePath());
        Log.d(CallRecorder,设置文件:+录音);
        recorder.setOnInfoListener(本);
        recorder.setOnErrorListener(本);
        尝试 {
            。录音机prepare();
        }赶上(java.io.IOException异常E){
            Log.e(CallRecorder,RecordService:ONSTART()IOException异常试图记录prepare()\ñ。);
            吐司T = Toast.makeText(getApplicationContext(),CallRecorder无法启动录音:+ E,Toast.LENGTH_LONG);
            t.show();
            记录= NULL;
            返回; //返回0; // START_STICKY;
        }
        Log.d(CallRecorder,录音机prepare()返回);
        recorder.start();
        isRecording = TRUE;
        Log.i(CallRecorder,recorder.start()返回);
        updateNotification(真正的);
        }赶上(java.lang.Exception的E){
        吐司T = Toast.makeText(getApplicationContext(),CallRecorder无法启动录音:+ E,Toast.LENGTH_LONG);
        t.show();
        Log.e(CallRecorder,RecordService:ONSTART陷入意外的异常,E);
        记录= NULL;
        }
        返回;
         }
         公共无效的onDestroy()
         {
         super.onDestroy();
         如果(NULL!=记录器){
        Log.i(CallRecorder,RecordService:的onDestroy调用recorder.release());
        isRecording = FALSE;
        recorder.release();
        长长度= recording.length();
        长度=长度/ 1024;
        Log.v(呼叫,pathh+ recording.getAbsolutePath()+长度+KB);
        如果(长度== 0)
        {
            Log.v(sizeeee,设置);
            Toast.makeText(getApplicationContext(),更改音频源设置,Toast.LENGTH_LONG).show();
            recording.delete();
            Log.v(文件,删除);
        }
        吐司T = Toast.makeText(getApplicationContext(),CallRecorder录完呼吁+录音,Toast.LENGTH_LONG);
        t.show();
        }
        updateNotification(假);
        }
        //方法来处理绑定的服务
        公众的IBinder onBind(意向意图)
        {
         返回null;
          }
        公共布尔onUnbind(意向意图)
       {
         返回false;
        }
      公共无效onRebind(意向意图)
       {
       }
      私人无效updateNotification(布尔状态)
       {
      上下文C = getApplicationContext();
     共享preferences preFS = preferenceManager.getDefaultShared preferences(C);
     字符串NS = Context.NOTIFICATION_SERVICE;
     NotificationManager mNotificationManager =(NotificationManager)getSystemService(NS);
       如果(状态){
        INT图标= R.drawable.ic_launcher;
        CharSequence的tickerText =录音电话+ prefs.getString(preferences preF_AUDIO_SOURCE,1);
        // CharSequence的tickerText =录音电话+ prefs.getString(preferences preF_AUDIO_SOURCE,1);
        时长= System.currentTimeMillis的();
        //通知的通知=新的通知(图标,tickerText时);
        通知通知=新的通知(图标,tickerText时);
        上下文的背景下= getApplicationContext();
        CharSequence的contentTitle =CallRecorder状态;
        CharSequence的contentText =录音电话......;
        意图notificationIntent =新的意图(这一点,RecordService.class);
        PendingIntent contentIntent = PendingIntent.getActivity(此,0,notificationIntent,0);
        notification.setLatestEventInfo(背景下,contentTitle,contentText,contentIntent);
        mNotificationManager.notify(RECORDING_NOTIFICATION_ID,通知);
          } 其他 {
        mNotificationManager.cancel(RECORDING_NOTIFICATION_ID);
        }
         }
         // MediaRecorder.OnInfoListener
         公共无效onInfo(MediaRecorder先生,诠释了什么,整型附加)
       {
           Log.i(CallRecorder,RecordService得到MediaRecorder onInfo回调什么:+什么+额外+另计);
    isRecording = FALSE;
        }
        // MediaRecorder.OnErrorListener
         公共无效onerror的(MediaRecorder先生,诠释了什么,整型附加)
          {
           Log.e(CallRecorder,RecordService得到MediaRecorder的onError回调什么:+什么+额外+另计);
          isRecording = FALSE;
          mr.release();
        }
        } *
 

解决方案

您必须营造出的的BroadcastReceiver 的。该接收器检测如果呼叫传入或传出。在那里,你可以记录您的来电。使用TelephonyManager类。而在清单中添加权限。

在连结与源 - code下载一个基本描述:的 的http://www.devlper.com/2010/08/detecting-incoming-and-outgoing-calls-in-android/

如果你的工作,你只需要创建一个Dictionary(HashMap中)。在那里,你可以设置字典键保存号码并传入或传出呼叫的键值。

获取熟悉自定义的ListView创建具有图像的ListView。http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/

创建2图像,传入和传出。 LOPP通过你的字典,并设置图像的权利。

问候

*I am developing recording application. In that it will record all incoming and outgoing calls and am displayed these calls in listview. I want to display separate symbols for incoming and outgoing recording files. How can i separate it. please provide solution. If possible provide source code. thank you.am new to android development.please can any one tell me the solution..

CallBroadCastReceiver.java

public class CallBroadcastReceiver extends BroadcastReceiver

{ public void onReceive(Context context, Intent intent) { Log.d("CallRecorder", "CallBroadcastReceiver:onReceive got Intent: " + intent.toString());

    if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
        String numberToCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);

        Log.d("CallRecorder", "CallBroadcastReceiver intent has EXTRA_PHONE_NUMBER: " + numberToCall);
    }
    PhoneListener phoneListener = new PhoneListener(context);
    TelephonyManager telephony = (TelephonyManager)
        context.getSystemService(Context.TELEPHONY_SERVICE);
    telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
    Log.d("PhoneStateReceiver:onReceive", "set PhoneStateListener");
}

}*

PhoneListener.java


public class PhoneListener extends PhoneStateListener

{ private Context context;

public PhoneListener(Context c) {
    Log.i("CallRecorder", "PhoneListener constructor");
    context = c;
}

public void onCallStateChanged (int state, String incomingNumber)
{
    Log.d("CallRecorder", "PhoneListener::onCallStateChanged state:" + state + " incomingNumber:" + incomingNumber);

    switch (state) {
    case TelephonyManager.CALL_STATE_IDLE:
        Log.d("CallRecorder", "CALL_STATE_IDLE, stoping recording");
        Boolean stopped = context.stopService(new Intent(context, RecordService.class));
        Log.i("CallRecorder", "stopService for RecordService returned " + stopped);
        break;
    case TelephonyManager.CALL_STATE_RINGING:
        Log.d("CallRecorder", "CALL_STATE_RINGING");
        break;
    case TelephonyManager.CALL_STATE_OFFHOOK:
        Log.d("CallRecorder", "CALL_STATE_OFFHOOK starting recording");
        Intent callIntent = new Intent(context, RecordService.class);
        ComponentName name = context.startService(callIntent);
        if (null == name) {
            Log.e("CallRecorder", "startService for RecordService returned null ComponentName");
        } else {
            Log.i("CallRecorder", "startService returned " + name.flattenToString());
        }
        break;
    }
}




  CallLog.java


  public class CallLoglist extends Activity 
  {
  private final String TAG = "CallRecorder";
  private ListView fileList = null;
  //public static ArrayAdapter<String> fAdapter = null;
  private SeekBar seekbar;
  private MediaPlayer mediaPlayer=new MediaPlayer();
  public static ImageButton pauseButton;
   public TextView startTimeField,endTimeField;
  AudioManager audioManager;
  public static final String STORAGE_LOCATIONN =  Environment.getExternalStorageDirectory()+"/Android/data/com.callrecorder/favourites";
  Handler seekHandler = new Handler();
  Dialog seekDialog;
  private Utilities utils;
  long totalDuration,currentDuration;
  public static ImageView img;
  String[] dlist;
  String recordlist;
  private list fAdapter;
  ArrayList<String> alist;
  Cursor managedCursor;
  StringBuffer sb;
  public String name;
  public String number;
  File source;
  CallLoglist cc;
  public static boolean ss;
  String phNumber;
  public static int a;
  public static Editor ed;
  public static SharedPreferences pref;

  public static  ArrayList<Boolean> arr= new ArrayList<Boolean>();

  private class CallItemClickListener implements AdapterView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
    {
        view.showContextMenu();

        CharSequence s = (CharSequence)parent.getItemAtPosition(position);
        Log.w(TAG, "CallLog just got an item clicked: " + s);

        //File f = new File(RecordService.DEFAULT_STORAGE_LOCATION + "/" + s.toString());


        /*boolean useMediaController = true;

        if (useMediaController) {
            Intent playIntent = new Intent(getApplicationContext(), CallPlayer.class); //Intent.ACTION_VIEW);
            Uri uri = Uri.fromFile(f);
            playIntent.setData(uri);
            startActivity(playIntent);

        } else {
            playFile(s.toString());
        }*/


      }
    }


         @SuppressLint("ShowToast")
      @Override
     public void onCreate(Bundle savedInstanceState) 
      {
         super.onCreate(savedInstanceState);
     audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
     setContentView(R.layout.call_log);
     fileList = (ListView)findViewById(R.id.play_file_list);
     img=(ImageView)findViewById(R.id.image);
     Context context = getApplicationContext();
     setVolumeControlStream(AudioManager.STREAM_MUSIC);
     utils=new Utilities();
     File dir = new File(RecordService.LOCATION);
     dlist = dir.list();
     alist=new ArrayList<String>(Arrays.asList(dlist));
     Log.v("fille", "recording file" +recordlist);
     fAdapter=new list(this,alist);
     fileList.setAdapter(fAdapter);
     fileList.setOnItemClickListener(new CallItemClickListener());
     registerForContextMenu(fileList);
     pref=getSharedPreferences("mm", MODE_PRIVATE);
     ed=pref.edit();
    /* ed.putString("rr", "R.drawable.arrow");
    ed.putString("re", "R.drawable.arroww");*/
    ed.commit();

    ////////////////

    /*String[] projection = new String[] {android.provider.CallLog.Calls.NUMBER, android.provider.CallLog.Calls.DATE, android.provider.CallLog.Calls.CACHED_NAME};
     Uri contacts =  android.provider.CallLog.Calls.CONTENT_URI;

     Cursor managedCursor = managedQuery(contacts, projection, null, null, android.provider.CallLog.Calls.DATE + " ASC");
     getColumnData(managedCursor);

     }

      private void getColumnData(Cursor cur){
       try{
        if (cur.moveToFirst()) {

            long date;
            int nameColumn = cur.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
            int numberColumn = cur.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
            int dateColumn = cur.getColumnIndex(android.provider.CallLog.Calls.DATE);

            System.out.println("Reading Call Details: ");
            do {
                name = cur.getString(nameColumn);
                number = cur.getString(numberColumn);
                date = cur.getLong(dateColumn);
                System.out.println(number + ":"+ new Date(date) +":"+name);


            } while (cur.moveToNext());
            }
           }

          finally{
              cur.close();
          }*/
          }




       public void onCreateContextMenu(ContextMenu menu, View v,
        ContextMenuInfo menuInfo) {
         // TODO Auto-generated method stub
      super.onCreateContextMenu(menu, v, menuInfo);
       MenuInflater m = getMenuInflater();  
        m.inflate(R.menu.nn, menu);

          }


      @SuppressLint({ "ShowToast", "SdCardPath" })
     @Override
     public boolean onContextItemSelected(MenuItem item) {
    // TODO Auto-generated method stub
    AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();  
    int index=info.position;
    recordlist=alist.get(index);

    //pp=dlist.
    switch(item.getItemId()){ 

    case R.id.play:

        seekDialog = new Dialog(this);  
        seekDialog.setTitle("play");  
        seekDialog.setContentView(R.layout.dialog); 
        startTimeField=(TextView)seekDialog.findViewById(R.id.textView1);
        endTimeField=(TextView)seekDialog.findViewById(R.id.textView2);
        pauseButton = (ImageButton)seekDialog.findViewById(R.id.imageButton2);
        seekbar = (SeekBar)seekDialog.findViewById(R.id.seek);
        seekDialog.show();

        Log.v("file", ""+index);
        if (mediaPlayer != null) {

            mediaPlayer.release();
        }

        /*mediaPlayer=MediaPlayer.create(this, Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath() 
                + "/Android/data/com.callrecorder/recordings/" +pathh ));*/
        mediaPlayer=MediaPlayer.create(this, Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath() 
                + "/Android/data/com.callrecorder/recordings/" +recordlist));
        mediaPlayer.start();
        seekUpdation();
        totalDuration=mediaPlayer.getDuration();
        seekbar.setMax((int) totalDuration);

        pauseButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if(mediaPlayer.isPlaying())
                {
                    mediaPlayer.pause();
                    pauseButton.setImageResource(R.drawable.play);
                    Toast.makeText(getApplicationContext(), "pause", 1000).show();
                }
                else
                {
                    mediaPlayer.start();
                    pauseButton.setImageResource(R.drawable.pause);
                    Toast.makeText(getApplicationContext(), "play", 1000).show();
                }

            }
        });

        seekDialog.setOnDismissListener(new OnDismissListener() {

            @Override
            public void onDismiss(DialogInterface dialog) {
                // TODO Auto-generated method stub
                mediaPlayer.release();

            }
        });

        seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                    boolean fromUser) {
                // TODO Auto-generated method stub
                if(fromUser)
                {
                    mediaPlayer.pause();
                    seekbar.setProgress(mediaPlayer.getCurrentPosition());
                    seekbar.setMax(mediaPlayer.getDuration());
                    mediaPlayer.seekTo(progress);
                    mediaPlayer.start();
                    pauseButton.setImageResource(R.drawable.pause);
                    seekUpdation();
                }
                }
              });

           break;
         case R.id.delete:
        Toast.makeText(getApplicationContext(), "delete", 1000).show();
        //new File(Environment.getExternalStorageDirectory()+"/callrecorder/" + pathh).delete();
        new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/com.callrecorder/recordings/" +recordlist).delete();
        alist.remove(index);
        alist.clear();
        fAdapter.notifyDataSetChanged();
        fAdapter.notifyDataSetInvalidated();

         break;

        case R.id.favorites:

        Toast.makeText(getApplicationContext(), "favouraties", 1000).show();
        source=new File(Environment.getExternalStorageDirectory() + "/Android/data/com.callrecorder/recordings/" +recordlist);

        File dir=new File(STORAGE_LOCATIONN);

        if(!dir.exists())
        {
            try {

                dir.mkdir();

            } catch (Exception e) {
                // TODO: handle exception

            }
        }

        try {
            InputStream in=new FileInputStream(source);
            OutputStream out = new FileOutputStream(STORAGE_LOCATIONN+"/"+recordlist);

            // Transfer bytes from in to out
            byte[] buf = new byte[1024];
            int len;

            while ((len = in.read(buf)) > 0){
                out.write(buf, 0, len);
            }
            in.close();
            out.close();


          } catch (Exception e) {
            // TODO: handle exception
            Log.v("copyyy", "errorrrrr");
         }
         source.delete();
         alist.remove(index);
         fAdapter.notifyDataSetChanged();
         fAdapter.notifyDataSetInvalidated();
         break;

          default:
         }
         return super.onContextItemSelected(item);
          }

           Runnable runn = new Runnable() { 
          @Override public void run() {

         try {
            seekUpdation();
         } catch (Exception e) {
            // TODO: handle exception
         }

         try {
            totalDuration = mediaPlayer.getDuration();
            currentDuration = mediaPlayer.getCurrentPosition();
            // Displaying Total Duration time
            endTimeField.setText(""+utils.milliSecondsToTimer(totalDuration));
            // Displaying time completed playing
            startTimeField.setText(""+utils.milliSecondsToTimer(currentDuration));
            seekbar.setProgress((int) currentDuration); //move seek bar
            // Updating progress bar
            /* int progress = (int)(utils.getProgressPercentage(currentDuration,totalDuration));
                  //Log.d("Progress", ""+progress);
                  seekbar.setProgress(progress);*/
            // seekHandler.postDelayed(this, 100);

            } catch (Exception e) {
            // TODO: handle exception
           }
          }
        };

        public void seekUpdation() {

          //seekbar.setProgress(mediaPlayer.getCurrentPosition());

         //mHandler.postDelayed(mUpdateTimeTask, 100); 
          seekHandler.postDelayed(runn, 1000);

          }
           public void onStart()
         {
            super.onStart();
        Log.i(TAG, "CallLog onStart");
           }

        public void onRestart()
          {
           super.onRestart();
           Log.i(TAG, "CallLog onRestart");
          }

       /*public void onResume()
         {
        super.onResume();
          //Log.i(TAG, "CallLog onResume about to load recording list again, does this work?");

           loadRecordingsFromDir();

            }*/

      @Override
       protected void onDestroy() {
            /*if(null!=mediaPlayer){
          mediaPlayer.release();
           }*/
         super.onDestroy();
         if(mediaPlayer!=null){
         //mediaPlayer.stop();
         mediaPlayer.release();
         mediaPlayer = null;

           }

             }


        ///////////////////////////////////////////


          private class list extends BaseAdapter
    {

    private CallLoglist callLog;
    private ArrayList<String> alist;

    public list(CallLoglist callLog, ArrayList<String> alist) {
        // TODO Auto-generated constructor stub
        this.callLog=callLog;
        this.alist=alist;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return alist.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    } 

    @Override
    public View getView(int position, View v, ViewGroup parent) {
        // TODO Auto-generated method stub


        LayoutInflater inflater = (LayoutInflater)getApplicationContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.calllist, parent, false);
        TextView textView = (TextView)v.findViewById(R.id.text);
        ImageView imageView = (ImageView)v.findViewById(R.id.image);
        textView.setText(alist.get(position));
        String aa=pref.getString("rr", "");
        String dd=pref.getString("re", "");

        if (aa.equals("0")) {
            imageView.setImageResource(R.drawable.arrow);
        }
        else {
            imageView.setImageResource(R.drawable.arroww);
        }
        //imageView.setImageResource(R.drawable.arrow);

        //TextView text=(TextView)v.findViewById(R.id.namee);


        /*if(arr.get(position))
        {
            imageView.setImageResource(R.drawable.arrow);
        }
        else {
            imageView.setImageResource(R.drawable.arroww);
        }*/


        return v;
       }

       }








  Recordservice.java  



  *public class RecordService 
   extends Service
   implements MediaRecorder.OnInfoListener, MediaRecorder.OnErrorListener
  {
  private static final String TAG = "CallRecorder";
  //public static final String DEFAULT_STORAGE_LOCATION = "/sdcard/callrecorder";
  public static final String            DEFAULT_STORAGE_LOCATION="/sdcard/Android/data/com.callrecorder/recordings";
  private static final int RECORDING_NOTIFICATION_ID = 1;
  private MediaRecorder recorder = null;
  private boolean isRecording = false;
  private String incoming;
  private Toast size;
  public static File recording = null;;
  Intent intent;
  private File makeOutputFile (SharedPreferences prefs)
  {
     File dir = new File(DEFAULT_STORAGE_LOCATION);
     // test dir for existence and writeability
     if (!dir.exists()) {
        try {
            dir.mkdirs();
        } catch (Exception e) {
            Log.e("CallRecorder", "RecordService:makeOutputFile unable to create directory " + dir + ": " + e);
            Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to create the directory " + dir + " to store recordings: " + e, Toast.LENGTH_LONG);
            t.show();
            return null;
         }
       } else {
        if (!dir.canWrite()) {
            Log.e(TAG, "RecordService:makeOutputFile does not have write permission for directory: " + dir);
            Toast t = Toast.makeText(getApplicationContext(), "CallRecorder does not have write permission for the directory directory " + dir + " to store recordings", Toast.LENGTH_LONG);
            t.show();
            return null;
         }
       }
       String prefix = "cal";
       //String prefix= PhoneListener.incoming;

       int audiosource = Integer.parseInt(prefs.getString(Preferences.PREF_AUDIO_SOURCE, "1"));
        //prefix += "-" + audiosource ;

        prefix+= "" +PhoneListener.incoming;
       String suffix = "";
        int audioformat = Integer.parseInt(prefs.getString(Preferences.PREF_AUDIO_FORMAT, "1"));
       switch (audioformat) {
       case MediaRecorder.OutputFormat.THREE_GPP:
        suffix = ".3gpp";
        break;
       case MediaRecorder.OutputFormat.MPEG_4:
        suffix = ".mpg";
        break;
       case MediaRecorder.OutputFormat.RAW_AMR:
        suffix = ".amr";
        break;
       }
      try {
        return File.createTempFile(prefix, suffix, dir);
        } catch (IOException e) {
        Log.e("CallRecorder", "RecordService:makeOutputFile unable to create temp file in " + dir + ": " + e);
         Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to create temp file in " + dir + ": " + e, Toast.LENGTH_LONG);
        t.show();
        return null;
        }
         }
        public void onCreate()
        {
       super.onCreate();
       recorder = new MediaRecorder();
       Log.i("CallRecorder", "onCreate created MediaRecorder object");
       } 
       @SuppressLint("ShowToast")
         public void onStart(Intent intent, int startId) {
        Log.i("CallRecorder", "RecordService:onStartCommand called while isRecording:" + isRecording);
      if (isRecording) return;
       Context c = getApplicationContext();
      SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
      Boolean shouldRecord = prefs.getBoolean(Preferences.PREF_RECORD_CALLS, false);
       if (!shouldRecord) {
        Log.i("CallRecord", "RecordService:onStartCommand with PREF_RECORD_CALLS false, not recording");
         return;
        }
        int audiosource = Integer.parseInt(prefs.getString(Preferences.PREF_AUDIO_SOURCE, "1"));
        int audioformat = Integer.parseInt(prefs.getString(Preferences.PREF_AUDIO_FORMAT, "1"));
         recording = makeOutputFile(prefs);
         if (recording == null) {
         recorder = null;
         return; //return 0;
        }
       Log.i("CallRecorder", "RecordService will config MediaRecorder with audiosource: " + audiosource + " audioformat: " + audioformat);
        try {
        recorder.reset();
        recorder.setAudioSource(audiosource);
        Log.d("CallRecorder", "set audiosource " + audiosource);
        recorder.setOutputFormat(audioformat);
        Log.d("CallRecorder", "set output " + audioformat);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
        Log.d("CallRecorder", "set encoder default");
        recorder.setOutputFile(recording.getAbsolutePath());
        Log.d("CallRecorder", "set file:" + recording);
        recorder.setOnInfoListener(this);
        recorder.setOnErrorListener(this);
        try {
            recorder.prepare();
        } catch (java.io.IOException e) {
            Log.e("CallRecorder", "RecordService:onStart() IOException attempting recorder.prepare()\n");
            Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to start recording: " + e, Toast.LENGTH_LONG);
            t.show();
            recorder = null;
            return; //return 0; //START_STICKY;
        }
        Log.d("CallRecorder", "recorder.prepare() returned");
        recorder.start();
        isRecording = true;
        Log.i("CallRecorder", "recorder.start() returned");
        updateNotification(true);
        } catch (java.lang.Exception e) {
        Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to start recording: " + e, Toast.LENGTH_LONG);
        t.show();
        Log.e("CallRecorder", "RecordService:onStart caught unexpected exception", e);
        recorder = null;
        }
        return; 
         }
         public void onDestroy()
         {
         super.onDestroy();
         if (null != recorder) {
        Log.i("CallRecorder", "RecordService:onDestroy calling recorder.release()");
        isRecording = false;
        recorder.release();
        long length=recording.length();
        length=length/1024;
        Log.v("call",  "pathh" +recording.getAbsolutePath()  + length + "KB" );
        if(length==0)
        { 
            Log.v("sizeeee", "settings");
            Toast.makeText(getApplicationContext(), "change the audio source settings", Toast.LENGTH_LONG).show();
            recording.delete();
            Log.v("file", "delete");
        }
        Toast t = Toast.makeText(getApplicationContext(), "CallRecorder finished recording call to" + recording, Toast.LENGTH_LONG);
        t.show();
        }
        updateNotification(false);
        }
        // methods to handle binding the service
        public IBinder onBind(Intent intent)
        {
         return null;
          }
        public boolean onUnbind(Intent intent)
       {
         return false;
        }
      public void onRebind(Intent intent)
       {
       }
      private void updateNotification(Boolean status)
       {
      Context c = getApplicationContext();
     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
     String ns = Context.NOTIFICATION_SERVICE;
     NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
       if (status) {
        int icon = R.drawable.ic_launcher;
        CharSequence tickerText = "Recording call " + prefs.getString(Preferences.PREF_AUDIO_SOURCE, "1");
        //CharSequence tickerText = "Recording call " + prefs.getString(Preferences.PREF_AUDIO_SOURCE, "1");
        long when = System.currentTimeMillis();
        //Notification notification = new Notification(icon, tickerText, when);
        Notification notification=new Notification(icon,tickerText,when);
        Context context = getApplicationContext();
        CharSequence contentTitle = "CallRecorder Status";
        CharSequence contentText = "Recording call...";
        Intent notificationIntent = new Intent(this, RecordService.class);
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
        notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
        mNotificationManager.notify(RECORDING_NOTIFICATION_ID, notification);
          } else {
        mNotificationManager.cancel(RECORDING_NOTIFICATION_ID);
        }
         }
         // MediaRecorder.OnInfoListener
         public void onInfo(MediaRecorder mr, int what, int extra)
       {
           Log.i("CallRecorder", "RecordService got MediaRecorder onInfo callback with what: " + what + " extra: " + extra);
    isRecording = false;
        }
        // MediaRecorder.OnErrorListener
         public void onError(MediaRecorder mr, int what, int extra) 
          {
           Log.e("CallRecorder", "RecordService got MediaRecorder onError callback with what: " + what + " extra: " + extra);
          isRecording = false;
          mr.release();
        }
        }*

解决方案

You would have to create a a broadcastreceiver. The receiver detects if an call is incoming or outgoing. There you can record your calls. Use TelephonyManager Class. And add permissions in the manifest.

In the link is a basic description with source-code download: http://www.devlper.com/2010/08/detecting-incoming-and-outgoing-calls-in-android/

If you get that working, you just would have to create a Dictionary(HashMap). There you could set the dictionary-key to save numbers and a key-value for incoming or outgoing calls.

Get familiar with custom ListView to create a ListView with an image. http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/

Create 2 images, incoming and outgoing. Lopp through your dictionary and set the images right.

Greets

这篇关于我怎么可以单独在列表视图中的Andr​​oid呼入呼​​出记录文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆