2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-22 09:58:08 +00:00
This commit is contained in:
Albert Vaca 2015-08-20 00:59:21 -07:00
parent 0eb3c6e9f5
commit 12334f5a31
46 changed files with 1839 additions and 72 deletions

View File

@ -8,22 +8,27 @@
android:targetSdkVersion="22" />
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true"
/>
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:xlargeScreens="true" />
<uses-feature android:name="android.hardware.telephony" android:required="false" />
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" android:required="false" />
<uses-permission
android:name="android.permission.READ_PHONE_STATE"
android:required="false" />
<uses-permission android:name="android.permission.BATTERY_STATS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" android:required="false" />
<uses-permission
android:name="android.permission.RECEIVE_SMS"
android:required="false" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@ -36,14 +41,14 @@
>
<service
android:enabled="true"
android:name="org.kde.kdeconnect.BackgroundService">
android:name="org.kde.kdeconnect.BackgroundService"
android:enabled="true" >
</service>
<activity
android:name="org.kde.kdeconnect.UserInterface.MainActivity"
android:label="KDE Connect" >
android:name="org.kde.kdeconnect.NewUserInterface.MaterialActivity"
android:label="KDE Connect"
android:theme="@style/KdeConnectTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@ -51,65 +56,74 @@
</activity>
<activity
android:name="org.kde.kdeconnect.UserInterface.MainSettingsActivity"
android:label="@string/settings"
android:parentActivityName="org.kde.kdeconnect.UserInterface.MainActivity"
android:name="org.kde.kdeconnect.UserInterface.MainActivity"
android:label="KDE Connect"
>
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="org.kde.kdeconnect.UserInterface.MainSettingsActivity"
android:label="@string/settings"
android:parentActivityName="org.kde.kdeconnect.UserInterface.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity>
<activity
android:name="org.kde.kdeconnect.UserInterface.DeviceActivity"
android:label="@string/device"
android:parentActivityName="org.kde.kdeconnect.UserInterface.MainActivity"
>
<meta-data android:name="android.support.PARENT_ACTIVITY"
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity>
<activity
android:name="org.kde.kdeconnect.UserInterface.PairActivity"
android:label="@string/pair_device"
android:parentActivityName="org.kde.kdeconnect.UserInterface.MainActivity"
>
<meta-data android:name="android.support.PARENT_ACTIVITY"
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity>
<activity
android:name="org.kde.kdeconnect.UserInterface.SettingsActivity"
android:label="@string/device_menu_plugins"
android:parentActivityName="org.kde.kdeconnect.UserInterface.DeviceActivity"
>
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:parentActivityName="org.kde.kdeconnect.UserInterface.DeviceActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.DeviceActivity" />
</activity>
<activity
android:name="org.kde.kdeconnect.UserInterface.CustomDevicesActivity"
android:label="@string/custom_devices_settings"
android:parentActivityName="org.kde.kdeconnect.UserInterface.DeviceActivity"
>
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:parentActivityName="org.kde.kdeconnect.UserInterface.DeviceActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.DeviceActivity" />
</activity>
<activity
android:name="org.kde.kdeconnect.UserInterface.PluginSettingsActivity"
android:label="@string/device_menu_plugins"
android:parentActivityName="org.kde.kdeconnect.UserInterface.SettingsActivity"
>
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:parentActivityName="org.kde.kdeconnect.UserInterface.SettingsActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.SettingsActivity" />
</activity>
<receiver android:name="org.kde.kdeconnect.KdeConnectBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" android:path="org.kde.kdeconnect" />
<data
android:path="org.kde.kdeconnect"
android:scheme="package" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
@ -120,7 +134,8 @@
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
<!--<intent-filter>
<!--
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
<intent-filter>
@ -128,7 +143,8 @@
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED" />
</intent-filter>-->
</intent-filter>
-->
</receiver>
<!-- Plugin-related activities and services -->
@ -138,39 +154,43 @@
android:label="@string/remote_control"
android:parentActivityName="org.kde.kdeconnect.UserInterface.DeviceActivity"
>
<meta-data android:name="android.support.PARENT_ACTIVITY"
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.DeviceActivity" />
</activity>
<activity
android:name="org.kde.kdeconnect.Plugins.MousePadPlugin.MousePadActivity"
android:label="@string/remote_control"
android:windowSoftInputMode="stateHidden|adjustResize"
android:configChanges="orientation|keyboardHidden|screenSize"
android:screenOrientation="fullSensor"
android:label="@string/remote_control"
android:parentActivityName="org.kde.kdeconnect.UserInterface.DeviceActivity"
>
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:screenOrientation="fullSensor"
android:windowSoftInputMode="stateHidden|adjustResize" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.DeviceActivity" />
</activity>
<activity
android:name="org.kde.kdeconnect.Plugins.SharePlugin.ShareActivity"
android:label="KDE Connect"
>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
<service android:name="org.kde.kdeconnect.Plugins.NotificationsPlugin.NotificationReceiver"
<service
android:name="org.kde.kdeconnect.Plugins.NotificationsPlugin.NotificationReceiver"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 994 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/my_accent" />
<corners android:bottomRightRadius="2dip"
android:bottomLeftRadius="2dip"
android:topRightRadius="2dip"
android:topLeftRadius="2dip"/>
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/drawer_header"
android:gravity="center|clip_vertical|clip_horizontal"
/>

