Error de carga de video de Android Facebook con la API de Android 4+
Tengo este código, después de iniciar sesión en Facebook, quiero subir el vídeo seleccionado a Facebook a través de Facebook Android SDK v4.13.1 ,
Problema :
La respuesta me parece bien, pero el video no se muestra en la Línea de tiempo del usuario de prueba.
- Ejecución de múltiples instancias de la misma aplicación en kitkat android
- Error en el ID de aplicación de la aplicación facebook en Manifest
- "Facebook no se puede resolver a un tipo" en Facebook SDK para Android
- Falta el mensaje o error de adjunto al enviar el mensaje en Facebook
- Obtener amigos taggable Facebook Android
Código:
public void shareVideoFB(String videoPath, final ProgressDialog pd) { AccessToken accessToken = AccessToken.getCurrentAccessToken(); GraphRequest request = GraphRequest.newPostRequest(accessToken, "https://graph-video.facebook.com/me/videos", null, new GraphRequest.Callback() { @Override public void onCompleted(GraphResponse response) { try { if (pd.isShowing()) pd.dismiss(); } catch (Exception e) { e.printStackTrace(); } onFBShareVideoCompleted(response); } }); Bundle params = request.getParameters(); try { byte[] data = readBytes(videoPath); params.putByteArray("video.mp4", data); String albumName = "testFBUpload"; params.putString("title", albumName); params.putString("description", " #SomeTag"); request.setParameters(params); request.executeAsync(); } catch (Exception e) { e.printStackTrace(); } }
Respuesta 1:
{Response: responseCode:200, graphObject:{"id":"10150481253673034", "url":"https:\/\/graph-video.facebook.com\/me\/videos"}, error:null}
Respuesta 2:
{Response: responseCode:200, graphObject:null, error:{HTTPStatus:-1,errorCode:-1,errorType:null, errorMessage:"could not construct request body"}}
EDITAR 1
He creado un nuevo usuario de prueba con varios permisos como
- Perfil público
- Amigos_usuario,
- correo electrónico,
- User_about_me,
- User_actions.video,
- User_likes
- User_videos,
- Publish_pages,
- Publish_actions
Y suba el video pero sigue recibiendo la misma respuesta que la Respuesta 1 .
Editar 2
Acabo de notar que para los usuarios de prueba la respuesta es la misma que la respuesta 1 y con el mismo ID 10150481253673034
- Cordova-plugin-facebook4 mensaje con error de imagen en Android
- Facebook Android SDK Sesión openForPublish no crear una nueva sesión
- Facebook SDK 4.x Android Publicar como página de Facebook
- Android facebook sdk 4.0 ProfileTracker onCurrentProfileChanged nunca se llama
- Obtener lista de amigos facebook 3.0
- Nombre del paquete y clase Nombre de la aplicación de Facebook
- Uso de Facebook app_link_hosts La respuesta de la API es 403 permisos de error - Android
- Desconexión externa de Android Facebook SDK 4.0
Tienes 2 respuestas.
La respuesta 1 es del usuario user.ie de prueba se comparte correctamente. -> Así que necesitas iniciar sesión en facebook usando las credenciales de usuario de prueba proporcionadas desde la Facebook developer console
y comprobar en la línea de tiempo. Si no lo encuentras en la línea de tiempo, compruébalo en el perfil. Usted definitivamente lo encontrará por ahí.
A veces no muestra post compartido en la línea de tiempo debido a algunas configuraciones de privacidad establecidas en esa cuenta.
La respuesta 2 es de otra cuenta. -> Se ha fallado porque, a menos que Facebook apruebe tu aplicación, no te permitirá compartir vídeos con otra cuenta excepto con la cuenta de prueba. Así que cuando la aplicación obtendrá la aprobación de publish_actions
desde el proceso de presentación de Facebook, entonces usted puede probar con diferentes cuentas. Así que está bien para este caso.
Consulte https://developers.facebook.com/docs/opengraph/submission-process para el proceso de envío.
En la creación de GraphRequest reemplazar la ruta del gráfico https://graph-video.facebook.com/me/videos
por /me/videos
.
GraphRequest request = GraphRequest.newPostRequest(accessToken, "/me/videos", null, new GraphRequest.Callback() { @Override public void onCompleted(GraphResponse response) { // your code } });
Fuente:
Subida de video con Graph API
Referencia del API de gráficos: Video
Puede publicar vídeos usando los siguientes bordes:
-
/{user-id}/videos
-
/{event-id}/videos
-
/{page-id}/videos
-
/{group-id}/videos
Nota:
Mi solución a continuación sólo funciona para los usuarios de prueba. Para publicar videos de usuarios reales, refiérase a este proceso de envío.
Aunque @Morales Batovski Respuesta me ayudó pero quiero responder a mi propia pregunta ya que ninguna respuesta fue completa, estoy publicando una solución de trabajo completa:
Crear usuario de prueba:
Crear un nuevo usuario de prueba con permisos (puede excluir algunos de los permisos innecesarios):
-
public_profile
-
user_friends
-
email
, -
user_about_me
, -
user_actions.video
, -
user_likes
-
user_videos
, -
publish_pages
, -
publish_actions
Añade estos permisos aquí (Captura de pantalla)
Build.gradle:
compile 'com.facebook.android:facebook-android-sdk:[4,5)'
MyAbstractFacebookActivity:
import android.annotation.TargetApi; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.util.Base64; import android.util.Log; import android.webkit.MimeTypeMap; import android.widget.Toast; import com.facebook.AccessToken; import com.facebook.AccessTokenTracker; import com.facebook.CallbackManager; import com.facebook.FacebookCallback; import com.facebook.FacebookException; import com.facebook.FacebookSdk; import com.facebook.GraphRequest; import com.facebook.GraphResponse; import com.facebook.Profile; import com.facebook.ProfileTracker; import com.facebook.login.LoginManager; import com.facebook.login.LoginResult; import com.facebook.share.Sharer; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; import org.json.JSONObject; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; /** * Created by Nadeem Iqbal on 6/20/2016. */ public abstract class MyAbstractFacebookActivity extends MyAbstractActivity { private static String[] FB_BASIC_PERMISSIONS = new String[]{"public_profile", "email"}; private CallbackManager callbackManager; private FacebookCallback<Sharer.Result> fbCallback; private AccessTokenTracker accessTokenTracker; private AccessToken accessToken; private ProfileTracker profileTracker; private Profile profile; private String fbId = ""; byte[] data; private boolean LOG_FB_HASH = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e("FB HASH", getFBHashKey()); fbInit(); } public String getFBHashKey() { String key = ""; try { PackageInfo info = getPackageManager().getPackageInfo( getApplicationContext().getPackageName(), PackageManager.GET_SIGNATURES); for (android.content.pm.Signature signature : info.signatures) { MessageDigest md = MessageDigest.getInstance("SHA"); md.update(signature.toByteArray()); key = Base64.encodeToString(md.digest(), Base64.DEFAULT); if (LOG_FB_HASH) { copyToClipBoard(key); } log("KeyHash FB:", key); } } catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) { } return key; } @TargetApi(Build.VERSION_CODES.HONEYCOMB) public void copyToClipBoard(String textToCopy) { int sdk_Version = Build.VERSION.SDK_INT; if (sdk_Version < Build.VERSION_CODES.HONEYCOMB) { android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); clipboard.setText(textToCopy); Toast.makeText(getApplicationContext(), "Copied to Clipboard!", Toast.LENGTH_SHORT).show(); } else { android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); android.content.ClipData clip = android.content.ClipData.newPlainText("Text Label", textToCopy); clipboard.setPrimaryClip(clip); Toast.makeText(getApplicationContext(), "Copied to Clipboard!", Toast.LENGTH_SHORT).show(); } } ///////// FB Work Start ////////// @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); ///// FB Work Start ////// callbackManager.onActivityResult(requestCode, resultCode, data); ///// FB Work End ////// } void fbInit() { FacebookSdk.sdkInitialize(getApplicationContext()); callbackManager = CallbackManager.Factory.create(); fbCallback = new FacebookCallback<Sharer.Result>() { @Override public void onSuccess(Sharer.Result result) { log("Post Shared on FB"); onPostSharedSuccessfully(result); } @Override public void onCancel() { toast("Cancelled"); onPostSharedCancelled(); } @Override public void onError(FacebookException e) { toast("Error:" + e.getMessage()); e.printStackTrace(); onPostSharedError(e); } }; profileTracker = new ProfileTracker() { @Override protected void onCurrentProfileChanged(Profile oldProfile, Profile currentProfile) { Profile.setCurrentProfile(currentProfile); profile = currentProfile; } }; accessTokenTracker = new AccessTokenTracker() { @Override protected void onCurrentAccessTokenChanged( AccessToken oldAccessToken, AccessToken currentAccessToken) { // On AccessToken changes fetch the new profile which fires the event on // the ProfileTracker if the profile is different Profile.fetchProfileForCurrentAccessToken(); } }; // Ensure that our profile is up to date Profile.fetchProfileForCurrentAccessToken(); LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() { @Override public void onSuccess(LoginResult loginResult) { accessToken = AccessToken.getCurrentAccessToken(); onFBLoginSuccessfully(loginResult, accessToken); getNewFBId(); } @Override public void onCancel() { warning("Cancel", "User cancelled the process"); onFBLoginCancelled(); } @Override public void onError(FacebookException exception) { warning("Error", "" + exception.getMessage()); onFBLoginError(exception); } }); } protected void getNewFBId() { GraphRequest request = GraphRequest.newMeRequest( AccessToken.getCurrentAccessToken(), new GraphRequest.GraphJSONObjectCallback() { @Override public void onCompleted( JSONObject object, GraphResponse response) { try { fbId = object.getString("id"); onFbId(fbId); } catch (JSONException e) { e.printStackTrace(); } } }); Bundle parameters = new Bundle(); parameters.putString("fields", "id"); request.setParameters(parameters); request.executeAsync(); } public abstract void onFbId(String fbId); public void doLogin() { doLogin(FB_BASIC_PERMISSIONS); } public void doLogin(String[] permissions) { try { LoginManager.getInstance().logOut(); } catch (Exception e) { e.printStackTrace(); } LoginManager.getInstance().logInWithPublishPermissions(this, Arrays.asList(permissions)); } ///////// FB Work End ////////// public AccessToken getAccessToken() { return accessToken; } public ProfileTracker getProfileTracker() { return profileTracker; } public Profile getProfile() { return profile; } public String getFBId() { return fbId; } public static String getMimeType(String url) { String type = null; String extension = MimeTypeMap.getFileExtensionFromUrl(url); if (extension != null) { type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); } return type; } private static String getPrivacy(String privacy) { String str; if (privacy.equalsIgnoreCase("Everyone")) str = "EVERYONE"; if (privacy.equalsIgnoreCase("Friends and Networks")) str = "NETWORKS_FRIENDS"; else if (privacy.equalsIgnoreCase("Friends of Friends")) str = "FRIENDS_OF_FRIENDS"; else if (privacy.equalsIgnoreCase("Friends Only")) str = "ALL_FRIENDS"; else if (privacy.equalsIgnoreCase("Custom")) str = "CUSTOM"; else if (privacy.equalsIgnoreCase("Specific People...")) str = "SOME_FRIENDS"; else str = "SELF"; return str; } public void shareVideoFB(String videoPath, final ProgressDialog pd) { AccessToken accessToken = AccessToken.getCurrentAccessToken(); Uri fileUri = Uri.parse(videoPath); String fileName = videoPath.substring(videoPath.lastIndexOf('/') + 1, videoPath.length()); String mimeType = getMimeType(videoPath); try { data = readBytes(videoPath); } catch (IOException e) { e.printStackTrace(); } int videoSize = data.length; String privacy = getPrivacy("Friends Only"); GraphRequest request = GraphRequest.newPostRequest(accessToken, "/me/videos", null, new GraphRequest.Callback() { @Override public void onCompleted(GraphResponse response) { try { if (pd.isShowing()) pd.dismiss(); } catch (Exception e) { } onFBShareVideoCompleted(response); } }); Bundle params = request.getParameters(); params = request.getParameters(); params.putByteArray(fileName, data); params.putString("title", fileName); params.putString("description", "Some Description..."); // params.putString("upload_phase", "start"); params.putInt("file_size", data.length); request.setParameters(params); request.executeAsync(); } public byte[] readBytes(String dataPath) throws IOException { InputStream inputStream = new FileInputStream(dataPath); ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) != -1) { byteBuffer.write(buffer, 0, len); } return byteBuffer.toByteArray(); } protected abstract void onFBShareVideoCompleted(GraphResponse response); protected abstract void onFBLoginError(FacebookException exception); protected abstract void onFBLoginCancelled(); protected abstract void onFBLoginSuccessfully(LoginResult loginResult, AccessToken accessToken); protected abstract void onPostSharedError(FacebookException e); protected abstract void onPostSharedCancelled(); protected abstract void onPostSharedSuccessfully(Sharer.Result result); }
Compartir:
(Esta actividad implementa MyAbstractFacebookActivity y requiere el valor de la ruta de acceso de cadena de la intención, Mi escucha del botón Share My FB es onFacebookShareButtonClick () )
import android.app.ProgressDialog; import android.os.Bundle; import android.support.v7.app.ActionBar; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; import com.facebook.AccessToken; import com.facebook.FacebookException; import com.facebook.GraphResponse; import com.facebook.login.LoginResult; import com.facebook.share.Sharer; public class Share extends MyAbstractFacebookActivity { String path = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_share); setHeader("Share"); path = getIntent().getStringExtra("path"); if (TextUtils.isEmpty(path)) { toast("Path is null, Exiting Activity"); finish(); } } public void setHeader(String header_title) { // ... My Implementation } public void back(View v) { finish(); } public void onFacebookShareButtonClick(View view) { // Facebook Share button Click Listener... String[] FB_BASIC_PERMISSIONS = new String[]{"publish_actions"}; doLogin(FB_BASIC_PERMISSIONS); } @Override protected void onFBLoginError(FacebookException exception) { } @Override protected void onFBLoginCancelled() { } @Override protected void onFBLoginSuccessfully(LoginResult loginResult, AccessToken accessToken) { // getNewFBId(); ProgressDialog pd = new ProgressDialog(this); pd.setMessage("Uploading Video, Please wait..."); pd.setCancelable(false); pd.setCanceledOnTouchOutside(false); pd.show(); shareVideoFB(path, pd); } @Override protected void onPostSharedError(FacebookException e) { } @Override protected void onPostSharedCancelled() { } @Override protected void onPostSharedSuccessfully(Sharer.Result result) { } boolean isCalledEarlier = false; @Override public void onFbId(String fbId) { if (!isCalledEarlier) { ProgressDialog pd = new ProgressDialog(this); pd.setMessage("Uploading Video, Please wait..."); pd.setCancelable(false); pd.setCanceledOnTouchOutside(false); pd.show(); shareVideoFB(path, pd); isCalledEarlier = true; } } @Override protected void onFBShareVideoCompleted(GraphResponse response) { // Here the video share response will come... toast(response.toString()); log(response.toString()); } }
Resultado:
- ¿Cómo enlazar con bibliotecas estáticas para Android?
- Llamar a un método en el proceso del sistema sin un error de usuario calificado