java - bindService android AIDL 总是返回 false

标签 java android aidl

我想提供一个可以被其他应用程序调用的服务。因此,我有一个服务和一个援助。但是,当我尝试使用单独的应用程序来绑定(bind)此服务(bindService)时,它只是返回 false,这意味着失败。这是我的代码。

我正在使用书籍 Pro Android 2 中的代码

我已经在与此类似的其他问题中尝试了许多解决方案,但没有任何适合我的解决方案。

我已尝试修复aidl Intent 过滤器,但它仍然不起作用

我尝试修复客户端应用程序中的包名称和类名称,但仍然无法正常工作。

请帮助我!

在客户端:

// IStockQuoteService.aidl
package id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice;

// Declare any non-default types here with import statements

interface IStockQuoteService {
    double getQuote(String ticker);
}
package id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteclient;

import id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice.IStockQuoteService;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
    protected static final String TAG = "StockQuoteClient";
    private IStockQuoteService stockService = null;
    private Button bindBtn;
    private Button callBtn;
    private Button unbindBtn;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindBtn = (Button)findViewById(R.id.bindBtn);
        bindBtn.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.setClassName("com.id.ac.ui.cs.mobileprogramming" +
                        ".ahmad_fauzan_amirul_isnain.stockquoteservice",
                        "com.id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain" +
                                ".stockquoteservice.IStockQuoteService");
                Log.d("Hasil", String.valueOf(bindService(intent,
                        serConn, Context.BIND_AUTO_CREATE)));
                bindBtn.setEnabled(false);
                callBtn.setEnabled(true);
                unbindBtn.setEnabled(true);
            }});
        callBtn = (Button)findViewById(R.id.callBtn);
        callBtn.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View view) {
                callService();
            }});
        callBtn.setEnabled(false);

        unbindBtn = (Button)findViewById(R.id.unbindBtn);
        unbindBtn.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View view) {
                unbindService(serConn);
                bindBtn.setEnabled(true);
                callBtn.setEnabled(false);
                unbindBtn.setEnabled(false);
            }});
        unbindBtn.setEnabled(false);
    }
    private void callService() {
        try {
            double val = stockService.getQuote("SYH");
            Toast.makeText(MainActivity.this, "Value from service is "+val,
                    Toast.LENGTH_SHORT).show();
        } catch (RemoteException ee) {
            Log.e("MainActivity", ee.getMessage(), ee);
        }
    }
    private ServiceConnection serConn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service)
        {
            Log.v(TAG, "onServiceConnected() called");
            stockService = IStockQuoteService.Stub.asInterface(service);
            callService();
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.v(TAG, "onServiceDisconnected() called");
            stockService = null;
        }
    };
}

服务中:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="StockQuoteService">
            <intent-filter>
                <action android:name="com.id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice.IStockQuoteService"
                    />
            </intent-filter>
        </service>
    </application>

</manifest>
package id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class StockQuoteService extends Service
{
    private static final String TAG = "StockQuoteService";
    public class StockQuoteServiceImpl extends IStockQuoteService.Stub
    {
        @Override
        public double getQuote(String ticker) throws RemoteException
        {
            Log.v(TAG, "getQuote() called for " + ticker);
            return 20.0;
        }
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.v(TAG, "onCreate() called");
    }
    @Override
    public void onDestroy()
    {
        super.onDestroy();
        Log.v(TAG, "onDestroy() called");
    }
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.v(TAG, "onStart() called");
    }
    @Override
    public IBinder onBind(Intent intent)
    {
        Log.v(TAG, "onBind() called");
        return new StockQuoteServiceImpl();
    }
}
// IStockQuoteService.aidl
package id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice;

// Declare any non-default types here with import statements

interface IStockQuoteService {
    double getQuote(String ticker);
}

最佳答案

I'm using the code from books Pro Android 2

那本书是 2010 年的。那本书的大部分内容都会过时。请使用更新的东西。不出意外的话可以下载older editions of one of my books免费。目前,最新版本是 2015 年的——虽然也有点旧,但它比 2010 年的书要更新得多

I've already tried many solutions in other questions similar to this, but there isn't any working solution for me.

你有:

            intent.setClassName("com.id.ac.ui.cs.mobileprogramming" +
                    ".ahmad_fauzan_amirul_isnain.stockquoteservice",
                    "com.id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain" +
                            ".stockquoteservice.IStockQuoteService");

package您的 list 中有id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice 。假设您的applicationId在你的模块的 build.gradle 中文件是相同的,我认为这与您代码中的内容相匹配。您的应用程序 ID 很长 - 将来,我建议您使用更短且更易于直观比较的内容。

但是,你的类名是错误的。您的<service>类(class)是 StockQuoteService ,不是IStockQuoteServiceIStockQuoteService是 AIDL 的名称,而不是服务的名称,而您的 Intent需要指向服务。所以,尝试:

            intent.setClassName("com.id.ac.ui.cs.mobileprogramming" +
                    ".ahmad_fauzan_amirul_isnain.stockquoteservice",
                    "com.id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain" +
                            ".stockquoteservice.StockQuoteService");

或者,为了减少重复:

            String packageName = "com.id.ac.ui.cs.mobileprogramming" +
                    ".ahmad_fauzan_amirul_isnain.stockquoteservice";
            intent.setClassName(packageName, packageName+".StockQuoteService");

关于java - bindService android AIDL 总是返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58780591/

相关文章:

java - AES 加密 256 ECB 模式

android - 两个应用程序之间的 AIDL 接口(interface)

android - 删除谷歌日历中的单次事件

android - "private"aidl 对系统进程有多安全

android - 为什么 ITelephony.aidl 有效?

java - Spring Data JPA findAll 之间有表(PropertyReferenceException)

java - 从 JPanel 中删除多个 JComboBox

java - 如何在顶部、底部和透明中心对 View 进行渐变?

java - 如何在不耗尽内存或使用非常小的图像的情况下加载多个 AnimationDrawables?

Android 应用安装失败 : Package com. my.app 在 AndroidManifest.xml 入口处没有证书