,當我使用此代碼作爲基礎我的應用程序:https://github.com/commonsguy/cw-omnibus/tree/master/MediaProjection/andcorder的Android screenrecorder崩潰寫入到外部存儲
現在我改變了路徑輸出文件。我想將其保存到外置SD卡上,但如果我開始拍攝,我得到這個錯誤:
09-24 01:37:50.225 4428-4428/me.bleuzen.android.screenrecorder E/AndroidRuntime: FATAL EXCEPTION: main
Process: me.bleuzen.android.screenrecorder, PID: 4428
java.lang.RuntimeException: Unable to start service [email protected] with Intent { act=me.bleuzen.android.screenrecorder.RECORD flg=0x10000000 cmp=me.bleuzen.android.screenrecorder/.RecorderService bnds=[257,1321][832,1513] }: java.lang.RuntimeException: Exception preparing recorder
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3045)
at android.app.ActivityThread.access$2200(ActivityThread.java:157)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1454)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5525)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
Caused by: java.lang.RuntimeException: Exception preparing recorder
at me.bleuzen.android.screenrecorder.RecordingSession.start(RecordingSession.java:98)
at me.bleuzen.android.screenrecorder.RecorderService.startRecorder(RecorderService.java:169)
at me.bleuzen.android.screenrecorder.RecorderService.onStartCommand(RecorderService.java:76)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3028)
at android.app.ActivityThread.access$2200(ActivityThread.java:157)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1454)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5525)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
Caused by: java.io.FileNotFoundException: /storage/3E0D-1BF9/20160924_013750.mp4: open failed: EACCES (Permission denied)
at libcore.io.IoBridge.open(IoBridge.java:452)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:117)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:149)
at android.media.MediaRecorder.prepare(MediaRecorder.java:780)
at me.bleuzen.android.screenrecorder.RecordingSession.start(RecordingSession.java:89)
at me.bleuzen.android.screenrecorder.RecorderService.startRecorder(RecorderService.java:169)
at me.bleuzen.android.screenrecorder.RecorderService.onStartCommand(RecorderService.java:76)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3028)
at android.app.ActivityThread.access$2200(ActivityThread.java:157)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1454)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5525)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Posix.open(Native Method)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
at libcore.io.IoBridge.open(IoBridge.java:438)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:117)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:149)
at android.media.MediaRecorder.prepare(MediaRecorder.java:780)
at me.bleuzen.android.screenrecorder.RecordingSession.start(RecordingSession.java:89)
at me.bleuzen.android.screenrecorder.RecorderService.startRecorder(RecorderService.java:169)
at me.bleuzen.android.screenrecorder.RecorderService.onStartCommand(RecorderService.java:76)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3028)
at android.app.ActivityThread.access$2200(ActivityThread.java:157)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1454)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5525)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
我的清單:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="me.bleuzen.android.screenrecorder">
<application
android:icon="@drawable/ic_videocam_white_24dp"
android:label="@string/app_name">
<activity
android:name="me.bleuzen.android.screenrecorder.MainActivity"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="me.bleuzen.android.screenrecorder.RecorderService"
android:exported="true" />
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
我已經把在WRITE_EXTERNAL_STORAGE許可。 WRITE_SETTINGS是設置顯示觸摸。
最有趣的行應該是:java.io.FileNotFoundException: 所致/storage/3E0D-1BF9/20160924_013750.mp4:打開失敗:EACCES(拒絕) ,其中/存儲/ 3E0D-1BF9 /是我的外部SD卡。但爲什麼「權限被拒絕」?我添加了WRITE_EXTERNAL_STORAGE。任何想法?
編輯1:我在主/設置和唯一的活動已將此添加的onCreate:
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_SETTINGS, Manifest.permission.RECORD_AUDIO}, RecorderService.NOTIFY_ID);
其中RecorderService.NOTIFY_ID只是一個int
,並檢查了它:
showToast(String.valueOf(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) + " " +
String.valueOf(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED) + " " +
String.valueOf(ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED));
static void showToast(String msg) {
Toast.makeText(appContext, msg, Toast.LENGTH_SHORT).show();
}
輸出結果爲:「true false true」
WRITE_SETTINGS保持爲假:( ...但如果我可以將視頻保存到外部SD卡上,那就沒問題。也許我們也會爲此找到一個解決辦法;)
現在WRITE_EXTERNAL_STORAGE被允許,應該解決問題,但它仍然不起作用。如果我能猜出原因: 要請求權限,該方法需要一個活動。這是否意味着每個活動都需要獲得許可?問題在於:錄音機是一項服務。如果沒有任何活動,我無法申請許可。
編輯2:實施例: 在AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
activity_main.xml中:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="me.bleuzen.android.screenrecorder.MainActivity"
android:background="@android:color/background_light">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:id="@+id/textView"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
MainActivity:
package me.bleuzen.android.screenrecorder;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.widget.TextView;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class MainActivity extends Activity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
boolean canWrite = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
textView.append("WRITE_EXTERNAL_STORAGE: " + canWrite + "\n");
if(canWrite) {
textView.append("Befor: " + new File("/storage/emulated/0/z.txt").exists() + " " + new File("/storage/6301-17FC/z.txt").exists() + "\n");
writeToFile("Unglaublich wichtig", "/storage/emulated/0/z.txt");
writeToFile("Unglaublich wichtig", "/storage/6301-17FC/z.txt");
textView.append("After: " + new File("/storage/emulated/0/z.txt").exists() + " " + new File("/storage/6301-17FC/z.txt").exists() + "\n");
} else {
textView.append("Please restart this app after granting permission.");
}
}
private static void writeToFile(String s, String f) {
File file = new File(f);
try {
file.createNewFile();
FileOutputStream outputStream = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(outputStream);
writer.append(s);
writer.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
的該示例代碼結果: 論/ storage/emulated/0(內部)創建文件,在/ st上orage/6301-17FC(我的外部SD卡)沒有。
編輯3:我tryed這一點:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
try {
new File("/storage/6391-A617/test").createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
,其中6391-617是我的外置SD卡(這時候另外一個測試)。 結果:
09-27 15:39:16.624 4965-4965/me.bleuzen.android.screenrecorder W/System.err: java.io.IOException: open failed: EACCES (Permission denied)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at java.io.File.createNewFile(File.java:939)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at me.bleuzen.android.screenrecorder.MainActivity.onRequestPermissionsResult(MainActivity.java:226)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6588)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at android.app.Activity.dispatchActivityResult(Activity.java:6467)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at android.app.ActivityThread.deliverResults(ActivityThread.java:3738)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at android.app.ActivityThread.handleSendResult(ActivityThread.java:3785)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at android.app.ActivityThread.access$1400(ActivityThread.java:157)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at android.os.Looper.loop(Looper.java:148)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5525)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at java.lang.reflect.Method.invoke(Native Method)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
09-27 15:39:16.633 4965-4965/me.bleuzen.android.screenrecorder W/System.err: Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
09-27 15:39:16.634 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at libcore.io.Posix.open(Native Method)
09-27 15:39:16.634 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
09-27 15:39:16.634 4965-4965/me.bleuzen.android.screenrecorder W/System.err: at java.io.File.createNewFile(File.java:932)
09-27 15:39:16.634 4965-4965/me.bleuzen.android.screenrecorder W/System.err: ... 13 more
請直接在這裏發佈相關的代碼幾個環節。包含RecordingSession.java的第98行。 –
很好,你已經在你的Manifest中添加了'WRITE_EXTERNAL_STORAGE'。你是否實現了運行時權限?設備在哪個操作系統版本上運行? –
@SrikarReddy我的測試設備:LG G4(Android 6.0) 如果我實現了運行時權限?你的意思是在應用程序運行期間詢問用戶的權限?如果是,我不知道如何實現這一點呢。 – Bleuzen