如何解决:错误的第一个参数类型。找到:“ com.harrysoft.androidbluetoothserial.demoapp.CommunicateViewModel”,必需:“ android.content.Context”

时间:2019-09-05 14:29:03

标签: android android-intent

我试图构建一个必须在后台运行的应用程序。因此,为此我使用ForegroundService,但是当我在CommunicateViewModel类中编写“ this”时,其下划线并显示给我:

  

“无法解析构造函数   'Intent(com.harrysoft.androidbluetoothserial.demoapp.CommunicateViewModel,   java.lang.Class)'“

和下一个:

  

“第一个参数类型错误。找到:   'com.harrysoft.androidbluetoothserial.demoapp.CommunicateViewModel',   必需:“ android.content.Context”少...检查信息:   startForegroundService(android.content.Context,Intent)在   ContextCompat无法应用于   (com.harrysoft.androidbluetoothserial.demoapp.CommunicateViewModel,   意向)

我该如何解决这个问题?

CommunicateViewModel:

package com.harrysoft.androidbluetoothserial.demoapp;

import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.content.Intent;
import android.os.CountDownTimer;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.harrysoft.androidbluetoothserial.BluetoothManager;
import com.harrysoft.androidbluetoothserial.SimpleBluetoothDeviceInterface;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;


public class CommunicateViewModel extends AndroidViewModel {

    // A CompositeDisposable that keeps track of all of our asynchronous tasks
    private CompositeDisposable compositeDisposable = new CompositeDisposable();

    // Our BluetoothManager!
    private BluetoothManager bluetoothManager;

    // Our Bluetooth Device! When disconnected it is null, so make sure we know that we need to deal with it potentially being null
    @Nullable
    private SimpleBluetoothDeviceInterface deviceInterface;

    // The messages feed that the activity sees
    private MutableLiveData<String> messagesData = new MutableLiveData<>();
    // The connection status that the activity sees
    private MutableLiveData<ConnectionStatus> connectionStatusData = new MutableLiveData<>();
    // The device name that the activity sees
    private MutableLiveData<String> deviceNameData = new MutableLiveData<>();
    // The message in the message box that the activity sees
    private MutableLiveData<String> messageData = new MutableLiveData<>();

    // Our modifiable record of the conversation
    private StringBuilder messages = new StringBuilder();

    // Our configuration
    private String deviceName;
    private String mac;

    // A variable to help us not double-connect
    private boolean connectionAttemptedOrMade = false;
    // A variable to help us not setup twice
    private boolean viewModelSetup = false;

    // Called by the system, this is just a constructor that matches AndroidViewModel.
    public CommunicateViewModel(@NonNull Application application) {
        super(application);
    }

    // Called in the activity's onCreate(). Checks if it has been called before, and if not, sets up the data.
    // Returns true if everything went okay, or false if there was an error and therefore the activity should finish.
    public boolean setupViewModel(String deviceName, String mac) {
        // Check we haven't already been called
        if (!viewModelSetup) {
            viewModelSetup = true;

            // Setup our BluetoothManager
            bluetoothManager = BluetoothManager.getInstance();
            if (bluetoothManager == null) {
                // Bluetooth unavailable on this device :( tell the user
                toast(R.string.bluetooth_unavailable);
                // Tell the activity there was an error and to close
                return false;
            }

            // Remember the configuration
            this.deviceName = deviceName;
            this.mac = mac;

            // Tell the activity the device name so it can set the title
            deviceNameData.postValue(deviceName);
            // Tell the activity we are disconnected.
            connectionStatusData.postValue(ConnectionStatus.DISCONNECTED);
        }
        // If we got this far, nothing went wrong, so return true
        return true;
    }

    // Called when the user presses the connect button

    public void toconnect(){

        Intent serviceIntent = new Intent(this, TimeService.class);
        serviceIntent.putExtra("inputExtra", "this can be set invissable");

        ContextCompat.startForegroundService(this, serviceIntent);
        connect();
    }

    public void connect() {
        // Check we are not already connecting or connected
        if (!connectionAttemptedOrMade) {
            // Connect asynchronously
            compositeDisposable.add(bluetoothManager.openSerialDevice(mac)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(device -> onConnected(device.toSimpleDeviceInterface()), t -> {
                        toast(R.string.connection_failed);
                        connectionAttemptedOrMade = false;
                        connectionStatusData.postValue(ConnectionStatus.DISCONNECTED);
                    }));
            // Remember that we made a connection attempt.
            connectionAttemptedOrMade = true;
            // Tell the activity that we are connecting.
            connectionStatusData.postValue(ConnectionStatus.CONNECTING);
        }
    }