View File

@ -3,11 +3,7 @@
android:id="@+id/buttons_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:layout_margin="16dip"
android:fillViewport="true"
android:divider="@null"
tools:context=".MainActivity"
tools:context=".DeviceActivity"
/>

View File

@ -2,10 +2,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:layout_margin="16dip"
tools:context=".MainActivity"
android:id="@+id/listView1"
android:addStatesFromChildren="true"

View File

@ -0,0 +1,36 @@
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="org.kde.kdeconnect.NewUserInterface.MaterialActivity"> <!-- fitSystemWindows to make the drawer slide below the Lollipop transparent status bar -->
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:background="?attr/colorPrimary" />
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation_drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"
/>
</android.support.v4.widget.DrawerLayout>

View File

@ -0,0 +1,12 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="org.kde.kdeconnect.NewUserInterface.MaterialActivity$PlaceholderFragment">
<TextView android:id="@+id/section_label" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>

View File

@ -0,0 +1,77 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/my_primary"
android:orientation="vertical"
tools:context="org.kde.kdeconnect.NewUserInterface.NavigationDrawerFragment" >
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:padding="15dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="This device!"
android:layout_gravity="center_vertical"
android:layout_weight="1" />
<ImageView
android:src="@drawable/ic_action_image_edit"
android:padding="10dp"
android:clickable="true"
android:background="@drawable/abc_list_selector_holo_dark"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:contentDescription="string/re"
android:longClickable="true"
android:id="@+id/rename" />
</LinearLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="322dp"
android:id="@+id/deviceList"
android:choiceMode="singleChoice"
android:background="#FFFFFF"
android:layout_gravity="center_horizontal"
android:layout_weight="1" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dip"
android:clickable="true"
android:background="@drawable/abc_list_selector_holo_dark"
android:id="@+id/add_device_button"
android:layout_gravity="center_horizontal"
android:nestedScrollingEnabled="false">
<ImageView
android:src="@drawable/ic_action_content_add_circle_outline"
android:layout_margin="5dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/pair_device_action"
android:layout_gravity="center_vertical" />
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:baselineAligned="false"
android:layout_height="wrap_content"
android:paddingLeft="12dip"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize"
android:orientation="horizontal">
<ImageView android:id="@+id/list_item_entry_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_device_laptop"
android:layout_weight="0" />
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_weight="1"
android:layout_height="wrap_content">
<TextView android:id="@+id/list_item_entry_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dip"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:text=""/>
<TextView android:id="@+id/list_item_entry_summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:singleLine="true"
android:textColor="#CC2222"
android:visibility="gone"
android:text="" />
</LinearLayout>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progressBar"
android:layout_weight="0"
android:indeterminate="true" />
<Button
android:layout_width="wrap_content"
android:minWidth="128dip"
android:layout_height="wrap_content"
android:text="Request pair"
android:padding="8dip"
android:background="@drawable/button_round"
android:textColor="#FFFFFF"
android:id="@+id/entry_pair_button"
android:layout_weight="0"
android:nestedScrollingEnabled="false" />
</LinearLayout>

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:baselineAligned="false"
android:layout_height="wrap_content"
android:paddingLeft="12dip"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize"
android:clickable="true"
android:background="@drawable/abc_list_selector_holo_dark"
android:orientation="horizontal">
<ImageView android:id="@+id/list_item_entry_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_device_laptop"
/>
<LinearLayout
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView android:id="@+id/list_item_entry_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dip"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:text="" />
<TextView android:id="@+id/list_item_entry_summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:singleLine="true"
android:textColor="#CC2222"
android:visibility="gone"
android:text="" />
</LinearLayout>
</LinearLayout>

49
res/layout/nav_header.xml Normal file
View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="160dp"
android:padding="16dp"
android:background="@drawable/drawer_header"
android:orientation="vertical"
android:gravity="bottom">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="KDE Connect"
android:textColor="#FFF"
android:textStyle="bold"
android:paddingBottom="4dp"
android:layout_above="@+id/device_name"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="My device"
android:id="@+id/device_name"
android:layout_marginBottom="8dp"
android:textColor="#fff"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
/>
<!--
<ImageView
android:src="@drawable/ic_action_image_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:clickable="true"
android:background="@drawable/abc_list_selector_holo_dark"
android:layout_gravity="center_vertical"
android:contentDescription="@string/rename_device"
android:id="@+id/rename"
/>
-->
</RelativeLayout>

5
res/menu/global.xml Normal file
View File

@ -0,0 +1,5 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_settings" android:title="@string/settings"
android:orderInCategory="100" app:showAsAction="never" />
</menu>

36
res/menu/new_pairing.xml Normal file
View File

