java android nullpointerexception sinch

java - No se puede crear una instancia del cliente Sinch: Error de NullPointerException



android (1)

Prueba esto :

en su BaseActivity.java

en lugar de

protected void onServiceConnected() { // for subclasses }

poner

protected void onServiceConnected(IBinder iBinder) { mSinchServiceInterface = (SinchService.SinchServiceInterface) iBinder; }

y en su LoginActivity.java

Anular la función onServiceConnected(IBinder iBinder)

@Override protected void onServiceConnected(IBinder iBinder) { super.onServiceConnected(iBinder); getSinchServiceInterface().setStartListener(this); }

Estoy utilizando un tutorial de Sinch ( https://github.com/sinch/android-app-app-calling-headers ) como marco para una aplicación que estoy tratando de desarrollar. La siguiente es la clase de inicio de sesión del tutorial que he actualizado y he tenido éxito en la inicialización del cliente de sinch.

public class LoginActivity extends BaseActivity implements SinchService.StartFailedListener { private Button mLoginButton; private EditText mLoginName; private static final int REQUEST_PERMISSION = 10; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.login); mLoginName = (EditText) findViewById(R.id.loginName); mLoginButton = (Button) findViewById(R.id.loginButton); mLoginButton.setEnabled(false); requestAppPermissions(new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.ACCESS_FINE_LOCATION}, R.string.msg, REQUEST_PERMISSION); mLoginButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { loginClicked(); } }); } @Override public void onPermissionGranted(int requestCode) { } @Override protected void onServiceConnected() { mLoginButton.setEnabled(true); getSinchServiceInterface().setStartListener(this); } @Override protected void onPause() { super.onPause(); } @Override public void onStartFailed(SinchError error) { Toast.makeText(this, error.toString(), Toast.LENGTH_LONG).show(); } @Override public void onStarted() { openPlaceCallActivity(); } private void loginClicked() { String userName = mLoginName.getText().toString(); if (userName.isEmpty()) { Toast.makeText(this, "Please enter a name", Toast.LENGTH_LONG).show(); return; } if (!getSinchServiceInterface().isStarted()) { getSinchServiceInterface().startClient(userName); } else { openPlaceCallActivity(); } } private void openPlaceCallActivity() { Intent mainActivity = new Intent(this, PlaceCallActivity.class); startActivity(mainActivity); } }

La instanciación del cliente ocurre en la clase SinchService que es la siguiente:

private static final String APP_KEY = ""; private static final String APP_SECRET = ""; private static final String ENVIRONMENT = "sandbox.sinch.com"; public static final String LOCATION = "LOCATION"; public static final String CALL_ID = "CALL_ID"; static final String TAG = SinchService.class.getSimpleName(); private SinchServiceInterface mSinchServiceInterface = new SinchServiceInterface(); private SinchClient mSinchClient; private String mUserId; private StartFailedListener mListener; @Override public void onCreate() { super.onCreate(); } @Override public void onDestroy() { if (mSinchClient != null && mSinchClient.isStarted()) { mSinchClient.terminate(); } super.onDestroy(); } private void start(String userName) { if (mSinchClient == null) { mUserId = userName; mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext()).userId(userName) .applicationKey(APP_KEY) .applicationSecret(APP_SECRET) .environmentHost(ENVIRONMENT).build(); mSinchClient.setSupportCalling(true); mSinchClient.startListeningOnActiveConnection(); mSinchClient.addSinchClientListener(new MySinchClientListener()); mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener()); mSinchClient.start(); } } private void stop() { if (mSinchClient != null) { mSinchClient.terminate(); mSinchClient = null; } } private boolean isStarted() { return (mSinchClient != null && mSinchClient.isStarted()); } @Override public IBinder onBind(Intent intent) { return mSinchServiceInterface; } public class SinchServiceInterface extends Binder { public Call callPhoneNumber(String phoneNumber) { return mSinchClient.getCallClient().callPhoneNumber(phoneNumber); } public Call callUser(String userId) { return mSinchClient.getCallClient().callUser(userId); } public Call callUser(String userId, Map<String, String> headers) { return mSinchClient.getCallClient().callUser(userId, headers); } public String getUserName() { return mUserId; } public boolean isStarted() { return SinchService.this.isStarted(); } public void startClient(String userName) { start(userName); } public void stopClient() { stop(); } public void setStartListener(StartFailedListener listener) { mListener = listener; } public Call getCall(String callId) { return mSinchClient.getCallClient().getCall(callId); } } public interface StartFailedListener { void onStartFailed(SinchError error); void onStarted(); } private class MySinchClientListener implements SinchClientListener { @Override public void onClientFailed(SinchClient client, SinchError error) { if (mListener != null) { mListener.onStartFailed(error); } mSinchClient.terminate(); mSinchClient = null; } @Override public void onClientStarted(SinchClient client) { Log.d(TAG, "SinchClient started"); if (mListener != null) { mListener.onStarted(); } } @Override public void onClientStopped(SinchClient client) { Log.d(TAG, "SinchClient stopped"); } @Override public void onLogMessage(int level, String area, String message) { switch (level) { case Log.DEBUG: Log.d(area, message); break; case Log.ERROR: Log.e(area, message); break; case Log.INFO: Log.i(area, message); break; case Log.VERBOSE: Log.v(area, message); break; case Log.WARN: Log.w(area, message); break; } } @Override public void onRegistrationCredentialsRequired(SinchClient client, ClientRegistration clientRegistration) { } } private class SinchCallClientListener implements CallClientListener { @Override public void onIncomingCall(CallClient callClient, Call call) { Log.d(TAG, "Incoming call"); Intent intent = new Intent(SinchService.this, IncomingCallScreenActivity.class); intent.putExtra(CALL_ID, call.getCallId()); intent.putExtra(LOCATION, call.getHeaders().get("location")); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); SinchService.this.startActivity(intent); } } }

Para mis propósitos, necesito derivar el nombre de usuario para el cliente de mi carpeta de preferencias compartidas. Hice una aplicación ficticia que utiliza el mismo marco anterior con la adición de preferencias compartidas, pero siempre recibo un error NullPointerException. La siguiente es mi clase de inicio de sesión desde mi aplicación ficticia.

public class LoginActivity extends BaseActivity implements SinchService.StartFailedListener { private EditText mLoginName, recipientName, coordinateA, coordinateB; private Button loginButton; private static final int REQUEST_PERMISSION = 10; public static final String DEFAULT = "N/A"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); userName = (EditText) findViewById(R.id.userInput); recipientName = (EditText) findViewById(R.id.recipientInput); loginButton = (Button) findViewById(R.id.loginButton); requestAppPermissions(new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.ACCESS_FINE_LOCATION}, R.string.msg, REQUEST_PERMISSION); SharedPreferences sharedPreferences = getSharedPreferences("MyData", MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString("user_name", mLoginName.getText().toString()); editor.putString("recipient_name", recipientName.getText().toString()); editor.commit(); loginButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { loginClicked(); } }); } @Override public void onPermissionGranted(int requestCode) { } @Override protected void onServiceConnected() { getSinchServiceInterface().setStartListener(this); } @Override protected void onPause() { super.onPause(); } @Override public void onStartFailed(SinchError error) { Toast.makeText(this, error.toString(), Toast.LENGTH_LONG).show(); } @Override public void onStarted() { openPlaceCallActivity(); } private void loginClicked() { SharedPreferences sharedPreferences = getSharedPreferences("MyData", MODE_PRIVATE); String userName = sharedPreferences.getString("user_name", DEFAULT); if (userName.isEmpty()) { Toast.makeText(this, "Please enter a name", Toast.LENGTH_LONG).show(); return; } if (!getSinchServiceInterface().isStarted()) { getSinchServiceInterface().startClient(userName); } else { openPlaceCallActivity(); } } private void openPlaceCallActivity() { Intent mainActivity = new Intent(LoginActivity.this, PlaceCallActivity.class); startActivity(mainActivity); } }

