2016-09-24 3 views
1

Я использую этот код в качестве базы для моего приложения: https://github.com/commonsguy/cw-omnibus/tree/master/MediaProjection/andcorderAndroid аварии 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)  

Моего Manifest:

<?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. Есть идеи?

Edit 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: я судимое это:

@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-A617 мой внешний SD Card (на этот раз еще один, чтобы проверить). Результат:

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 
+0

Пожалуйста отправьте соответствующий код здесь непосредственно. Включите строку 98 записи RecordingSession.java. –

+0

Замечательно, что вы добавили 'WRITE_EXTERNAL_STORAGE' в ​​ваш манифест. Вы внедрили Runtime Permission? В какой версии ОС работает устройство ?. –

+0

@SrikarReddy Мое тестовое устройство: LG G4 (Android 6.0) Если я внедрил Runtime Permission? Вы хотите спросить у пользователя о разрешениях при запуске приложения? Если да, я не знаю, как это реализовать. – Bleuzen

ответ

2

Поскольку вы запускаете приложение на Android 6.0, разрешение реализации среды выполнения является обязательным для WRITE_EXTERNAL_STORAGE. Это причина аварии.

Вот несколько ссылок, которые вы начали с реализацией прав доступа среды выполнения https://developer.android.com/training/permissions/index.html https://github.com/googlesamples/android-RuntimePermissions http://www.androidwarriors.com/2016/05/runtime-permissions-android-m-example.html

+0

Потому что слишком долго для комментария: http://pastebin.com/KZzUMM22 RecorderService.NOTIFY_ID в коде - это просто int. – Bleuzen

+0

@Bleuzen Если это слишком долго для комментария, вы должны изменить свой исходный вопрос. –

+0

@ Code-Apprentice Вопрос отредактирован;) – Bleuzen

Смежные вопросы