@ -0,0 +1,36 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:kdeconnect="http://schemas.android.com/apk/res-auto/android">
<item
android:id="@+id/menu_refresh"
android:icon="@drawable/ic_action_refresh"
android:orderInCategory="200"
kdeconnect:showAsAction="ifRoom"
android:title="@string/reconnect"
/>
<item
android:id="@+id/menu_progress"
android:orderInCategory="200"
android:visible="false"
kdeconnect:showAsAction="ifRoom"
kdeconnect:actionViewClass="android.widget.ProgressBar"
/>
<item
android:id="@+id/menu_settings"
android:icon="@drawable/ic_action_settings"
android:orderInCategory="300"
android:title="@string/settings"
kdeconnect:showAsAction="never"
/>
<item
android:id="@+id/menu_custom_device_list"
android:icon="@drawable/ic_action_settings"
android:orderInCategory="900"
android:title="@string/custom_device_list"
kdeconnect:showAsAction="never"
/>
</menu>

20
res/menu/refresh.xml Normal file
View File

@ -0,0 +1,20 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:kdeconnect="http://schemas.android.com/apk/res-auto/android">
<item
android:id="@+id/menu_refresh"
android:icon="@drawable/ic_action_refresh"
android:orderInCategory="200"
kdeconnect:showAsAction="ifRoom"
android:title="@string/reconnect"
/>
<item
android:id="@+id/menu_progress"
android:orderInCategory="200"
android:visible="false"
kdeconnect:showAsAction="ifRoom"
kdeconnect:actionViewClass="android.widget.ProgressBar"
/>
</menu>

View File

@ -0,0 +1,6 @@
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>

14
res/values/colors.xml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="window_background">#CC000000</color>
<color name="my_primary">#ED1C24</color>
<color name="my_primary_dark">#CC0000</color>
<color name="my_primary_light">#B3E5FC</color>
<color name="my_accent">#ED1C24</color>
<color name="my_primary_text">#ffffff</color>
<color name="my_secondary_text">#ffffff</color>
<color name="my_icons">#FFFFFF</color>
<color name="my_divider">#B6B6B6</color>
</resources>

View File

@ -2,4 +2,13 @@
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<!-- Per the design guidelines, navigation drawers should be between 240dp and 320dp:
https://developer.android.com/design/patterns/navigation-drawer.html -->
<dimen name="navigation_drawer_width">320dp</dimen>
<dimen name="card_margin">16dp</dimen><dimen name="detail_backdrop_height">256dp</dimen>
</resources>

View File

@ -125,6 +125,8 @@
<string name="invalid_device_name">Invalid device name</string>
<string name="shareplugin_text_saved">Received text, saved to clipboard</string>
<string name="custom_devices_settings">Custom device list</string>
<string name="pair_device_action">Pair a new device</string>
<string name="unpair_device_action">Unpair %s</string>
<string name="custom_device_list">Add devices by IP</string>
<string name="share_notification_preference">Noisy notifications</string>
<string name="share_notification_preference_summary">Vibrate and play a sound when receiving a file</string>
@ -141,5 +143,8 @@
<string name="no_players_connected">No players found</string>
<string name="custom_dev_list_help">Use this option only if your device is not automatically detected. Enter IP address or hostname below and touch the button to add it to the list. Touch an existing item to remove it from the list.</string>
<string name="mpris_player_on_device">%1$s on %2$s</string>
<string name="send_files">Send files</string>
<string name="pairing_title">KDE Connect Devices</string>
</resources>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="drawer_open">Open navigation drawer</string>
<string name="drawer_close">Close navigation drawer</string>
</resources>

View File

@ -1,7 +1,22 @@
<resources>
<color name="primary">#3daee9</color>
<color name="primaryDark">#318bba</color>
<color name="accent">#4ebffa</color>
<style name="KdeConnectTheme" parent="Theme.AppCompat">
<color name="positive">#689F38</color>
<color name="negative">#FF5252</color>
<!-- NoActionBar because we use a Toolbar widget as ActionBar -->
<style name="KdeConnectTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- The three colors used by system widgets, according to https://chris.banes.me/2014/10/17/appcompat-v21/ -->
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primaryDark</item>
<item name="colorAccent">@color/accent</item>
</style>
<style name="KdeConnectTheme.NoActionBar" parent="KdeConnectTheme">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
</resources>

16
res/values/styles_nou.xml Normal file
View File

@ -0,0 +1,16 @@
<resources><style name="Base.Theme.HMKCodeApp" parent="Theme.AppCompat.NoActionBar"><item name="colorPrimary">@color/my_primary</item><!-- darker variant for the status bar and contextual app bars
--><item name="colorPrimaryDark">@color/my_primary_dark</item><!-- theme UI controls like checkboxes and text fields e.g. FloatActionButton
--><item name="colorAccent">@color/my_accent</item><!-- Title Text Color -->
<item name="android:textColorPrimary">@color/my_primary_text</item><!-- color of the menu overflow icon (three vertical dots)
--><item name="android:textColorSecondary">@color/my_secondary_text</item><item name="android:windowBackground">@color/window_background</item></style><!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
--><style name="AppBaseTheme" parent="Base.Theme.HMKCodeApp"><!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
--></style><!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme"><!-- All customizations that are NOT specific to a particular API-level can go here.
--></style><style name="Widget.CardContent" parent="android:Widget"><item name="android:paddingLeft">16dp</item><item name="android:paddingRight">16dp</item><item name="android:paddingTop">24dp</item><item name="android:paddingBottom">24dp</item><item name="android:orientation">vertical</item></style></resources>

