折腾:
【部分解决】安装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