- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下代码,它应该使用服务记录设备屏幕。
问题是,要使用它,我需要使用如下调用:startActivityForResult/onActivityResult
,以获得能够录制屏幕的权限。
但是在 Android Service 上没有这样的调用。
我必须开始这样的事情:
startActivityForResult (mProjectionManager.createScreenCaptureIntent (), CAST_PERMISSION_CODE);
代码:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != CAST_PERMISSION_CODE) {
Log.w("class:", "Unknown request code: " + requestCode);
return;
}
Log.w("class:", "onActivityResult:resultCode");
if (resultCode != RESULT_OK) {
startRec = false;
Toast.makeText(this, "Screen Cast Permission Denied :(", Toast.LENGTH_SHORT).show();
return;
}
prepareRecording("start");
mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
Log.w("class:", "onActivityResult:mMediaProjection");
// TODO Register a callback that will listen onStop and release & prepare the recorder for next WidgetProvider
// mMediaProjection.registerCallback(callback, null);
mVirtualDisplay = getVirtualDisplay();
mMediaRecorder.start();
}
我如何提出建议?
完整代码:
package com.unkinstagram;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Environment;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import static android.app.Activity.RESULT_OK;
class Constants {
public interface ACTION {
public static String MAIN_ACTION = "com.unkinstagram.action.main";
public static String STARTFOREGROUND_ACTION = "com.unkinstagram.action.startforeground";
public static String STOPFOREGROUND_ACTION = "com.unkinstagram.action.stopforeground";
public static String REC_ACTION = "com.unkinstagram.action.rec";
public static String STOP_ACTION = "com.unkinstagram.action.stop";
}
public interface NOTIFICATION_ID {
public static int FOREGROUND_SERVICE = 101;
}
}
public class ForegroundService extends Service {
private static final String LOG_TAG = "class:";
private static final int CAST_PERMISSION_CODE = 22;
private DisplayMetrics mDisplayMetrics;
private MediaProjection mMediaProjection;
private VirtualDisplay mVirtualDisplay;
private MediaRecorder mMediaRecorder;
private MediaProjectionManager mProjectionManager;
private boolean startRec = false;
@Override
public void onCreate() {
super.onCreate();
mDisplayMetrics = new DisplayMetrics();
mMediaRecorder = new MediaRecorder();
mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
window.getDefaultDisplay().getMetrics(mDisplayMetrics);
Log.v(LOG_TAG,"create");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Start Foreground Intent ");
Intent notificationIntent = new Intent(this, MainActivity2.class);
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Intent recIntent = new Intent(this, ForegroundService.class);
recIntent.setAction(Constants.ACTION.REC_ACTION);
PendingIntent pRecIntent = PendingIntent.getService(this, 0, recIntent, 0);
Intent stopIntent = new Intent(this, ForegroundService.class);
stopIntent.setAction(Constants.ACTION.STOP_ACTION);
PendingIntent pStopIntent = PendingIntent.getService(this, 0, stopIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Stai per registrare lo schermo del device.")
.setSmallIcon(R.drawable.ic_videocam_off)
.setContentIntent(pendingIntent)
.setOngoing(true)
.addAction(0, "Rec", pRecIntent)
.addAction(0, "Stop", pStopIntent)
.build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, notification);
} else if (intent.getAction().equals(Constants.ACTION.REC_ACTION)) {
Log.i(LOG_TAG, "Clicked Rec");
startRecording();
} else if (intent.getAction().equals(Constants.ACTION.STOP_ACTION)) {
Log.i(LOG_TAG, "Clicked Stop");
stopRecording();
stopForeground(true);
stopSelf();
} else if (intent.getAction().equals(Constants.ACTION.STOPFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Stop Foreground Intent");
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(LOG_TAG, "In onDestroy");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void startRecording() {
startRec = true;
// If mMediaProjection is null that means we didn't get a context, lets ask the user
Log.w("class:", "startRecording:start");
if (mMediaProjection == null) {
// This asks for user permissions to capture the screen
Log.w("class:", "startRecording:startResult");
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), CAST_PERMISSION_CODE);
Log.w("class:", "startRecording:endResult");
return;
}
Log.w("class:", "startRecording:end");
mVirtualDisplay = getVirtualDisplay();
mMediaRecorder.start();
}
private void stopRecording() {
startRec = false;
Log.w("class:", "stopRecording:start");
if (mMediaRecorder != null) {
mMediaRecorder.stop();
mMediaRecorder.reset();
//mMediaRecorder = null;
}
if (mVirtualDisplay != null) {
mVirtualDisplay.release();
//mVirtualDisplay = null;
}
if (mMediaProjection != null) {
mMediaProjection.stop();
//mMediaProjection = null;
}
Log.w("class:", "stopRecording:end");
}
public String getCurSysDate() {
return new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(new Date());
}
private void prepareRecording(String name) {
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
Toast.makeText(this, "Failed to get External Storage", Toast.LENGTH_SHORT).show();
return;
}
final String directory = Environment.getExternalStorageDirectory() + File.separator + "Recordings";
final File folder = new File(directory);
boolean success = true;
if (!folder.exists()) {
success = folder.mkdir();
}
if (!success) {
Toast.makeText(this, "Failed to create Recordings directory", Toast.LENGTH_SHORT).show();
return;
}
String videoName = (name + "_" + getCurSysDate() + ".mp4");
String filePath = directory + File.separator + videoName;
int width = mDisplayMetrics.widthPixels;
int height = mDisplayMetrics.heightPixels;
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoEncodingBitRate(8000 * 1000);
mMediaRecorder.setVideoFrameRate(24);
mMediaRecorder.setVideoSize(width, height);
mMediaRecorder.setOutputFile(filePath);
try {
mMediaRecorder.prepare();
} catch (Exception e) {
e.printStackTrace();
return;
}
}
private VirtualDisplay getVirtualDisplay() {
int screenDensity = mDisplayMetrics.densityDpi;
int width = mDisplayMetrics.widthPixels;
int height = mDisplayMetrics.heightPixels;
return mMediaProjection.createVirtualDisplay(this.getClass().getSimpleName(),
width, height, screenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mMediaRecorder.getSurface(), null, null);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != CAST_PERMISSION_CODE) {
Log.w("class:", "Unknown request code: " + requestCode);
return;
}
Log.w("class:", "onActivityResult:resultCode");
if (resultCode != RESULT_OK) {
startRec = false;
Toast.makeText(this, "Screen Cast Permission Denied :(", Toast.LENGTH_SHORT).show();
return;
}
prepareRecording("start");
mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
Log.w("class:", "onActivityResult:mMediaProjection");
// TODO Register a callback that will listen onStop and release & prepare the recorder for next WidgetProvider
// mMediaProjection.registerCallback(callback, null);
mVirtualDisplay = getVirtualDisplay();
mMediaRecorder.start();
}
}
最佳答案
所以您想在服务中使用 MediaProjection。要使用MediaProjection,需要用户授予权限,然后使用onActivityResult中返回的Intent创建MediaProjection。但是,您正在使用服务,并且没有可用的 onActivityResult。
这是一个有用的 github 问题:https://github.com/mtsahakis/MediaProjectionDemo/issues/7 。还有一些您可以使用的要点。
基本思想是使用 Activity 来请求权限,然后使用包装结果 Intent 的 Intent 启动服务(Intent 也是一个 parceable,因此可以将其放入另一个 Intent 中)。
关于java - 在服务中实现 onActivityResult(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54022097/
背景: 我最近一直在使用 JPA,我为相当大的关系数据库项目生成持久层的轻松程度给我留下了深刻的印象。 我们公司使用大量非 SQL 数据库,特别是面向列的数据库。我对可能对这些数据库使用 JPA 有一
我已经在我的 maven pom 中添加了这些构建配置,因为我希望将 Apache Solr 依赖项与 Jar 捆绑在一起。否则我得到了 SolarServerException: ClassNotF
interface ITurtle { void Fight(); void EatPizza(); } interface ILeonardo : ITurtle {
我希望可用于 Java 的对象/关系映射 (ORM) 工具之一能够满足这些要求: 使用 JPA 或 native SQL 查询获取大量行并将其作为实体对象返回。 允许在行(实体)中进行迭代,并在对当前
好像没有,因为我有实现From for 的代码, 我可以转换 A到 B与 .into() , 但同样的事情不适用于 Vec .into()一个Vec . 要么我搞砸了阻止实现派生的事情,要么这不应该发
在 C# 中,如果 A 实现 IX 并且 B 继承自 A ,是否必然遵循 B 实现 IX?如果是,是因为 LSP 吗?之间有什么区别吗: 1. Interface IX; Class A : IX;
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在阅读标准haskell库的(^)的实现代码: (^) :: (Num a, Integral b) => a -> b -> a x0 ^ y0 | y0 a -> b ->a expo x0
我将把国际象棋游戏表示为 C++ 结构。我认为,最好的选择是树结构(因为在每个深度我们都有几个可能的移动)。 这是一个好的方法吗? struct TreeElement{ SomeMoveType
我正在为用户名数据库实现字符串匹配算法。我的方法采用现有的用户名数据库和用户想要的新用户名,然后检查用户名是否已被占用。如果采用该方法,则该方法应该返回带有数据库中未采用的数字的用户名。 例子: “贾
我正在尝试实现 Breadth-first search algorithm , 为了找到两个顶点之间的最短距离。我开发了一个 Queue 对象来保存和检索对象,并且我有一个二维数组来保存两个给定顶点
我目前正在 ika 中开发我的 Python 游戏,它使用 python 2.5 我决定为 AI 使用 A* 寻路。然而,我发现它对我的需要来说太慢了(3-4 个敌人可能会落后于游戏,但我想供应 4-
我正在寻找 Kademlia 的开源实现C/C++ 中的分布式哈希表。它必须是轻量级和跨平台的(win/linux/mac)。 它必须能够将信息发布到 DHT 并检索它。 最佳答案 OpenDHT是
我在一本书中读到这一行:-“当我们要求 C++ 实现运行程序时,它会通过调用此函数来实现。” 而且我想知道“C++ 实现”是什么意思或具体是什么。帮忙!? 最佳答案 “C++ 实现”是指编译器加上链接
我正在尝试使用分支定界的 C++ 实现这个背包问题。此网站上有一个 Java 版本:Implementing branch and bound for knapsack 我试图让我的 C++ 版本打印
在很多情况下,我需要在 C# 中访问合适的哈希算法,从重写 GetHashCode 到对数据执行快速比较/查找。 我发现 FNV 哈希是一种非常简单/好/快速的哈希算法。但是,我从未见过 C# 实现的
目录 LRU缓存替换策略 核心思想 不适用场景 算法基本实现 算法优化
1. 绪论 在前面文章中提到 空间直角坐标系相互转换 ,测绘坐标转换时,一般涉及到的情况是:两个直角坐标系的小角度转换。这个就是我们经常在测绘数据处理中,WGS-84坐标系、54北京坐标系
在软件开发过程中,有时候我们需要定时地检查数据库中的数据,并在发现新增数据时触发一个动作。为了实现这个需求,我们在 .Net 7 下进行一次简单的演示. PeriodicTimer .
二分查找 二分查找算法,说白了就是在有序的数组里面给予一个存在数组里面的值key,然后将其先和数组中间的比较,如果key大于中间值,进行下一次mid后面的比较,直到找到相等的,就可以得到它的位置。
我是一名优秀的程序员,十分优秀!