View File

@ -0,0 +1,271 @@
/*
* Copyright 2014 Albert Vaca Cintora <albertvaka@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.NewUserInterface;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
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.Button;
import android.widget.ListView;
import android.widget.TextView;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NewUserInterface.List.PluginItem;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.UserInterface.List.ButtonItem;
import org.kde.kdeconnect.UserInterface.List.CustomItem;
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
import org.kde.kdeconnect.UserInterface.List.SmallEntryItem;
import org.kde.kdeconnect.UserInterface.List.TextItem;
import org.kde.kdeconnect.UserInterface.SettingsActivity;
import org.kde.kdeconnect_tp.R;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
/**
* Main view. Displays the current device and its plugins
*/
public class DeviceFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_DEVICE_ID = "deviceId";
private View rootView;
static private String mDeviceId; //Static because if we get here by using the back button in the action bar, the extra deviceId will not be set.
private Device device;
public static final int RESULT_NEEDS_RELOAD = Activity.RESULT_FIRST_USER;
private TextView errorHeader;
private Activity mActivity;
public DeviceFragment(String deviceId) {
Bundle args = new Bundle();
args.putString(ARG_DEVICE_ID, deviceId);
this.setArguments(args);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mActivity = getActivity();
rootView = inflater.inflate(R.layout.activity_device, container, false);
String deviceId = getArguments().getString(ARG_DEVICE_ID);
if (deviceId != null) {
mDeviceId = deviceId;
}
Log.e("DeviceFragment","device: " +deviceId);
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
device = service.getDevice(mDeviceId);
if (device == null) return;
mActivity.setTitle(device.getName());
device.addPluginsChangedListener(pluginsChangedListener);
pluginsChangedListener.onPluginsChanged(device);
if (!device.hasPluginsLoaded()) {
device.reloadPluginsFromSettings();
}
}
});
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
private final Device.PluginsChangedListener pluginsChangedListener = new Device.PluginsChangedListener() {
@Override
public void onPluginsChanged(final Device device) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
ArrayList<ListAdapter.Item> items = new ArrayList<ListAdapter.Item>();
if (!device.isReachable()) {
//Not reachable, show unpair button
Button b = new Button(mActivity);
b.setText(R.string.device_menu_unpair);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
device.unpair();
//finish();
}
});
items.add(new TextItem(getString(R.string.device_not_reachable)));
items.add(new ButtonItem(b));
} else {
//Plugins button list
final Collection<Plugin> plugins = device.getLoadedPlugins().values();
for (final Plugin p : plugins) {
if (!p.hasMainActivity()) continue;
if (p.displayInContextMenu()) continue;
items.add(new PluginItem(p, new View.OnClickListener() {
@Override
public void onClick(View v) {
p.startMainActivity(mActivity);
}
}));
}
//Failed plugins List
final Collection<Plugin> failed = device.getFailedPlugins().values();
if (!failed.isEmpty()) {
if (errorHeader == null) {
errorHeader = new TextView(mActivity);
errorHeader.setPadding(0, 48, 0, 0);
errorHeader.setOnClickListener(null);
errorHeader.setOnLongClickListener(null);
errorHeader.setText(getResources().getString(R.string.plugins_failed_to_load));
}
items.add(new CustomItem(errorHeader));
for (final Plugin p : failed) {
items.add(new SmallEntryItem(p.getDisplayName(), new View.OnClickListener() {
@Override
public void onClick(View v) {
p.getErrorDialog(mActivity).show();
}
}));
}
}
}
ListView buttonsList = (ListView) rootView.findViewById(R.id.buttons_list);
ListAdapter adapter = new ListAdapter(mActivity, items);
buttonsList.setAdapter(adapter);
} catch (ConcurrentModificationException e) {
Log.e("DeviceActivity", "ConcurrentModificationException");
this.run(); //Try again
}
}
});
}
};
@Override
public void onDestroyView() {
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(mDeviceId);
if (device == null) return;
device.removePluginsChangedListener(pluginsChangedListener);
}
});
super.onDestroyView();
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.clear();
if (device == null || !device.isPaired()) {
return;
}
//Plugins button list
final Collection<Plugin> plugins = device.getLoadedPlugins().values();
for (final Plugin p : plugins) {
if (!p.displayInContextMenu()) {
continue;
}
menu.add(p.getActionName()).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
p.startMainActivity(mActivity);
return true;
}
});
}
menu.add(R.string.device_menu_plugins).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
Intent intent = new Intent(mActivity, SettingsActivity.class);
intent.putExtra("deviceId", mDeviceId);
startActivity(intent);
return true;
}
});
menu.add(R.string.device_menu_unpair).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
device.unpair();
//finish();
return true;
}
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode)
{
case RESULT_NEEDS_RELOAD:
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(mDeviceId);
device.reloadPluginsFromSettings();
}
});
break;
default:
super.onActivityResult(requestCode, resultCode, data);
}
}
}

