我正在尝试在我的应用程序中集成this wifi p2p示例。但是在调用活动时我有这个错误:
Process: com.github.hiteshsondhi88.sampleffmpeg, PID: 8157
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.wifi.p2p.THIS_DEVICE_CHANGED flg=0x4000010 (has extras) } in it.linup.maint.activity.WiFiDirectBroadcastReceiver@7aa8d91
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:979)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5665)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:822)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:712)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void it.linup.maint.activity.DeviceListFragment.updateThisDevice(android.net.wifi.p2p.WifiP2pDevice)' on a null object reference
at it.linup.maint.activity.WiFiDirectBroadcastReceiver.onReceive(WiFiDirectBroadcastReceiver.java:91)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:969)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5665)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:822)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:712)
这是wifi直接的活动
package it.linup.maint.activity;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pManager;
import android.provider.*;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.*;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.github.hiteshsondhi88.sampleffmpeg.R;
import static android.os.Looper.getMainLooper;
public class P2P extends Activity implements WifiP2pManager.ChannelListener, DeviceListFragment.DeviceActionListener {
public static final String TAG = "wifidirectdemo";
private WifiP2pManager manager;
private boolean isWifiP2pEnabled = false;
private boolean retryChannel = false;
private final IntentFilter intentFilter = new IntentFilter();
private WifiP2pManager.Channel channel;
private BroadcastReceiver receiver = null;
/**
* @param isWifiP2pEnabled the isWifiP2pEnabled to set
*/
public void setIsWifiP2pEnabled(boolean isWifiP2pEnabled) {
this.isWifiP2pEnabled = isWifiP2pEnabled;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// add necessary intent values to be matched.
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
channel = manager.initialize(this, getMainLooper(), null);
}
/** register the BroadcastReceiver with the intent values to be matched */
@Override
public void onResume() {
super.onResume();
receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
registerReceiver(receiver, intentFilter);
}
@Override
public void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
/**
* Remove all peers and clear all fields. This is called on
* BroadcastReceiver receiving a state change event.
*/
public void resetData() {
DeviceListFragment fragmentList = (DeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_list);
DeviceDetailFragment fragmentDetails = (DeviceDetailFragment) getFragmentManager()
.findFragmentById(R.id.frag_detail);
if (fragmentList != null) {
fragmentList.clearPeers();
}
if (fragmentDetails != null) {
fragmentDetails.resetViews();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.action_items, menu);
return true;
}
/*
* (non-Javadoc)
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.atn_direct_enable:
if (manager != null && channel != null) {
// Since this is the system wireless settings activity, it's
// not going to send us a result. We will be notified by
// WiFiDeviceBroadcastReceiver instead.
startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
} else {
android.util.Log.e(TAG, "channel or manager is null");
}
return true;
case R.id.atn_direct_discover:
if (!isWifiP2pEnabled) {
Toast.makeText(P2P.this, R.string.p2p_off_warning,
Toast.LENGTH_SHORT).show();
return true;
}
final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_list);
fragment.onInitiateDiscovery();
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
Toast.makeText(P2P.this, "Discovery Initiated",
Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(int reasonCode) {
Toast.makeText(P2P.this, "Discovery Failed : " + reasonCode,
Toast.LENGTH_SHORT).show();
}
});
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void showDetails(WifiP2pDevice device) {
DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
.findFragmentById(R.id.frag_detail);
fragment.showDetails(device);
}
@Override
public void connect(WifiP2pConfig config) {
manager.connect(channel, config, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
// WiFiDirectBroadcastReceiver will notify us. Ignore for now.
}
@Override
public void onFailure(int reason) {
Toast.makeText(P2P.this, "Connect failed. Retry.",
Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void disconnect() {
final DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
.findFragmentById(R.id.frag_detail);
fragment.resetViews();
manager.removeGroup(channel, new WifiP2pManager.ActionListener() {
@Override
public void onFailure(int reasonCode) {
android.util.Log.d(TAG, "Disconnect failed. Reason :" + reasonCode);
}
@Override
public void onSuccess() {
fragment.getView().setVisibility(View.GONE);
}
});
}
@Override
public void onChannelDisconnected() {
// we will try once more
if (manager != null && !retryChannel) {
Toast.makeText(this, "Channel lost. Trying again", Toast.LENGTH_LONG).show();
resetData();
retryChannel = true;
manager.initialize(this, getMainLooper(), this);
} else {
Toast.makeText(this,
"Severe! Channel is probably lost premanently. Try Disable/Re-Enable P2P.",
Toast.LENGTH_LONG).show();
}
}
@Override
public void cancelDisconnect() {
/*
* A cancel abort request by user. Disconnect i.e. removeGroup if
* already connected. Else, request WifiP2pManager to abort the ongoing
* request
*/
if (manager != null) {
final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_list);
if (fragment.getDevice() == null
|| fragment.getDevice().status == WifiP2pDevice.CONNECTED) {
disconnect();
} else if (fragment.getDevice().status == WifiP2pDevice.AVAILABLE
|| fragment.getDevice().status == WifiP2pDevice.INVITED) {
manager.cancelConnect(channel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
Toast.makeText(P2P.this, "Aborting connection",
Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(int reasonCode) {
Toast.makeText(P2P.this,
"Connect abort request failed. Reason Code: " + reasonCode,
Toast.LENGTH_SHORT).show();
}
});
}
}
}
}
这与示例基本相同。
这是广播接收器类
package it.linup.maint.activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pManager;
import android.util.*;
import com.github.hiteshsondhi88.sampleffmpeg.R;
/**
* Created by utente on 10/04/2017.
*/
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager manager;
private WifiP2pManager.Channel channel;
private P2P activity;
/**
* @param manager WifiP2pManager system service
* @param channel Wifi p2p channel
* @param activity activity associated with the receiver
*/
public WiFiDirectBroadcastReceiver(WifiP2pManager manager, WifiP2pManager.Channel channel,
P2P activity) {
super();
this.manager = manager;
this.channel = channel;
this.activity = activity;
}
/*
* (non-Javadoc)
* @see android.content.BroadcastReceiver#onReceive(android.content.Context,
* android.content.Intent)
*/
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
// UI update to indicate wifi p2p status.
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
// Wifi Direct mode is enabled
activity.setIsWifiP2pEnabled(true);
} else {
activity.setIsWifiP2pEnabled(false);
activity.resetData();
}
android.util.Log.d(P2P.TAG, "P2P state changed - " + state);
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
// request available peers from the wifi p2p manager. This is an
// asynchronous call and the calling activity is notified with a
// callback on PeerListListener.onPeersAvailable()
if (manager != null) {
manager.requestPeers(channel, (WifiP2pManager.PeerListListener) activity.getFragmentManager()
.findFragmentById(R.id.frag_list));
}
android.util.Log.d(P2P.TAG, "P2P peers changed");
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
if (manager == null) {
return;
}
NetworkInfo networkInfo = (NetworkInfo) intent
.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()) {
// we are connected with the other device, request connection
// info to find group owner IP
DeviceDetailFragment fragment = (DeviceDetailFragment) activity
.getFragmentManager().findFragmentById(R.id.frag_detail);
manager.requestConnectionInfo(channel, fragment);
} else {
// It's a disconnect
activity.resetData();
}
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
DeviceListFragment fragment = (DeviceListFragment) activity.getFragmentManager()
.findFragmentById(R.id.frag_list);
fragment.updateThisDevice((WifiP2pDevice) intent.getParcelableExtra(
WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));
}
}
}
我已在清单中添加了所有必需的权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.hiteshsondhi88.sampleffmpeg">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-feature android:name="android.hardware.wifi.direct" android:required="true"/>
<application
android:allowBackup="true"
android:icon="@drawable/launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="it.linup.maint.activity.Main"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="it.linup.maint.activity.Home"
android:label="Home"
android:screenOrientation="portrait"></activity>
<activity
android:name="it.linup.maint.activity.Log"
android:label="Log"
android:screenOrientation="portrait"></activity>
<activity
android:name="it.linup.maint.activity.Settings"
android:label="Settings"
android:screenOrientation="portrait"></activity>
<activity
android:name="it.linup.maint.activity.DebugActivity"
android:screenOrientation="portrait"></activity>
<activity
android:name="it.linup.maint.activity.Help"
android:screenOrientation="portrait"></activity>
<activity android:name="it.linup.maint.activity.P2P" >
</activity>
</application>
应用程序由一个tabhost组成,其中包含三个链接到三个活动的选项卡。当我单击P2P活动上的选项卡时,应用程序会出现错误,显示上面发布的错误。奇怪的是,如果我从头开始创建一个项目,只包括与wifi相关的类直接所有工作。
感谢您的帮助
答案 0 :(得分:1)
您正在获得NullPointerException
:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void
it.linup.maint.activity.DeviceListFragment.updateThisDevice(android.net.wifi.p2p.WifiP2pDevice)'
on a null object reference
at it.linup.maint.activity.WiFiDirectBroadcastReceiver.onReceive(WiFiDirectBroadcastReceiver.java:91)
这意味着在此代码中:
DeviceListFragment fragment = (DeviceListFragment) activity.getFragmentManager()
.findFragmentById(R.id.frag_list);
fragment.updateThisDevice((WifiP2pDevice) intent.getParcelableExtra(
WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));
变量fragment
为null
(暗示对findFragmentById()
的调用正在返回null
。