Al comparar mi clase de inicio de sesión con la clase de inicio de sesión del tutorial, la única diferencia es donde se deriva la variable "nombre de usuario". Ambos tenemos un valor adjunto al nombre de usuario; sin embargo, solo un cliente puede establecer, mientras que el otro arroja un error NullPointerException. Alguien sabe por qué?

EDITAR: El mensaje de error es el siguiente:

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.dejon_000.sinchtest2, PID: 32470 java.lang.NullPointerException: Attempt to invoke virtual method ''boolean com.example.dejon_000.sinchtest2.SinchService$SinchServiceInterface.isStarted()'' on a null object reference at com.example.dejon_000.sinchtest2.LoginActivity.loginClicked(LoginActivity.java:83) at com.example.dejon_000.sinchtest2.LoginActivity.access$000(LoginActivity.java:17) at com.example.dejon_000.sinchtest2.LoginActivity$1.onClick(LoginActivity.java:47) at android.view.View.performClick(View.java:4802) at android.view.View$PerformClick.run(View.java:20059) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5422) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)

SEGUNDA EDICIÓN: El método getSinchServiceInterface () se encuentra en la clase BaseActivity. Es como sigue:

public abstract class BaseActivity extends Activity implements ServiceConnection { private SparseIntArray mErrorString; public static final String DEFAULT = "N/A"; private SinchService.SinchServiceInterface mSinchServiceInterface; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getApplicationContext().bindService(new Intent(this, SinchService.class), this, BIND_AUTO_CREATE); mErrorString = new SparseIntArray(); } @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { if (SinchService.class.getName().equals(componentName.getClassName())) { mSinchServiceInterface = (SinchService.SinchServiceInterface) iBinder; onServiceConnected(); } } @Override public void onServiceDisconnected(ComponentName componentName) { if (SinchService.class.getName().equals(componentName.getClassName())) { mSinchServiceInterface = null; onServiceDisconnected(); } } protected void onServiceConnected() { // for subclasses } protected void onServiceDisconnected() { // for subclasses } protected SinchService.SinchServiceInterface getSinchServiceInterface() { return mSinchServiceInterface; } public abstract void onPermissionGranted(int requestCode); public void requestAppPermissions(final String[] requestedPermissions, final int stringId, final int requestCode) { mErrorString.put(requestCode, stringId); int permissionCheck = PackageManager.PERMISSION_GRANTED; boolean showRequestPermissions = false; for (String permission : requestedPermissions) { permissionCheck = permissionCheck + ContextCompat.checkSelfPermission(this, permission); showRequestPermissions = showRequestPermissions || ActivityCompat.shouldShowRequestPermissionRationale(this, permission); } if (permissionCheck != PackageManager.PERMISSION_GRANTED) { if (showRequestPermissions) { Snackbar.make(findViewById(android.R.id.content), stringId, Snackbar.LENGTH_INDEFINITE).setAction("GRANT", new View.OnClickListener() { @Override public void onClick(View view) { ActivityCompat.requestPermissions(BaseActivity.this, requestedPermissions, requestCode); } }).show(); } else { ActivityCompat.requestPermissions(this, requestedPermissions, requestCode); } } else { onPermissionGranted(requestCode); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); int permissionCheck = PackageManager.PERMISSION_GRANTED; for(int permission : grantResults){ permissionCheck = permissionCheck + permission; } if((grantResults.length > 0)&& PackageManager.PERMISSION_GRANTED == permissionCheck ){ onPermissionGranted(requestCode); }else{ Snackbar.make(findViewById(android.R.id.content), mErrorString.get(requestCode), Snackbar.LENGTH_INDEFINITE).setAction("ENABLE", new View.OnClickListener() { @Override public void onClick(View view) { Intent i = new Intent(); i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); i.setData(Uri.parse("package:"+ getPackageName())); i.addCategory(Intent.CATEGORY_DEFAULT); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); startActivity(i); } }).show(); } } }