服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android采用消息推送实现类似微信视频接听

Android采用消息推送实现类似微信视频接听

2022-11-08 14:33jiabaokang Android

这篇文章主要为大家详细介绍了Android采用消息推送实现类似微信视频接听,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Android实现类似微信视频接听的具体代码,供大家参考,具体内容如下

1、背景需求:业务需要接入视频审核功能,在PC 端发起视频通话,移动端显示通话界面点击接听后进行1对1视频通话。

2、解决方案:因为项目没有IM功能。只集成了极光消息推送(极光消息推送接入参考官方文档,经过跟需求沟通,采用消息推送调起通话接听界面。再集成腾讯实时音视频SDK(具体集成方式参考官方文档)。最终实现类似微信1对1通话功能。

3、技术实现:

A:编写一个广播接收器,并且在 AndroidManifest中注册,这就是一个全局的广播接收器。应用退到后台或者应用进程被kill,只要极光的push进程是Live,就能接受到消息,启动通话接听界面。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
 * Created on 2018/3/29 16:19
 * @author baokang.jia
 * 极光推送广播接收器
 */
public class JiGuangPushReceiver extends BroadcastReceiver {
  private static final String TAG = "JPushReceiver";
  @Override
  public void onReceive(Context context, Intent intent) {
    Bundle bundle = intent.getExtras();
    if (bundle == null) {
      return;
    }
    //拿到锁屏管理者
    KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
    if (km != null && km.isKeyguardLocked()) {  //为true就是锁屏状态下
      startLoginOrCallActivity(context,bundle);
    } else {
      if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
        String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);
        LogUtil.d(TAG, "[MyReceiver] 接收Registration Id : " + regId);
        //send the Registration Id to yours server...
      } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
        LogUtil.d(TAG, "[MyReceiver] 接收到推送下来的自定义消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));
      } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {//接收到推送下来的通知
        //启动通话界面
        startLoginOrCallActivity(context, bundle);
      } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {//点击通知栏
        //启动通话界面
        startLoginOrCallActivity(context, bundle);
        //清除所有状态的通知
        JPushInterface.clearAllNotifications(context);
      } else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction())) {
        LogUtil.d(TAG, "[MyReceiver] 用户收到到RICH PUSH CALLBACK: " + bundle.getString(JPushInterface.EXTRA_EXTRA));
        //在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码,比如打开新的Activity, 打开一个网页等..
      }
    }
  }
 
  /**
   * 未登录跳转登录界面,
   * else 启动通话接听界面
   */
  private void startLoginOrCallActivity(Context context, Bundle bundle) {
    //EXTRA_EXTRA
    String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
    String userID = SPUtil.getString(context, Constants.LOGIN_USER_ID);
    if (TextUtils.isEmpty(userID)) {
      //启动登录界面
      Intent intent = new Intent(context, LoginActivity.class);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      context.startActivity(intent);
    } else {
      //启动通话接听界面
      int notifyId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);
      if (!TextUtils.isEmpty(extras) && extras.contains("androidNotification extras key")){
        ReceiveTalkActivity.startReceiveTalkActivity(context, extras,notifyId);
      }
    }
  }
 }
//在AndroidManifest注册全局自定义广播接收器
<receiver
      android:name=".event.JiGuangP`在这里插入代码片`ushReceiver"
      android:enabled="true"
      android:exported="false">
      <intent-filter>
        <action android:name="cn.jpush.android.intent.REGISTRATION" /> <!-- Required 用户注册SDK的intent -->
        <action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" /> <!-- Required 用户接收SDK消息的intent -->
        <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" /> <!-- Required 用户接收SDK通知栏信息的intent -->
        <action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" /> <!-- Required 用户打开自定义通知栏的intent -->
        <action android:name="cn.jpush.android.intent.CONNECTION" /> <!-- 接收网络变化 连接/断开 since 1.6.3 -->
        <category android:name="${PACKAGE_NAME}" />
      </intent-filter>
    </receiver>

B:启动通话接听界面,启动接听界面后获取当前手机模式

