最新消息:20210917 已从crifan.com换到crifan.org

【未解决】rcsjta中RCS的RI中各种功能都提示:The service is not available Please retry later

Service crifan 298浏览 0评论
折腾:
【部分解决】安装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

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
90 queries in 0.184 seconds, using 23.33MB memory