    // Called when the user presses the disconnect button
    public void disconnect() {
        // Check we were connected
        if (connectionAttemptedOrMade && deviceInterface != null) {
            connectionAttemptedOrMade = false;
            // Use the library to close the connection
            bluetoothManager.closeDevice(deviceInterface);
            // Set it to null so no one tries to use it
            deviceInterface = null;
            // Tell the activity we are disconnected
            connectionStatusData.postValue(ConnectionStatus.DISCONNECTED);
        }
    }

    // Called once the library connects a bluetooth device
    private void onConnected(SimpleBluetoothDeviceInterface deviceInterface) {
        this.deviceInterface = deviceInterface;
        if (this.deviceInterface != null) {
            // We have a device! Tell the activity we are connected.
            connectionStatusData.postValue(ConnectionStatus.CONNECTED);
            // Setup the listeners for the interface
            this.deviceInterface.setListeners(this::onMessageReceived, this::onMessageSent, t -> toast(R.string.message_send_error));
            // Tell the user we are connected.
            toast(R.string.connected);
            // Reset the conversation
            messages = new StringBuilder();
            messagesData.postValue(messages.toString());
        } else {
            // deviceInterface was null, so the connection failed
            toast(R.string.connection_failed);
            connectionStatusData.postValue(ConnectionStatus.DISCONNECTED);
        }
        getCurrentTime();
    }

    // Adds a received message to the conversation
    private void onMessageReceived(String message) {
        messages.append(deviceName).append(": ").append(message).append('\n');
        messagesData.postValue(messages.toString());
    }

    // Adds a sent message to the conversation
    private void onMessageSent(String message) {
        // Add it to the conversation
        messages.append(getApplication().getString(R.string.you_sent)).append(": ").append(message).append('\n');
        messagesData.postValue(messages.toString());
        // Reset the message box
        messageData.postValue("");
    }

    // Send a message
    public void sendMessage(String message) {
        new CountDownTimer(1000, 1000) {
            public void onTick(long millisUntilFinished) {
                if (deviceInterface != null && !TextUtils.isEmpty(message)) {
                    Log.i("info", "sendMessage: send");
                }
                deviceInterface.sendMessage(message);
            }
            public void onFinish() {

                disconnect();
                timer();
            }
        }.start();
        // Check we have a connected device and the message is not empty, then send the message -----------------


    }

    //---------------------------------------------------------------------------MY Code
    //timer
    public void timer(){
        new CountDownTimer(28000, 1000) {
            public void onTick(long millisUntilFinished) {
                Log.i("INFO", "onTick: ");
            }
            public void onFinish() {
                connect();
            }
        }.start();
    }

    // Get Time
    public void getCurrentTime() {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat mdformat = new SimpleDateFormat("HHmm");
        SimpleDateFormat seconds = new SimpleDateFormat("ss");
        String strSec = seconds.format(calendar.getTime());
        String strDate = "Time" + mdformat.format(calendar.getTime());

        //if ((strSec == "29") || (strSec == "59")) {
            sendMessage(strDate);

        //}
    }



    // Called when the activity finishes - clear up after ourselves.
    @Override
    protected void onCleared() {
        // Dispose any asynchronous operations that are running
        compositeDisposable.dispose();
        // Shutdown bluetooth connections
        bluetoothManager.close();
    }

    // Helper method to create toast messages.
    private void toast(@StringRes int messageResource) { Toast.makeText(getApplication(), messageResource, Toast.LENGTH_LONG).show(); }

    // Getter method for the activity to use.
    public LiveData<String> getMessages() { return messagesData; }

    // Getter method for the activity to use.
    public LiveData<ConnectionStatus> getConnectionStatus() { return connectionStatusData; }

    // Getter method for the activity to use.
    public LiveData<String> getDeviceName() { return deviceNameData; }

    // Getter method for the activity to use.
    public LiveData<String> getMessage() { return messageData; }

    // An enum that is passed to the activity to indicate the current connection status
    enum ConnectionStatus {
        DISCONNECTED,
        CONNECTING,
        CONNECTED
    }
}

TimeService:

package com.harrysoft.androidbluetoothserial.demoapp;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.app.*;


import io.reactivex.annotations.Nullable;

import static com.harrysoft.androidbluetoothserial.demoapp.App.CHANNEL_ID;


public class TimeService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        String input = intent.getStringExtra("inputExtra");

        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, 0);

        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("Example Service")
                .setContentText(input)
                .setSmallIcon(R.drawable.ic_android)
                .setContentIntent(pendingIntent)
                .build();

        startForeground(1, notification);

        //do heavy work on a background thread
        //stopSelf();

        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

1 个答案:

答案 0 :(得分:0)

您必须传递Context作为Intent构造函数的第一个参数。您可以借助application对象来检索它。

Intent serviceIntent = new Intent(getApplication().getApplicationContext(), TimeService.class);