折腾:
【部分解决】安装rcsjta的RI的build出的RCS-debug的apk到安卓小米9中
期间,之前去尝试rcsjta的RI中的功能
结果发现各种功能都弹框提示服务不可用。
后来在折腾:
【已解决】安装rcsjta的settings的build出的settings-debug的apk到安卓小米9中
期间,安装了settings,看到提示说是已开启了服务service
或许就是此处的 RI的app所要用到的服务?
去点击看看,之前的选项是可用
问题依旧:

The service is not available Please retry later
去代码中找找,这个service具体是什么
【基本解决】研究rcsjta中源码中和启动RCS的服务的相关代码和逻辑
再去重新运行RI的app
结果还是会有 服务不可用的情况。
然后注意到RI的app启动那一刻会显示 正在初始化:

Initializing …
无意间发现,代码中能搜到这个:
RI/res/values/strings.xml
<string name="label_wait_cnx_start">Initializing…</string>

看来就是 初始化启动时候的字符串
然后看看哪里调用了这个
label_wait_cnx_start
竟然没有java代码中直接用到
不过
(1)有另外的
tools/settings/src/com/gsma/rcs/core/control/settings/SettingsDisplay.java
private class WaitForConnectionManagerStart extends AsyncTask<Long, Void, Void> {
。。。
@Override
protected void onPreExecute() {
mProgressDialog = SettingsDisplay.this.showProgressDialog(SettingsDisplay.this
.getString(R.string.rcs_settings_label_wait_cnx_start));
}用到了另外一个相关的:rcs_settings_label_wait_cnx_start
而其定义找到了,也是一样的:
tools/settings/res/values/strings.xml
<string name="rcs_settings_label_wait_cnx_start">Initializing...</string>
(2)找到另外有地方调用:
RI/res/layout/ri_list.xml
<LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/wait_cnx_start" android:orientation="vertical" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dip" android:text="@string/label_wait_cnx_start" /> <ProgressBar android:id="@android:id/progress" style="@android:style/Widget.ProgressBar.Horizontal" android:layout_width="fill_parent" android:layout_height="50dp" /> </LinearLayout>
看起来:
对应的上,UI界面中的布局

再仔细看看,好像上面的:
WaitForConnectionManagerStart
更像是 代码运行的逻辑
不过也去看看 ri_list对应哪个java页面调用了
ri_list.xml
RI/src/com/gsma/rcs/ri/RI.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
。。。
setContentView(R.layout.ri_list);是对的,RI的初始化中,定义了布局,就是ri_list
而初始化后,才被 列表替换:

再去看完整的代码:
RI/src/com/gsma/rcs/ri/RI.java
public class RI extends RcsListActivity {
。。。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Set layout */
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.ri_list);
mListView = (ListView) findViewById(android.R.id.list);
mProgressBar = (ProgressBar) findViewById(android.R.id.progress);
mInitLayout = (LinearLayout) findViewById(R.id.wait_cnx_start);
/* Set items */
// @formatter:off
String[] items = {
getString(R.string.menu_contacts),
getString(R.string.menu_capabilities),
getString(R.string.menu_messaging),
getString(R.string.menu_sharing),
getString(R.string.menu_mm_session),
getString(R.string.menu_intents),
getString(R.string.menu_service),
getString(R.string.menu_upload),
getString(R.string.menu_about)
};
// @formatter:on
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, items));
ContactUtil contactUtil = ContactUtil.getInstance(this);
try {
/* The country code must be read to check that ContactUtil is ready to be used */
String cc = contactUtil.getMyCountryCode();
if (LogUtils.isActive) {
Log.w(LOGTAG, "Country code is '" + cc + "'");
}
} catch (RcsPermissionDeniedException e) {
Log.w(LOGTAG, ExceptionUtil.getFullStackTrace(e));
/* We should not be allowed to continue if this exception occurs */
showMessageThenExit(R.string.error_api_permission_denied);
}
/*
* The initialization of the connection manager is delayed to avoid non response during
* application initialization after installation. The application waits until end of
* connection manager initialization.
*/
if (!RiApplication.sCnxManagerStarted) {
new WaitForConnectionManagerStart()
.execute(RiApplication.DELAY_FOR_STARTING_CNX_MANAGER);
} else {
mInitLayout.setVisibility(View.GONE);
}
}是先显示 init的布局,其他部分都初始化完毕后,再去让init布局消失GONE,才看到后续的设置页面。
继续看看代码:
new WaitForConnectionManagerStart().execute(RiApplication.DELAY_FOR_STARTING_CNX_MANAGER);
RI/src/com/gsma/rcs/ri/RI.java
private class WaitForConnectionManagerStart extends AsyncTask<Long, Integer, Void> {
@Override
protected void onPreExecute() {
mInitLayout.setVisibility(View.VISIBLE);
mListView.setVisibility(View.GONE);
}
@Override
protected void onProgressUpdate(Integer... progress) {
mProgressBar.setProgress(progress[0]);
}
@Override
protected Void doInBackground(Long... duration) {
long delay = (duration[0] / PROGRESS_INIT_INCREMENT);
for (int i = 0; i < PROGRESS_INIT_INCREMENT; i++) {
try {
Thread.sleep(delay);
publishProgress((int) (delay * (i + 1) * 100 / duration[0]));
if (RiApplication.sCnxManagerStarted) {
break;
}
} catch (InterruptedException ignore) {
}
}
return null;
}
@Override
protected void onPostExecute(Void res) {
mInitLayout.setVisibility(View.GONE);
mListView.setVisibility(View.VISIBLE);
}
}就是当前文件实现了WaitForConnectionManagerStart
只是个切换页面,更新进度的。
核心在于 sCnxManagerStarted
去找找:sCnxManagerStarted
又回到了之前见过的
tools/settings/src/com/gsma/rcs/core/control/CoreControlApplication.java
public class CoreControlApplication extends Application {
/**
* Delay (ms) before starting connection manager.
*/
public static final long DELAY_FOR_STARTING_CNX_MANAGER = 2000;
public static boolean sCnxManagerStarted = false;
private static RcsServiceControl mRcsServiceControl;
@Override
public void onCreate() {
super.onCreate();
Context context = getApplicationContext();
mRcsServiceControl = RcsServiceControl.getInstance(context);
final ConnectionManager cnxManager = ConnectionManager.createInstance(context,
mRcsServiceControl, RcsServiceName.FILE_TRANSFER, RcsServiceName.CHAT,
RcsServiceName.CONTACT);
/* Do not execute the ConnectionManager on the main thread */
Handler mainThreadHandler = new Handler(Looper.getMainLooper());
mainThreadHandler.postDelayed(new Runnable() {
@Override
public void run() {
cnxManager.start();
sCnxManagerStarted = true;
}
}, DELAY_FOR_STARTING_CNX_MANAGER);
}看起来,感觉是:
此处的
cnxManager.start();
的确是启动了service
但是由于:
final ConnectionManager cnxManager = ConnectionManager.createInstance(context, mRcsServiceControl, RcsServiceName.FILE_TRANSFER, RcsServiceName.CHAT, RcsServiceName.CONTACT);
只启动了 FILE_TRANSFER、CHAT、CONTACT
所以后续的其他服务,包括Capability等,都无法显示
不过后续去看了,对应的:
File Transfer
Chat
中:

去试了:

Transfer a file
结果也依旧提示服务不可用:

以及Chat也是:

所以看来是:整个的底层服务,都不可用。
所以要去找根本原因。
去搜:
The service is not available
libs/api_cnx/src/main/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="error_not_registered">Not registered to IMS</string> <string name="label_service_not_available">The service is not available. Please retry later.</string> <string name="title_msg">Information</string> <string name="label_ok">OK</string> <string name="error_exception_message">%1$s: see Logcat!</string> <string name="error_exception">"Exception occurred! See Logcat."</string> </resources>
定义是:label_service_not_available
搜:label_service_not_available
libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/utils/RcsActivity.java
@Override
public void showExceptionThenExit(Exception e) {
/*
* Non bug exception should not produce log of stack trace.
*/
if (e instanceof RcsServiceNotAvailableException) {
DialogUtil.showMessageThenExit(this, getString(R.string.label_service_not_available),
mLockAcces);
} else if (e instanceof RcsServiceNotRegisteredException) {
DialogUtil.showMessageThenExit(this, getString(R.string.error_not_registered),
mLockAcces);
} else {
DialogUtil.showExceptionThenExit(this, e, mLockAcces);
}
}记得是很多地方都调用到了这个showExceptionThenExit
- libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/utils/RcsFragmentActivity.java
- libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/utils/RcsListActivity.java
- libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/utils/RcsPreferenceActivity.java
也是类似的实现。
回到调用的地方
RI/src/com/gsma/rcs/ri/capabilities/MyCapabilities.java
import com.gsma.rcs.api.connection.utils.RcsActivity;
public class MyCapabilities extends RcsActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.capabilities_mine);
/* Register to API connection manager */
if (!isServiceConnected(RcsServiceName.CAPABILITY)) {
showMessageThenExit(R.string.label_service_not_available);
return;
}
startMonitorServices(RcsServiceName.CAPABILITY);
}问题回到了:
isServiceConnected
搜:
isServiceConnected(
libs/api/src/main/java/com/gsma/services/rcs/RcsService.java
/**
* Returns true if the service is connected, else returns false
*
* @return Returns true if connected else returns false
*/
public boolean isServiceConnected() {
return (mApi != null);
}libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/utils/IConnectionManager.java
/** * Check if services are connected * * @param services list of services * @return true if all services of the list are connected */ boolean isServiceConnected(RcsServiceName... services);
好像是个Interface?
前面导入的是:
RcsActivity
对应着此处的
libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/utils/RcsActivity.java
@Override
public boolean isServiceConnected(RcsServiceName... services) {
return mCnxManager.isServiceConnected(services);
}对应定义是之前已找到的
libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/ConnectionManager.java
/**
* Check if services are connected
*
* @param services list of services
* @return true if all services of the list are connected
*/
public boolean isServiceConnected(RcsServiceName... services) {
for (RcsServiceName service : services) {
if (!mManagedServices.contains(service)) {
throw new IllegalArgumentException("Service " + service
+ " does not belong to set of managed services!");
}
if (!mConnectedServices.contains(service)) {
return false;
}
}
return true;
}而前面初始化得到这个实例是
libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/utils/RcsActivity.java
public abstract class RcsActivity extends Activity implements DialogUtil.IRegisterCloseDialog,
IRcsDialog, IConnectionManager {
。。。
private ConnectionManager mCnxManager;
。。。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCnxManager = ConnectionManager.getInstance();去通过getInstance得到的
libs/api_cnx/src/main/java/com/gsma/rcs/api/connection/ConnectionManager.java
/**
* Gets the singleton instance of ConnectionManager.
*
* @return the singleton instance.
*/
public static ConnectionManager getInstance() {
return sInstance;
}是单例
private static volatile ConnectionManager sInstance;
/**
* Get an instance of ConnectionManager.
*
* @param ctx the context
* @param rcsServiceControl instance of RcsServiceControl
* @param managedServices Set of managed services
* @return the singleton instance.
*/
public static ConnectionManager createInstance(Context ctx,
RcsServiceControl rcsServiceControl, Set<RcsServiceName> managedServices) {
if (sInstance != null) {
return sInstance;
}
synchronized (ConnectionManager.class) {
if (sInstance == null) {
if (ctx == null) {
throw new IllegalArgumentException("Context is null");
}
sInstance = new ConnectionManager(ctx, managedServices, rcsServiceControl);
}
}
return sInstance;
}
去搜:
ConnectionManager(
/**
* Constructor
*
* @param context The context
* @param managedServices Set of managed services
* @param rcsServiceControl instance of RcsServiceControl
*/
private ConnectionManager(Context context, Set<RcsServiceName> managedServices,
RcsServiceControl rcsServiceControl) {
mCtx = context;
mCnxIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_CONNECT), 0);
mAlarmManager = (AlarmManager) mCtx.getSystemService(Context.ALARM_SERVICE);
mManagedServices = managedServices;
mRcsServiceControl = rcsServiceControl;
/* Construct list of connected services */
mConnectedServices = new HashSet<>();
/* Construct list of clients to notify */
mClientsToNotify = new HashMap<>();
/* Construct list of APIs */
mApis = new HashMap<>();
if (managedServices == null || managedServices.isEmpty()) {
throw new RuntimeException("Incorrect parameter managedService!");
}
/* Instantiate APIs */
for (RcsServiceName service : mManagedServices) {
switch (service) {
case CAPABILITY:
mApis.put(RcsServiceName.CAPABILITY, new CapabilityService(context,
newRcsServiceListener(RcsServiceName.CAPABILITY)));
break;
case CHAT:
mApis.put(RcsServiceName.CHAT, new ChatService(context,
newRcsServiceListener(RcsServiceName.CHAT)));
break;
case CONTACT:
mApis.put(RcsServiceName.CONTACT, new ContactService(context,
newRcsServiceListener(RcsServiceName.CONTACT)));
break;
case FILE_TRANSFER:
mApis.put(RcsServiceName.FILE_TRANSFER, new FileTransferService(context,
newRcsServiceListener(RcsServiceName.FILE_TRANSFER)));
break;
case FILE_UPLOAD:
mApis.put(RcsServiceName.FILE_UPLOAD, new FileUploadService(context,
newRcsServiceListener(RcsServiceName.FILE_UPLOAD)));
break;
case GEOLOC_SHARING:
mApis.put(RcsServiceName.GEOLOC_SHARING, new GeolocSharingService(context,
newRcsServiceListener(RcsServiceName.GEOLOC_SHARING)));
break;
case HISTORY:
mApis.put(RcsServiceName.HISTORY, new HistoryService(context,
newRcsServiceListener(RcsServiceName.HISTORY)));
break;
case IMAGE_SHARING:
mApis.put(RcsServiceName.IMAGE_SHARING, new ImageSharingService(context,
newRcsServiceListener(RcsServiceName.IMAGE_SHARING)));
break;
case MULTIMEDIA:
mApis.put(RcsServiceName.MULTIMEDIA, new MultimediaSessionService(context,
newRcsServiceListener(RcsServiceName.MULTIMEDIA)));
break;
case VIDEO_SHARING:
mApis.put(RcsServiceName.VIDEO_SHARING, new VideoSharingService(context,
newRcsServiceListener(RcsServiceName.VIDEO_SHARING)));
break;
}
}
}很明显就是最早已经看到的代码
看起来是 代码估计运行了但是服务的确 由于某种原因 没启动?
那去找找,是否有什么log文件?
如果有,看看是否有异常信息输出
看看能否协助找到服务没启动的根本原因。
【未解决】寻找安卓中rcsjta的3个app的log日志文件
转载请注明:在路上 » 【未解决】rcsjta中RCS的RI中各种功能都提示:The service is not available Please retry later