2

我使用cling库为 DLNA 创建了演示。我已按照cling android page上给出的所有说明进行操作。但它给了我内存不足的错误。我已经在 HTC salsa 和三星 Galaxy S3 上对其进行了测试。

日志:

    08-17 13:45:26.032: E/AndroidRuntime(1504): FATAL EXCEPTION: Thread 12 (Active: 4)
08-17 13:45:26.032: E/AndroidRuntime(1504): java.lang.OutOfMemoryError
08-17 13:45:26.032: E/AndroidRuntime(1504):     at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:97)
08-17 13:45:26.032: E/AndroidRuntime(1504):     at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:144)
08-17 13:45:26.032: E/AndroidRuntime(1504):     at java.lang.StringBuilder.append(StringBuilder.java:125)
08-17 13:45:26.032: E/AndroidRuntime(1504):     at org.teleal.common.http.Headers.readLine(Headers.java:193)
08-17 13:45:26.032: E/AndroidRuntime(1504):     at org.teleal.common.http.Headers.<init>(Headers.java:73)
08-17 13:45:26.032: E/AndroidRuntime(1504):     at org.teleal.cling.model.message.UpnpHeaders.<init>(UpnpHeaders.java:50)
08-17 13:45:26.032: E/AndroidRuntime(1504):     at org.teleal.cling.transport.impl.DatagramProcessorImpl.readRequestMessage(DatagramProcessorImpl.java:127)
08-17 13:45:26.032: E/AndroidRuntime(1504):     at org.teleal.cling.transport.impl.DatagramProcessorImpl.read(DatagramProcessorImpl.java:63)
08-17 13:45:26.032: E/AndroidRuntime(1504):     at org.teleal.cling.transport.impl.MulticastReceiverImpl.run(MulticastReceiverImpl.java:125)
08-17 13:45:26.032: E/AndroidRuntime(1504):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
08-17 13:45:26.032: E/AndroidRuntime(1504):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
08-17 13:45:26.032: E/AndroidRuntime(1504):     at java.lang.Thread.run(Thread.java:1102)

主要活动:

    package com.example.demodlns;

import org.teleal.cling.android.AndroidUpnpService;
import org.teleal.cling.android.AndroidUpnpServiceImpl;
import org.teleal.cling.model.meta.Device;
import org.teleal.cling.model.meta.LocalDevice;
import org.teleal.cling.model.meta.RemoteDevice;
import org.teleal.cling.model.meta.Service;
import org.teleal.cling.registry.DefaultRegistryListener;
import org.teleal.cling.registry.Registry;

import android.app.ListActivity;
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.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Toast;

public class MainActivity extends ListActivity {
    private ArrayAdapter<DeviceDisplay> listAdapter;
    private BrowseRegistryListener registryListener = new BrowseRegistryListener();
    private AndroidUpnpService upnpService;
    private ServiceConnection serviceConnection = new ServiceConnection() {     
        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            // TODO Auto-generated method stub         
            upnpService = null;         
        }

        @Override
        public void onServiceConnected(ComponentName arg0, IBinder service) {
            // TODO Auto-generated method stub          
            Log.d("test", "service connection establish");

            upnpService = (AndroidUpnpService) service; 

            // Clear the list
            listAdapter.clear();

            // Get ready for future device advertisements
            upnpService.getRegistry().addListener(registryListener);

            // Now add all devices to the list we already know about
            for (Device device : upnpService.getRegistry().getDevices()) {
                registryListener.deviceAdded(device);                  
            }

            // Search asynchronously for all devices, they will respond soon
            upnpService.getControlPoint().search();                         
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        listAdapter = new ArrayAdapter<DeviceDisplay>(this, android.R.layout.simple_list_item_1);
        setListAdapter(listAdapter);    
        bindService(new Intent(MainActivity.this, AndroidUpnpServiceImpl.class),serviceConnection, Context.BIND_AUTO_CREATE );
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();      
        if (upnpService != null) {
            upnpService.getRegistry().removeListener(registryListener);
        }
        // This will stop the UPnP service if nobody else is bound to it
        getApplicationContext().unbindService(serviceConnection);        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
          menu.add(0, 0, 0, R.string.searchLAN).setIcon(android.R.drawable.ic_menu_search);
        return true;

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
          Log.d("test","ID:"+ item.getItemId());
          if (item.getItemId() == 0 && upnpService != null) {
             Log.d("test", "search");
             upnpService.getRegistry().removeAllRemoteDevices();
             upnpService.getControlPoint().search();
          }
          return false;
    }