?
1
2
3
AudioManager audio = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
//手机模式,振动,精英、响铃,更具不同模式振动或者响铃,具体可参考以下的实现代码。
//点击接听按钮后跳转腾讯视频通话界面
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/**
 * Created on 2019/4/28 16:19
 * @author baokang.jia
 * 视频预审接听界面
 */
public class ReceiveTalkActivity extends BaseActivity {
 
  private static String PUSH_MSG_KEY = "push_msg_key";
 
  private static String NOTIFICATION_ID_KEY = "notification_id_key";
 
  /**
   * 腾讯云注册分配的appId
   */
  private int sdkAppId =
 
  /**
   * 检查运行时权限
   */
  private boolean mCheckPermissionResult = false;
 
  private PushMsgBean mPushMsgBean;
  /**
   * 媒体播放
   */
  private MediaPlayer mMediaPlayer;
 
  /**
   * 震动
   */
  private Vibrator mVibrator;
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    Window window = getWindow();
    //悬浮窗
    WindowViewUtil.setWindowFloatAndScreenOn(window,this);
    super.onCreate(savedInstanceState);
 
    //初始化倒计时器
    initCountDownTimer();
    //请求权限
    requestMustPermission();
    initViews();
    //根据通知Id清除状态栏对应的通知
    JPushInterface.clearAllNotifications(this);
    //持续震动和响铃
    continuedVibratorAndMediaPlayer();
  }
 
  /**
   * 60秒后关闭activity
   */
  private void initCountDownTimer() {
    long time = 30000;
    long countDownInterval = 1000;
    CountDownTimer downTimer = new CountDownTimer(time, countDownInterval) {
      @Override
      public void onTick(long millisUntilFinished) {
      }
 
      @Override
      public void onFinish() {
        finish();
      }
    };
    downTimer.start();
  }
 
  @Override
  protected int getLayoutId() {
    return R.layout.activity_receive_talk;
  }
 
  @Override
  protected boolean initToolbar() {
    return false;
  }
 
  @Override
  protected void getIntent(Intent intent) {
    String pushMsg = getIntent().getStringExtra(PUSH_MSG_KEY);
    //notificationId = getIntent().getIntExtra(NOTIFICATION_ID_KEY, 0);
    parsePushMsg(pushMsg);
  }
 
  @Override
  protected void initViews() {
    Button btnCancel = findViewById(R.id.btn_cancel_call);
    Button btnAnswer = findViewById(R.id.btn_answer_call);
 
    btnCancel.setOnClickListener(v ->{
      mVibrator.cancel();
      mMediaPlayer.stop();
      finish();
    });
 
    btnAnswer.setOnClickListener(v -> {
      mVibrator.cancel();
      mMediaPlayer.stop();
      if (mCheckPermissionResult) {
        Intent intent = new Intent(this, TRTCMainActivity.class);
        intent.putExtra("roomId", Integer.valueOf(mPushMsgBean.getRoomId()));
        intent.putExtra("userId", mPushMsgBean.getUserId());
        intent.putExtra("sdkAppId", sdkAppId);
        intent.putExtra("userSig", mPushMsgBean.getUserSig());
        startActivity(intent);
        finish();
      } else {
        ToastUtil.longToast("需要的权限被拒绝,无法开启视频审核");
      }
    });
  }
 
  /**
   * 持续响铃和震动
   */
  private void continuedVibratorAndMediaPlayer() {
 
    //获取媒体播放器
    mMediaPlayer = new MediaPlayer();
    try {
      mMediaPlayer.setDataSource(this, RingtoneManager
          .getDefaultUri(RingtoneManager.TYPE_RINGTONE));//这里我用的通知声音,还有其他的,大家可以点进去看
      mMediaPlayer.prepare();
    } catch (IOException e) {
      e.printStackTrace();
    }
 
    //取得震动服务的句柄
    mVibrator = (Vibrator)this. getSystemService(VIBRATOR_SERVICE);
 
    //获取当前手机模式
    AudioManager audio = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
    if (audio != null) {
      switch (audio.getRingerMode()) {
        case AudioManager.RINGER_MODE_SILENT://静音
          //do sth
          break;
        case AudioManager.RINGER_MODE_NORMAL://响铃
          mMediaPlayer.start();
          mMediaPlayer.setLooping(true); //循环播放
          break;
        case AudioManager.RINGER_MODE_VIBRATE://震动
          //数组参数意义:第一个参数为等待指定时间后开始震动,
          //震动时间为第二个参数。后边的参数依次为等待震动和震动的时间
          //第二个参数为重复次数,-1为不重复,0为一直震动
          if (mVibrator != null) {
            mVibrator.vibrate( new long[]{1000,1000},0);
          }
          break;
      }
    }
  }
 
  private void parsePushMsg(String pushMsg) {
    if (!TextUtils.isEmpty(pushMsg)) {
      CustomerMsg customerMsg = GsonUtil.fromJson(pushMsg, CustomerMsg.class);
      String pushMsgContent = customerMsg.getPushMsgContent();
      pushMsgContent = pushMsgContent.replace("\\", "");
      LogUtil.d(Constants.LOG,"pushMsgContent="+pushMsgContent);
      mPushMsgBean = GsonUtil.fromJson(pushMsgContent, PushMsgBean.class);
    }
  }
 
  /**
   * 申请应用必须的权限
   */
  private void requestMustPermission() {
    AndPermission.with(this)
        .requestCode(Constants.REQUEST_CODE_PERMISSION)
        .permission(
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA,
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.VIBRATE,
            Manifest.permission.DISABLE_KEYGUARD,
            Manifest.permission.WAKE_LOCK
        )
        .rationale((requestCode, rationale) ->
            //再次申请被拒绝的权限
            AlertDialog.newBuilder(this)
                .setTitle(R.string.title_dialog)
                .setMessage(R.string.message_permission_failed)
                .setPositiveButton(R.string.ok, (dialog, which) -> {
                  dialog.cancel();
                  rationale.resume();
                })
                .setNegativeButton(R.string.no, (dialog, which) -> {
                  dialog.cancel();
                  rationale.cancel();
                }).show())
        .callback(new PermissionListener() {
          @Override
          public void onSucceed(int requestCode, @NonNull List<String> grantPermissions) {
            mCheckPermissionResult = true;
          }
 
          @Override
          public void onFailed(int requestCode, @NonNull List<String> deniedPermissions) {
            mCheckPermissionResult = false;
          }
        })
        .start();
  }
 
  /**
   * 界面未销毁,启动此界面时回调
   */
  @Override
  protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    String pushMsg = intent.getStringExtra(PUSH_MSG_KEY);
    //notificationId = intent.getIntExtra(NOTIFICATION_ID_KEY, 0);
    parsePushMsg(pushMsg);
  }
 
  /**
   * 提供给外部调用启动接听界面的activity
   *
   * @param cex   上下文对象
   * @param pushMsg 消息内容
   * @param notifyId 通知id
   */
  public static void startReceiveTalkActivity(Context cex, String pushMsg, int notifyId) {
    Intent calIntent = new Intent(cex, ReceiveTalkActivity.class);
    //携带数据
    calIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    calIntent.putExtra(PUSH_MSG_KEY, pushMsg);
    calIntent.putExtra(NOTIFICATION_ID_KEY, notifyId);
    cex.startActivity(calIntent);
  }
 
  @Override
  protected void onDestroy() {
    super.onDestroy();
    mMediaPlayer.stop();
    mVibrator.cancel();
  }
}
 
//注册ReceiveTalkActivity, android:launchMode="singleTask"
<activity android:name=".trtc.view.ReceiveTalkActivity"
      android:launchMode="singleTask"
      android:screenOrientation="portrait"
      />

总结:项目中考虑时间和成本问题。没有接入IM功能。消息推送不可靠,极光的push进程被杀,是收不到消息。当打开app后,会蹦出很多通知。这只是简易的实现了在pc调起移动端进行视频通话。这有很多因素是没有考虑进去的,在此先记录下吧。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/jiabaokang/article/details/91371123

延伸 · 阅读

精彩推荐