Youtube Watch Me Android неожиданно закрывается

Я создаю приложение для Android от https://github.com/youtube/yt-watchme .

Когда я пытаюсь создать событие, используя кнопку «CREATE LIVE EVENT». Он выдает следующую ошибку. Я думаю, что это происходит из-за проблемы с разрешением камеры.

ОШИБКА:

09-17 11:43:53.582 32383-32383/com.google.android.apps.watchme E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.google.android.apps.watchme, PID: 32383 java.lang.NoSuchMethodError: com.google.android.apps.watchme.StreamerActivity.checkSelfPermission at com.google.android.apps.watchme.StreamerActivity.startStreaming(StreamerActivity.java:174) at com.google.android.apps.watchme.StreamerActivity.access$200(StreamerActivity.java:46) at com.google.android.apps.watchme.StreamerActivity$1.onServiceConnected(StreamerActivity.java:63) at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1110) at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1127) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5097) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) at dalvik.system.NativeStart.main(Native Method) 

Любой, пожалуйста, предложите. Как я могу решить эту проблему.

Заранее спасибо

Обновление кода:

Файл манифеста XML

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.android.apps.watchme"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- For authorization. --> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <!-- For recording audio and video without going to lock. --> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission."/> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" android:required="true"></uses-feature> <uses-feature android:name="android.hardware.camera.front" android:required="true"></uses-feature> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <activity android:name="com.google.android.apps.watchme.MainActivity" android:configChanges="orientation|screenSize" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.google.android.apps.watchme.StreamerActivity" android:label="@string/app_name" android:screenOrientation="landscape"></activity> <service android:name="com.google.android.apps.watchme.StreamerService" /> </application> <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23"/> </manifest> Размер <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.android.apps.watchme"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- For authorization. --> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <!-- For recording audio and video without going to lock. --> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission."/> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" android:required="true"></uses-feature> <uses-feature android:name="android.hardware.camera.front" android:required="true"></uses-feature> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <activity android:name="com.google.android.apps.watchme.MainActivity" android:configChanges="orientation|screenSize" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.google.android.apps.watchme.StreamerActivity" android:label="@string/app_name" android:screenOrientation="landscape"></activity> <service android:name="com.google.android.apps.watchme.StreamerService" /> </application> <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23"/> </manifest> 

