在应用中集成搜索
上一节是关于如何添加应用设置和帮助,这一篇讲的是和设置类似的搜索。
So…… Let’s do it !
先从简单的页面布局开始,想想我们需要什么,一个带搜索事件的Button,还需要一些TextBlock来提示用户,核心部分自然是一个GridView咯。
<Grid Background="Wheat">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Vertical">
<Button Grid.Row="0" Name="btnSearch" VerticalAlignment="Center" HorizontalAlignment="Left"
Content="搜索" FontFamily="华文行楷" Click="btnSearch_Click" Margin="12" FontSize="34" Foreground="Red"/>
<StackPanel Orientation="Horizontal">
<TextBlock Text="搜索关键词" Foreground="Green" FontSize="28" Margin="12"/>
<TextBlock FontSize="28" Foreground="Green" Name="tBlockKeyword" Margin="12"/>
</StackPanel>
</StackPanel>
<GridView Grid.Row="1" Margin="12" x:Name="gridView">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontSize="24" Foreground="Pink" FontFamily="楷体"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
既然界面完成了,就该去后台捣鼓咯。搜索的核心在于SearchPane,所以先来实例化它。为了简化,我们就将待搜索的内容设置为一串字符串数组好了,当然了,初始化数组的方式大家随意就好了。
SearchPane searchPane = null;
string[] exampleStr = new string[100];
public void InitExampleStr()
{
Random ran = new Random();
int exNumber;
for(int i=0;i<100;i++)
{
exNumber = ran.Next(1000, 9999);
exampleStr[i] = exNumber.ToString();
}
}
当用户在搜索框中输入的内容发生了更改时就会触发searchPane_QueryChange事件。
当用户在完成输入后按下Enter键或者点击旁边的搜索确认按钮后就会触发searchPane_QuerySubmitted事件。
void searchPane_QueryChanged(SearchPane sender, SearchPaneQueryChangedEventArgs args)
{
this.tBlockKeyword.Text = args.QueryText;
}
void searchPane_QuerySubmitted(SearchPane sender, SearchPaneQuerySubmittedEventArgs args)
{
string key = args.QueryText;
var result = exampleStr.Where(s => s.Contains(key)).ToArray();
this.gridView.ItemsSource = result;
}
然后我们还需要这两个事件在OnNavigatedTo中绑定以及在OnNavigatedFrom中解绑。
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.searchPane.QuerySubmitted += searchPane_QuerySubmitted;
this.searchPane.QueryChanged += searchPane_QueryChanged;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
this.searchPane.QuerySubmitted -= searchPane_QuerySubmitted;
this.searchPane.QueryChanged -= searchPane_QueryChanged;
}
然后我们需要点击Button控件来调出系统的搜索框,一行代码就足以搞定了。如果不想点击按钮也是可以得哦,可以让用户直接在键盘输入而调出搜索框呢。
private void btnSearch_Click(object sender, RoutedEventArgs e)
{
this.searchPane.Show();
}
this.searchPane.ShowOnKeyboardInput = true;
最后别忘了将他们都放到MainPage()中哦,
public MainPage()
{
this.InitializeComponent();
searchPane = SearchPane.GetForCurrentView();
InitExampleStr();
this.searchPane.PlaceholderText = "请输入关键字";
this.searchPane.ShowOnKeyboardInput = true;
}
所以说,总的代码是这样的。
SearchPane searchPane = null;
string[] exampleStr = new string[100];
public MainPage()
{
this.InitializeComponent();
searchPane = SearchPane.GetForCurrentView();
InitExampleStr();
this.searchPane.PlaceholderText = "请输入关键字";
this.searchPane.ShowOnKeyboardInput = true;
}
public void InitExampleStr()
{
Random ran = new Random();
int exNumber;
for(int i=0;i<100;i++)
{
exNumber = ran.Next(1000, 9999);
exampleStr[i] = exNumber.ToString();
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.searchPane.QuerySubmitted += searchPane_QuerySubmitted;
this.searchPane.QueryChanged += searchPane_QueryChanged;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
this.searchPane.QuerySubmitted -= searchPane_QuerySubmitted;
this.searchPane.QueryChanged -= searchPane_QueryChanged;
}
void searchPane_QueryChanged(SearchPane sender, SearchPaneQueryChangedEventArgs args)
{
this.tBlockKeyword.Text = args.QueryText;
}
void searchPane_QuerySubmitted(SearchPane sender, SearchPaneQuerySubmittedEventArgs args)
{
string key = args.QueryText;
var result = exampleStr.Where(s => s.Contains(key)).ToArray();
this.gridView.ItemsSource = result;
}
private void btnSearch_Click(object sender, RoutedEventArgs e)
{
this.searchPane.Show();
}
}
在清单文件中声明你需要使用“Search”功能后就可以开始调试咯。
大家肯定都用的音乐播放器肯定都会在搜索框下面给出一些建议吧,或者大家常用的地图等App。
那么我们就对前面的代码进行更新就好啦。
下面这段代码呢,就是根据用户的输入来显示建议列表的方法咯。
void searchPane_SuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args)
{
var deferralSeg= args.Request.GetDeferral();
var q = from i in exampleStr
where i.Contains(args.QueryText)
select i;
var res = q.Take(suggestionLen).ToArray();
foreach (var item in res)
{
args.Request.SearchSuggestionCollection.AppendQuerySuggestion(item);
}
deferralSeg.Complete();
}
这篇博客,使用大量LINQ技术,如果不太懂的话可以看看这里。
【LINQ技术】扩展特性和LINQ操作符:http://blog.csdn.net/nomasp/article/details/45461517
使用搜索建议的最大好处在于我们可以选择并非自己输入的内容,这个功能就由下面这段代码提供动力支持。
void searchPane_ResultSuggestionChosen(SearchPane sender, SearchPaneResultSuggestionChosenEventArgs args)
{
sender.TrySetQueryText(args.Tag);
var q = from t in exampleStr
where t.Contains(args.Tag)
select t;
this.gridView.ItemsSource = q.ToArray();
}
我们还可以对前面的searchPane_QuerySubmitted函数做如下修改。
void searchPane_QuerySubmitted(SearchPane sender, SearchPaneQuerySubmittedEventArgs args)
{
//var q = from extStr in exampleStr
// where extStr.Contains(args.QueryText)
// select extStr;
//this.gridView.ItemsSource = q.ToArray();
string key = args.QueryText;
var result = exampleStr.Where(s => s.Contains(key)).ToArray();
this.gridView.ItemsSource = result;
}
最后还需要将他们添加到OnNavigatedTo和OnNavigatedFrom方法中。
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.searchPane.QuerySubmitted += searchPane_QuerySubmitted;
this.searchPane.QueryChanged += searchPane_QueryChanged;
this.searchPane.SuggestionsRequested += searchPane_SuggestionsRequested;
this.searchPane.ResultSuggestionChosen += searchPane_ResultSuggestionChosen;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
this.searchPane.QuerySubmitted -= searchPane_QuerySubmitted;
this.searchPane.QueryChanged -= searchPane_QueryChanged;
this.searchPane.SuggestionsRequested -= searchPane_SuggestionsRequested;
this.searchPane.ResultSuggestionChosen -= searchPane_ResultSuggestionChosen;
}
然后调试就会是这个效果咯。
使用粘贴板
记得智能手机刚出来那会比较火的一个概念“能够复制粘贴的手机就是智能手机”。现在看来,这不过是个老掉牙的功能了,但实际用处却是非常强大的,那么现在我们就来试试怎么做到这个功能。
粘贴板的英文名叫做Clipboard,这也是它的类名了。
新建工程这种就不说了,在XAML中代码如下:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid Margin="12" HorizontalAlignment="Left" VerticalAlignment="Top" Width="500" Height="500">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Name="btnClip" Margin="0,3,0,16" Content="粘贴" FontSize="32" Click="btnClip_Click" IsEnabled="False"/>
<ScrollViewer Name="scrollView" Grid.Row="1" Visibility="Collapsed">
<TextBlock Margin="12" Name="tBlockClipboard" FontSize="35" Foreground="Gainsboro" TextWrapping="Wrap" />
</ScrollViewer>
</Grid>
</Grid>
在后台代码中写上这么一个方法:
void Clipboard_ContentChanged(object sender, object e)
{
DataPackageView pv = Clipboard.GetContent();
if (pv.Contains(StandardDataFormats.Text))
{
btnClip.IsEnabled = true;
}
}
StandardDataFormats是标准数据格式,这里判断它是否是Text,如果是的话则让前面的Button按钮可用(之前设为不可用,以灰色显示)。
标准数据格式有Bitmap,HTML,RTF,StorageItems,Text,Uri等。
然后在按钮的Click事件中写如下代码:
private async void btnClip_Click(object sender, RoutedEventArgs e)
{
var txt = await Clipboard.GetContent().GetTextAsync();
tBlockClipboard.Text = txt;
}
这里我们使用了Clipboard类的GetContent()方法,用于在剪切板中取出DataPackageView对象数据;类似的还有SetContent(),用于把数据存入剪切板中。还有Clear事件来清空剪切板,Flush事件把数据从源写入到剪切板,并且在应用程序退出后依然保留在剪切板中。还有ContentChanged事件在剪切板中存储的数据内容发生变化时自动激活以达到监听剪切板内容变化的效果。
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Clipboard.ContentChanged += Clipboard_ContentChanged;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
Clipboard.ContentChanged -= Clipboard_ContentChanged;
}
void Clipboard_ContentChanged(object sender, object e)
{
DataPackageView pv = Clipboard.GetContent();
if (pv.Contains(StandardDataFormats.Text)||pv.Contains(StandardDataFormats.Bitmap))
{
btnClip.IsEnabled = true;
}
}
大家可以试试,已经完成了,但我们可以做的更多,不是吗?
完整的代码如下:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid Margin="12" HorizontalAlignment="Left" VerticalAlignment="Top" Width="500" Height="500">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Name="btnClip" Margin="0,3,0,16" Content="粘贴" FontSize="32" Click="btnClip_Click" IsEnabled="False"/>
<ScrollViewer Name="scrollView" Grid.Row="1" Visibility="Collapsed">
<TextBlock Margin="12" Name="tBlockClipboard" FontSize="35" Foreground="Gainsboro" TextWrapping="Wrap" />
</ScrollViewer>
<Image x:Name="imgClicpboard" Grid.Row="1" Margin="5" Stretch="Uniform" Visibility="Collapsed"/>
</Grid>
</Grid>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Clipboard.ContentChanged += Clipboard_ContentChanged;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
Clipboard.ContentChanged -= Clipboard_ContentChanged;
}
void Clipboard_ContentChanged(object sender, object e)
{
DataPackageView pv = Clipboard.GetContent();
if (pv.Contains(StandardDataFormats.Text)||pv.Contains(StandardDataFormats.Bitmap))
{
btnClip.IsEnabled = true;
}
}
private async void btnClip_Click(object sender, RoutedEventArgs e)
{
scrollView.Visibility = Visibility.Collapsed;
imgClicpboard.Visibility = Visibility.Collapsed;
tBlockClipboard.Text = " ";
imgClicpboard.Source = null;
DataPackageView pv = Clipboard.GetContent();
if (pv.Contains(StandardDataFormats.Text))
{
scrollView.Visibility = Visibility;
var txt = await Clipboard.GetContent().GetTextAsync();
tBlockClipboard.Text = txt;
}
else if(pv.Contains(StandardDataFormats.Bitmap))
{
imgClicpboard.Visibility = Visibility;
var bmp = await Clipboard.GetContent().GetBitmapAsync();
Windows.UI.Xaml.Media.Imaging.BitmapImage bitMap = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
bitMap.SetSource(await bmp.OpenReadAsync());
this.imgClicpboard.Source = bitMap;
}
}
}
现在它还可以复制图片了哦~
设置共享(共享源和共享目标)
上一节简单介绍了通过粘贴板来共享数据,这一节将会添加更为强大的功能哦。
以下就是大概的样式了,随便看看就好了,这都不是重点。
<Grid Background="AliceBlue">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition />
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" FontSize="25" Foreground="Red" Text="共享源示例" Margin="12"/>
<ScrollViewer Grid.Row="1" Margin="14" VerticalScrollMode="Auto" HorizontalScrollMode="Disabled">
<StackPanel>
<StackPanel Orientation="Horizontal">
<RadioButton x:Name="radioBtnText" Foreground="Aqua" FontWeight="Bold" FontSize="22" Content="共享文本" Checked="OnChecked" GroupName="g" Tag="text"/>
<RadioButton x:Name="radioBtnImg" Foreground="Aqua" FontWeight="Bold" FontSize="22" Content="共享图像" Margin="12,0,0,0" Checked="OnChecked" GroupName="g" Tag="image"/>
<RadioButton x:Name="radioBtnFile" Foreground="Aqua" FontWeight="Bold" FontSize="22" Content="共享文件" Margin="12,0,0,0" Checked="OnChecked" GroupName="g" Tag="file"/>
</StackPanel>
<StackPanel Name="stackPText" Visibility="Collapsed" Margin="8">
<TextBlock Text="共享文本" FontSize="25"/>
<TextBlock Foreground="Gold" FontSize="25" Text="输入要共享的内容" />
<TextBox x:Name="tBlockText" Foreground="Gold" />
</StackPanel>
<StackPanel Name="stackPImg" Visibility="Collapsed" Margin="8">
<TextBlock Text="共享图像" FontSize="25"/>
<TextBlock Foreground="Gold" FontSize="25" Text="共享以下图片"/>
<Image Width="600" Height="400" Stretch="UniformToFill" HorizontalAlignment="Left"
Margin="1,5,0,5" Source="Assets/SpaceNeedle1.jpg"/>
</StackPanel>
<StackPanel Name="stackPFile" Visibility="Collapsed" Margin="8">
<TextBlock Text="共享文件" FontSize="28"/>
<TextBlock Foreground="Gold" FontSize="25" Text="选择要共享的文件"/>
<StackPanel>
<Button Content="选择文件" Click="OnPickFile"/>
<TextBlock x:Name="tBlockFile" Foreground="Gold" FontSize="24"/>
</StackPanel>
</StackPanel>
</StackPanel>
</ScrollViewer>
<Button Grid.Row="2" Name="btnShare" Margin="12" Content="确定共享" FontSize="35" FontFamily="隶书" Foreground="Azure" Background="Black" Click="btnShare_Click"/>
</Grid>
这里通过3个StackPanel的“显示“与”隐藏“来达到在一个位置显示3个界面的功能,然后在后台通过以下方法更改Visibility属性。
private void OnChecked(object sender, RoutedEventArgs e)
{
RadioButton rbtn = sender as RadioButton;
if (rbtn != null)
{
string tag = rbtn.Tag.ToString();
switch (tag)
{
case "text":
this.stackPText.Visibility = Windows.UI.Xaml.Visibility.Visible;
this.stackPImg.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
this.stackPFile.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
break;
case "image":
this.stackPText.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
this.stackPImg.Visibility = Windows.UI.Xaml.Visibility.Visible;
this.stackPFile.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
break;
case "file":
this.stackPText.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
this.stackPImg.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
this.stackPFile.Visibility = Windows.UI.Xaml.Visibility.Visible;
break;
default:
this.stackPText.Visibility = Windows.UI.Xaml.Visibility.Visible;
this.stackPImg.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
this.stackPFile.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
break;
}
}
}
以下是核心代码,通过RadioButton的选择来共享不同的内容。这里没有进行try、catch异常检测,但在实际工程中则是必要的,因为如果你不共享任何内容而点击共享按钮你就知道了……
void MainPage_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
var deferral = args.Request.GetDeferral();
if (radioBtnText.IsChecked == true)
{
args.Request.Data.Properties.Title = "共享文本";
args.Request.Data.Properties.Description = "共享你输入的文本数据。";
args.Request.Data.SetText(this.tBlockText.Text);
}
else if (radioBtnImg.IsChecked == true)
{
args.Request.Data.Properties.Title = "共享图像";
args.Request.Data.Properties.Description = "共享以下图片。";
args.Request.Data.SetBitmap(Windows.Storage.Streams.RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/SpaceNeedle1.jpg")));
}
else if (radioBtnFile.IsChecked == true)
{
args.Request.Data.Properties.Title = "共享文件";
args.Request.Data.Properties.Description = "共享你选择的文件。";
var file = this.tBlockFile.Tag as Windows.Storage.StorageFile;
List<IStorageItem> files = new List<IStorageItem>();
files.Add(file);
args.Request.Data.SetStorageItems(files);
}
deferral.Complete();
}
选择文件的方法我们在前面也都介绍过了,直接贴代码……
private async void OnPickFile(object sender, RoutedEventArgs e)
{
Windows.Storage.Pickers.FileOpenPicker picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.FileTypeFilter.Add(".mp3");
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".png");
picker.FileTypeFilter.Add(".docx");
picker.FileTypeFilter.Add(".pptx");
picker.FileTypeFilter.Add(".txt");
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
this.tBlockFile.Text = file.Path;
this.tBlockFile.Tag = file;
}
}
当然了,记得下面这些操作……
protected override void OnNavigatedTo(NavigationEventArgs e)
{
DataTransferManager.GetForCurrentView().DataRequested += MainPage_DataRequested;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
DataTransferManager.GetForCurrentView().DataRequested -= MainPage_DataRequested;
}
最后就是共享确认按钮了,一行代码搞定。
private void btnShare_Click(object sender, RoutedEventArgs e)
{
DataTransferManager.ShowShareUI();
}
以上这个App,你将需要共享的数据从这里发出,也叫共享源,但共享到哪里了呢?
看到”共享图像“和”共享以下图片“想起来刚才的两行代码了么?这两个属性就用在了这里。
args.Request.Data.Properties.Title = "共享文本";
args.Request.Data.Properties.Description = "共享你输入的文本数据。";
我们当然可以将数据共享到邮件、OneNote里,但如果你是要写一个自己的接收共享数据的应用呢,如何来写?
接下来就来写另一个App咯,也就是上图中的App49了。首先在清单文件中做如下操作,当然了,具体要添加哪些东西大家自己看着办就好了。
然后添加一个XAML页面来接收数据,因为你不可能只让你的APP专门用来接收数据咯,所以就不建议在MainPage中写了。
在新页面中大概做一下页面布局,我的布局通常来说都不是很美观的……
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<Grid x:Name="gridText" Margin="24" Visibility="Collapsed" Grid.Row="0">
<StackPanel>
<TextBlock FontSize="25" Foreground="Red" Text="接收到的文本:"/>
<TextBlock FontSize="30" Foreground="Pink" FontWeight="Bold" x:Name="tbText" Margin="8"/>
</StackPanel>
</Grid>
<Grid x:Name="gridImg" Margin="25" Visibility="Collapsed" Grid.Row="0">
<StackPanel>
<TextBlock FontSize="25" Foreground="Red" Text="接收到的图像:"/>
<Image x:Name="img" Margin="12" Width="500" Height="400" HorizontalAlignment="Left" Stretch="Uniform"/>
</StackPanel>
</Grid>
<Grid x:Name="gridStorageItems" Margin="25" Visibility="Collapsed" Grid.Row="0">
<StackPanel>
<TextBlock FontSize="25" Foreground="Red" Text="接收到的文件:"/>
<TextBlock FontSize="30" Margin="12" x:Name="tbStorageItem"/>
</StackPanel>
</Grid>
<Button Grid.Row="1" HorizontalAlignment="Center" Margin="0,15,0,20"
Content="完成共享" FontSize="28" Width="200" Click="btnCompleteShare_Click"/>
</Grid>
后台代码中写以下代码,核心在于if中的3个判断,就是3中共享的文件了咯。
public sealed partial class ShareTargetPage : Page
{
ShareOperation shareOperation = null;
public ShareTargetPage()
{
this.InitializeComponent();
}
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
ShareOperation sp = e.Parameter as ShareOperation;
if (sp != null)
{
this.shareOperation = sp;
DataPackageView pack = sp.Data;
if (pack.Contains(StandardDataFormats.Text))
{
string s = await pack.GetTextAsync();
this.tbText.Text = s;
this.gridText.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
else if (pack.Contains(StandardDataFormats.Bitmap))
{
var stream = await pack.GetBitmapAsync();
BitmapImage bmp = new BitmapImage();
bmp.SetSource(await stream.OpenReadAsync());
this.img.Source = bmp;
this.gridImg.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
else if (pack.Contains(StandardDataFormats.StorageItems))
{
var storageItems = await pack.GetStorageItemsAsync();
StorageFile file = storageItems[0] as StorageFile;
this.tbStorageItem.Text = file.Name;
this.gridStorageItems.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
}
}
private void btnCompleteShare_Click(object sender, RoutedEventArgs e)
{
this.shareOperation.ReportCompleted();
}
}
接着我们就要来调试这两个程序啦。只需要将接受共享数据的App按F5运行后关掉就好了,因为它会部署到本地的,或者也可以在Build选项卡中直接部署也是一样的。然后按F5运行共享数据的数据源App就好啦。
截图如下:
这张图片我压缩过了,不如太大上传不了,所以可能看不清楚吧。下面是共享文本数据的过程截图啦。
这个是共享图像的截图,忘了说了,在前面的SpaceNeedle1.jpg就是下面这张图片我已经事先添加到工程里了的。
紧接着我们共享这个docx文件,却发现在共享栏里没有了App49,发生了什么?
下面这首刚才添加的受支持的文件类型,明显没有添加.docx,所以这也是一个需要注意的地方。
这样我们的APP就具备了共享数据的本领了,下一篇我们再看看如何使用Toast通知和利用开始菜单的图标来显示一些应用信息。