     class BrowseRegistryListener extends DefaultRegistryListener {

            /* Discovery performance optimization for very slow Android devices! */

            public void remoteDeviceDiscoveryStarted(Registry registry, RemoteDevice device) {              
                deviceAdded(device);
            }


            public void remoteDeviceDiscoveryFailed(Registry registry, final RemoteDevice device, final Exception ex) {
                runOnUiThread(new Runnable() {
                    public void run() {
                        Toast.makeText(
                            MainActivity.this,
                            "Discovery failed of '" + device.getDisplayString() + "': "
                                + (ex != null ? ex.toString() : "Couldn't retrieve device/service descriptors"),
                            Toast.LENGTH_LONG
                        ).show();
                    }
                });
                deviceRemoved(device);
            }
            /* End of optimization, you can remove the whole block if your Android handset is fast (>= 600 Mhz) */


            public void remoteDeviceAdded(Registry registry, RemoteDevice device) {
                deviceAdded(device);

            }


            public void remoteDeviceRemoved(Registry registry, RemoteDevice device) {
                deviceRemoved(device);

            }


            public void localDeviceAdded(Registry registry, LocalDevice device) {
                deviceAdded(device);
            }


            public void localDeviceRemoved(Registry registry, LocalDevice device) {
                deviceRemoved(device);

            }

            public void deviceAdded(final Device device) {              
                runOnUiThread(new Runnable() {
                    public void run() {
                        DeviceDisplay d = new DeviceDisplay(device);
                        int position = listAdapter.getPosition(d);
                        if (position >= 0) {
                            // Device already in the list, re-set new value at same position
                            listAdapter.remove(d);
                            listAdapter.insert(d, position);
                        } else {
                            listAdapter.add(d);
                        }
                    }
                });
            }

            public void deviceRemoved(final Device device) {
                Log.d("test", "RDRemove");
                runOnUiThread(new Runnable() {
                    public void run() {
                        listAdapter.remove(new DeviceDisplay(device));
                    }
                });
            }
        }


     class DeviceDisplay {

            Device device;

            public DeviceDisplay(Device device) {
                this.device = device;
            }

            public Device getDevice() {
                return device;
            }

            // DOC:DETAILSAndroidUpnpService
            public String getDetailsMessage() {
                StringBuilder sb = new StringBuilder();
                if (getDevice().isFullyHydrated()) {
                    sb.append(getDevice().getDisplayString());
                    sb.append("\n\n");
                    for (Service service : getDevice().getServices()) {
                        sb.append(service.getServiceType()).append("\n");
                    }
                } else {
                    sb.append(getString(R.string.deviceDetailsNotYetAvailable));
                }
                Log.d("test", "SB "+sb.toString());
                return sb.toString();
            }
            // DOC:DETAILS

            @Override
            public boolean equals(Object o) {
                if (this == o) return true;
                if (o == null || getClass() != o.getClass()) return false;
                DeviceDisplay that = (DeviceDisplay) o;
                return device.equals(that.device);
            }

            @Override
            public int hashCode() {
                return device.hashCode();
            }

            @Override
            public String toString() {
                String name =
                    getDevice().getDetails() != null && getDevice().getDetails().getFriendlyName() != null
                        ? getDevice().getDetails().getFriendlyName()
                        : getDevice().getDisplayString();
                // Display a little star while the device is being loaded (see performance optimization earlier)
                return device.isFullyHydrated() ? name : name + " *";
            }
        }

}

显现:

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.demodlns"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>


    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.demodlns.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name="org.teleal.cling.android.AndroidUpnpServiceImpl"/>

    </application>

</manifest>

我错过了什么吗?任何帮助表示赞赏。

提前致谢。

4

0 回答 0