Файл активности потока

 /* * Copyright (c) 2014 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.android.apps.watchme; import android.Manifest; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.hardware.Camera; import android.os.Bundle; import android.os.IBinder; import android.os.PowerManager; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.ToggleButton; import com.google.android.apps.watchme.util.Utils; import com.google.android.apps.watchme.util.YouTubeApi; import java.util.ArrayList; import java.util.List; /** * @author Ibrahim Ulukaya <ulukaya@google.com> * <p/> * StreamerActivity class which previews the camera and streams via StreamerService. */ public class StreamerActivity extends Activity { // CONSTANTS // TODO: Stop hardcoding this and read values from the camera's supported sizes. public static final int CAMERA_WIDTH = 640; public static final int CAMERA_HEIGHT = 480; private static final int REQUEST_CAMERA_MICROPHONE = 0; // Member variables private StreamerService streamerService; private ServiceConnection streamerConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { Log.d(MainActivity.APP_NAME, "onServiceConnected"); streamerService = ((StreamerService.LocalBinder) service).getService(); restoreStateFromService(); startStreaming(); } @Override public void onServiceDisconnected(ComponentName className) { Log.e(MainActivity.APP_NAME, "onServiceDisconnected"); // This should never happen, because our service runs in the same process. streamerService = null; } }; private PowerManager.WakeLock wakeLock; private Preview preview; private String rtmpUrl; private String broadcastId; @Override public void onCreate(Bundle savedInstanceState) { Log.d(MainActivity.APP_NAME, "onCreate"); super.onCreate(savedInstanceState); broadcastId = getIntent().getStringExtra(YouTubeApi.BROADCAST_ID_KEY); //Log.v(MainActivity.APP_NAME, broadcastId); rtmpUrl = getIntent().getStringExtra(YouTubeApi.RTMP_URL_KEY); if (rtmpUrl == null) { Log.w(MainActivity.APP_NAME, "No RTMP URL was passed in; bailing."); finish(); } Log.i(MainActivity.APP_NAME, String.format("Got RTMP URL '%s' from calling activity.", rtmpUrl)); setContentView(R.layout.streamer); preview = (Preview) findViewById(R.id.surfaceViewPreview); if (!bindService(new Intent(this, StreamerService.class), streamerConnection, BIND_AUTO_CREATE | BIND_DEBUG_UNBIND)) { Log.e(MainActivity.APP_NAME, "Failed to bind StreamerService!"); } final ToggleButton toggleButton = (ToggleButton) findViewById(R.id.toggleBroadcasting); toggleButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (toggleButton.isChecked()) { streamerService.startStreaming(rtmpUrl); } else { streamerService.stopStreaming(); } } }); } @Override protected void onResume() { Log.d(MainActivity.APP_NAME, "onResume"); super.onResume(); if (streamerService != null) { restoreStateFromService(); } } @Override protected void onPause() { Log.d(MainActivity.APP_NAME, "onPause"); super.onPause(); if (preview != null) { preview.setCamera(null); } if (streamerService != null) { streamerService.releaseCamera(); } } @Override protected void onDestroy() { Log.d(MainActivity.APP_NAME, "onDestroy"); super.onDestroy(); if (streamerConnection != null) { unbindService(streamerConnection); } stopStreaming(); if (streamerService != null) { streamerService.releaseCamera(); } } private void restoreStateFromService() { preview.setCamera(Utils.getCamera(Camera.CameraInfo.CAMERA_FACING_FRONT)); } private void startStreaming() { Log.d(MainActivity.APP_NAME, "startStreaming"); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, this.getClass().getName()); wakeLock.acquire(); if (!streamerService.isStreaming()) { String cameraPermission = Manifest.permission.CAMERA; String microphonePermission = Manifest.permission.RECORD_AUDIO; int hasCamPermission = checkSelfPermission(cameraPermission); int hasMicPermission = checkSelfPermission(microphonePermission); List<String> permissions = new ArrayList<String>(); if (hasCamPermission != PackageManager.PERMISSION_GRANTED) { permissions.add(cameraPermission); if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { // Provide rationale in Snackbar to request permission Snackbar.make(preview, R.string.permission_camera_rationale, Snackbar.LENGTH_INDEFINITE).show(); } else { // Explain in Snackbar to turn on permission in settings Snackbar.make(preview, R.string.permission_camera_explain, Snackbar.LENGTH_INDEFINITE).show(); } } if (hasMicPermission != PackageManager.PERMISSION_GRANTED) { permissions.add(microphonePermission); if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) { // Provide rationale in Snackbar to request permission Snackbar.make(preview, R.string.permission_microphone_rationale, Snackbar.LENGTH_INDEFINITE).show(); } else { // Explain in Snackbar to turn on permission in settings Snackbar.make(preview, R.string.permission_microphone_explain, Snackbar.LENGTH_INDEFINITE).show(); } } if (!permissions.isEmpty()) { String[] params = permissions.toArray(new String[permissions.size()]); ActivityCompat.requestPermissions(this, params, REQUEST_CAMERA_MICROPHONE); } else { // We already have permission, so handle as normal streamerService.startStreaming(rtmpUrl); } } } /** * Callback received when a permissions request has been completed. */ @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case REQUEST_CAMERA_MICROPHONE: { Log.i(MainActivity.APP_NAME, "Received response for camera with mic permissions request."); // We have requested multiple permissions for contacts, so all of them need to be // checked. if (Utils.verifyPermissions(grantResults)) { // permissions were granted, yay! do the // streamer task you need to do. streamerService.startStreaming(rtmpUrl); } else { Log.i(MainActivity.APP_NAME, "Camera with mic permissions were NOT granted."); Snackbar.make(preview, R.string.permissions_not_granted, Snackbar.LENGTH_SHORT) .show(); } break; } // other 'switch' lines to check for other // permissions this app might request } return; } private void stopStreaming() { Log.d(MainActivity.APP_NAME, "stopStreaming"); if (wakeLock != null) { wakeLock.release(); wakeLock = null; } if (streamerService.isStreaming()) { streamerService.stopStreaming(); } } public void endEvent(View view) { Intent data = new Intent(); data.putExtra(YouTubeApi.BROADCAST_ID_KEY, broadcastId); if (getParent() == null) { setResult(Activity.RESULT_OK, data); } else { getParent().setResult(Activity.RESULT_OK, data); } finish(); } } 

Обновить КОД ОШИБКИ:

 08:57:14.447 18829-18829/com.google.android.apps.watchme E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.google.android.apps.watchme, PID: 18829 java.lang.UnsatisfiedLinkError: Couldn't load ffmpeg from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.google.android.apps.watchme-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.google.android.apps.watchme-1, /vendor/lib, /system/lib]]]: findLibrary returned null at java.lang.Runtime.loadLibrary(Runtime.java:358) at java.lang.System.loadLibrary(System.java:526) at com.google.android.apps.watchme.Ffmpeg.<clinit>(Ffmpeg.java:26) at com.google.android.apps.watchme.VideoStreamingConnection.open(VideoStreamingConnection.java:71) at com.google.android.apps.watchme.StreamerService.startStreaming(StreamerService.java:80) at com.google.android.apps.watchme.StreamerActivity.startStreaming(StreamerActivity.java:212) at com.google.android.apps.watchme.StreamerActivity.access$200(StreamerActivity.java:47) at com.google.android.apps.watchme.StreamerActivity$1.onServiceConnected(StreamerActivity.java:64) at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1110) at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1127) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5097) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) at dalvik.system.NativeStart.main(Native Method) 

В вашем коде активности, где происходят вызовы, заверните его в чек:

 int hasCamPermission = checkSelfPermission(cameraPermission); int hasMicPermission = checkSelfPermission(microphonePermission); 

Сначала добавьте следующий метод в StreamerActivity:

 private boolean shouldCheckForPermission() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; } 

Измените эти строки так:

 int hasCamPermission = shouldCheckForPermission() ? checkSelfPermission(cameraPermission) : PackageManager.PERMISSION_GRANTED; int hasMicPermission = shouldCheckForPermission() ? checkSelfPermission(microphonePermission) : PackageManager.PERMISSION_GRANTED; 

Для этого вам нужно скомпилировать и настроить с помощью SDK 23, как указано выше в моем ответе.

Этот метод доступен только для версии API> = 23, с

 targetSdkVersion 23 compileSdkVersion 23 

И в вашем коде вам нужно проверить текущую версию API перед вызовом этого метода.

  public static boolean shouldCheckForPermission() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; } 

Если этот метод возвращает true, вы можете вызвать метод «checkSelfPermission».