服务中的Android MediaProjectionManager

时间:2015-09-03 16:55:38

标签: android service broadcastreceiver android-mediaprojection

我想构建一个应用程序,我必须在服务中使用MediaProjectionManager。但是我无法解决它作为“startActivityForResult'无法在服务类中使用。

3 个答案:

答案 0 :(得分:11)

我真的想从服务中做到这一点,这就是我发现这个问题的方法。这是我最接近的,所以把它扔到那里,直到更好的答案出现。这是一种从与服务相似的活动中实现这一目标的方法:

import static your.package.YourClass.mediaProjectionManager;

public class MainActivity extends Activity {

@Override
protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(null);
    mediaProjectionManager = (MediaProjectionManager)getContext().getSystemService(MEDIA_PROJECTION_SERVICE);
    startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), 1);
    }

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 1) {
        if (resultCode == Activity.RESULT_OK) {
            mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
            this.finish();
        }
    }
}

然后在你的服务中,当你需要许可电话时

private void openMainActivity() {
    Intent mainIntent = new Intent(getContext(), MainActivity.class);
    mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(mainIntent);
    }

使活动在AndroidManifest.xml中不可见

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoDisplay"
        android:excludeFromRecents="true"
        android:screenOrientation="portrait">
    </activity>

警告:

短暂的一次,您进行过屏幕检查的应用程序将失去焦点。

短暂的一秒钟,你的应用程序将成为前台应用程序,所以不要错过你自己的鞋带

答案 1 :(得分:0)

好吧,我设法做到这一点,不是最干净的方式,而是有效:

  1. 本地绑定服务:将您的服务设为Local Bound Service,这意味着您的服务会将自己的引用传递给主要活动。
  2. 将活动实例传递给服务:将您的活动参考传递给服务连接中的服务 - &gt; Activity类
  3. 中的onServiceConnected()
  4. 调用startActivityForResult :使用服务中的活动实例调用startActivityForResult函数。
  5. 注意: 在被调用时,startActivityForResult将被捕获在Activity类的onActivityResult()中。您需要在Activity中覆盖此函数,并使用服务引用返回到服务类。您也可以在完成后从服务中取消绑定活动。

    我希望这是有道理的,抱歉不包含任何代码。如果您有任何问题,我很乐意为您提供更详细的帮助。

答案 2 :(得分:0)

我在这里使用了相同的方法https://medium.com/@debuggingisfun/android-10-audio-capture-77dd8e9070f9
在我的活动中:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Intent intent = new Intent(this, MediaProjectionService.class);
    startForegroundService(intent);
    mProjectionManager =
            (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
    startActivityForResult(mProjectionManager.createScreenCaptureIntent(),
            1);
}

服务本身只是一个样板,如果要在前台运行,则需要通知

class MediaProjectionService : Service() {

    override fun onCreate() {
        super.onCreate()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val builder = NotificationCompat.Builder(this, "messages")
                    .setContentText("streaming enabled")
                    .setContentTitle("Stream to e-ink")
            startForeground(101, builder.build())
        }
    }

    override fun onBind(intent: Intent): IBinder? {
        return null
    }
}

我不是Android专家,而且我正在使用Flutter-显然,您还需要先创建一个通知通道-这是我的Flutter应用程序代码-可能与非Flutter类似

class StreaminkApplication : FlutterApplication() {
    override fun onCreate() {
        super.onCreate()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel("messages", "Messages", NotificationManager.IMPORTANCE_LOW)
            val manager = getSystemService(NotificationManager::class.java)
            manager.createNotificationChannel(channel)
        }
    }
}

如果您使用应用程序,则应在清单中进行更改-就我而言:

<application
    android:name=".StreaminkApplication"