View File

@ -0,0 +1,117 @@
/*
* Copyright 2014 Albert Vaca Cintora <albertvaka@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.NewUserInterface.List;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NewUserInterface.NavigationDrawerFragment;
import org.kde.kdeconnect.UserInterface.DeviceActivity;
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
import org.kde.kdeconnect.UserInterface.PairActivity;
import org.kde.kdeconnect_tp.R;
public class MaterialDeviceItem implements ListAdapter.Item {
private final Device device;
private final Activity activity;
private final NavigationDrawerFragment.NavigationDrawerCallbacks callback;
private TextView titleView;
private ImageView icon;
private View rootView;
public MaterialDeviceItem(Activity activity, Device device, NavigationDrawerFragment.NavigationDrawerCallbacks callback) {
this.device = device;
this.activity = activity;
this.callback = callback;
}
@Override
public View inflateView(LayoutInflater layoutInflater) {
rootView = layoutInflater.inflate(R.layout.list_item_with_icon_entry, null);
icon = (ImageView)rootView.findViewById(R.id.list_item_entry_icon);
icon.setImageDrawable(device.getIcon());
titleView = (TextView)rootView.findViewById(R.id.list_item_entry_title);
titleView.setText(device.getName());
if (device.compareProtocolVersion() != 0) {
TextView summaryView = (TextView)rootView.findViewById(R.id.list_item_entry_summary);
summaryView.setVisibility(View.VISIBLE);
if (device.compareProtocolVersion() > 0) {
summaryView.setText(R.string.protocol_version_newer);
} else {
summaryView.setText(R.string.protocol_version_older);
}
} else {
rootView.findViewById(R.id.list_item_entry_summary).setVisibility(View.GONE);
}
rootView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent;
if (device.isPaired()) {
//intent = new Intent(activity, DeviceActivity.class);
//intent.putExtra("deviceId", device.getDeviceId());
//activity.startActivity(intent);
setSelected(true);
callback.onDeviceSelected(device);
} else {
intent = new Intent(activity, PairActivity.class);
intent.putExtra("deviceId", device.getDeviceId());
activity.startActivity(intent);
}
}
});
return rootView;
}
void setSelected(boolean b) {
Resources r = activity.getResources();
if (b) {
titleView.setTextColor(r.getColor(R.color.primaryDark));
titleView.setTypeface(Typeface.DEFAULT_BOLD);
} else {
titleView.setTextColor(r.getColor(android.R.color.black));
titleView.setTypeface(Typeface.DEFAULT);
}
Drawable drawable = device.getIcon();
drawable.setColorFilter(r.getColor(R.color.primaryDark), PorterDuff.Mode.SRC_ATOP);
icon.setImageDrawable(drawable);
}
}

View File

@ -0,0 +1,93 @@
/*
* Copyright 2014 Albert Vaca Cintora <albertvaka@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.NewUserInterface.List;
import android.app.Activity;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
import org.kde.kdeconnect.UserInterface.PairActivity;
import org.kde.kdeconnect_tp.R;
public class PairingDeviceItem implements ListAdapter.Item {
private final Device device;
private final Activity activity;
private TextView titleView;
private ImageView icon;
public PairingDeviceItem(Activity activity, Device device) {
this.device = device;
this.activity = activity;
}
@Override
public View inflateView(LayoutInflater layoutInflater) {
final View v = layoutInflater.inflate(R.layout.list_item_with_button_entry, null);
icon = (ImageView)v.findViewById(R.id.list_item_entry_icon);
icon.setImageDrawable(device.getIcon());
titleView = (TextView)v.findViewById(R.id.list_item_entry_title);
titleView.setText(device.getName());
if (device.compareProtocolVersion() != 0) {
TextView summaryView = (TextView)v.findViewById(R.id.list_item_entry_summary);
summaryView.setVisibility(View.VISIBLE);
if (device.compareProtocolVersion() > 0) {
summaryView.setText(R.string.protocol_version_newer);
} else {
summaryView.setText(R.string.protocol_version_older);
}
} else {
v.findViewById(R.id.list_item_entry_summary).setVisibility(View.GONE);
}
Button b = (Button)v.findViewById(R.id.entry_pair_button);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent;
/*if (device.isPaired()) {
//intent = new Intent(activity, DeviceActivity.class);
//intent.putExtra("deviceId", device.getDeviceId());
//activity.startActivity(intent);
//callback.onDeviceSelected(device);
} else {
intent = new Intent(activity, PairActivity.class);
intent.putExtra("deviceId", device.getDeviceId());
activity.startActivity(intent);
}*/
}
});
return v;
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright 2014 Albert Vaca Cintora <albertvaka@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.NewUserInterface.List;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
import org.kde.kdeconnect_tp.R;
public class PluginItem implements ListAdapter.Item {
private final Plugin plugin;
private final View.OnClickListener clickListener;
public PluginItem(Plugin p, View.OnClickListener clickListener) {
this.plugin = p;
this.clickListener = clickListener;
}
@Override
public View inflateView(final LayoutInflater layoutInflater) {
View v = layoutInflater.inflate(R.layout.list_item_with_icon_entry, null);
TextView titleView = (TextView)v.findViewById(R.id.list_item_entry_title);
titleView.setText(plugin.getActionName());
ImageView imageView = (ImageView)v.findViewById(R.id.list_item_entry_icon);
imageView.setImageDrawable(plugin.getIcon());
v.setOnClickListener(clickListener);
return v;
}
}

