Reputation: 1
this is an app that play music simultaneously on multiple Android device whith wifi connections
there is 2 sections, one is dj player mode (the device that play music) and the other one is speaker mode
dj play mode activity work good on android jelly bean (4.1,4.2,4.3) but on newer versions (4.4,5) force close occur
what is the problem?
the dj player activity
package com.example.musicsaround.dj;
import java.io.File;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.ActionListener;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.ChannelListener;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import com.example.musicsaround.R;
import com.example.musicsaround.Timer;
import com.example.musicsaround.Utilities;
import com.example.musicsaround.dj.ServerDeviceListFragment.DJFragmentListener;
public class DJActivity extends Activity implements ChannelListener,
DJFragmentListener
{
public final static int DJ_MODE = 15;
public static final String TAG = "DJ Mode Activity";
private WifiP2pManager manager;
private boolean channelRetried = false;
private boolean isWifiP2pEnabled = false;
private BroadcastReceiver receiver = null;
ProgressDialog progressDialog = null;
private Timer timer;
private CountDownTimer keepAliveTimer;
// Keep the Wifi Alive every 5 seconds
private static final int KEEPALIVE_INTERVAL = 5000;
// critical component for Wi-fi Direct connectivity
private Channel channel;
private final IntentFilter intentFilter = new IntentFilter();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dj);
// need these intent filters to catch the Wi-fi direct events
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);
TextView txt_time = (TextView) this.findViewById(R.id.txt_dj_time);
// start a timer with 25 ms precision
this.timer = new Timer(Timer.DEFAULT_TIMER_PRECISION);
// asynchronous call to start a timer
this.timer.startTimer();
keepAliveTimer = new CountDownTimer(KEEPALIVE_INTERVAL,
KEEPALIVE_INTERVAL)
{
@Override
public void onTick(long millisUntilFinished)
{
}
@Override
public void onFinish()
{
enableWifi();
keepAliveTimer.start();
}
};
}
/** register the BroadcastReceiver with the intent values to be matched */
@Override
public void onResume()
{
super.onResume();
receiver = new ServerWiFiDirectBR(manager, channel, this);
registerReceiver(receiver, intentFilter);
// ***Start discovering right away!
discoverDevices();
keepAliveTimer.start();
}
public void enableWifi()
{
WifiManager wifiManager = (WifiManager) this
.getSystemService(this.WIFI_SERVICE);
wifiManager.setWifiEnabled(true);
}
/**
* UI to show the discovery process
*/
public void onInitiateDiscovery()
{
if (progressDialog != null && progressDialog.isShowing())
{
progressDialog.dismiss();
}
progressDialog = ProgressDialog.show(this, "Press back to cancel",
"finding peers", true, true,
new DialogInterface.OnCancelListener()
{
@Override
public void onCancel(DialogInterface dialog)
{
// stop discovery
manager.stopPeerDiscovery(channel,
new WifiP2pManager.ActionListener()
{
@Override
public void onFailure(int reason)
{
// Toast.makeText(DJActivity.this,
// "Stopping Discovery Failed : " +
// reason,
// Toast.LENGTH_SHORT).show();
Log.e(TAG,
"Stopping Discovery Failed. Error Code is: "
+ reason);
}
@Override
public void onSuccess()
{
Log.d(TAG, "Discovery stopped.");
}
});
}
});
}
public void discoverDevices()
{
// TODO: need a better non-blocking UI to notify users we are
// discovering
// onInitiateDiscovery();
// first turn on the wifi p2p
enableWifi();
channelRetried = false;
manager.discoverPeers(channel, new WifiP2pManager.ActionListener()
{
@Override
public void onSuccess()
{
// Toast.makeText(DJActivity.this,
// "Discovery Initiated",
// Toast.LENGTH_SHORT).show();
Log.d(TAG, "Discovery Initiated.");
}
// if we failed, then stop the discovery and start again
@Override
public void onFailure(int reasonCode)
{
Log.e(TAG, "Discovery Failed. Error Code is: " + reasonCode);
manager.stopPeerDiscovery(channel,
new WifiP2pManager.ActionListener()
{
@Override
public void onFailure(int reason)
{
// Toast.makeText(DJActivity.this,
// "Stopping Discovery Failed : " + reason,
// Toast.LENGTH_SHORT).show();
Log.e(TAG,
"Stopping Discovery Failed. Error Code is: "
+ reason);
}
@Override
public void onSuccess()
{
manager.discoverPeers(channel,
new WifiP2pManager.ActionListener()
{
@Override
public void onSuccess()
{
// Toast.makeText(DJActivity.this,
// "Discovery Initiated",
// Toast.LENGTH_SHORT)
// .show();
Log.d(TAG,
"Discovery Initiated.");
}
@Override
public void onFailure(int reasonCode)
{
Log.e(TAG,
"Discovery Failed. Error Code is: "
+ reasonCode);
}
});
}
});
}
});
}
@Override
public void onPause()
{
super.onPause();
unregisterReceiver(receiver);
keepAliveTimer.cancel();
}
@Override
public void onDestroy()
{
disconnect();
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.wifidirect_less, menu);
return true;
}
@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.
Intent intent = new Intent();
// jump to wi-fi Direct settings
intent.setClassName("com.android.settings",
"com.android.settings.Settings$WifiP2pSettingsActivity");
startActivity(intent);
}
else
{
Log.e(TAG, "channel or manager is null");
}
return true;
case R.id.atn_direct_discover:
discoverDevices();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Remove all peers and clear all fields. This is called on
* BroadcastReceiver receiving a state change event. This is merely an UI
* update.
*/
public void resetDeviceList()
{
ServerDeviceListFragment fragmentList = (ServerDeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_djs_devices);
if (fragmentList != null)
{
fragmentList.clearPeers();
}
}
@Override
public void onChannelDisconnected()
{
// we will try once more
if (manager != null && !channelRetried)
{
Toast.makeText(this, "Wi-fi Direct Channel lost. Trying again...",
Toast.LENGTH_LONG).show();
resetDeviceList();
channelRetried = true;
manager.initialize(this, getMainLooper(), this);
}
else
{
Toast.makeText(
this,
"Wi-fi Direct Channel is still lost. Try disabling / re-enabling Wi-fi Direct in the P2P Settings.",
Toast.LENGTH_LONG).show();
}
}
@Override
public void showDetails(WifiP2pDevice device)
{
// TODO: This is for debugging, showing the device details
DJMusicFragment fragMusic = (DJMusicFragment) getFragmentManager()
.findFragmentById(R.id.frag_dj_music);
}
@Override
public void showInfo(WifiP2pInfo info)
{
DJMusicFragment fragMusic = (DJMusicFragment) getFragmentManager()
.findFragmentById(R.id.frag_dj_music);
if (info.isGroupOwner)
{
// fragMusic.setDebugText("I am the group owner.");
}
else
{
// fragMusic.setDebugText("I am not the group owner.");
}
}
/*
* Cancel an ongoing connection in progress. We won't actually use this
* method all that much
*
* (non-Javadoc)
*
* @see
* com.example.musicsaround.dj.ServerDeviceListFragment.DJFragmentListener
* #cancelDisconnect()
*/
@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)
{
Log.d(TAG, "Someone requested a cancel connect!");
final ServerDeviceListFragment fragment = (ServerDeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_djs_devices);
if (fragment.getDevice() == null
|| fragment.getDevice().status == WifiP2pDevice.CONNECTED)
{
// we don't disconnect the whole group... it would be nice just
// to disconnect that one guy
// disconnect();
}
else if (fragment.getDevice().status == WifiP2pDevice.AVAILABLE
|| fragment.getDevice().status == WifiP2pDevice.INVITED
|| fragment.getDevice().status == WifiP2pDevice.CONNECTED)
{
manager.cancelConnect(channel, new ActionListener()
{
@Override
public void onSuccess()
{
// Toast.makeText(DJActivity.this,
// "Aborting connection",
// Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(int reasonCode)
{
// Toast.makeText(
// DJActivity.this,
// "Connect abort request failed. Reason Code: "
// + reasonCode, Toast.LENGTH_SHORT)
// .show();
Log.e(TAG,
"Could not abort connection, the reason is: "
+ reasonCode);
}
});
}
}
}
/*
* This is the main method to connect to a device through Wi-Fi Direct!
*
* (non-Javadoc)
*
* @see
* com.example.musicsaround.dj.ServerDeviceListFragment.DJFragmentListener
* #connect(android.net.wifi.p2p.WifiP2pConfig)
*/
@Override
public void connect(WifiP2pConfig config)
{
if (manager == null)
{
return;
}
// in DJ mode, we want to become the group owner
WifiP2pConfig newConfig = config;
newConfig.groupOwnerIntent = DJ_MODE;
manager.connect(channel, newConfig, new ActionListener()
{
@Override
public void onSuccess()
{
// WiFiDirectBroadcastReceiver will notify us. Ignore for now.
}
@Override
public void onFailure(int reason)
{
Toast.makeText(DJActivity.this,
"Connection failed. Retrying...", Toast.LENGTH_SHORT)
.show();
Log.e(TAG,
"Wi-fi Direct connection failed. The error code is: "
+ reason);
}
});
}
@Override
public void disconnect()
{
if (manager == null)
{
return;
}
// TODO: why do we have to remove the whole group upon disconnect?
// perhaps we only need to do so upon exiting DJ mode
manager.removeGroup(channel, new ActionListener()
{
@Override
public void onFailure(int reasonCode)
{
Log.e(TAG, "Disconnect failed. Reason is: " + reasonCode);
}
@Override
public void onSuccess()
{
Toast.makeText(DJActivity.this, "Disconnected a device.",
Toast.LENGTH_SHORT).show();
Log.d(TAG, "Disconnected from a device.");
}
});
}
/**
* @param isWifiP2pEnabled
* the isWifiP2pEnabled to set
*/
public void setIsWifiP2pEnabled(boolean isWifiP2pEnabled)
{
this.isWifiP2pEnabled = isWifiP2pEnabled;
}
public void playRemoteMusic(Uri musicFileURI, long startTime, int startPos)
{
ServerDeviceListFragment fragmentList = (ServerDeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_djs_devices);
// convert URI to actual file path
Uri filePathFromActivity = Uri.parse(Utilities.getRealPathFromUri(
(Activity) this, musicFileURI));
File audioFile = new File(filePathFromActivity.getPath());
fragmentList.playMusicOnClients(audioFile, startTime, startPos);
}
public void playRemoteMusic(String musicFilePath, long startTime,
int startPos)
{
ServerDeviceListFragment fragmentList = (ServerDeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_djs_devices);
File audioFile = new File(musicFilePath);
fragmentList.playMusicOnClients(audioFile, startTime, startPos);
}
public void stopRemoteMusic()
{
ServerDeviceListFragment fragmentList = (ServerDeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_djs_devices);
fragmentList.stopMusicOnClients();
}
public Timer getTimer()
{
return timer;
}
}
songsmanager:
package com.example.musicsaround;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.HashMap;
public class SongsManager {
// SDCard Path
final String MEDIA_PATH = new String("/sdcard/Download");
private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
// Constructor
public SongsManager(){
}
/**
* Function to read all mp3 files from sdcard
* and store the details in ArrayList
* */
public ArrayList<HashMap<String, String>> getPlayList(){
File home = new File(MEDIA_PATH);
if (home.listFiles(new FileExtensionFilter()).length > 0) {
for (File file : home.listFiles(new FileExtensionFilter())) {
HashMap<String, String> song = new HashMap<String, String>();
song.put("songTitle", file.getName().substring(0, (file.getName().length() - 4)));
song.put("songPath", file.getPath());
// Adding each song to SongList
songsList.add(song);
}
}
// return songs list array
return songsList;
}
/**
* Class to filter files which are having .mp3 extension
* */
class FileExtensionFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return (name.endsWith(".mp3") || name.endsWith(".MP3"));
}
}
}
and logcat errors:
10-19 02:07:55.147: E/AndroidRuntime(1521): Process: com.example.musicsaround, PID: 1521
10-19 02:07:55.147: E/AndroidRuntime(1521): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.musicsaround/com.example.musicsaround.dj.DJActivity}: android.view.InflateException: Binary XML file line #13: Error inflating class fragment
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.ActivityThread.access$800(ActivityThread.java:135)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.os.Handler.dispatchMessage(Handler.java:102)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.os.Looper.loop(Looper.java:136)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.ActivityThread.main(ActivityThread.java:5001)
10-19 02:07:55.147: E/AndroidRuntime(1521): at java.lang.reflect.Method.invokeNative(Native Method)
10-19 02:07:55.147: E/AndroidRuntime(1521): at java.lang.reflect.Method.invoke(Method.java:515)
10-19 02:07:55.147: E/AndroidRuntime(1521): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
10-19 02:07:55.147: E/AndroidRuntime(1521): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
10-19 02:07:55.147: E/AndroidRuntime(1521): at dalvik.system.NativeStart.main(Native Method)
10-19 02:07:55.147: E/AndroidRuntime(1521): Caused by: android.view.InflateException: Binary XML file line #13: Error inflating class fragment
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
10-19 02:07:55.147: E/AndroidRuntime(1521): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:290)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.Activity.setContentView(Activity.java:1929)
10-19 02:07:55.147: E/AndroidRuntime(1521): at com.example.musicsaround.dj.DJActivity.onCreate(DJActivity.java:62)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.Activity.performCreate(Activity.java:5231)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
10-19 02:07:55.147: E/AndroidRuntime(1521): ... 11 more
10-19 02:07:55.147: E/AndroidRuntime(1521): Caused by: java.lang.NullPointerException
10-19 02:07:55.147: E/AndroidRuntime(1521): at com.example.musicsaround.SongsManager.getPlayList(SongsManager.java:25)
10-19 02:07:55.147: E/AndroidRuntime(1521): at com.example.musicsaround.dj.DJMusicFragment.onCreateView(DJMusicFragment.java:126)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.Fragment.performCreateView(Fragment.java:1700)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:866)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1040)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1142)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.app.Activity.onCreateView(Activity.java:4786)
10-19 02:07:55.147: E/AndroidRuntime(1521): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)
Upvotes: 0
Views: 736
Reputation: 32271
Its right in your log:
9 02:07:55.147: E/AndroidRuntime(1521): Caused by: java.lang.NullPointerException 10-19 02:07:55.147: E/AndroidRuntime(1521): at com.example.musicsaround.SongsManager.getPlayList(SongsManager.java:25) 10-19 02:07:55.147: E/AndroidRuntime(1521): at com.example.musicsaround.dj.DJMusicFragment.onCreateView(DJMusicFragment.java:126)
You got NullPointerException
at line 25 in your SongsManager
class at getPlayList
method.
Upvotes: 2
Reputation: 1388
you can using FrameLayout instead of fragment
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".DJActivity" >
<FrameLayout
android:id="@+id/frag_dj_music"
android:name="com.example.musicsaround.dj.DJMusicFragment"
android:layout_width="match_parent"
android:layout_height="300dp" />
<FrameLayout
android:id="@+id/frag_djs_devices"
android:name="com.example.musicsaround.dj.ServerDeviceListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/txt_dj_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DJ Time" />
</LinearLayout>
Upvotes: 0