2016-12-23 33 views
0

我正在使用Sinch教程(https://github.com/sinch/android-app-app-calling-headers)作爲我嘗試開發的應用程序的框架。以下是我已經更新併成功初始化sinch客戶端的教程中的登錄類。無法實例化Sinch客戶端-NullPointerException錯誤

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); 
    } 

} 

的客戶端的實例發生在SinchService類,這是如下:

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); 
     } 
    } 

} 

對於我而言,我需要從我的共享偏好文件夾導出用於所述客戶端的用戶名。我製作了一個虛擬應用程序,它使用了上面相同的框架並添加了共享偏好設置,但我總是得到一個NullPointerException錯誤。以下是我的虛擬應用程序的登錄類。

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); 
    } 

} 

將我的登錄類與教程的登錄類進行比較時,唯一區別是變量「userName」的派生位置。我們都有附加在用戶名上的價值;但是,只有一個客戶端能夠建立,而另一個客戶端會拋出NullPointerException錯誤。有人知道爲什麼

編輯:錯誤消息是如下:

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) 

SECOND編輯:getSinchServiceInterface()方法在BaseActivity類中找到。其計算方法如下:

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(); 
    } 

    } 

} 
+1

的【什麼是一個NullPointerException,如何解決呢?(可能的複製http://stackoverflow.com/questions/218384/ what-is-a-nullpointerexception-and-how-do-i-fix-it) –

+1

我有點煩惱所有的nullpointerException甚至沒有試圖解決讀取什麼異常說.. btw getSinchServiceInterface爲null時你調用它的isStarted()方法.. –

+0

我讀錯誤消息,並看到錯誤正在拋出isStarted()方法 - 我知道這是空的那一點,但我不知道爲什麼 – Wdej

回答

0

試試這個:

您BaseActivity.java

,而不是

protected void onServiceConnected() { 
// for subclasses 
} 

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

並在LoginActivity.java

覆蓋功能onServiceConnected(IBinder iBinder)

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