我一直在尝试请求(并从firebase消息服务中接收令牌),但还没有能够这样做。
首先,一旦应用程序启动,我就会在logcat中显示以下错误(甚至在模拟器或设备屏幕上显示某些内容之前)
09-21 18:11:33.183 17858-17858/? D/FirebaseInstanceId: Missing wake lock permission, service start may be delayed
09-21 18:11:33.233 17858-18021/? E/FirebaseInstanceId: Unable to get master token
java.lang.SecurityException: Not allowed to start service Intent { act=com.google.android.c2dm.intent.REGISTER pkg=com.google.android.gms (has extras) } without permission com.google.android.c2dm.permission.RECEIVE
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1728)
at android.app.ContextImpl.startService(ContextImpl.java:1705)
at android.content.ContextWrapper.startService(ContextWrapper.java:516)
at com.google.firebase.iid.zzf.a(Unknown Source)
at com.google.firebase.iid.zzf.a(Unknown Source)
at com.google.firebase.iid.zzf.b(Unknown Source)
at com.google.firebase.iid.zzf.a(Unknown Source)
at com.google.firebase.iid.zzd.c(Unknown Source)
at com.google.firebase.iid.zzd.b(Unknown Source)
at com.google.firebase.iid.FirebaseInstanceId.a(Unknown Source)
at com.google.firebase.iid.FirebaseInstanceId.f(Unknown Source)
at com.google.firebase.iid.FirebaseInstanceIdService.a(Unknown Source)
at com.google.firebase.iid.FirebaseInstanceIdService.b(Unknown Source)
at com.google.firebase.iid.zzb$2.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
[ 09-21 18:11:33.303 18029:18029 W/ ]
[ColorAdjust] Set temp_prefer temp_ce!
09-21 18:11:37.693 17858-17912/? V/FA: Inactivity, disconnecting from AppMeasurementService
09-21 18:13:56.973 19009-19261/? E/MarketConnection: Connection Exception for resolver.gslb.mi-idc.com :java.net.SocketTimeoutException: failed to connect to resolver.gslb.mi-idc.com/54.255.183.200 (port 80) after 10000ms
09-21 18:13:56.973 19009-19261/? E/MarketConnection: Connection failed : NETWORK_ERROR
09-21 18:14:07.113 19009-19261/? E/MarketConnection: Connection Exception for resolver.gslb.mi-idc.com :java.net.SocketTimeoutException: failed to connect to resolver.gslb.mi-idc.com/54.255.183.200 (port 80) after 10000ms
09-21 18:14:07.113 19009-19261/? E/MarketConnection: Connection failed : NETWORK_ERROR
这是 AndroidMainfest.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demoapp.myapp">
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.example.googlemaps.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name="com.demoapp.myapp.MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<uses-feature android:name="android.hardware.screen.portrait" />
</activity>
<activity
android:name="com.demoapp.myapp.SplashScreen"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:hardwareAccelerated="true"
android:configChanges="keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<uses-feature android:name="android.hardware.screen.portrait" />
</activity>
<!-- Google Maps API Key -->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="API_KEY"/>
<!-- Firebase Message Listening Service -->
<service
android:name=".FirebaseMessageService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- Firebase Token Service -->
<service
android:name=".FirebaseTokenService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
</application>
</manifest>
MainActivity.java
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private NavigationView navigationView;
private ListView drawerListView;
Thread tokenService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
//Subscribe to be notified
FirebaseMessaging.getInstance().subscribeToTopic("test");
FirebaseInstanceId.getInstance().getToken();
}
FirebaseTokenService.java
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
public class FirebaseTokenService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIDService";
@Override
public void onTokenRefresh() {
String token = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + token);
registerToken(token);
}
private void registerToken(String token) {
OkHttpClient client = new OkHttpClient();
RequestBody body = new FormBody.Builder()
.add("Token", token)
.build();
Request request = new Request.Builder()
.url('192.168.1.2/myapp/register.php')
.post(body)
.build();
try {
client.newCall(request).execute();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
FirebaseMessagingService.java
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import com.google.firebase.messaging.RemoteMessage;
public class FirebaseMessageService extends com.google.firebase.messaging.FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
showNotification(remoteMessage.getData().get("message"));
}
private void showNotification(String message) {
Intent i = new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setAutoCancel(true)
.setContentTitle(getString(R.string.org_name))
.setContentText(message)
.setSmallIcon(R.drawable.logo)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(0, builder.build());
}
}
我还更新了build.gradle文件中的必要条目
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0'
//Firebase entry
classpath 'com.google.gms:google-services:3.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
并且还会更新应用级build.gradle文件
.
.
.
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
// (v4.5)
compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.android.support:design:24.0.0'
compile 'com.android.support:support-v4:24.0.0'
compile 'com.google.android.gms:play-services:9.4.0'
compile 'com.google.firebase:firebase-messaging:9.0.0'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
}
apply plugin: 'com.google.gms.google-services'
我在DEBUG中提交了应用程序,但即使完全执行了MainActivity.java代码,也从未调用过FirebaseTokenService!
我做错了什么/失踪了?请帮忙!