View File

@ -0,0 +1,193 @@
package org.kde.kdeconnect.NewUserInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.UserInterface.MainSettingsActivity;
import org.kde.kdeconnect_tp.R;
import java.util.Collection;
import java.util.HashMap;
public class MaterialActivity extends AppCompatActivity {
private static final String STATE_SELECTED_DEVICE = "selected_device";
private NavigationView mNavigationView;
private DrawerLayout mDrawerLayout;
private String mCurrentDevice;
HashMap<MenuItem, String> mMapMenuToDeviceId = new HashMap<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_material);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mNavigationView = (NavigationView) findViewById(R.id.navigation_drawer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeAsUpIndicator(R.drawable.ic_drawer);
actionBar.setDisplayHomeAsUpEnabled(true);
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
String deviceName = MainSettingsActivity.initializeDeviceName(this);
TextView nameView = (TextView) mDrawerLayout.findViewById(R.id.device_name);
nameView.setText(deviceName);
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
String deviceId = mMapMenuToDeviceId.get(menuItem);
onDeviceSelected(deviceId);
mDrawerLayout.closeDrawer(mNavigationView);
return true;
}
});
if (savedInstanceState != null) {
String savedDevice = savedInstanceState.getString(STATE_SELECTED_DEVICE);
onDeviceSelected(savedDevice);
}
}
@Override
public void onBackPressed() {
if (mDrawerLayout.isDrawerOpen(mNavigationView)) {
mDrawerLayout.closeDrawer(mNavigationView);
} else {
super.onBackPressed();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
mDrawerLayout.openDrawer(mNavigationView);
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
private void updateComputerList() {
BackgroundService.RunCommand(MaterialActivity.this, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(final BackgroundService service) {
Menu menu = mNavigationView.getMenu();
menu.clear();
mMapMenuToDeviceId.clear();
int id = 0;
Collection<Device> devices = service.getDevices().values();
for (Device device : devices) {
if (device.isReachable() && device.isPaired()) {
MenuItem item = menu.add(0,id++,0,device.getName());
item.setIcon(device.getIcon());
item.setCheckable(true);
mMapMenuToDeviceId.put(item, device.getDeviceId());
}
}
MenuItem item = menu.add(99, id++, 0, "Pair new device");
item.setIcon(R.drawable.ic_action_content_add_circle_outline);
item.setCheckable(true);
mMapMenuToDeviceId.put(item, null);
}
});
}
@Override
protected void onStart() {
super.onStart();
BackgroundService.RunCommand(MaterialActivity.this, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
service.onNetworkChange();
service.setDeviceListChangedCallback(new BackgroundService.DeviceListChangedCallback() {
@Override
public void onDeviceListChanged() {
updateComputerList();
}
});
}
});
}
@Override
protected void onStop() {
BackgroundService.RunCommand(MaterialActivity.this, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
service.setDeviceListChangedCallback(null);
}
});
super.onStop();
}
@Override
protected void onResume() {
super.onResume();
updateComputerList();
}
public void onDeviceSelected(String deviceId) {
mCurrentDevice = deviceId;
for(HashMap.Entry<MenuItem, String> entry : mMapMenuToDeviceId.entrySet()) {
boolean selected = TextUtils.equals(entry.getValue(), deviceId); //null-safe
entry.getKey().setChecked(selected);
}
Fragment fragment;
if (deviceId == null) {
fragment = new PairingFragment();
} else {
fragment = new DeviceFragment(deviceId);
}
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, fragment)
.commit();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(STATE_SELECTED_DEVICE, mCurrentDevice);
}
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String savedDevice = savedInstanceState.getString(STATE_SELECTED_DEVICE);
onDeviceSelected(savedDevice);
}
}

View File

