• ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION


     java.lang.SecurityException:  Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION


    对services配置:

    <service
    android:name=".ScreenRecorder"
    android:enabled="true"
    android:foregroundServiceType="mediaProjection"/>
    MediaProjection获取屏幕数据主要是三步

    1.//准备MediaProjection
    mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
    Intent captureIntent = mMediaProjectionManager.createScreenCaptureIntent();
    startActivityForResult(captureIntent, 1);
    2.在回调中将数据用intent传递到services中
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.e(TAG, "onActivityResult: " + resultCode);
    if (resultCode == Activity.RESULT_CANCELED) {
    Log.e(TAG, "User cancel");
    } else {

    try {
    WindowManager mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
    DisplayMetrics metrics = new DisplayMetrics();
    mWindowManager.getDefaultDisplay().getMetrics(metrics);
    } catch (Exception e){
    Log.e(TAG, "MediaProjection error");
    }

    Intent service = new Intent(this, ScreenRecorder.class);
    service.putExtra("code", resultCode);
    service.putExtra("data", data);
    startForegroundService(service);

    }
    }
    3.mediaprojection必须在services中进行。
    @Override
    public int onStartCommand(final Intent intent, int flags, int startId) {
    createNotificationChannel();

    mResultCode = intent.getIntExtra("code", -1);
    mResultData = intent.getParcelableExtra("data");
    //mResultData = intent.getSelector();

    mMediaProjection = mMediaProjectionManager.getMediaProjection(mResultCode, Objects.requireNonNull(mResultData));
    //mMediaProjection = ((MediaProjectionManager) Objects.requireNonNull(getSystemService(Context.MEDIA_PROJECTION_SERVICE))).getMediaProjection(mResultCode, mResultData);
    Log.e(TAG, "mMediaProjection created: " + mMediaProjection);

    return super.onStartCommand(intent, flags, startId);
    }
    最后就可以通过mMediaProjection.createVirtualDisplay获取屏幕数据啦。

    private void createNotificationChannel() {
    Notification.Builder builder = new Notification.Builder(this.getApplicationContext()); //获取一个Notification构造器
    Intent nfIntent = new Intent(this, MainActivity.class); //点击后跳转的界面,可以设置跳转数据

    builder.setContentIntent(PendingIntent.getActivity(this, 0, nfIntent, 0)) // 设置PendingIntent
    .setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher)) // 设置下拉列表中的图标(大图标)
    //.setContentTitle("SMI InstantView") // 设置下拉列表里的标题
    .setSmallIcon(R.mipmap.ic_launcher) // 设置状态栏内的小图标
    .setContentText("is running......") // 设置上下文内容
    .setWhen(System.currentTimeMillis()); // 设置该通知发生的时间

    /*以下是对Android 8.0的适配*/
    //普通notification适配
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    builder.setChannelId("notification_id");
    }
    //前台服务notification适配
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    NotificationChannel channel = new NotificationChannel("notification_id", "notification_name", NotificationManager.IMPORTANCE_LOW);
    notificationManager.createNotificationChannel(channel);
    }

    Notification notification = builder.build(); // 获取构建好的Notification
    notification.defaults = Notification.DEFAULT_SOUND; //设置为默认的声音
    startForeground(110, notification);

  • 相关阅读:
    构造方法
    封装 private
    局部变量和成员变量区别
    IOC
    Linux端口占用查询命令
    Nginx小白入门实战
    SQL left join right join inner join之间的区别
    IDEA导入maven工程时,不会自动识别怎么办
    Spring中Controller层中的method显示为灰色并且提示method is never used的原因
    查看服务器公网IP
  • 原文地址:https://www.cnblogs.com/endv/p/16109507.html
Copyright © 2020-2023  润新知