/* * Copyright (C) 2014 Kevin Shen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.kevinshen.beyondupnp.ui; import android.app.Activity; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.PopupMenu; import android.widget.TextView; import com.kevinshen.beyondupnp.R; import com.kevinshen.beyondupnp.core.PlaybackCommand; import com.kevinshen.beyondupnp.core.SystemManager; import com.kevinshen.beyondupnp.database.BeyondUpnpContract.PlaylistItem; import com.kevinshen.beyondupnp.util.MD5; import org.fourthline.cling.model.action.ActionInvocation; import org.fourthline.cling.model.message.UpnpResponse; import org.fourthline.cling.model.meta.Device; import org.fourthline.cling.model.meta.Service; import org.fourthline.cling.model.types.UDN; import org.fourthline.cling.support.contentdirectory.DIDLParser; import org.fourthline.cling.support.contentdirectory.callback.Browse; import org.fourthline.cling.support.model.BrowseFlag; import org.fourthline.cling.support.model.DIDLContent; import org.fourthline.cling.support.model.DIDLObject; import org.fourthline.cling.support.model.Res; import org.fourthline.cling.support.model.SortCriterion; import org.fourthline.cling.support.model.container.Container; import org.fourthline.cling.support.model.item.Item; import java.security.NoSuchAlgorithmException; public class ContentContainerActivity extends Activity { private static final String TAG = ContentContainerActivity.class.getSimpleName(); public static final String OBJECT_ID_TAG = "object_id"; public static final String IDENTIFIER_STRING_TAG = "identifier_string"; public static final String CONTENT_CONTAINER_TITLE = "container_title"; private static final int ADD_OBJECTS = 0x01; private String mObjectId; private String mIdentifierString; private DIDLObjectAdapter mDidlObjectAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listview); mObjectId = getIntent().getStringExtra(OBJECT_ID_TAG); mIdentifierString = getIntent().getStringExtra(IDENTIFIER_STRING_TAG); String title = getIntent().getStringExtra(CONTENT_CONTAINER_TITLE); //Display container title. if (title != null) { setTitle(title); }else{ setTitle(""); } mDidlObjectAdapter = new DIDLObjectAdapter(ContentContainerActivity.this); ListView listView = (ListView)findViewById(android.R.id.list); listView.setAdapter(mDidlObjectAdapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { DIDLObject didlObject = mDidlObjectAdapter.getItem(position); if (didlObject instanceof Container){ Intent intent = new Intent(ContentContainerActivity.this,ContentContainerActivity.class); intent.putExtra(ContentContainerActivity.OBJECT_ID_TAG,didlObject.getId()); intent.putExtra(ContentContainerActivity.IDENTIFIER_STRING_TAG,mIdentifierString); intent.putExtra(ContentContainerActivity.CONTENT_CONTAINER_TITLE,didlObject.getTitle()); startActivity(intent); }else if (didlObject instanceof Item){ Item item = (Item)didlObject; playItem(item); } } }); loadContent(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_content_container, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_close) { Intent intent = new Intent(getApplication(),MainActivity.class); startActivity(intent); return true; } return super.onOptionsItemSelected(item); } @Override protected void onDestroy() { super.onDestroy(); } private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ case ADD_OBJECTS: DIDLContent didlContent = (DIDLContent)msg.obj; mDidlObjectAdapter.addAll(didlContent.getContainers()); mDidlObjectAdapter.addAll(didlContent.getItems()); break; } } }; private void playItem(Item item){ if (item == null) return; Res res = item.getFirstResource(); String uri = res.getValue(); DIDLContent content = new DIDLContent(); content.addItem(item); DIDLParser didlParser = new DIDLParser(); String metadata = null; try { metadata = didlParser.generate(content); } catch (Exception e) { //ignore } //Log.d(TAG,"Item metadata:" + metadata); //Play on the selected device. PlaybackCommand.playNewItem(uri,metadata); } private void addToPlaylist(Item item){ if (item == null) return; Res res = item.getFirstResource(); String uri = res.getValue(); //Parse content. DIDLContent content = new DIDLContent(); content.addItem(item); DIDLParser didlParser = new DIDLParser(); String metadata = null; try { //Generate track metadata. metadata = didlParser.generate(content); } catch (Exception e) { //ignore } String albumUri = null; try{ for (DIDLObject.Property property: item.getProperties()){ if (property instanceof DIDLObject.Property.UPNP.ALBUM_ART_URI){ albumUri = ((DIDLObject.Property.UPNP.ALBUM_ART_URI) property).getValue().toString(); } } }catch (Exception e){ //ignore } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(item.getCreator()); stringBuilder.append(item.getTitle()); stringBuilder.append(res.getSize()); //Create md5 code String md5 = null; try { md5 = MD5.createMD5(stringBuilder.toString()); } catch (NoSuchAlgorithmException e) { md5 = null; } ContentValues values = new ContentValues(); values.put(PlaylistItem.ITEM_TITLE,item.getTitle()); values.put(PlaylistItem.ITEM_URI,uri); values.put(PlaylistItem.ITEM_THUMB,albumUri); values.put(PlaylistItem.ITEM_METADATA,metadata); values.put(PlaylistItem.ITEM_DATE,System.currentTimeMillis()); values.put(PlaylistItem.ITEM_VERIFICATION_CODE,md5); getContentResolver().insert(PlaylistItem.CONTENT_URI, values); } private void loadContent() { SystemManager systemManager = SystemManager.getInstance(); Device device = null; try { device = systemManager.getRegistry().getDevice(new UDN(mIdentifierString), false); } catch (NullPointerException e) { Log.e(TAG, "Get device error."); } if (device != null) { //Get cds to browse children directories. Service contentDeviceService = device.findService(SystemManager.CONTENT_DIRECTORY_SERVICE); //Execute Browse action and init list view systemManager.getControlPoint().execute(new Browse(contentDeviceService, mObjectId, BrowseFlag.DIRECT_CHILDREN, "*", 0, null, new SortCriterion(true, "dc:title")) { @Override public void received(ActionInvocation actionInvocation, DIDLContent didl) { Message msg = Message.obtain(handler,ADD_OBJECTS,didl); msg.sendToTarget(); } @Override public void updateStatus(Status status) { } @Override public void failure(ActionInvocation invocation, UpnpResponse operation, String defaultMsg) { } }); } } private class DIDLObjectAdapter extends ArrayAdapter<DIDLObject> { private LayoutInflater mLayoutInflater; public DIDLObjectAdapter(Context context) { super(context, 0); mLayoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) convertView = mLayoutInflater.inflate(R.layout.listview_items, null); final DIDLObject item = getItem(position); if (item == null) { return convertView; } //Init container icon if (item instanceof Container){ ImageView imageView = (ImageView)convertView.findViewById(R.id.listview_item_image); imageView.setBackgroundResource(R.drawable.ic_action_dock); }else if (item instanceof Item){ ImageView moreBtn = (ImageView)convertView.findViewById(R.id.listview_item_popup_menu); moreBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Init popup menu. PopupMenu popupMenu = new PopupMenu(ContentContainerActivity.this, v); popupMenu.inflate(R.menu.menu_item_actions); popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem menuItem) { switch (menuItem.getItemId()){ case R.id.action_play : playItem((Item)item); break; case R.id.action_add_to_playlist : addToPlaylist((Item)item); break; default: break; } return true; } }); popupMenu.show(); } }); moreBtn.setVisibility(View.VISIBLE); } TextView titleView = (TextView)convertView.findViewById(R.id.listview_item_line_one); titleView.setText(item.getTitle()); TextView creatorView = (TextView)convertView.findViewById(R.id.listview_item_line_two); creatorView.setText(item.getCreator()); return convertView; } } }