@ -0,0 +1,397 @@
package org.kde.kdeconnect.NewUserInterface;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.app.Activity;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.ListView;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.Helpers.CheatSheet;
import org.kde.kdeconnect.NewUserInterface.List.MaterialDeviceItem;
import org.kde.kdeconnect.UserInterface.CustomDevicesActivity;
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
import org.kde.kdeconnect.UserInterface.List.SectionItem;
import org.kde.kdeconnect.UserInterface.MainSettingsActivity;
import org.kde.kdeconnect_tp.R;
import java.util.ArrayList;
import java.util.Collection;
public class NavigationDrawerFragment extends Fragment {
/**
* Callbacks interface that all activities using this fragment must implement.
*/
public interface NavigationDrawerCallbacks {
void onDeviceSelected(Device device);
}
private static final String STATE_SELECTED_DEVICE = "selected_device";
private NavigationDrawerCallbacks mCallbacks;
private NavigationDrawerCallbacks mDeviceCallback = new NavigationDrawerCallbacks() {
@Override
public void onDeviceSelected(Device device) {
selectDevice(device);
}
};
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private LinearLayout rootView;
private ListView mDrawerListView;
private View mFragmentContainerView;
private SharedPreferences preferences;
private Activity mActivity;
private String mCurrentSelectedDeviceId = null;
public NavigationDrawerFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivity = getActivity();
preferences = mActivity.getSharedPreferences(STATE_SELECTED_DEVICE, Context.MODE_PRIVATE);
if (savedInstanceState != null) {
mCurrentSelectedDeviceId = savedInstanceState.getString(STATE_SELECTED_DEVICE);
} else {
mCurrentSelectedDeviceId = preferences.getString(STATE_SELECTED_DEVICE, null);
}
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
Device lastSelected = mCurrentSelectedDeviceId != null? service.getDevice(mCurrentSelectedDeviceId) : null;
selectDevice(lastSelected);
}
});
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = (LinearLayout) inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
mDrawerListView = (ListView) rootView.findViewById(R.id.deviceList);
View v = rootView.findViewById(R.id.add_device_button);
/*v.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("AAAAAAAAAA", "AAA" + event);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
v.setBackgroundColor(getResources().getColor(R.color.accent));
} else {
v.setBackgroundColor(getResources().getColor(R.color.primary));
}
return true;
}
});*/
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectDevice(null);
}
});
View renameButton = rootView.findViewById(R.id.rename);
CheatSheet.setup(renameButton); //Show contentDescription as tooltip if long-pressed
return rootView;
}
public boolean isDrawerOpen() {
return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
}
/**
* Users of this fragment must call this method to set up the navigation drawer interactions.
*
* @param fragmentId The android:id of this fragment in its activity's layout.
* @param drawerLayout The DrawerLayout containing this fragment's UI.
*/
public void setUp(int fragmentId, DrawerLayout drawerLayout) {
mFragmentContainerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener
//ActionBar actionBar = getActionBar();
//actionBar.setDisplayHomeAsUpEnabled(true);
//actionBar.setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the navigation drawer and the action bar app icon.
/* mDrawerToggle = new ActionBarDrawerToggle(getActivity(), mDrawerLayout, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
if (!isAdded()) return;
getActivity().supportInvalidateOptionsMenu();
}
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if (!isAdded()) return;
getActivity().supportInvalidateOptionsMenu();
}
};
// Defer code dependent on restoration of previous instance state.
mDrawerLayout.post(new Runnable() {
@Override
public void run() {
mDrawerToggle.syncState();
}
});
mDrawerLayout.setDrawerListener(mDrawerToggle);
*/
}
private void selectDevice(Device device) {
if (mDrawerLayout != null) {
mDrawerLayout.closeDrawer(mFragmentContainerView);
}
if (mCallbacks != null) {
mCallbacks.onDeviceSelected(device);
}
if (device != null) {
mCurrentSelectedDeviceId = device.getDeviceId();
preferences.edit().putString(STATE_SELECTED_DEVICE, mCurrentSelectedDeviceId).apply();
/*
if (mDrawerListView != null) {
mDrawerListView.setItemChecked(0, true);
}
*/
}
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (NavigationDrawerCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
}
}
@Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(STATE_SELECTED_DEVICE, mCurrentSelectedDeviceId);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Needed for the drawer to work (see onOptionsItemSelected below)
setHasOptionsMenu(true);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Forward the new configuration the drawer toggle component.
mDrawerToggle.onConfigurationChanged(newConfig);
}
//private MenuItem menuProgress;
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// If the drawer is open, show the global app actions in the action bar. See also
// showGlobalContextActionBar, which controls the top-left area of the action bar.
/*if (isDrawerOpen()) {
inflater.inflate(R.menu.refresh, menu);
menuProgress = menu.findItem(R.id.menu_progress);
}*/
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
switch (item.getItemId()) {
/* case R.id.menu_refresh:
//updateComputerList();
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
service.onNetworkChange();
}
});
item.setVisible(false);
menuProgress.setVisible(true);
new Thread(new Runnable() {
@Override
public void run() {
try { Thread.sleep(1500); } catch (InterruptedException e) { }
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
menuProgress.setVisible(false);
item.setVisible(true);
}
});
}
}).start();
break;
*/
case R.id.menu_settings:
startActivity(new Intent(mActivity,MainSettingsActivity.class));
break;
case R.id.menu_custom_device_list:
startActivity(new Intent(mActivity, CustomDevicesActivity.class));
break;
default:
break;
}
return true;
}
void updateComputerList() {
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(final BackgroundService service) {
Collection<Device> devices = service.getDevices().values();
final ArrayList<ListAdapter.Item> items = new ArrayList<>();
SectionItem section;
Resources res = getResources();
// section = new SectionItem(res.getString(R.string.category_connected_devices));
// section.isSectionEmpty = true;
// items.add(section);
for (Device d : devices) {
if (d.isReachable() && d.isPaired()) {
items.add(new MaterialDeviceItem(mActivity, d, mDeviceCallback));
// section.isSectionEmpty = false;
}
}
/*
section = new SectionItem(res.getString(R.string.category_not_paired_devices));
section.isSectionEmpty = true;
items.add(section);
for (Device d : devices) {
if (d.isReachable() && !d.isPaired()) {
items.add(new MaterialDeviceItem(mActivity, d, mDeviceCallback));
section.isSectionEmpty = false;
}
}
*/
section = new SectionItem(res.getString(R.string.category_remembered_devices));
section.isSectionEmpty = true;
items.add(section);
for (Device d : devices) {
if (!d.isReachable() && d.isPaired()) {
items.add(new MaterialDeviceItem(mActivity, d, mDeviceCallback));
section.isSectionEmpty = false;
}
}
if (section.isSectionEmpty) {
items.remove(items.size() - 1); //Remove remembered devices section if empty
}
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mDrawerListView.setAdapter(new ListAdapter(mActivity, items));
mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
view.performClick();
}
});
}
});
}
});
}
@Override
public void onStart() {
super.onStart();
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
service.onNetworkChange();
service.setDeviceListChangedCallback(new BackgroundService.DeviceListChangedCallback() {
@Override
public void onDeviceListChanged() {
updateComputerList();
}
});
}
});
}
@Override
public void onStop() {
super.onStop();
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
service.setDeviceListChangedCallback(null);
}
});
}
@Override
public void onResume() {
super.onResume();
updateComputerList();
}
}

View File

@ -0,0 +1,171 @@
/*
* Copyright 2014 Albert Vaca Cintora <albertvaka@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.NewUserInterface;
import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NewUserInterface.List.PairingDeviceItem;
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
import org.kde.kdeconnect.UserInterface.List.SectionItem;
import org.kde.kdeconnect_tp.R;
import java.util.ArrayList;
import java.util.Collection;
/**
* The view that the user will see when there are no devices paired, or when you choose "add a new device" from the sidebar.
*/
public class PairingFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private View rootView;
private AppCompatActivity mActivity;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mActivity.getSupportActionBar().setTitle(R.string.pairing_title);
rootView = inflater.inflate(R.layout.activity_main, container, false);
TextView text = new TextView(inflater.getContext());
text.setText("Other devices running KDE Connect in your same network should appear here.");
((ListView)rootView).addHeaderView(text);
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = ((AppCompatActivity) getActivity());
}
void updateComputerList() {
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(final BackgroundService service) {
Collection<Device> devices = service.getDevices().values();
final ArrayList<ListAdapter.Item> items = new ArrayList<ListAdapter.Item>();
SectionItem section;
Resources res = getResources();
section = new SectionItem(res.getString(R.string.category_not_paired_devices));
section.isSectionEmpty = true;
items.add(section);
for (Device d : devices) {
if (d.isReachable() && !d.isPaired()) {
items.add(new PairingDeviceItem(mActivity, d));
section.isSectionEmpty = false;
}
}
section = new SectionItem(res.getString(R.string.category_connected_devices));
section.isSectionEmpty = true;
items.add(section);
for (Device d : devices) {
if (d.isReachable() && d.isPaired()) {
items.add(new PairingDeviceItem(mActivity, d));
section.isSectionEmpty = false;
}
}
if (section.isSectionEmpty) {
items.remove(items.size() - 1); //Remove connected devices section if empty
}
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
ListView list = (ListView) rootView.findViewById(R.id.listView1);
list.setAdapter(new ListAdapter(mActivity, items));
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
view.performClick();
}
});
}
});
}
});
}
@Override
public void onStart() {
super.onStart();
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
service.setDeviceListChangedCallback(new BackgroundService.DeviceListChangedCallback() {
@Override
public void onDeviceListChanged() {
updateComputerList();
}
});
service.onNetworkChange();
}
});
}
@Override
public void onStop() {
super.onStop();
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
service.setDeviceListChangedCallback(null);
}
});
}
@Override
public void onResume() {
super.onResume();
updateComputerList();
}
}

View File

@ -66,6 +66,21 @@ public class SharePlugin extends Plugin {
return context.getResources().getString(R.string.pref_plugin_sharereceiver_desc);
}
@Override
public boolean hasMainActivity() {
return true;
}
@Override
public String getActionName() {
return context.getString(R.string.send_files);
}
@Override
public void startMainActivity(Activity parentActivity) {
//TODO
}
@Override
public boolean hasSettings() {
return true;